summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@gnome.org>2014-11-25 13:39:07 +0100
committerMathieu Duponchelle <mathieu.duponchelle@opencreed.com>2014-11-26 19:38:48 +0100
commit35f6259b24da1120ffeaa111c90dc3c528c22d4c (patch)
treedb479ecc76709e0a4cacf1d6149e3412a6ca11c4
parent68edf0ebd6eb7b63d6747bc030a90f3092c51aaf (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.c39
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);