diff options
author | Thibault Saunier <tsaunier@gnome.org> | 2014-11-25 13:39:07 +0100 |
---|---|---|
committer | Mathieu Duponchelle <mathieu.duponchelle@opencreed.com> | 2014-11-26 19:38:48 +0100 |
commit | 35f6259b24da1120ffeaa111c90dc3c528c22d4c (patch) | |
tree | db479ecc76709e0a4cacf1d6149e3412a6ca11c4 | |
parent | 68edf0ebd6eb7b63d6747bc030a90f3092c51aaf (diff) |
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
-rw-r--r-- | gst/playback/gstdecodebin2.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index c233747de..fc496d4d7 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -1974,6 +1974,39 @@ error_message_to_string (GstMessage * msg) 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: * * 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; gboolean subtitle; 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 * 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, GST_ELEMENT_METADATA_KLASS), "Parser") != NULL; + is_simple_demuxer = is_simple_demuxer_factory (factory); + if (is_parser_converter) { gboolean skip = FALSE; GList *l; @@ -2349,7 +2384,7 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad, /* link this element further */ to_connect = connect_element (dbin, delem, chain); - if (is_parser_converter && to_connect) { + if ((is_simple_demuxer || is_parser_converter) && to_connect) { GList *l; for (l = to_connect; l; l = g_list_next (l)) { GstPad *opad = GST_PAD_CAST (l->data); |