diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2011-08-15 15:44:28 +0800 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2011-08-15 20:38:12 +0800 |
commit | 8f7a0a9cce1f8e08d4a50cc181d8a11ce3b48ec1 (patch) | |
tree | 9eed31790ade51b5011cced5a8e7a46088c82d9e /src | |
parent | 80c90eb2c847fe095eca1f741a4cfa772ec388a8 (diff) | |
download | gsoc2013-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.
Diffstat (limited to 'src')
-rw-r--r-- | 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 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); } |