On Fri, 2016-06-03 at 15:02 +0200, Francois Gouget wrote: > The dimensions sent by the remote end are redundant and should not be > trusted. > > Signed-off-by: Francois Gouget <fgouget@xxxxxxxxxxxxxxx> Acked-by: Pavel Grunt <pgrunt@xxxxxxxxxx> Thanks, Pavel > --- > 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); _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel