mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
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
This commit is contained in:
parent
3674742957
commit
acd08a828d
1 changed files with 44 additions and 39 deletions
|
@ -2067,6 +2067,12 @@ demuxer_source_pad_probe (GstPad * pad, GstPadProbeInfo * info,
|
||||||
return GST_PAD_PROBE_OK;
|
return GST_PAD_PROBE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GstDecodeChain *chain;
|
||||||
|
GstPad *pad;
|
||||||
|
} PadExposeData;
|
||||||
|
|
||||||
/* connect_pad:
|
/* connect_pad:
|
||||||
*
|
*
|
||||||
* Try to connect the given pad to an element created from one of the factories,
|
* 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;
|
GParamSpec *pspec;
|
||||||
gboolean subtitle;
|
gboolean subtitle;
|
||||||
GList *to_connect = NULL;
|
GList *to_connect = NULL;
|
||||||
|
GList *to_expose = NULL;
|
||||||
gboolean is_parser_converter = FALSE;
|
gboolean is_parser_converter = FALSE;
|
||||||
|
|
||||||
/* Set dpad target to pad again, it might've been unset
|
/* 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 */
|
/* link this element further */
|
||||||
to_connect = connect_element (dbin, delem, chain);
|
to_connect = connect_element (dbin, delem, chain);
|
||||||
|
|
||||||
{
|
while (to_connect) {
|
||||||
GList *l;
|
GstPad *opad = to_connect->data;
|
||||||
for (l = to_connect; l;) {
|
gboolean expose_pad = FALSE;
|
||||||
GstPad *opad = GST_PAD_CAST (l->data);
|
GstDecodeChain *new_chain;
|
||||||
gboolean to_expose = FALSE;
|
GstCaps *ocaps;
|
||||||
GstCaps *ocaps;
|
|
||||||
|
|
||||||
ocaps = get_pad_caps (opad);
|
ocaps = get_pad_caps (opad);
|
||||||
to_expose =
|
expose_pad =
|
||||||
analyze_new_pad (dbin, delem->element, opad, ocaps, chain, &chain);
|
analyze_new_pad (dbin, delem->element, opad, ocaps, chain,
|
||||||
|
&new_chain);
|
||||||
|
|
||||||
if (ocaps)
|
if (ocaps)
|
||||||
gst_caps_unref (ocaps);
|
gst_caps_unref (ocaps);
|
||||||
|
|
||||||
if (!to_expose) {
|
if (expose_pad) {
|
||||||
GList *l2 = l;
|
PadExposeData *expose_data = g_new0 (PadExposeData, 1);
|
||||||
|
expose_data->chain = new_chain;
|
||||||
gst_object_unref (opad);
|
expose_data->pad = gst_object_ref (opad);
|
||||||
|
to_expose = g_list_prepend (to_expose, expose_data);
|
||||||
l2 = g_list_next (l);
|
|
||||||
to_connect = g_list_delete_link (to_connect, l);
|
|
||||||
l = l2;
|
|
||||||
} else {
|
|
||||||
l = g_list_next (l);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* 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 */
|
/* 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_WARNING_OBJECT (dbin, "Couldn't set %s to PAUSED",
|
||||||
GST_ELEMENT_NAME (element));
|
GST_ELEMENT_NAME (element));
|
||||||
|
|
||||||
g_list_foreach (to_connect, (GFunc) gst_object_unref, NULL);
|
while (to_expose) {
|
||||||
g_list_free (to_connect);
|
PadExposeData *expose_data = to_expose->data;
|
||||||
to_connect = NULL;
|
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);
|
remove_error_filter (dbin, element, &error_msg);
|
||||||
|
|
||||||
|
@ -2586,22 +2593,20 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
SUBTITLE_UNLOCK (dbin);
|
SUBTITLE_UNLOCK (dbin);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
while (to_expose) {
|
||||||
GList *l;
|
PadExposeData *expose_data = to_expose->data;
|
||||||
for (l = to_connect; l; l = g_list_next (l)) {
|
GstCaps *ocaps;
|
||||||
GstPad *opad = GST_PAD_CAST (l->data);
|
|
||||||
GstCaps *ocaps;
|
|
||||||
|
|
||||||
ocaps = get_pad_caps (opad);
|
ocaps = get_pad_caps (expose_data->pad);
|
||||||
expose_pad (dbin, delem->element, dpad, opad, ocaps, chain, TRUE);
|
expose_pad (dbin, delem->element, expose_data->chain->current_pad,
|
||||||
|
expose_data->pad, ocaps, expose_data->chain, TRUE);
|
||||||
|
|
||||||
if (ocaps)
|
if (ocaps)
|
||||||
gst_caps_unref (ocaps);
|
gst_caps_unref (ocaps);
|
||||||
|
|
||||||
gst_object_unref (opad);
|
gst_object_unref (expose_data->pad);
|
||||||
}
|
g_free (expose_data);
|
||||||
g_list_free (to_connect);
|
to_expose = g_list_delete_link (to_expose, to_expose);
|
||||||
to_connect = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
|
|
Loading…
Reference in a new issue