From fe4e9bb02cc859715eaac37ca4ee02e3b9e4f76e Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Wed, 4 May 2016 11:33:50 +1000 Subject: [PATCH] decodebin: an element can negotiate before we block it When we initialize an element in decodebin, we 1) set it to PAUSED and push sticky events on its sinkpad to trigger negotiation 2) block its src pad(s) to detect CAPS events. We can't block before 1) as that would lead to a deadlock. It's possible (and common) tho that an element configures its srcpad during 1) and before 2). Therefore before this change we would typically block and expose an element's pad only once the element output its first buffer, triggering sticky events to be resent. One consequence of this behaviour is that it sometimes broke renegotiation. With this change now we consider a pad ready to be exposed when it's ->blocked or has fixed caps (which were set before we could block it). https://bugzilla.gnome.org/show_bug.cgi?id=765456 --- gst/playback/gstdecodebin2.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index ed67426..d1a7afc 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -553,6 +553,7 @@ static void gst_decode_pad_unblock (GstDecodePad * dpad); static void gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked); static gboolean gst_decode_pad_query (GstPad * pad, GstObject * parent, GstQuery * query); +static gboolean gst_decode_pad_is_exposable (GstDecodePad * endpad); static void gst_pending_pad_free (GstPendingPad * ppad); static GstPadProbeReturn pad_event_cb (GstPad * pad, GstPadProbeInfo * info, @@ -3940,7 +3941,7 @@ gst_decode_chain_is_complete (GstDecodeChain * chain) goto out; } - if (chain->endpad && (chain->endpad->blocked || chain->endpad->exposed)) { + if (chain->endpad && gst_decode_pad_is_exposable (chain->endpad)) { complete = TRUE; goto out; } @@ -4746,7 +4747,7 @@ gst_decode_chain_expose (GstDecodeChain * chain, GList ** endpads, } if (chain->endpad) { - if (!chain->endpad->blocked && !chain->endpad->exposed) + if (!gst_decode_pad_is_exposable (chain->endpad) && !chain->endpad->exposed) return FALSE; *endpads = g_list_prepend (*endpads, gst_object_ref (chain->endpad)); return TRUE; @@ -5052,6 +5053,15 @@ gst_decode_pad_query (GstPad * pad, GstObject * parent, GstQuery * query) return ret; } +static gboolean +gst_decode_pad_is_exposable (GstDecodePad * endpad) +{ + if (endpad->blocked || endpad->exposed) + return TRUE; + + return gst_pad_has_current_caps (GST_PAD_CAST (endpad)); +} + /*gst_decode_pad_new: * * Creates a new GstDecodePad for the given pad. -- 2.7.4