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;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 5
0
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;
}