From: Michael Smith Date: Wed, 11 Feb 2009 01:10:33 +0000 (-0800) Subject: playbin2: Look for volume/mute properties recursively in audio element. X-Git-Tag: 1.19.3~511^2~10022 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a264efc627c90c2007a5f19c46b1b0104e532925;p=platform%2Fupstream%2Fgstreamer.git playbin2: Look for volume/mute properties recursively in audio element. Rather than only checking for volume property on the audio sink directly, recursively look for it on sinks within it (if it's a bin). Allows use of sink-as-volume-control where the application has supplied an audio-sink bin that includes a real audio sink internally. --- diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index 822cc45..f926e3d 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -640,6 +640,50 @@ gst_play_sink_find_property (GstPlaySink * playsink, GstElement * obj, return result; } +static gint +find_property_sink (GstElement * element, const gchar * name) +{ + gint res; + gboolean is_sink; + + GST_OBJECT_LOCK (element); + is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK); + GST_OBJECT_UNLOCK (element); + + if (is_sink && + g_object_class_find_property (G_OBJECT_GET_CLASS (element), name)) { + res = 0; + GST_DEBUG_OBJECT (element, "found %s property on sink", name); + } else { + GST_DEBUG_OBJECT (element, "did not find %s property", name); + res = 1; + gst_object_unref (element); + } + return res; +} + +/* find a sink in the hierarchy with a property named @name */ +static GstElement * +gst_play_sink_find_property_sinks (GstPlaySink * playsink, GstElement * obj, + const gchar * name) +{ + GstElement *result = NULL; + GstIterator *it; + + if (GST_IS_BIN (obj)) { + it = gst_bin_iterate_recurse (GST_BIN_CAST (obj)); + result = gst_iterator_find_custom (it, + (GCompareFunc) find_property_sink, (gpointer) name); + gst_iterator_free (it); + } else { + if (g_object_class_find_property (G_OBJECT_GET_CLASS (obj), name)) { + result = obj; + gst_object_ref (obj); + } + } + return result; +} + /* try to change the state of an element. This function returns the element when * the state change could be performed. When this function returns NULL an error * occured and the element is unreffed. */ @@ -956,21 +1000,28 @@ gen_audio_chain (GstPlaySink * playsink, gboolean raw, gboolean queue) prev = NULL; } - /* check if the sink has the volume property, if it does we don't need to - * add a volume element. */ + /* check if the sink, or something within the sink, has the volume property. + * If it does we don't need to add a volume element. */ + elem = NULL; if (g_object_class_find_property (G_OBJECT_GET_CLASS (chain->sink), "volume")) { + elem = gst_object_ref (chain->sink); + } else if (GST_IS_BIN (chain->sink)) { + elem = gst_play_sink_find_property_sinks (playsink, chain->sink, "volume"); + } + if (elem) { GST_DEBUG_OBJECT (playsink, "the sink has a volume property"); have_volume = TRUE; /* use the sink to control the volume */ - chain->volume = chain->sink; - g_object_set (G_OBJECT (chain->volume), "volume", playsink->volume, NULL); + chain->volume = elem; + g_object_set (G_OBJECT (elem), "volume", playsink->volume, NULL); /* if the sink also has a mute property we can use this as well. We'll only * use the mute property if there is a volume property. We can simulate the * mute with the volume otherwise. */ - if (g_object_class_find_property (G_OBJECT_GET_CLASS (chain->sink), "mute")) { + if (g_object_class_find_property (G_OBJECT_GET_CLASS (elem), "mute")) { GST_DEBUG_OBJECT (playsink, "the sink has a mute property"); - chain->mute = chain->sink; + chain->mute = elem; } + gst_object_unref (elem); } else { /* no volume, we need to add a volume element when we can */ GST_DEBUG_OBJECT (playsink, "the sink has no volume property");