diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2016-01-21 18:30:40 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2016-01-25 13:50:26 +0100 |
commit | acd08a828d109599eb39e43e70e8e92fba1a9366 (patch) | |
tree | 7f6719f3e56a87fd590a7ee0582f1db981af65d9 /gst | |
parent | 3674742957efcd217344f9a114551f02f60265f8 (diff) |
decodebin: Correctly expose pads from elements that have directly exposable pads
analyze_new_pad() can return a new decode chain, which might have a new
GstDecodePad in the end. We should use those two for expose_pad() and not the
original ones that were passed to analyze_new_pad().
This fails when having a demuxer element that has raw pads immediately or
if a decoder with raw caps is after an adaptive demuxer.
https://bugzilla.gnome.org/show_bug.cgi?id=760949
Diffstat (limited to 'gst')
-rw-r--r-- | gst/playback/gstdecodebin2.c | 89 |
1 files changed, 47 insertions, 42 deletions
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 966884936..e97cf2a41 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -2067,6 +2067,12 @@ demuxer_source_pad_probe (GstPad * pad, GstPadProbeInfo * info, return GST_PAD_PROBE_OK; } +typedef struct +{ + GstDecodeChain *chain; + GstPad *pad; +} PadExposeData; + /* connect_pad: * * Try to connect the given pad to an element created from one of the factories, @@ -2124,6 +2130,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, GParamSpec *pspec; gboolean subtitle; GList *to_connect = NULL; + GList *to_expose = NULL; gboolean is_parser_converter = FALSE; /* Set dpad target to pad again, it might've been unset @@ -2448,34 +2455,31 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, /* link this element further */ to_connect = connect_element (dbin, delem, chain); - { - GList *l; - for (l = to_connect; l;) { - GstPad *opad = GST_PAD_CAST (l->data); - gboolean to_expose = FALSE; - GstCaps *ocaps; - - ocaps = get_pad_caps (opad); - to_expose = - analyze_new_pad (dbin, delem->element, opad, ocaps, chain, &chain); - - if (ocaps) - gst_caps_unref (ocaps); - - if (!to_expose) { - GList *l2 = l; - - gst_object_unref (opad); - - l2 = g_list_next (l); - to_connect = g_list_delete_link (to_connect, l); - l = l2; - } else { - l = g_list_next (l); - } + while (to_connect) { + GstPad *opad = to_connect->data; + gboolean expose_pad = FALSE; + GstDecodeChain *new_chain; + GstCaps *ocaps; + + ocaps = get_pad_caps (opad); + expose_pad = + analyze_new_pad (dbin, delem->element, opad, ocaps, chain, + &new_chain); + + if (ocaps) + gst_caps_unref (ocaps); + + if (expose_pad) { + PadExposeData *expose_data = g_new0 (PadExposeData, 1); + expose_data->chain = new_chain; + expose_data->pad = gst_object_ref (opad); + to_expose = g_list_prepend (to_expose, expose_data); } - /* any pads left in to_connect are to be exposed */ + + gst_object_unref (opad); + to_connect = g_list_delete_link (to_connect, to_connect); } + /* any pads left in to_expose are to be exposed */ /* Bring the element to the state of the parent */ @@ -2496,9 +2500,12 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, GST_WARNING_OBJECT (dbin, "Couldn't set %s to PAUSED", GST_ELEMENT_NAME (element)); - g_list_foreach (to_connect, (GFunc) gst_object_unref, NULL); - g_list_free (to_connect); - to_connect = NULL; + while (to_expose) { + PadExposeData *expose_data = to_expose->data; + gst_object_unref (expose_data->pad); + g_free (expose_data); + to_expose = g_list_delete_link (to_expose, to_expose); + } remove_error_filter (dbin, element, &error_msg); @@ -2586,22 +2593,20 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, SUBTITLE_UNLOCK (dbin); } - { - GList *l; - for (l = to_connect; l; l = g_list_next (l)) { - GstPad *opad = GST_PAD_CAST (l->data); - GstCaps *ocaps; + while (to_expose) { + PadExposeData *expose_data = to_expose->data; + GstCaps *ocaps; - ocaps = get_pad_caps (opad); - expose_pad (dbin, delem->element, dpad, opad, ocaps, chain, TRUE); + ocaps = get_pad_caps (expose_data->pad); + expose_pad (dbin, delem->element, expose_data->chain->current_pad, + expose_data->pad, ocaps, expose_data->chain, TRUE); - if (ocaps) - gst_caps_unref (ocaps); + if (ocaps) + gst_caps_unref (ocaps); - gst_object_unref (opad); - } - g_list_free (to_connect); - to_connect = NULL; + gst_object_unref (expose_data->pad); + g_free (expose_data); + to_expose = g_list_delete_link (to_expose, to_expose); } res = TRUE; |