aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-08-15 15:44:28 +0800
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2011-08-15 20:38:12 +0800
commit8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1 (patch)
tree9eed31790ade51b5011cced5a8e7a46088c82d9e
parent80c90eb2c847fe095eca1f741a4cfa772ec388a8 (diff)
downloadgsoc2013-empathy-8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1.tar
gsoc2013-empathy-8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1.tar.gz
gsoc2013-empathy-8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1.tar.bz2
gsoc2013-empathy-8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1.tar.lz
gsoc2013-empathy-8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1.tar.xz
gsoc2013-empathy-8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1.tar.zst
gsoc2013-empathy-8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1.zip
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.
-rw-r--r--src/empathy-audio-sink.c245
1 files changed, 40 insertions, 205 deletions
diff --git a/src/empathy-audio-sink.c b/src/empathy-audio-sink.c
index c410d7a30..e571b2426 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);
}