[empathy] Use pulesink as audio sink



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]