The dimensions sent by the remote end are redundant and should not be trusted. Signed-off-by: Francois Gouget <fgouget@xxxxxxxxxxxxxxx> --- src/channel-display-gst.c | 41 +++++++++++++++++++++++++++++++++-------- src/channel-display-mjpeg.c | 11 ++++++----- src/channel-display-priv.h | 3 +-- src/channel-display.c | 24 +----------------------- 4 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c index ca6b6e7..c752639 100644 --- a/src/channel-display-gst.c +++ b/src/channel-display-gst.c @@ -87,26 +87,51 @@ static void schedule_frame(SpiceGstDecoder *decoder); static gboolean display_frame(gpointer video_decoder) { SpiceGstDecoder *decoder = (SpiceGstDecoder*)video_decoder; + SpiceFrame *frame; + GstCaps *caps; + gint width, height; + GstStructure *s; + GstBuffer *buffer; + GstMapInfo mapinfo; decoder->timer_id = 0; g_mutex_lock(&decoder->queues_mutex); - SpiceFrame *frame = g_queue_pop_head(decoder->display_queue); + frame = g_queue_pop_head(decoder->display_queue); g_mutex_unlock(&decoder->queues_mutex); + /* If the queue is empty we don't even need to reschedule */ g_return_val_if_fail(frame, G_SOURCE_REMOVE); - GstBuffer *buffer = frame->sample ? gst_sample_get_buffer(frame->sample) : NULL; - GstMapInfo mapinfo; if (!frame->sample) { spice_warning("got a frame without a sample!"); - } else if (gst_buffer_map(buffer, &mapinfo, GST_MAP_READ)) { - stream_display_frame(decoder->base.stream, frame->msg, mapinfo.data); - gst_buffer_unmap(buffer, &mapinfo); - } else { + goto error; + } + + caps = gst_sample_get_caps(frame->sample); + if (!caps) { + spice_warning("GStreamer error: could not get the caps of the sample"); + goto error; + } + + s = gst_caps_get_structure(caps, 0); + if (!gst_structure_get_int(s, "width", &width) || + !gst_structure_get_int(s, "height", &height)) { + spice_warning("GStreamer error: could not get the size of the frame"); + goto error; + } + + buffer = gst_sample_get_buffer(frame->sample); + if (!gst_buffer_map(buffer, &mapinfo, GST_MAP_READ)) { spice_warning("GStreamer error: could not map the buffer"); + goto error; } - free_frame(frame); + stream_display_frame(decoder->base.stream, frame->msg, + width, height, mapinfo.data); + gst_buffer_unmap(buffer, &mapinfo); + + error: + free_frame(frame); schedule_frame(decoder); return G_SOURCE_REMOVE; } diff --git a/src/channel-display-mjpeg.c b/src/channel-display-mjpeg.c index a2dae82..4976d53 100644 --- a/src/channel-display-mjpeg.c +++ b/src/channel-display-mjpeg.c @@ -86,12 +86,13 @@ static gboolean mjpeg_decoder_decode_frame(gpointer video_decoder) { MJpegDecoder *decoder = (MJpegDecoder*)video_decoder; gboolean back_compat = decoder->base.stream->channel->priv->peer_hdr.major_version == 1; - int width; - int height; + JDIMENSION width, height; uint8_t *dest; uint8_t *lines[4]; - stream_get_dimensions(decoder->base.stream, decoder->cur_frame_msg, &width, &height); + jpeg_read_header(&decoder->mjpeg_cinfo, 1); + width = decoder->mjpeg_cinfo.image_width; + height = decoder->mjpeg_cinfo.image_height; if (decoder->out_size < width * height * 4) { g_free(decoder->out_frame); decoder->out_size = width * height * 4; @@ -99,7 +100,6 @@ static gboolean mjpeg_decoder_decode_frame(gpointer video_decoder) } dest = decoder->out_frame; - jpeg_read_header(&decoder->mjpeg_cinfo, 1); #ifdef JCS_EXTENSIONS // requires jpeg-turbo if (back_compat) @@ -168,7 +168,8 @@ static gboolean mjpeg_decoder_decode_frame(gpointer video_decoder) jpeg_finish_decompress(&decoder->mjpeg_cinfo); /* Display the frame and dispose of it */ - stream_display_frame(decoder->base.stream, decoder->cur_frame_msg, decoder->out_frame); + stream_display_frame(decoder->base.stream, decoder->cur_frame_msg, + width, height, decoder->out_frame); spice_msg_in_unref(decoder->cur_frame_msg); decoder->cur_frame_msg = NULL; decoder->timer_id = 0; diff --git a/src/channel-display-priv.h b/src/channel-display-priv.h index 3155015..3fcf2e2 100644 --- a/src/channel-display-priv.h +++ b/src/channel-display-priv.h @@ -135,10 +135,9 @@ struct display_stream { uint32_t report_drops_seq_len; }; -void stream_get_dimensions(display_stream *st, SpiceMsgIn *frame_msg, int *width, int *height); guint32 stream_get_time(display_stream *st); void stream_dropped_frame_on_playback(display_stream *st); -void stream_display_frame(display_stream *st, SpiceMsgIn *frame_msg, uint8_t* data); +void stream_display_frame(display_stream *st, SpiceMsgIn *frame_msg, uint32_t width, uint32_t height, uint8_t *data); uint32_t spice_msg_in_frame_data(SpiceMsgIn *frame_msg, uint8_t **data); diff --git a/src/channel-display.c b/src/channel-display.c index 54bc30e..22e64e2 100644 --- a/src/channel-display.c +++ b/src/channel-display.c @@ -1174,26 +1174,6 @@ uint32_t spice_msg_in_frame_data(SpiceMsgIn *frame_msg, uint8_t **data) } G_GNUC_INTERNAL -void stream_get_dimensions(display_stream *st, SpiceMsgIn *frame_msg, int *width, int *height) -{ - g_return_if_fail(width != NULL); - g_return_if_fail(height != NULL); - - if (frame_msg == NULL || - spice_msg_in_type(frame_msg) != SPICE_MSG_DISPLAY_STREAM_DATA_SIZED) { - SpiceMsgDisplayStreamCreate *info = spice_msg_in_parsed(st->msg_create); - - *width = info->stream_width; - *height = info->stream_height; - } else { - SpiceMsgDisplayStreamDataSized *op = spice_msg_in_parsed(frame_msg); - - *width = op->width; - *height = op->height; - } -} - -G_GNUC_INTERNAL guint32 stream_get_time(display_stream *st) { SpiceSession *session = spice_channel_get_session(st->channel); @@ -1210,13 +1190,11 @@ void stream_dropped_frame_on_playback(display_stream *st) /* main context */ G_GNUC_INTERNAL void stream_display_frame(display_stream *st, SpiceMsgIn *frame_msg, - uint8_t* data) + uint32_t width, uint32_t height, uint8_t *data) { - int width, height; const SpiceRect *dest; int stride; - stream_get_dimensions(st, frame_msg, &width, &height); dest = stream_get_dest(st, frame_msg); stride = width * sizeof(uint32_t); -- 2.8.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel