common/marshaller.c | 12 ++++++------ gtk/Makefile.am | 4 ++-- gtk/channel-display-mjpeg.c | 31 +++++++++++++++++++------------ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/common/marshaller.c b/common/marshaller.c index 97c65af..8bf3427 100644 --- a/common/marshaller.c +++ b/common/marshaller.c @@ -27,12 +27,12 @@ #ifdef WORDS_BIGENDIAN #define write_int8(ptr,v) (*((int8_t *)(ptr)) = v) #define write_uint8(ptr,v) (*((uint8_t *)(ptr)) = v) -#define write_int16(ptr,v) (*((int16_t)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v))) -#define write_uint16(ptr,v) (*((uint16_t)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v))) -#define write_int32(ptr,v) (*((int32_t)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v))) -#define write_uint32(ptr,v) (*((uint32_t)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v))) -#define write_int64(ptr,v) (*((int64_t)(ptr)) = SPICE_BYTESWAP64((uint63_t)(v))) -#define write_uint64(ptr,v) (*((uint64_t)(ptr)) = SPICE_BYTESWAP64((uint63_t)(v))) +#define write_int16(ptr,v) (*((int16_t *)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v))) +#define write_uint16(ptr,v) (*((uint16_t *)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v))) +#define write_int32(ptr,v) (*((int32_t *)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v))) +#define write_uint32(ptr,v) (*((uint32_t *)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v))) +#define write_int64(ptr,v) (*((int64_t *)(ptr)) = SPICE_BYTESWAP64((uint64_t)(v))) +#define write_uint64(ptr,v) (*((uint64_t *)(ptr)) = SPICE_BYTESWAP64((uint64_t)(v))) #else #define write_int8(ptr,v) (*((int8_t *)(ptr)) = v) #define write_uint8(ptr,v) (*((uint8_t *)(ptr)) = v) diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 1a9cf27..edec166 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -75,7 +75,7 @@ AM_CPPFLAGS = \ # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html SPICE_GTK_LDFLAGS_COMMON = \ - -version-number 1:2:0 \ + -version-info 1:2:0 \ -no-undefined \ $(VERSION_LDFLAGS) \ $(NULL) @@ -127,7 +127,7 @@ libspice_client_gtkinclude_HEADERS = \ $(NULL) libspice_client_glib_2_0_la_LDFLAGS = \ - -version-number 4:0:3 \ + -version-info 4:0:3 \ -no-undefined \ $(VERSION_LDFLAGS) \ $(NULL) diff --git a/gtk/channel-display-mjpeg.c b/gtk/channel-display-mjpeg.c index b9ff108..cb1bc87 100644 --- a/gtk/channel-display-mjpeg.c +++ b/gtk/channel-display-mjpeg.c @@ -69,7 +69,6 @@ void stream_mjpeg_data(display_stream *st) int height = info->stream_height; uint8_t *dest; uint8_t *lines[4]; - int i, j; dest = malloc(width * height * 4); @@ -95,10 +94,19 @@ void stream_mjpeg_data(display_stream *st) #endif // TODO: in theory should check cinfo.output_height match with our height jpeg_start_decompress(&st->mjpeg_cinfo); - for (i = 0; i < height; ) { - // according to header - g_return_if_fail(st->mjpeg_cinfo.rec_outbuf_height <= 4); - for (j = 0; j < st->mjpeg_cinfo.rec_outbuf_height; j++) { + /* rec_outbuf_height is the recommended size of the output buffer we + * pass to libjpeg for optimum performance + */ + if (st->mjpeg_cinfo.rec_outbuf_height > G_N_ELEMENTS(lines)) { + jpeg_abort_decompress(&st->mjpeg_cinfo); + g_return_if_reached(); + } + + while (st->mjpeg_cinfo.output_scanline < st->mjpeg_cinfo.output_height) { + /* only used when JCS_EXTENSIONS is undefined */ + G_GNUC_UNUSED unsigned int lines_read; + + for (unsigned int j = 0; j < st->mjpeg_cinfo.rec_outbuf_height; j++) { lines[j] = dest; #ifdef JCS_EXTENSIONS dest += 4 * width; @@ -106,16 +114,14 @@ void stream_mjpeg_data(display_stream *st) dest += 3 * width; #endif } - j = jpeg_read_scanlines(&st->mjpeg_cinfo, lines, + lines_read = jpeg_read_scanlines(&st->mjpeg_cinfo, lines, st->mjpeg_cinfo.rec_outbuf_height); - // this shouldn't happen either.. - g_return_if_fail(j == st->mjpeg_cinfo.rec_outbuf_height); #ifndef JCS_EXTENSIONS { uint8_t *s = lines[0]; - uint32_t *d = (uint32_t *)&st->out_frame[i * width * 4]; + uint32_t *d = (uint32_t *)s; - for (j = j * width; j > 0; ) { + for (unsigned int j = lines_read * width; j > 0; ) { j -= 1; // reverse order, bad for cache? d[j] = s[j * 3 + 0] << 16 | s[j * 3 + 1] << 8 | @@ -123,8 +129,7 @@ void stream_mjpeg_data(display_stream *st) } } #endif - i += st->mjpeg_cinfo.rec_outbuf_height; - dest = &st->out_frame[i * width * 4]; + dest = &st->out_frame[st->mjpeg_cinfo.output_scanline * width * 4]; } jpeg_finish_decompress(&st->mjpeg_cinfo); } @@ -133,4 +138,6 @@ G_GNUC_INTERNAL void stream_mjpeg_cleanup(display_stream *st) { jpeg_destroy_decompress(&st->mjpeg_cinfo); + free(st->out_frame); + st->out_frame = NULL; }