mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
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.
This commit is contained in:
parent
67948a4027
commit
a264efc627
1 changed files with 57 additions and 6 deletions
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue