summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-01-21 18:30:40 +0200
committerSebastian Dröge <sebastian@centricular.com>2016-01-25 13:50:26 +0100
commitacd08a828d109599eb39e43e70e8e92fba1a9366 (patch)
tree7f6719f3e56a87fd590a7ee0582f1db981af65d9
parent3674742957efcd217344f9a114551f02f60265f8 (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
-rw-r--r--gst/playback/gstdecodebin2.c89
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;