ao/pulse: wait for command completion when setting volume or mute

This makes the behavior of all control messages consistent,
fixing an inconsistency that has been with us since
4d8266c739 - which is the initial
rework of the polyaudio AO into the pulseaudio AO.

Muting the stream also directly triggers an update to the OSD.
When not waiting for the command completion this read of the mute
property may read the old state. A stale read.

Note that this somehow was not triggered on native Pulseaudio, but it is
an issue on Pipewire.

See https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/868
This commit is contained in:
Thomas Weißschuh 2021-03-09 13:22:53 +01:00 committed by Jan Ekström
parent 45e6804478
commit 4f07607888
1 changed files with 8 additions and 13 deletions

View File

@ -696,8 +696,6 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
case AOCONTROL_SET_MUTE:
case AOCONTROL_SET_VOLUME: {
pa_operation *o;
pa_threaded_mainloop_lock(priv->mainloop);
uint32_t stream_index = pa_stream_get_index(priv->stream);
if (cmd == AOCONTROL_SET_VOLUME) {
@ -711,27 +709,24 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
volume.values[0] = VOL_MP2PA(vol->left);
volume.values[1] = VOL_MP2PA(vol->right);
}
o = pa_context_set_sink_input_volume(priv->context, stream_index,
&volume, NULL, NULL);
if (!o) {
pa_threaded_mainloop_unlock(priv->mainloop);
if (!waitop(priv, pa_context_set_sink_input_volume(priv->context,
stream_index,
&volume,
NULL, NULL))) {
GENERIC_ERR_MSG("pa_context_set_sink_input_volume() failed");
return CONTROL_ERROR;
}
} else if (cmd == AOCONTROL_SET_MUTE) {
const bool *mute = arg;
o = pa_context_set_sink_input_mute(priv->context, stream_index,
*mute, NULL, NULL);
if (!o) {
pa_threaded_mainloop_unlock(priv->mainloop);
if (!waitop(priv, pa_context_set_sink_input_mute(priv->context,
stream_index,
*mute,
NULL, NULL))) {
GENERIC_ERR_MSG("pa_context_set_sink_input_mute() failed");
return CONTROL_ERROR;
}
} else
abort();
/* We don't wait for completion here */
pa_operation_unref(o);
pa_threaded_mainloop_unlock(priv->mainloop);
return CONTROL_OK;
}