From 3e4aec6e7b675c80e5a9bc4aaf885f0decc7251d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 8 May 2013 15:50:34 +0200 Subject: [PATCH] video: Make sure to push pre-caps events before the caps event https://bugzilla.gnome.org/show_bug.cgi?id=699894 --- gst-libs/gst/video/gstvideodecoder.c | 28 +++++++++++++++++++++++++++- gst-libs/gst/video/gstvideoencoder.c | 28 +++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c index 21935560ed..0c7055a063 100644 --- a/gst-libs/gst/video/gstvideodecoder.c +++ b/gst-libs/gst/video/gstvideodecoder.c @@ -2973,6 +2973,7 @@ gst_video_decoder_negotiate_default (GstVideoDecoder * decoder) GstAllocator *allocator; GstAllocationParams params; gboolean ret = TRUE; + GstVideoCodecFrame *frame; g_return_val_if_fail (GST_VIDEO_INFO_WIDTH (&state->info) != 0, FALSE); g_return_val_if_fail (GST_VIDEO_INFO_HEIGHT (&state->info) != 0, FALSE); @@ -2988,7 +2989,32 @@ gst_video_decoder_negotiate_default (GstVideoDecoder * decoder) GST_DEBUG_OBJECT (decoder, "setting caps %" GST_PTR_FORMAT, state->caps); - ret = gst_pad_set_caps (decoder->srcpad, state->caps); + /* Push all pending pre-caps events of the oldest frame before + * setting caps */ + frame = decoder->priv->frames ? decoder->priv->frames->data : NULL; + if (frame && frame->events) { + GList *l; + gboolean set_caps = FALSE; + + ret = FALSE; + for (l = g_list_last (frame->events); l; l = l->prev) { + GstEvent *event = GST_EVENT (l->data); + + if (GST_EVENT_TYPE (event) > GST_EVENT_CAPS && !set_caps) { + ret = gst_pad_set_caps (decoder->srcpad, state->caps); + set_caps = TRUE; + } + gst_video_decoder_push_event (decoder, event); + } + g_list_free (frame->events); + frame->events = NULL; + if (!set_caps) { + ret = gst_pad_set_caps (decoder->srcpad, state->caps); + } + } else { + ret = gst_pad_set_caps (decoder->srcpad, state->caps); + } + if (!ret) goto done; decoder->priv->output_state_changed = FALSE; diff --git a/gst-libs/gst/video/gstvideoencoder.c b/gst-libs/gst/video/gstvideoencoder.c index 46ecd7fbbd..fc2b3dcb27 100644 --- a/gst-libs/gst/video/gstvideoencoder.c +++ b/gst-libs/gst/video/gstvideoencoder.c @@ -1451,6 +1451,7 @@ gst_video_encoder_negotiate_default (GstVideoEncoder * encoder) GstVideoCodecState *state = encoder->priv->output_state; GstVideoInfo *info = &state->info; GstQuery *query = NULL; + GstVideoCodecFrame *frame; g_return_val_if_fail (state->caps != NULL, FALSE); @@ -1477,7 +1478,32 @@ gst_video_encoder_negotiate_default (GstVideoEncoder * encoder) encoder->priv->output_state_changed = FALSE; } - ret = gst_pad_set_caps (encoder->srcpad, state->caps); + /* Push all pending pre-caps events of the oldest frame before + * setting caps */ + frame = encoder->priv->frames ? encoder->priv->frames->data : NULL; + if (frame && frame->events) { + GList *l; + gboolean set_caps = FALSE; + + ret = FALSE; + for (l = g_list_last (frame->events); l; l = l->prev) { + GstEvent *event = GST_EVENT (l->data); + + if (GST_EVENT_TYPE (event) > GST_EVENT_CAPS && !set_caps) { + ret = gst_pad_set_caps (encoder->srcpad, state->caps); + set_caps = TRUE; + } + gst_video_encoder_push_event (encoder, event); + } + g_list_free (frame->events); + frame->events = NULL; + if (!set_caps) { + ret = gst_pad_set_caps (encoder->srcpad, state->caps); + } + } else { + ret = gst_pad_set_caps (encoder->srcpad, state->caps); + } + if (!ret) goto done;