static gboolean empathy_audio_sink_volume_idle_updated (gpointer user_data) { EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (user_data); g_static_mutex_lock (&self->priv->volume_mutex); self->priv->volume_idle_id = 0; g_static_mutex_unlock (&self->priv->volume_mutex); g_object_notify (G_OBJECT (self), "volume"); return FALSE; }
static void empathy_audio_sink_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { switch (property_id) { case PROP_VOLUME: g_value_set_double (value, empathy_audio_sink_get_volume (EMPATHY_GST_AUDIO_SINK (object))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static void empathy_audio_sink_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (object); switch (property_id) { case PROP_VOLUME: g_static_mutex_lock (&self->priv->volume_mutex); self->priv->volume = g_value_get_double (value); g_static_mutex_unlock (&self->priv->volume_mutex); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static void empathy_audio_sink_dispose (GObject *object) { EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (object); EmpathyGstAudioSinkPrivate *priv = self->priv; if (priv->volume_idle_id != 0) g_source_remove (priv->volume_idle_id); priv->volume_idle_id = 0; g_static_mutex_free (&self->priv->volume_mutex); /* release any references held by the object here */ if (G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose) G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose (object); }
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->volume != NULL) g_object_unref (priv->volume); priv->volume = NULL; if (G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose) G_OBJECT_CLASS (empathy_audio_sink_parent_class)->dispose (object); }
static void empathy_audio_sink_volume_updated (GObject *object, GParamSpec *pspec, gpointer user_data) { EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (user_data); gdouble volume; g_static_mutex_lock (&self->priv->volume_mutex); g_object_get (object, "volume", &volume, NULL); if (self->priv->volume == volume) goto out; self->priv->volume = volume; if (self->priv->volume_idle_id == 0) self->priv->volume_idle_id = g_idle_add ( empathy_audio_sink_volume_idle_updated, self); out: g_static_mutex_unlock (&self->priv->volume_mutex); }
static gboolean empathy_audio_sink_volume_idle_setup (gpointer user_data) { EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (user_data); gdouble volume; g_static_mutex_lock (&self->priv->volume_mutex); self->priv->volume_idle_id = 0; g_static_mutex_unlock (&self->priv->volume_mutex); /* We can't do a bidirection bind as the ::notify comes from another * thread, for other bits of empathy it's most simpler if it comes from * the main thread */ g_object_bind_property (self, "volume", self->priv->sink, "volume", G_BINDING_DEFAULT); /* sync and callback for bouncing */ g_object_get (self->priv->sink, "volume", &volume, NULL); g_object_set (self, "volume", volume, NULL); g_signal_connect (self->priv->sink, "notify::volume", G_CALLBACK (empathy_audio_sink_volume_updated), self); return FALSE; }
static GstPad * empathy_audio_sink_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar* name) { EmpathyGstAudioSink *self = EMPATHY_GST_AUDIO_SINK (element); GstElement *bin, *resample, *audioconvert0, *audioconvert1; GstPad *pad = NULL; GstPad *subpad, *filterpad; bin = gst_bin_new (NULL); audioconvert0 = gst_element_factory_make ("audioconvert", NULL); if (audioconvert0 == NULL) goto error; gst_bin_add (GST_BIN (bin), audioconvert0); resample = gst_element_factory_make ("audioresample", NULL); if (resample == NULL) goto error; gst_bin_add (GST_BIN (bin), resample); audioconvert1 = gst_element_factory_make ("audioconvert", NULL); if (audioconvert1 == NULL) goto error; gst_bin_add (GST_BIN (bin), audioconvert1); self->priv->sink = create_sink (self); if (self->priv->sink == NULL) goto error; if (GST_IS_STREAM_VOLUME (self->priv->sink)) { g_static_mutex_lock (&self->priv->volume_mutex); if (self->priv->volume_idle_id == 0) self->priv->volume_idle_id = g_idle_add ( empathy_audio_sink_volume_idle_setup, self); g_static_mutex_unlock (&self->priv->volume_mutex); } else { gchar *n = gst_element_get_name (self->priv->sink); DEBUG ("Element %s doesn't support volume", n); g_free (n); } gst_bin_add (GST_BIN (bin), self->priv->sink); if (!gst_element_link_many (audioconvert0, resample, audioconvert1, self->priv->sink, NULL)) goto error; filterpad = gst_element_get_static_pad (audioconvert0, "sink"); if (filterpad == NULL) goto error; subpad = gst_ghost_pad_new ("sink", filterpad); if (!gst_element_add_pad (GST_ELEMENT (bin), subpad)) goto error; gst_bin_add (GST_BIN (self), bin); pad = gst_ghost_pad_new (name, subpad); g_assert (pad != NULL); if (!gst_element_sync_state_with_parent (bin)) goto error; if (!gst_pad_set_active (pad, TRUE)) goto error; if (!gst_element_add_pad (GST_ELEMENT (self), pad)) goto error; return pad; error: if (pad != NULL) { gst_object_unref (pad); } gst_object_unref (bin); g_warning ("Failed to create output subpipeline"); return NULL; }