mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-17 12:55:53 +00:00
pulsesink: Implement mute property
This commit is contained in:
parent
d4316e74fc
commit
7fb6ad6d4c
2 changed files with 140 additions and 2 deletions
|
@ -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 */
|
||||
|
@ -1635,6 +1652,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);
|
||||
|
|
|
@ -61,6 +61,8 @@ struct _GstPulseSink
|
|||
|
||||
gdouble volume;
|
||||
gboolean volume_set;
|
||||
gboolean mute;
|
||||
gboolean mute_set;
|
||||
gint notify;
|
||||
|
||||
const gchar *pa_version;
|
||||
|
|
Loading…
Reference in a new issue