playback: Always prefer parsers over decoders
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 12 Jun 2012 09:58:29 +0000 (11:58 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 12 Jun 2012 09:59:39 +0000 (11:59 +0200)
...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.

gst/playback/gstdecodebin2.c
gst/playback/gstplaybin2.c
gst/playback/gsturidecodebin.c

index 5bef2e3..09555fc 100644 (file)
 
 #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;
   }
 }
index 857ce2c..9a4f247 100644 (file)
@@ -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;
index 3054899..a501143 100644 (file)
@@ -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;
   }
 }