From 11bf488b85877530ef34fb81ceeba877c11bac00 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 30 Nov 2007 17:47:15 +0000 Subject: [PATCH] gst/playback/: Refactor some common code to filter factories and check caps compat. Original commit message from CVS: * gst/playback/Makefile.am: * gst/playback/gstfactorylists.c: (compare_ranks), (print_feature), (get_feature_array), (decoders_filter), (sinks_filter), (gst_factory_list_get_decoders), (gst_factory_list_get_sinks), (gst_factory_list_filter): * gst/playback/gstfactorylists.h: Refactor some common code to filter factories and check caps compat. * gst/playback/gstdecodebin.c: * gst/playback/gstdecodebin2.c: (gst_decode_bin_class_init), (gst_decode_bin_init), (gst_decode_bin_dispose), (gst_decode_bin_autoplug_continue), (gst_decode_bin_autoplug_factories), (gst_decode_bin_autoplug_select), (analyze_new_pad), (find_compatibles): * gst/playback/gstplaybin.c: * gst/playback/gstplaybin2.c: (gst_play_bin_class_init), (gst_play_bin_init), (gst_play_bin_finalize), (autoplug_factories_cb), (activate_group): * gst/playback/gstqueue2.c: * gst/playback/gsturidecodebin.c: (proxy_unknown_type_signal), (proxy_autoplug_continue_signal), (proxy_autoplug_factories_signal), (proxy_autoplug_select_signal), (proxy_drained_signal): Add some more debug info and use factor filtering code. --- ChangeLog | 28 ++++ gst/playback/Makefile.am | 4 +- gst/playback/gstdecodebin.c | 4 +- gst/playback/gstdecodebin2.c | 143 ++++--------------- gst/playback/gstfactorylists.c | 254 +++++++++++++++++++++++++++++++++ gst/playback/gstfactorylists.h | 35 +++++ gst/playback/gstplaybin.c | 2 +- gst/playback/gstplaybin2.c | 47 +++++- gst/playback/gstqueue2.c | 3 +- gst/playback/gsturidecodebin.c | 17 ++- 10 files changed, 410 insertions(+), 127 deletions(-) create mode 100644 gst/playback/gstfactorylists.c create mode 100644 gst/playback/gstfactorylists.h diff --git a/ChangeLog b/ChangeLog index ffe5a7c12b..bb82b6a2c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2007-11-30 Wim Taymans + + * gst/playback/Makefile.am: + * gst/playback/gstfactorylists.c: (compare_ranks), (print_feature), + (get_feature_array), (decoders_filter), (sinks_filter), + (gst_factory_list_get_decoders), (gst_factory_list_get_sinks), + (gst_factory_list_filter): + * gst/playback/gstfactorylists.h: + Refactor some common code to filter factories and check caps compat. + + * gst/playback/gstdecodebin.c: + * gst/playback/gstdecodebin2.c: (gst_decode_bin_class_init), + (gst_decode_bin_init), (gst_decode_bin_dispose), + (gst_decode_bin_autoplug_continue), + (gst_decode_bin_autoplug_factories), + (gst_decode_bin_autoplug_select), (analyze_new_pad), + (find_compatibles): + * gst/playback/gstplaybin.c: + * gst/playback/gstplaybin2.c: (gst_play_bin_class_init), + (gst_play_bin_init), (gst_play_bin_finalize), + (autoplug_factories_cb), (activate_group): + * gst/playback/gstqueue2.c: + * gst/playback/gsturidecodebin.c: (proxy_unknown_type_signal), + (proxy_autoplug_continue_signal), + (proxy_autoplug_factories_signal), (proxy_autoplug_select_signal), + (proxy_drained_signal): + Add some more debug info and use factor filtering code. + 2007-11-26 Stefan Kost * gst/audiotestsrc/gstaudiotestsrc.c: diff --git a/gst/playback/Makefile.am b/gst/playback/Makefile.am index 57cfd6361f..5f5c9b882d 100644 --- a/gst/playback/Makefile.am +++ b/gst/playback/Makefile.am @@ -16,6 +16,7 @@ libgstplaybin_la_SOURCES = \ gstplaybin2.c \ gstplaysink.c \ gstplaybasebin.c \ + gstfactorylists.c \ gststreaminfo.c \ gststreamselector.c @@ -34,7 +35,7 @@ libgstdecodebin_la_LIBADD = \ $(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la \ $(GST_LIBS) -libgstdecodebin2_la_SOURCES = gstdecodebin2.c +libgstdecodebin2_la_SOURCES = gstdecodebin2.c gstfactorylists.c nodist_libgstdecodebin2_la_SOURCES = $(built_sources) libgstdecodebin2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) libgstdecodebin2_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) @@ -60,6 +61,7 @@ noinst_HEADERS = \ gstplaybasebin.h \ gstplaysink.h \ gststreaminfo.h \ + gstfactorylists.h \ gststreamselector.h noinst_PROGRAMS = test decodetest test2 test3 test4 test5 test6 test7 diff --git a/gst/playback/gstdecodebin.c b/gst/playback/gstdecodebin.c index 4078e7e6e4..792740685c 100644 --- a/gst/playback/gstdecodebin.c +++ b/gst/playback/gstdecodebin.c @@ -1,5 +1,5 @@ /* GStreamer - * Copyright (C) <2004> Wim Taymans + * Copyright (C) <2004> Wim Taymans * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -162,7 +162,7 @@ static const GstElementDetails gst_decode_bin_details = GST_ELEMENT_DETAILS ("Decoder Bin", "Generic/Bin/Decoder", "Autoplug and decode to raw media", - "Wim Taymans "); + "Wim Taymans "); static GType diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index e081a3b17b..10a8ac79dd 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -43,6 +43,7 @@ #include #include "gstplay-marshal.h" +#include "gstfactorylists.h" /* generic templates */ static GstStaticPadTemplate decoder_bin_sink_template = @@ -97,7 +98,7 @@ struct _GstDecodeBin * Should be freed in dispose */ gint nbpads; /* unique identifier for source pads */ - GList *factories; /* factories we can use for selecting elements */ + GValueArray *factories; /* factories we can use for selecting elements */ gboolean have_type; /* if we received the have_type signal */ guint have_type_id; /* signal id for have-type from typefind */ @@ -419,7 +420,13 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) * @caps: The #GstCaps found. * * This function is emited when an array of possible factories for @caps on - * @pad is needed. Decodebin2 will by default return + * @pad is needed. Decodebin2 will by default return an array with all + * compatible factories, sorted by rank. + * + * If this function returns NULL, @pad will be exposed as a final caps. + * + * If this function returns an empty array, the pad will be considered as + * having an unhandled type media type. * * Returns: a #GValueArray* with a list of factories to try. The factories are * by default tried in the returned order or based on the index returned by @@ -493,80 +500,11 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass) GST_DEBUG_FUNCPTR (gst_decode_bin_change_state); } -/* the filter function for selecting the elements we can use in - * autoplugging */ -static gboolean -gst_decode_bin_factory_filter (GstPluginFeature * feature, - GstDecodeBin * decode_bin) -{ - guint rank; - const gchar *klass; - - /* we only care about element factories */ - if (!GST_IS_ELEMENT_FACTORY (feature)) - return FALSE; - - klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature)); - /* only demuxers, decoders, depayloaders and parsers can play */ - if (strstr (klass, "Demux") == NULL && - strstr (klass, "Decoder") == NULL && - strstr (klass, "Depayloader") == NULL && - strstr (klass, "Parse") == NULL) { - return FALSE; - } - - /* only select elements with autoplugging rank */ - rank = gst_plugin_feature_get_rank (feature); - if (rank < GST_RANK_MARGINAL) - return FALSE; - - return TRUE; -} - -/* function used to sort element features */ -static gint -compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2) -{ - gint diff; - const gchar *rname1, *rname2; - - diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1); - if (diff != 0) - return diff; - - rname1 = gst_plugin_feature_get_name (f1); - rname2 = gst_plugin_feature_get_name (f2); - - diff = strcmp (rname2, rname1); - - return diff; -} - -static void -print_feature (GstPluginFeature * feature) -{ - const gchar *rname; - - rname = gst_plugin_feature_get_name (feature); - - GST_DEBUG ("%s", rname); -} - static void gst_decode_bin_init (GstDecodeBin * decode_bin) { - GList *factories; - /* first filter out the interesting element factories */ - factories = gst_default_registry_feature_filter ( - (GstPluginFeatureFilter) gst_decode_bin_factory_filter, - FALSE, decode_bin); - - /* sort them according to their ranks */ - decode_bin->factories = g_list_sort (factories, (GCompareFunc) compare_ranks); - /* do some debugging */ - g_list_foreach (decode_bin->factories, (GFunc) print_feature, NULL); - + decode_bin->factories = gst_factory_list_get_decoders (); /* we create the typefind element only once */ decode_bin->typefind = gst_element_factory_make ("typefind", "typefind"); @@ -622,7 +560,7 @@ gst_decode_bin_dispose (GObject * object) decode_bin = GST_DECODE_BIN (object); if (decode_bin->factories) - gst_plugin_feature_list_free (decode_bin->factories); + g_value_array_free (decode_bin->factories); decode_bin->factories = NULL; if (decode_bin->activegroup) { @@ -796,6 +734,8 @@ static gboolean gst_decode_bin_autoplug_continue (GstElement * element, GstPad * pad, GstCaps * caps) { + GST_DEBUG_OBJECT (element, "autoplug-continue returns TRUE"); + /* by default we always continue */ return TRUE; } @@ -809,6 +749,8 @@ gst_decode_bin_autoplug_factories (GstElement * element, GstPad * pad, /* return all compatible factories for caps */ result = find_compatibles (GST_DECODE_BIN (element), pad, caps); + GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result); + return result; } @@ -819,6 +761,8 @@ gst_decode_bin_autoplug_select (GstElement * element, GstPad * pad, g_return_val_if_fail (factories != NULL, -1); g_return_val_if_fail (factories->n_values > 0, -1); + GST_DEBUG_OBJECT (element, "default autoplug-select returns 0"); + /* Return first factory. */ return 0; } @@ -900,8 +844,15 @@ analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad, g_signal_emit (G_OBJECT (dbin), gst_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, pad, caps, &factories); - if (factories == NULL) { + + /* NULL means that we can expose the pad */ + if (factories == NULL) + goto expose_pad; + + /* if the array is empty, we have an unknown type */ + if (factories->n_values == 0) { /* no compatible factories */ + g_value_array_free (factories); goto unknown_type; } @@ -1421,49 +1372,13 @@ caps_notify_group_cb (GstPad * pad, GParamSpec * unused, GstDecodeGroup * group) static GValueArray * find_compatibles (GstDecodeBin * decode_bin, GstPad * pad, const GstCaps * caps) { - GList *factories; - GValueArray *to_try = g_value_array_new (0); + GValueArray *result; - /* loop over all the factories */ - for (factories = decode_bin->factories; factories; - factories = g_list_next (factories)) { - GstElementFactory *factory = GST_ELEMENT_FACTORY (factories->data); - const GList *templates; - GList *walk; + GST_DEBUG_OBJECT (decode_bin, "finding factories"); - /* get the templates from the element factory */ - templates = gst_element_factory_get_static_pad_templates (factory); - for (walk = (GList *) templates; walk; walk = g_list_next (walk)) { - GstStaticPadTemplate *templ = walk->data; + result = gst_factory_list_filter (decode_bin->factories, caps); - /* we only care about the sink templates */ - if (templ->direction == GST_PAD_SINK) { - GstCaps *intersect; - GstCaps *tmpl_caps; - - /* try to intersect the caps with the caps of the template */ - tmpl_caps = gst_static_caps_get (&templ->static_caps); - - intersect = gst_caps_intersect (caps, tmpl_caps); - gst_caps_unref (tmpl_caps); - - /* check if the intersection is empty */ - if (!gst_caps_is_empty (intersect)) { - /* non empty intersection, we can use this element */ - GValue val = { 0, }; - g_value_init (&val, G_TYPE_OBJECT); - g_value_set_object (&val, factory); - g_value_array_append (to_try, &val); - g_value_unset (&val); - gst_caps_unref (intersect); - break; - } - gst_caps_unref (intersect); - } - } - } - - return to_try; + return result; } /* Decide whether an element is a demuxer based on the diff --git a/gst/playback/gstfactorylists.c b/gst/playback/gstfactorylists.c new file mode 100644 index 0000000000..ca6166d837 --- /dev/null +++ b/gst/playback/gstfactorylists.c @@ -0,0 +1,254 @@ +/* GStreamer + * Copyright (C) <2007> Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#include + +#include "gstfactorylists.h" + +/* function used to sort element features. We first sort on the rank, then + * on the element name (to get a consistent, predictable list) */ +static gint +compare_ranks (GValue * v1, GValue * v2) +{ + gint diff; + const gchar *rname1, *rname2; + GstPluginFeature *f1, *f2; + + f1 = g_value_get_object (v1); + f2 = g_value_get_object (v2); + + diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1); + if (diff != 0) + return diff; + + rname1 = gst_plugin_feature_get_name (f1); + rname2 = gst_plugin_feature_get_name (f2); + + diff = strcmp (rname2, rname1); + + return diff; +} + +#if 0 +static void +print_feature (GstPluginFeature * feature) +{ + const gchar *rname; + + rname = gst_plugin_feature_get_name (feature); + + GST_DEBUG ("%s", rname); +} +#endif + +/* get a filtered feature list as a GValueArray */ +static GValueArray * +get_feature_array (GstPluginFeatureFilter filter) +{ + GValueArray *result; + GList *walk, *list; + + result = g_value_array_new (0); + + /* get the feature list using the filter */ + list = gst_default_registry_feature_filter (filter, FALSE, NULL); + + /* convert to an array */ + for (walk = list; walk; walk = g_list_next (walk)) { + GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data); + GValue val = { 0, }; + + g_value_init (&val, G_TYPE_OBJECT); + g_value_set_object (&val, factory); + g_value_array_append (result, &val); + g_value_unset (&val); + } + gst_plugin_feature_list_free (list); + + /* sort on rank and name */ + g_value_array_sort (result, (GCompareFunc) compare_ranks); + + return result; +} + +/* the filter function for selecting the elements we can use in + * autoplugging */ +static gboolean +decoders_filter (GstPluginFeature * feature) +{ + guint rank; + const gchar *klass; + + /* we only care about element factories */ + if (!GST_IS_ELEMENT_FACTORY (feature)) + return FALSE; + + klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature)); + /* only demuxers, decoders, depayloaders and parsers can play */ + if (strstr (klass, "Demux") == NULL && + strstr (klass, "Decoder") == NULL && + strstr (klass, "Depayloader") == NULL && + strstr (klass, "Parse") == NULL) { + return FALSE; + } + + /* only select elements with autoplugging rank */ + rank = gst_plugin_feature_get_rank (feature); + if (rank < GST_RANK_MARGINAL) + return FALSE; + + return TRUE; +} + +/* the filter function for selecting the elements we can use in + * autoplugging */ +static gboolean +sinks_filter (GstPluginFeature * feature) +{ + guint rank; + const gchar *klass; + + /* we only care about element factories */ + if (!GST_IS_ELEMENT_FACTORY (feature)) + return FALSE; + + klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature)); + /* only sinks can play */ + if (strstr (klass, "Sink") == NULL) { + return FALSE; + } + + /* must be audio or video sink */ + if (strstr (klass, "Audio") == NULL && strstr (klass, "Video") == NULL) { + return FALSE; + } + + /* only select elements with autoplugging rank */ + rank = gst_plugin_feature_get_rank (feature); + if (rank < GST_RANK_MARGINAL) + return FALSE; + + return TRUE; +} + + +/** + * gst_factory_list_get_decoders: + * + * Get a sorted list of factories that can be used in decoding pipelines. + * + * Returns: a #GValueArray of #GstElementFactory elements. Use + * g_value_array_free() after usage. + */ +GValueArray * +gst_factory_list_get_decoders (void) +{ + GValueArray *result; + + /* first filter out the interesting element factories */ + result = get_feature_array ((GstPluginFeatureFilter) decoders_filter); + + return result; +} + +/** + * gst_factory_list_get_sinks: + * + * Get a sorted list of factories that can be used as sinks in a decoding + * pipeline. + * + * Returns: a #GValueArray of #GstElementFactory elements. Use + * g_value_array_free() after usage. + */ +GValueArray * +gst_factory_list_get_sinks (void) +{ + GValueArray *result; + + /* first filter out the interesting element factories */ + result = get_feature_array ((GstPluginFeatureFilter) sinks_filter); + + return result; +} + +/** + * gst_factory_list_filter: + * @array: a #GValueArray to filter + * @caps: a #GstCaps + * + * Filter out all the elementfactories in @array that can handle @caps as + * input. + * + * Returns: a #GValueArray of #GstElementFactory elements. Use + * g_value_array_free() after usage. + */ +GValueArray * +gst_factory_list_filter (GValueArray * array, const GstCaps * caps) +{ + GValueArray *result; + gint i; + + result = g_value_array_new (0); + + GST_DEBUG ("finding factories"); + + /* loop over all the factories */ + for (i = 0; i < array->n_values; i++) { + GValue *value; + GstElementFactory *factory; + const GList *templates; + GList *walk; + + value = g_value_array_get_nth (array, i); + factory = g_value_get_object (value); + + /* get the templates from the element factory */ + templates = gst_element_factory_get_static_pad_templates (factory); + for (walk = (GList *) templates; walk; walk = g_list_next (walk)) { + GstStaticPadTemplate *templ = walk->data; + + /* we only care about the sink templates */ + if (templ->direction == GST_PAD_SINK) { + GstCaps *intersect; + GstCaps *tmpl_caps; + + /* try to intersect the caps with the caps of the template */ + tmpl_caps = gst_static_caps_get (&templ->static_caps); + + /* FIXME, intersect is not the right method, we ideally want to check + * for a subset here */ + intersect = gst_caps_intersect (caps, tmpl_caps); + gst_caps_unref (tmpl_caps); + + /* check if the intersection is empty */ + if (!gst_caps_is_empty (intersect)) { + /* non empty intersection, we can use this element */ + GValue resval = { 0, }; + g_value_init (&resval, G_TYPE_OBJECT); + g_value_set_object (&resval, factory); + g_value_array_append (result, &resval); + g_value_unset (&resval); + gst_caps_unref (intersect); + break; + } + gst_caps_unref (intersect); + } + } + } + return result; +} diff --git a/gst/playback/gstfactorylists.h b/gst/playback/gstfactorylists.h new file mode 100644 index 0000000000..100535c2cb --- /dev/null +++ b/gst/playback/gstfactorylists.h @@ -0,0 +1,35 @@ +/* GStreamer + * Copyright (C) <2007> Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __GST_FACTORY_LISTS_H__ +#define __GST_FACTORY_LISTS_H__ + +#include + +G_BEGIN_DECLS + +GValueArray * gst_factory_list_get_decoders (void); +GValueArray * gst_factory_list_get_sinks (void); + +GValueArray * gst_factory_list_filter (GValueArray *array, const GstCaps *caps); + +G_END_DECLS + +#endif /* __GST_FACTORY_LISTS_H__ */ diff --git a/gst/playback/gstplaybin.c b/gst/playback/gstplaybin.c index 4effe1d416..e944309031 100644 --- a/gst/playback/gstplaybin.c +++ b/gst/playback/gstplaybin.c @@ -345,7 +345,7 @@ static const GstElementDetails gst_play_bin_details = GST_ELEMENT_DETAILS ("Player Bin", "Generic/Bin/Player", "Autoplug and play media from an uri", - "Wim Taymans "); + "Wim Taymans "); static GType gst_play_bin_get_type (void) diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c index 5ea86414d0..5c6132ec01 100644 --- a/gst/playback/gstplaybin2.c +++ b/gst/playback/gstplaybin2.c @@ -249,6 +249,7 @@ #include #include "gstplaysink.h" +#include "gstfactorylists.h" #include "gststreaminfo.h" #include "gststreamselector.h" @@ -319,6 +320,9 @@ struct _GstPlayBin /* our play sink */ GstPlaySink *playsink; + + GValueArray *elements; /* factories we can use for selecting sinks */ + GValueArray *sinks; /* factories we can use for selecting sinks */ }; struct _GstPlayBinClass @@ -360,7 +364,7 @@ enum static void gst_play_bin_class_init (GstPlayBinClass * klass); static void gst_play_bin_init (GstPlayBin * play_bin); -static void gst_play_bin_dispose (GObject * object); +static void gst_play_bin_finalize (GObject * object); static void gst_play_bin_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * spec); @@ -379,10 +383,10 @@ static GstElementClass *parent_class; static guint gst_play_bin_signals[LAST_SIGNAL] = { 0 }; static const GstElementDetails gst_play_bin_details = -GST_ELEMENT_DETAILS ("Player Bin", +GST_ELEMENT_DETAILS ("Player Bin 2", "Generic/Bin/Player", "Autoplug and play media from an uri", - "Wim Taymans "); + "Wim Taymans "); static GType gst_play_bin_get_type (void) @@ -426,7 +430,7 @@ gst_play_bin_class_init (GstPlayBinClass * klass) gobject_klass->set_property = gst_play_bin_set_property; gobject_klass->get_property = gst_play_bin_get_property; - gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_play_bin_dispose); + gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_play_bin_finalize); g_object_class_install_property (gobject_klass, PROP_URI, g_param_spec_string ("uri", "URI", "URI of the media to play", @@ -545,16 +549,23 @@ gst_play_bin_init (GstPlayBin * playbin) playbin->next_group = &playbin->groups[1]; init_group (playbin, &playbin->groups[0]); init_group (playbin, &playbin->groups[1]); + + /* first filter out the interesting element factories */ + playbin->sinks = gst_factory_list_get_sinks (); + + /* get the caps */ } static void -gst_play_bin_dispose (GObject * object) +gst_play_bin_finalize (GObject * object) { GstPlayBin *play_bin; play_bin = GST_PLAY_BIN (object); - G_OBJECT_CLASS (parent_class)->dispose (object); + g_value_array_free (play_bin->sinks); + + G_OBJECT_CLASS (parent_class)->finalize (object); } static void @@ -938,6 +949,25 @@ drained_cb (GstElement * decodebin, GstSourceGroup * group) } } +/* a callback is called */ +static GValueArray * +autoplug_factories_cb (GstElement * decodebin, GstPad * pad, + GstCaps * caps, GstSourceGroup * group) +{ + GstPlayBin *playbin; + GValueArray *result = NULL; + + playbin = group->playbin; + + GST_DEBUG_OBJECT (playbin, "continue group %p for %s:%s, %" GST_PTR_FORMAT, + group, GST_DEBUG_PAD_NAME (pad), caps); + + + GST_DEBUG_OBJECT (playbin, "found factories %p", result); + + return result; +} + /* unlink a group of uridecodebins from the sink */ static void unlink_group (GstPlayBin * playbin, GstSourceGroup * group) @@ -992,6 +1022,11 @@ activate_group (GstPlayBin * playbin, GstSourceGroup * group) * next uri */ g_signal_connect (uridecodebin, "drained", G_CALLBACK (drained_cb), group); + /* will be called when a new media type is found. We will see if we have a + * working sink that can natively handle this format. */ + g_signal_connect (uridecodebin, "autoplug-factories", + G_CALLBACK (autoplug_factories_cb), group); + /* */ gst_bin_add (GST_BIN_CAST (playbin), uridecodebin); group->uridecodebin = uridecodebin; diff --git a/gst/playback/gstqueue2.c b/gst/playback/gstqueue2.c index 26838ac26e..41d261efdb 100644 --- a/gst/playback/gstqueue2.c +++ b/gst/playback/gstqueue2.c @@ -60,7 +60,8 @@ static const GstElementDetails gst_queue_details = GST_ELEMENT_DETAILS ("Queue", "Generic", "Simple data queue", - "Erik Walthinsen , " "Wim Taymans "); + "Erik Walthinsen , " + "Wim Taymans "); static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, diff --git a/gst/playback/gsturidecodebin.c b/gst/playback/gsturidecodebin.c index 1cbf874223..90d031a8f7 100644 --- a/gst/playback/gsturidecodebin.c +++ b/gst/playback/gsturidecodebin.c @@ -104,7 +104,7 @@ static const GstElementDetails gst_uri_decode_bin_details = GST_ELEMENT_DETAILS ("URI Decoder", "Generic/Bin/Decoder", "Autoplug and decode an URI to raw media", - "Wim Taymans "); + "Wim Taymans "); /* signals */ enum @@ -835,6 +835,8 @@ static void proxy_unknown_type_signal (GstElement * element, GstPad * pad, GstCaps * caps, GstURIDecodeBin * dec) { + GST_DEBUG_OBJECT (dec, "unknown-type signaled"); + g_signal_emit (G_OBJECT (dec), gst_uri_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps); } @@ -848,6 +850,9 @@ proxy_autoplug_continue_signal (GstElement * element, GstPad * pad, g_signal_emit (G_OBJECT (dec), gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, pad, caps, &result); + + GST_DEBUG_OBJECT (dec, "autoplug-continue returned %d", result); + return result; } @@ -855,11 +860,14 @@ static GValueArray * proxy_autoplug_factories_signal (GstElement * element, GstPad * pad, GstCaps * caps, GstURIDecodeBin * dec) { - GValueArray *result; + GValueArray *result = NULL; g_signal_emit (G_OBJECT (dec), gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, pad, caps, &result); + + GST_DEBUG_OBJECT (dec, "autoplug-factories returned %p", result); + return result; } @@ -872,12 +880,17 @@ proxy_autoplug_select_signal (GstElement * element, GstPad * pad, g_signal_emit (G_OBJECT (dec), gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT], 0, pad, caps, array, &result); + + GST_DEBUG_OBJECT (dec, "autoplug-select returned %d", result); + return result; } static void proxy_drained_signal (GstElement * element, GstURIDecodeBin * dec) { + GST_DEBUG_OBJECT (dec, "drained signaled"); + g_signal_emit (G_OBJECT (dec), gst_uri_decode_bin_signals[SIGNAL_DRAINED], 0, NULL); }