diff options
| author | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2009-09-11 16:09:40 +0200 | 
|---|---|---|
| committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2009-09-11 16:38:03 +0200 | 
| commit | 7fb6ad6d4c477daf4a51bb7edb24088c43455f42 (patch) | |
| tree | ab4bcd71798965489ed2dbba5e2b1281f61edc3e /ext | |
| parent | d4316e74fc952f08c4f724d5a4406c6999fb2747 (diff) | |
pulsesink: Implement mute property
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/pulse/pulsesink.c | 140 | ||||
| -rw-r--r-- | ext/pulse/pulsesink.h | 2 | 
2 files changed, 140 insertions, 2 deletions
diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c index 2ce538a1..b6a00be0 100644 --- a/ext/pulse/pulsesink.c +++ b/ext/pulse/pulsesink.c @@ -62,6 +62,7 @@ GST_DEBUG_CATEGORY_EXTERN (pulse_debug);  #define DEFAULT_DEVICE          NULL  #define DEFAULT_DEVICE_NAME     NULL  #define DEFAULT_VOLUME          1.0 +#define DEFAULT_MUTE            FALSE  #define MAX_VOLUME              10.0  enum @@ -71,6 +72,7 @@ enum    PROP_DEVICE,    PROP_DEVICE_NAME,    PROP_VOLUME, +  PROP_MUTE,    PROP_LAST  }; @@ -651,6 +653,11 @@ gst_pulseringbuffer_acquire (GstRingBuffer * buf, GstRingBufferSpec * spec)  #endif        PA_STREAM_START_CORKED; +#if HAVE_PULSE_0_9_12 +  if (psink->mute_set && psink->mute) +    flags |= PA_STREAM_START_MUTED; +#endif +    /* we always start corked (see flags above) */    pbuf->corked = TRUE; @@ -1081,8 +1088,10 @@ gst_pulseringbuffer_commit (GstRingBuffer * buf, guint64 * sample,    psink = GST_PULSESINK_CAST (GST_OBJECT_PARENT (pbuf));    /* FIXME post message rather than using a signal (as mixer interface) */ -  if (g_atomic_int_compare_and_exchange (&psink->notify, 1, 0)) +  if (g_atomic_int_compare_and_exchange (&psink->notify, 1, 0)) {      g_object_notify (G_OBJECT (psink), "volume"); +    g_object_notify (G_OBJECT (psink), "mute"); +  }    /* make sure the ringbuffer is started */    if (G_UNLIKELY (g_atomic_int_get (&buf->state) != @@ -1472,6 +1481,11 @@ gst_pulsesink_class_init (GstPulseSinkClass * klass)        g_param_spec_double ("volume", "Volume",            "Volume of this stream, 1.0=100%", 0.0, MAX_VOLUME, DEFAULT_VOLUME,            G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +  g_object_class_install_property (gobject_class, +      PROP_MUTE, +      g_param_spec_boolean ("mute", "Mute", +          "Mute state of this stream", DEFAULT_MUTE, +          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));  #endif  } @@ -1529,6 +1543,9 @@ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass)    pulsesink->volume = 1.0;    pulsesink->volume_set = FALSE; +  pulsesink->mute = FALSE; +  pulsesink->mute_set = FALSE; +    pulsesink->notify = 0;    /* needed for conditional execution */ @@ -1636,6 +1653,61 @@ volume_failed:  }  static void +gst_pulsesink_set_mute (GstPulseSink * psink, gboolean mute) +{ +  pa_operation *o = NULL; +  GstPulseRingBuffer *pbuf; +  uint32_t idx; + +  pa_threaded_mainloop_lock (psink->mainloop); + +  GST_DEBUG_OBJECT (psink, "setting mute state to %d", mute); + +  psink->mute = mute; +  psink->mute_set = TRUE; + +  pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer); +  if (pbuf == NULL || pbuf->stream == NULL) +    goto no_buffer; + +  if ((idx = pa_stream_get_index (pbuf->stream)) == PA_INVALID_INDEX) +    goto no_index; + +  if (!(o = pa_context_set_sink_input_mute (pbuf->context, idx, +              mute, NULL, NULL))) +    goto mute_failed; + +  /* We don't really care about the result of this call */ +unlock: + +  if (o) +    pa_operation_unref (o); + +  pa_threaded_mainloop_unlock (psink->mainloop); + +  return; + +  /* ERRORS */ +no_buffer: +  { +    GST_DEBUG_OBJECT (psink, "we have no ringbuffer"); +    goto unlock; +  } +no_index: +  { +    GST_DEBUG_OBJECT (psink, "we don't have a stream index"); +    goto unlock; +  } +mute_failed: +  { +    GST_ELEMENT_ERROR (psink, RESOURCE, FAILED, +        ("pa_stream_set_sink_input_mute() failed: %s", +            pa_strerror (pa_context_errno (pbuf->context))), (NULL)); +    goto unlock; +  } +} + +static void  gst_pulsesink_sink_input_info_cb (pa_context * c, const pa_sink_input_info * i,      int eol, void *userdata)  { @@ -1654,8 +1726,10 @@ gst_pulsesink_sink_input_info_cb (pa_context * c, const pa_sink_input_info * i,    /* If the index doesn't match our current stream,     * it implies we just recreated the stream (caps change)     */ -  if (i->index == pa_stream_get_index (pbuf->stream)) +  if (i->index == pa_stream_get_index (pbuf->stream)) {      psink->volume = pa_sw_volume_to_linear (pa_cvolume_max (&i->volume)); +    psink->mute = i->mute; +  }  done:    pa_threaded_mainloop_signal (psink->mainloop, 0); @@ -1721,6 +1795,62 @@ info_failed:      goto unlock;    }  } + +static gboolean +gst_pulsesink_get_mute (GstPulseSink * psink) +{ +  GstPulseRingBuffer *pbuf; +  pa_operation *o = NULL; +  uint32_t idx; +  gboolean mute; + +  pa_threaded_mainloop_lock (psink->mainloop); + +  pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer); +  if (pbuf == NULL || pbuf->stream == NULL) +    goto no_buffer; + +  if ((idx = pa_stream_get_index (pbuf->stream)) == PA_INVALID_INDEX) +    goto no_index; + +  if (!(o = pa_context_get_sink_input_info (pbuf->context, idx, +              gst_pulsesink_sink_input_info_cb, pbuf))) +    goto info_failed; + +  while (pa_operation_get_state (o) == PA_OPERATION_RUNNING) { +    pa_threaded_mainloop_wait (psink->mainloop); +    if (gst_pulsering_is_dead (psink, pbuf)) +      goto unlock; +  } + +unlock: +  if (o) +    pa_operation_unref (o); + +  mute = psink->mute; +  pa_threaded_mainloop_unlock (psink->mainloop); + +  return mute; + +  /* ERRORS */ +no_buffer: +  { +    GST_DEBUG_OBJECT (psink, "we have no ringbuffer"); +    goto unlock; +  } +no_index: +  { +    GST_DEBUG_OBJECT (psink, "we don't have a stream index"); +    goto unlock; +  } +info_failed: +  { +    GST_ELEMENT_ERROR (psink, RESOURCE, FAILED, +        ("pa_context_get_sink_input_info() failed: %s", +            pa_strerror (pa_context_errno (pbuf->context))), (NULL)); +    goto unlock; +  } +}  #endif  static void @@ -1816,6 +1946,9 @@ gst_pulsesink_set_property (GObject * object,      case PROP_VOLUME:        gst_pulsesink_set_volume (pulsesink, g_value_get_double (value));        break; +    case PROP_MUTE: +      gst_pulsesink_set_mute (pulsesink, g_value_get_boolean (value)); +      break;  #endif      default:        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1844,6 +1977,9 @@ gst_pulsesink_get_property (GObject * object,      case PROP_VOLUME:        g_value_set_double (value, gst_pulsesink_get_volume (pulsesink));        break; +    case PROP_MUTE: +      g_value_set_boolean (value, gst_pulsesink_get_mute (pulsesink)); +      break;  #endif      default:        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/ext/pulse/pulsesink.h b/ext/pulse/pulsesink.h index 6120609c..c7ff2e87 100644 --- a/ext/pulse/pulsesink.h +++ b/ext/pulse/pulsesink.h @@ -61,6 +61,8 @@ struct _GstPulseSink    gdouble volume;    gboolean volume_set; +  gboolean mute; +  gboolean mute_set;    gint notify;    const gchar *pa_version;  | 
