summaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian.droege@collabora.co.uk>2009-09-11 16:09:40 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2009-09-11 16:38:03 +0200
commit7fb6ad6d4c477daf4a51bb7edb24088c43455f42 (patch)
treeab4bcd71798965489ed2dbba5e2b1281f61edc3e /ext
parentd4316e74fc952f08c4f724d5a4406c6999fb2747 (diff)
pulsesink: Implement mute property
Diffstat (limited to 'ext')
-rw-r--r--ext/pulse/pulsesink.c140
-rw-r--r--ext/pulse/pulsesink.h2
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;