[Spice-devel] [PATCH spice-gtk 2/3] channel-display-gst: factor out get_decoded_frame

Victor Toso victortoso at redhat.com
Wed Jan 23 13:04:56 UTC 2019


Hi,

On Wed, Jan 23, 2019 at 12:08:53AM +0000, Frediano Ziglio wrote:
> Separate the code from fetch_pending_sample that extracts the
> SpiceGstFrame relative to a give GstBuffer.
> This new function will be reused later.
> 
> Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> ---
>  src/channel-display-gst.c | 84 ++++++++++++++++++++++++---------------
>  1 file changed, 53 insertions(+), 31 deletions(-)
> 
> diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
> index 1ad06f15..08c9f8fb 100644
> --- a/src/channel-display-gst.c
> +++ b/src/channel-display-gst.c
> @@ -107,6 +107,7 @@ static void free_gst_frame(SpiceGstFrame *gstframe)
>  
>  static void schedule_frame(SpiceGstDecoder *decoder);
>  static void fetch_pending_sample(SpiceGstDecoder *decoder);
> +static SpiceGstFrame *get_decoded_frame(SpiceGstDecoder *decoder, GstBuffer *buffer);
>  
>  static int spice_gst_buffer_get_stride(GstBuffer *buffer)
>  {
> @@ -204,6 +205,52 @@ static void schedule_frame(SpiceGstDecoder *decoder)
>      g_mutex_unlock(&decoder->queues_mutex);
>  }
>  
> +/* Get the decoded frame relative to buffer or NULL if not found.
> + * Dequeue the frame from decoding_queue and return it, caller
> + * is responsible to free the pointer.
> + * queues_mutex must be held.
> + */
> +static SpiceGstFrame *get_decoded_frame(SpiceGstDecoder *decoder, GstBuffer *buffer)
> +{
> +    guint num_frames_dropped = 0;
> +
> +    /* Gstreamer sometimes returns the same buffer twice
> +     * or buffers that have a modified, and thus unrecognizable, PTS.
> +     * Blindly removing frames from the decoding_queue until we find a
> +     * match would only empty the queue, resulting in later buffers not
> +     * finding a match either, etc. So check the buffer has a matching
> +     * frame first.
> +     */
> +    SpiceGstFrame *gstframe = NULL;
> +    GList *l = g_queue_peek_head_link(decoder->decoding_queue);

(1) 
I'm a bit confused. Here, g_queue_peek_head_link() gives the
pointer to the head, without removing it from the queue.

> +    while (l) {
> +        gstframe = l->data;
> +        if (gstframe->timestamp == GST_BUFFER_PTS(buffer)) {

(2)
Here we check if payload of the queue. If yes, then

> +            /* Now that we know there is a match, remove it and the older
> +             * frames from the decoding queue.
> +             */
> +            while ((gstframe = g_queue_pop_head(decoder->decoding_queue))) {

It gets the same pointer, because still is the head as it was not
popped above on (1).

> +                if (gstframe->timestamp == GST_BUFFER_PTS(buffer)) {
> +                    break;

It should reach this break for the same reason we are in this
code path due check on (2)

> +                }
> +                /* The GStreamer pipeline dropped the corresponding
> +                 * buffer.
> +                 */
> +                num_frames_dropped++;
> +                free_gst_frame(gstframe);
> +            }
> +            break;

Considering that gstframe might have changed after entering in
(2), we are breaking the while (l) loop with dangling pointer and
returning that.

> +        }
> +        gstframe = NULL;
> +        l = l->next;
> +    }
> +    if (num_frames_dropped != 0) {
> +        SPICE_DEBUG("the GStreamer pipeline dropped %u frames", num_frames_dropped);
> +    }
> +    return gstframe;
> +}
> +
>  static void fetch_pending_sample(SpiceGstDecoder *decoder)
>  {
>      GstSample *sample = gst_app_sink_pull_sample(decoder->appsink);
> @@ -212,7 +259,6 @@ static void fetch_pending_sample(SpiceGstDecoder *decoder)
>          decoder->pending_samples--;
>  
>          GstBuffer *buffer = gst_sample_get_buffer(sample);
> -        guint num_frames_dropped = 0;
>  
>          /* gst_app_sink_pull_sample() sometimes returns the same buffer twice
>           * or buffers that have a modified, and thus unrecognizable, PTS.
> @@ -221,36 +267,12 @@ static void fetch_pending_sample(SpiceGstDecoder *decoder)
>           * finding a match either, etc. So check the buffer has a matching
>           * frame first.
>           */
> -        SpiceGstFrame *gstframe;
> -        GList *l = g_queue_peek_head_link(decoder->decoding_queue);

You did not introduced what I consider to be my confusion (as this
code seems to be working fine).

> -        while (l) {
> -            gstframe = l->data;
> -            if (gstframe->timestamp == GST_BUFFER_PTS(buffer)) {
> -                /* The frame is now ready for display */
> -                gstframe->decoded_sample = sample;
> -                decoder->display_frame = gstframe;
> -
> -                /* Now that we know there is a match, remove it and the older
> -                 * frames from the decoding queue.
> -                 */
> -                while ((gstframe = g_queue_pop_head(decoder->decoding_queue))) {
> -                    if (gstframe->timestamp == GST_BUFFER_PTS(buffer)) {
> -                        break;
> -                    }

Same

> -                    /* The GStreamer pipeline dropped the corresponding
> -                     * buffer.
> -                     */
> -                    num_frames_dropped++;
> -                    free_gst_frame(gstframe);
> -                }
> -                break;
> -            }
> -            l = l->next;
> -        }
> -        if (num_frames_dropped != 0) {
> -            SPICE_DEBUG("the GStreamer pipeline dropped %u frames", num_frames_dropped);
> -        }
> -        if (!l) {
> +        SpiceGstFrame *gstframe = get_decoded_frame(decoder, buffer);
> +        if (gstframe) {
> +            /* The frame is now ready for display */
> +            gstframe->decoded_sample = sample;
> +            decoder->display_frame = gstframe;
> +        } else {

Cheers,
Victor
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/spice-devel/attachments/20190123/0360a21d/attachment.sig>


More information about the Spice-devel mailing list