X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/7ac850d3b7ce803044b58a357b4e27730cf53bc7..2f6364dfe454d3fe21cf98854ac8942870e52436:/src/pulsecore/sink.c diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 7dffedf8..fbb14d27 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -508,7 +508,7 @@ void pa_sink_set_write_volume_callback(pa_sink *s, pa_sink_cb_t cb) { pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); } -void pa_sink_set_get_mute_callback(pa_sink *s, pa_sink_cb_t cb) { +void pa_sink_set_get_mute_callback(pa_sink *s, pa_sink_get_mute_cb_t cb) { pa_assert(s); s->get_mute = cb; @@ -2196,19 +2196,30 @@ void pa_sink_set_mute(pa_sink *s, bool mute, bool save) { pa_sink_assert_ref(s); pa_assert_ctl_context(); - pa_assert(PA_SINK_IS_LINKED(s->state)); old_muted = s->muted; + + if (mute == old_muted) { + s->save_muted |= save; + return; + } + s->muted = mute; - s->save_muted = (old_muted == s->muted && s->save_muted) || save; + s->save_muted = save; - if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->set_mute) + if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->set_mute) { + s->set_mute_in_progress = true; s->set_mute(s); + s->set_mute_in_progress = false; + } - pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0); + if (!PA_SINK_IS_LINKED(s->state)) + return; - if (old_muted != s->muted) - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + pa_log_debug("The mute of sink %s changed from %s to %s.", s->name, pa_yes_no(old_muted), pa_yes_no(mute)); + pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0); + pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_MUTE_CHANGED], s); } /* Called from main thread */ @@ -2218,21 +2229,15 @@ bool pa_sink_get_mute(pa_sink *s, bool force_refresh) { pa_assert_ctl_context(); pa_assert(PA_SINK_IS_LINKED(s->state)); - if (s->refresh_muted || force_refresh) { - bool old_muted = s->muted; - - if (!(s->flags & PA_SINK_DEFERRED_VOLUME) && s->get_mute) - s->get_mute(s); - - pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, NULL, 0, NULL) == 0); - - if (old_muted != s->muted) { - s->save_muted = true; - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + if ((s->refresh_muted || force_refresh) && s->get_mute) { + bool mute; - /* Make sure the soft mute status stays in sync */ - pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_MUTE, NULL, 0, NULL) == 0); + if (s->flags & PA_SINK_DEFERRED_VOLUME) { + if (pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_GET_MUTE, &mute, 0, NULL) >= 0) + pa_sink_mute_changed(s, mute); + } else { + if (s->get_mute(s, &mute) >= 0) + pa_sink_mute_changed(s, mute); } } @@ -2245,15 +2250,17 @@ void pa_sink_mute_changed(pa_sink *s, bool new_muted) { pa_assert_ctl_context(); pa_assert(PA_SINK_IS_LINKED(s->state)); - /* The sink implementor may call this if the volume changed to make sure everyone is notified */ - - if (s->muted == new_muted) + if (s->set_mute_in_progress) return; - s->muted = new_muted; - s->save_muted = true; + /* pa_sink_set_mute() does this same check, so this may appear redundant, + * but we must have this here also, because the save parameter of + * pa_sink_set_mute() would otherwise have unintended side effects (saving + * the mute state when it shouldn't be saved). */ + if (new_muted == s->muted) + return; - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + pa_sink_set_mute(s, new_muted, true); } /* Called from main thread */ @@ -2738,7 +2745,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse case PA_SINK_MESSAGE_GET_MUTE: if (s->flags & PA_SINK_DEFERRED_VOLUME && s->get_mute) - s->get_mute(s); + return s->get_mute(s, userdata); return 0; @@ -3794,4 +3801,5 @@ void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume) { s->flags & PA_SINK_DECIBEL_VOLUME)); pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); + pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED], s); }