aboutsummaryrefslogtreecommitdiffstats
path: root/src/empathy-audio-sink.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/empathy-audio-sink.c')
-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);
}