summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2012-06-12 11:58:29 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-06-12 11:59:39 +0200
commite729ad1c9c58987984e1220d6323f7bb24a9cae5 (patch)
tree889abbcdf1c0e34d354e3569bebf64c1573704b2
parentf211cda2fce50c4d25876352c775e5b7d70fc29f (diff)
playback: Always prefer parsers over decoders
...and in playbin2 additionally prefer sinks over parsers. This makes sure that we a) always directly plug a sink if it supports the (compressed) format and b) always plug parsers in front of decoders.
-rw-r--r--gst/playback/gstdecodebin2.c39
-rw-r--r--gst/playback/gstplaybin2.c26
-rw-r--r--gst/playback/gsturidecodebin.c5
3 files changed, 65 insertions, 5 deletions
diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c
index 5bef2e39d..09555fc89 100644
--- a/gst/playback/gstdecodebin2.c
+++ b/gst/playback/gstdecodebin2.c
@@ -101,6 +101,9 @@
#include "gst/glib-compat-private.h"
+/* Also used by gsturidecodebin.c */
+gint _decode_bin_compare_factories_func (gconstpointer p1, gconstpointer p2);
+
/* generic templates */
static GstStaticPadTemplate decoder_bin_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
@@ -930,6 +933,40 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
GST_DEBUG_FUNCPTR (gst_decode_bin_handle_message);
}
+gint
+_decode_bin_compare_factories_func (gconstpointer p1, gconstpointer p2)
+{
+ GstPluginFeature *f1, *f2;
+ gint diff;
+ gboolean is_parser1, is_parser2;
+
+ f1 = (GstPluginFeature *) p1;
+ f2 = (GstPluginFeature *) p2;
+
+ is_parser1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
+ GST_ELEMENT_FACTORY_TYPE_PARSER);
+ is_parser2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
+ GST_ELEMENT_FACTORY_TYPE_PARSER);
+
+
+ /* We want all parsers first as we always want to plug parsers
+ * before decoders */
+ if (is_parser1 && !is_parser2)
+ return -1;
+ else if (!is_parser1 && is_parser2)
+ return 1;
+
+ /* And if it's a both a parser we first sort by rank
+ * and then by factory name */
+ diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
+ if (diff != 0)
+ return diff;
+
+ diff = strcmp (GST_OBJECT_NAME (f2), GST_OBJECT_NAME (f1));
+
+ return diff;
+}
+
/* Must be called with factories lock! */
static void
gst_decode_bin_update_factories_list (GstDecodeBin * dbin)
@@ -943,6 +980,8 @@ gst_decode_bin_update_factories_list (GstDecodeBin * dbin)
dbin->factories =
gst_element_factory_list_get_elements
(GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
+ dbin->factories =
+ g_list_sort (dbin->factories, _decode_bin_compare_factories_func);
dbin->factories_cookie = cookie;
}
}
diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
index 857ce2c77..9a4f24788 100644
--- a/gst/playback/gstplaybin2.c
+++ b/gst/playback/gstplaybin2.c
@@ -1294,21 +1294,37 @@ compare_factories_func (gconstpointer p1, gconstpointer p2)
{
GstPluginFeature *f1, *f2;
gint diff;
- gboolean s1, s2;
+ gboolean is_sink1, is_sink2;
+ gboolean is_parser1, is_parser2;
f1 = (GstPluginFeature *) p1;
f2 = (GstPluginFeature *) p2;
- s1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
+ is_sink1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
GST_ELEMENT_FACTORY_TYPE_SINK);
- s2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
+ is_sink2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
GST_ELEMENT_FACTORY_TYPE_SINK);
+ is_parser1 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f1),
+ GST_ELEMENT_FACTORY_TYPE_PARSER);
+ is_parser2 = gst_element_factory_list_is_type (GST_ELEMENT_FACTORY_CAST (f2),
+ GST_ELEMENT_FACTORY_TYPE_PARSER);
+
+ /* First we want all sinks as we prefer a sink if it directly
+ * supports the current caps */
+ if (is_sink1 && !is_sink2)
+ return -1;
+ else if (!is_sink1 && is_sink2)
+ return 1;
- if (s1 && !s2)
+ /* Then we want all parsers as we always want to plug parsers
+ * before decoders */
+ if (is_parser1 && !is_parser2)
return -1;
- else if (!s1 && s2)
+ else if (!is_parser1 && is_parser2)
return 1;
+ /* And if it's a both a parser or sink we first sort by rank
+ * and then by factory name */
diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
if (diff != 0)
return diff;
diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c
index 30548992a..a50114342 100644
--- a/gst/playback/gsturidecodebin.c
+++ b/gst/playback/gsturidecodebin.c
@@ -44,6 +44,9 @@
#include "gst/glib-compat-private.h"
+/* From gstdecodebin2.c */
+gint _decode_bin_compare_factories_func (gconstpointer p1, gconstpointer p2);
+
#define GST_TYPE_URI_DECODE_BIN \
(gst_uri_decode_bin_get_type())
#define GST_URI_DECODE_BIN(obj) \
@@ -292,6 +295,8 @@ gst_uri_decode_bin_update_factories_list (GstURIDecodeBin * dec)
dec->factories =
gst_element_factory_list_get_elements
(GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
+ dec->factories =
+ g_list_sort (dec->factories, _decode_bin_compare_factories_func);
dec->factories_cookie = cookie;
}
}