mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
decodebin: Analyze source pad before setting to PAUSED for 'simple demuxers'
Before we were setting them to PAUSED and (much) later connecting to their source pad caps notify signal. There was a race where that demuxer was pushing a caps and later a buffer on its source pad when we were not even connected to its source pad caps notify signal leading to decodebin missing the information and not keeping on building the pipeline on CAPS event thus the demuxer was posting an ERROR (not linked) message on the bus. This need to be done for 'simple demuxers' because those have one ALWAYS source pad, not like usual demuxers that have several dynamic source pads. A "simple demuxer" is a demuxer that has one and only one ALWAYS source pad. https://bugzilla.gnome.org/show_bug.cgi?id=740693
This commit is contained in:
parent
68edf0ebd6
commit
35f6259b24
1 changed files with 37 additions and 2 deletions
|
@ -1974,6 +1974,39 @@ error_message_to_string (GstMessage * msg)
|
||||||
return full_message;
|
return full_message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We consider elements as "simple demuxer" when they are a demuxer
|
||||||
|
* with one and only one ALWAYS source pad.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
is_simple_demuxer_factory (GstElementFactory * factory)
|
||||||
|
{
|
||||||
|
if (strstr (gst_element_factory_get_metadata (factory,
|
||||||
|
GST_ELEMENT_METADATA_KLASS), "Demuxer")) {
|
||||||
|
const GList *tmp;
|
||||||
|
gint num_alway_srcpads = 0;
|
||||||
|
|
||||||
|
for (tmp = gst_element_factory_get_static_pad_templates (factory);
|
||||||
|
tmp; tmp = tmp->next) {
|
||||||
|
GstStaticPadTemplate *template = tmp->data;
|
||||||
|
|
||||||
|
if (template->direction == GST_PAD_SRC) {
|
||||||
|
if (template->presence == GST_PAD_ALWAYS) {
|
||||||
|
if (num_alway_srcpads >= 0)
|
||||||
|
num_alway_srcpads++;
|
||||||
|
} else {
|
||||||
|
num_alway_srcpads = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_alway_srcpads == 1)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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,
|
||||||
|
@ -2027,7 +2060,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;
|
||||||
gboolean is_parser_converter = FALSE;
|
gboolean is_parser_converter = FALSE, is_simple_demuxer = FALSE;
|
||||||
|
|
||||||
/* Set dpad target to pad again, it might've been unset
|
/* Set dpad target to pad again, it might've been unset
|
||||||
* below but we came back here because something failed
|
* below but we came back here because something failed
|
||||||
|
@ -2095,6 +2128,8 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
||||||
*/
|
*/
|
||||||
is_parser_converter = strstr (gst_element_factory_get_metadata (factory,
|
is_parser_converter = strstr (gst_element_factory_get_metadata (factory,
|
||||||
GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
|
GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
|
||||||
|
is_simple_demuxer = is_simple_demuxer_factory (factory);
|
||||||
|
|
||||||
if (is_parser_converter) {
|
if (is_parser_converter) {
|
||||||
gboolean skip = FALSE;
|
gboolean skip = FALSE;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
@ -2349,7 +2384,7 @@ 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);
|
||||||
|
|
||||||
if (is_parser_converter && to_connect) {
|
if ((is_simple_demuxer || is_parser_converter) && to_connect) {
|
||||||
GList *l;
|
GList *l;
|
||||||
for (l = to_connect; l; l = g_list_next (l)) {
|
for (l = to_connect; l; l = g_list_next (l)) {
|
||||||
GstPad *opad = GST_PAD_CAST (l->data);
|
GstPad *opad = GST_PAD_CAST (l->data);
|
||||||
|
|
Loading…
Reference in a new issue