mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
decodebin: Link Parser/Converter directly and already connect to pad-added and other signals before setting elements to PAUSED
otherwise we're going to a) start Parser/Converter before they are linked to their capsfilter, breaking their negotiation of a proper stream format b) start demuxers without having connected to their pad-added signals. We miss pads and in the worst case don't link any pads at all
This commit is contained in:
parent
57999c28fd
commit
b15a47aa19
1 changed files with 51 additions and 19 deletions
|
@ -1422,7 +1422,7 @@ static gboolean is_adaptive_demuxer_element (GstElement * srcelement);
|
|||
static gboolean connect_pad (GstDecodeBin * dbin, GstElement * src,
|
||||
GstDecodePad * dpad, GstPad * pad, GstCaps * caps, GValueArray * factories,
|
||||
GstDecodeChain * chain);
|
||||
static gboolean connect_element (GstDecodeBin * dbin, GstDecodeElement * delem,
|
||||
static GList *connect_element (GstDecodeBin * dbin, GstDecodeElement * delem,
|
||||
GstDecodeChain * chain);
|
||||
static void expose_pad (GstDecodeBin * dbin, GstElement * src,
|
||||
GstDecodePad * dpad, GstPad * pad, GstCaps * caps, GstDecodeChain * chain);
|
||||
|
@ -1972,6 +1972,8 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
|||
GstPad *sinkpad;
|
||||
GParamSpec *pspec;
|
||||
gboolean subtitle;
|
||||
GList *to_connect = NULL;
|
||||
gboolean is_parser_converter = FALSE;
|
||||
|
||||
/* Set dpad target to pad again, it might've been unset
|
||||
* below but we came back here because something failed
|
||||
|
@ -2068,6 +2070,9 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
|||
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory)));
|
||||
continue;
|
||||
}
|
||||
|
||||
is_parser_converter = strstr (gst_element_factory_get_metadata (factory,
|
||||
GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
|
||||
}
|
||||
|
||||
/* emit autoplug-select to see what we should do with it. */
|
||||
|
@ -2252,6 +2257,26 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
|||
subtitle = FALSE;
|
||||
}
|
||||
|
||||
/* link this element further */
|
||||
to_connect = connect_element (dbin, delem, chain);
|
||||
|
||||
if (is_parser_converter && to_connect) {
|
||||
GList *l;
|
||||
for (l = to_connect; l; l = g_list_next (l)) {
|
||||
GstPad *opad = GST_PAD_CAST (l->data);
|
||||
GstCaps *ocaps;
|
||||
|
||||
ocaps = get_pad_caps (opad);
|
||||
analyze_new_pad (dbin, delem->element, opad, ocaps, chain);
|
||||
if (ocaps)
|
||||
gst_caps_unref (ocaps);
|
||||
|
||||
gst_object_unref (opad);
|
||||
}
|
||||
g_list_free (to_connect);
|
||||
to_connect = NULL;
|
||||
}
|
||||
|
||||
/* Bring the element to the state of the parent */
|
||||
if ((gst_element_set_state (element,
|
||||
GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE ||
|
||||
|
@ -2262,6 +2287,10 @@ 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;
|
||||
|
||||
remove_error_filter (dbin, element);
|
||||
|
||||
/* Remove all elements in this chain that were just added. No
|
||||
|
@ -2334,8 +2363,22 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
|||
SUBTITLE_UNLOCK (dbin);
|
||||
}
|
||||
|
||||
/* link this element further */
|
||||
connect_element (dbin, delem, chain);
|
||||
if (to_connect) {
|
||||
GList *l;
|
||||
for (l = to_connect; l; l = g_list_next (l)) {
|
||||
GstPad *opad = GST_PAD_CAST (l->data);
|
||||
GstCaps *ocaps;
|
||||
|
||||
ocaps = get_pad_caps (opad);
|
||||
analyze_new_pad (dbin, delem->element, opad, ocaps, chain);
|
||||
if (ocaps)
|
||||
gst_caps_unref (ocaps);
|
||||
|
||||
gst_object_unref (opad);
|
||||
}
|
||||
g_list_free (to_connect);
|
||||
to_connect = NULL;
|
||||
}
|
||||
|
||||
res = TRUE;
|
||||
break;
|
||||
|
@ -2366,13 +2409,14 @@ get_pad_caps (GstPad * pad)
|
|||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
/* Returns a list of pads that can be connected to already and
|
||||
* connects to pad-added and related signals */
|
||||
static GList *
|
||||
connect_element (GstDecodeBin * dbin, GstDecodeElement * delem,
|
||||
GstDecodeChain * chain)
|
||||
{
|
||||
GstElement *element = delem->element;
|
||||
GList *pads;
|
||||
gboolean res = TRUE;
|
||||
gboolean dynamic = FALSE;
|
||||
GList *to_connect = NULL;
|
||||
|
||||
|
@ -2450,21 +2494,9 @@ connect_element (GstDecodeBin * dbin, GstDecodeElement * delem,
|
|||
G_CALLBACK (no_more_pads_cb), chain);
|
||||
}
|
||||
|
||||
/* 3. for every available pad, connect it */
|
||||
for (pads = to_connect; pads; pads = g_list_next (pads)) {
|
||||
GstPad *pad = GST_PAD_CAST (pads->data);
|
||||
GstCaps *caps;
|
||||
/* 3. return all pads that can be connected to already */
|
||||
|
||||
caps = get_pad_caps (pad);
|
||||
analyze_new_pad (dbin, element, pad, caps, chain);
|
||||
if (caps)
|
||||
gst_caps_unref (caps);
|
||||
|
||||
gst_object_unref (pad);
|
||||
}
|
||||
g_list_free (to_connect);
|
||||
|
||||
return res;
|
||||
return to_connect;
|
||||
}
|
||||
|
||||
/* expose_pad:
|
||||
|
|
Loading…
Reference in a new issue