[empathy] Use pulesink as audio sink
- From: Guillaume Desmottes <gdesmott src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [empathy] Use pulesink as audio sink
- Date: Mon, 15 Aug 2011 13:23:25 +0000 (UTC)
commit 8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1
Author: Guillaume Desmottes <guillaume desmottes collabora co uk>
Date: Mon Aug 15 09:44:28 2011 +0200
Use pulesink as audio sink
As we did for puslesrc, this can still be overriden with an env variable for
debuging purposes.
Relying on pulse allows us to remove all the software volume control logic.
src/empathy-audio-sink.c | 245 ++++++++--------------------------------------
1 files changed, 40 insertions(+), 205 deletions(-)
---
diff --git a/src/empathy-audio-sink.c b/src/empathy-audio-sink.c
index c410d7a..e571b24 100644
--- a/src/empathy-audio-sink.c
+++ b/src/empathy-audio-sink.c
@@ -23,10 +23,11 @@
#include <stdlib.h>
#include <gst/audio/audio.h>
-#include <gst/farsight/fs-element-added-notifier.h>
#include "empathy-audio-sink.h"
+#define DEBUG_FLAG EMPATHY_DEBUG_VOIP
+#include <libempathy/empathy-debug.h>
G_DEFINE_TYPE(EmpathyGstAudioSink, empathy_audio_sink, GST_TYPE_BIN)
@@ -39,36 +40,6 @@ enum
static guint signals[LAST_SIGNAL] = {0};
#endif
-typedef struct {
- GstPad *pad;
- GstElement *bin;
- GstElement *volume;
- GstElement *sink;
-} AudioBin;
-
-static AudioBin *
-audio_bin_new (GstPad *pad,
- GstElement *bin,
- GstElement *volume,
- GstElement *sink)
-{
- AudioBin *result = g_slice_new0 (AudioBin);
-
- result->pad = pad;
- result->bin = bin;
- result->volume = gst_object_ref (volume);
- result->sink = sink;
-
- return result;
-}
-
-static void
-audio_bin_free (AudioBin *bin)
-{
- gst_object_unref (bin->volume);
- g_slice_free (AudioBin, bin);
-}
-
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE(
"sink%d",
@@ -84,16 +55,7 @@ enum {
struct _EmpathyGstAudioSinkPrivate
{
- gboolean dispose_has_run;
- FsElementAddedNotifier *notifier;
-
- gdouble volume;
-
- /* Pad -> *owned* subbin hash */
- GHashTable *audio_bins;
-
- /* Mutex to hold while change the hash table */
- GMutex *audio_bins_lock;
+ GstElement *sink;
};
#define EMPATHY_GST_AUDIO_SINK_GET_PRIVATE(o) \
@@ -101,72 +63,11 @@ struct _EmpathyGstAudioSinkPrivate
EmpathyGstAudioSinkPrivate))
static void
-empathy_audio_sink_element_added_cb (FsElementAddedNotifier *notifier,
- GstBin *bin, GstElement *element, EmpathyGstAudioSink *self)
-{
- EmpathyGstAudioSinkPrivate *priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (self);
-
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (element), "volume"))
- {
- /* An element was added with a volume property, lets find its subbin and
- * update the volume in it */
- GHashTableIter iter;
- AudioBin *audio_bin = NULL;
- gpointer value;
-
- g_mutex_lock (self->priv->audio_bins_lock);
- g_hash_table_iter_init (&iter, priv->audio_bins);
-
- while (g_hash_table_iter_next (&iter, NULL, &value))
- {
- AudioBin *b = value;
-
- if (gst_object_has_ancestor (GST_OBJECT (element),
- GST_OBJECT (b->bin)))
- {
- audio_bin = b;
- break;
- }
- }
-
- if (audio_bin == NULL)
- {
- g_warning ("Element added that doesn't belong to us ?");
- return;
- }
-
- /* Set the old volume to 1 and the new volume to the volume */
- g_object_set (audio_bin->volume, "volume", 1.0, NULL);
- gst_object_unref (audio_bin->volume);
-
- audio_bin->volume = gst_object_ref (element);
- g_object_set (audio_bin->volume, "volume", self->priv->volume, NULL);
- g_mutex_unlock (self->priv->audio_bins_lock);
- }
-}
-
-static void
empathy_audio_sink_init (EmpathyGstAudioSink *self)
{
- EmpathyGstAudioSinkPrivate *priv;
-
- priv = self->priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (self);
-
- priv->volume = 1.0;
-
- priv->audio_bins = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify) audio_bin_free);
-
- priv->audio_bins_lock = g_mutex_new ();
-
- priv->notifier = fs_element_added_notifier_new ();
- g_signal_connect (priv->notifier, "element-added",
- G_CALLBACK (empathy_audio_sink_element_added_cb), self);
+ self->priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (self);
}
-static void empathy_audio_sink_dispose (GObject *object);
-static void empathy_audio_sink_finalize (GObject *object);
-
static GstPad * empathy_audio_sink_request_new_pad (GstElement *self,
GstPadTemplate *templ,
const gchar* name);
@@ -219,9 +120,6 @@ empathy_audio_sink_class_init (EmpathyGstAudioSinkClass
g_type_class_add_private (empathy_audio_sink_class,
sizeof (EmpathyGstAudioSinkPrivate));
- object_class->dispose = empathy_audio_sink_dispose;
- object_class->finalize = empathy_audio_sink_finalize;
-
object_class->set_property = empathy_audio_sink_set_property;
object_class->get_property = empathy_audio_sink_get_property;
@@ -234,45 +132,6 @@ empathy_audio_sink_class_init (EmpathyGstAudioSinkClass
g_object_class_install_property (object_class, PROP_VOLUME, param_spec);
}
-void
-empathy_audio_sink_dispose (GObject *object)
-{
- EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (object);
- EmpathyGstAudioSinkPrivate *priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (self);
-
- if (priv->dispose_has_run)
- return;
-
- priv->dispose_has_run = TRUE;
-
- if (priv->notifier != NULL)
- g_object_unref (priv->notifier);
- priv->notifier = NULL;
-
- if (priv->audio_bins != NULL)
- g_hash_table_unref (priv->audio_bins);
- priv->audio_bins = NULL;
-
- if (priv->audio_bins_lock != NULL)
- g_mutex_free (priv->audio_bins_lock);
- priv->audio_bins_lock = NULL;
-
- if (G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose)
- G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose (object);
-}
-
-void
-empathy_audio_sink_finalize (GObject *object)
-{
- //EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (object);
- //EmpathyGstAudioSinkPrivate *priv =
- // EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (self);
-
- /* free any data held directly by the object here */
-
- G_OBJECT_CLASS (empathy_audio_sink_parent_class)->finalize (object);
-}
-
GstElement *
empathy_audio_sink_new (void)
{
@@ -287,32 +146,44 @@ empathy_audio_sink_new (void)
return gst_element_factory_make ("empathyaudiosink", NULL);
}
+static gboolean
+check_volume_support (EmpathyGstAudioSink *self)
+{
+ gchar *name;
+
+ if (g_object_class_find_property (G_OBJECT_GET_CLASS (self->priv->sink),
+ "volume"))
+ return TRUE;
+
+ name = gst_element_get_name (self->priv->sink);
+ DEBUG ("Element %s doesn't support volume", name);
+
+ g_free (name);
+ return FALSE;
+}
+
void
empathy_audio_sink_set_volume (EmpathyGstAudioSink *sink, gdouble volume)
{
EmpathyGstAudioSinkPrivate *priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (sink);
- GHashTableIter iter;
- gpointer value;
-
- priv->volume = volume;
- g_mutex_lock (priv->audio_bins_lock);
-
- g_hash_table_iter_init (&iter, priv->audio_bins);
- while (g_hash_table_iter_next (&iter, NULL, &value))
- {
- AudioBin *b = value;
- g_object_set (b->volume, "volume", volume, NULL);
- }
+ if (!check_volume_support (sink))
+ return;
- g_mutex_unlock (priv->audio_bins_lock);
+ g_object_set (priv->sink, "volume", volume, NULL);
}
gdouble
empathy_audio_sink_get_volume (EmpathyGstAudioSink *sink)
{
EmpathyGstAudioSinkPrivate *priv = EMPATHY_GST_AUDIO_SINK_GET_PRIVATE (sink);
- return priv->volume;
+ gdouble volume;
+
+ if (!check_volume_support (sink))
+ return 1.0;
+
+ g_object_get (priv->sink, "volume", &volume, NULL);
+ return volume;
}
static GstPad *
@@ -321,10 +192,10 @@ empathy_audio_sink_request_new_pad (GstElement *element,
const gchar* name)
{
EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (element);
- GstElement *bin, *sink, *volume, *resample, *audioconvert0, *audioconvert1;
+ GstElement *bin, *volume, *resample, *audioconvert0, *audioconvert1;
GstPad *pad = NULL;
GstPad *subpad, *filterpad;
- AudioBin *audiobin;
+ const gchar *sink_element;
bin = gst_bin_new (NULL);
@@ -352,15 +223,18 @@ empathy_audio_sink_request_new_pad (GstElement *element,
gst_bin_add (GST_BIN (bin), volume);
- sink = gst_element_factory_make ("gconfaudiosink", NULL);
- if (sink == NULL)
+ sink_element = g_getenv ("EMPATHY_AUDIO_SINK");
+ if (sink_element == NULL)
+ sink_element = "pulsesink";
+
+ self->priv->sink = gst_element_factory_make (sink_element, NULL);
+ if (self->priv->sink == NULL)
goto error;
- gst_bin_add (GST_BIN (bin), sink);
- fs_element_added_notifier_add (self->priv->notifier, GST_BIN (sink));
+ gst_bin_add (GST_BIN (bin), self->priv->sink);
if (!gst_element_link_many (audioconvert0, resample, audioconvert1,
- volume, sink, NULL))
+ volume, self->priv->sink, NULL))
goto error;
filterpad = gst_element_get_static_pad (audioconvert0, "sink");
@@ -372,25 +246,11 @@ empathy_audio_sink_request_new_pad (GstElement *element,
if (!gst_element_add_pad (GST_ELEMENT (bin), subpad))
goto error;
-
- /* Ensure that state changes only happen _after_ the element has been added
- * to the hash table. But add it to the bin first so we can create our
- * ghostpad (if we create the ghostpad before adding it to the bin it will
- * get unlinked) */
- gst_element_set_locked_state (GST_ELEMENT (bin), TRUE);
gst_bin_add (GST_BIN (self), bin);
pad = gst_ghost_pad_new (name, subpad);
g_assert (pad != NULL);
- audiobin = audio_bin_new (pad, bin, volume, sink);
-
- g_mutex_lock (self->priv->audio_bins_lock);
- g_hash_table_insert (self->priv->audio_bins, pad, audiobin);
- g_mutex_unlock (self->priv->audio_bins_lock);
-
- gst_element_set_locked_state (GST_ELEMENT (bin), FALSE);
-
if (!gst_element_sync_state_with_parent (bin))
goto error;
@@ -400,16 +260,11 @@ empathy_audio_sink_request_new_pad (GstElement *element,
if (!gst_element_add_pad (GST_ELEMENT (self), pad))
goto error;
-
return pad;
error:
if (pad != NULL)
{
- g_mutex_lock (self->priv->audio_bins_lock);
- g_hash_table_remove (self->priv->audio_bins, pad);
- g_mutex_unlock (self->priv->audio_bins_lock);
-
gst_object_unref (pad);
}
@@ -422,26 +277,6 @@ static void
empathy_audio_sink_release_pad (GstElement *element,
GstPad *pad)
{
- EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (element);
- AudioBin *abin;
-
- g_mutex_lock (self->priv->audio_bins_lock);
- abin = g_hash_table_lookup (self->priv->audio_bins, pad);
- g_hash_table_steal (self->priv->audio_bins, pad);
- g_mutex_unlock (self->priv->audio_bins_lock);
-
- if (abin == NULL)
- {
- g_warning ("Releasing a pad that doesn't belong to us ?");
- return;
- }
-
gst_pad_set_active (pad, FALSE);
gst_element_remove_pad (element, pad);
-
- gst_element_set_locked_state (abin->bin, TRUE);
- gst_element_set_state (abin->bin, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (self), abin->bin);
-
- audio_bin_free (abin);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]