From e729ad1c9c58987984e1220d6323f7bb24a9cae5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 12 Jun 2012 11:58:29 +0200 Subject: [PATCH] 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. --- gst/playback/gstdecodebin2.c | 39 +++++++++++++++++++++++++++++++++++++++ gst/playback/gstplaybin2.c | 26 +++++++++++++++++++++----- gst/playback/gsturidecodebin.c | 5 +++++ 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 5bef2e3..09555fc 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 857ce2c..9a4f247 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 3054899..a501143 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; } } -- 2.7.4