[pulseaudio-discuss] [PATCH v9] loopback: Correct corking logic during sink or source move
Tanu Kaskinen
tanuk at iki.fi
Fri Mar 17 20:50:45 UTC 2017
On Mon, 2017-02-27 at 18:17 +0100, Georg Chini wrote:
> The corking logic of module-loopback was incorrectly implemented. If you suspended
> the source, the sink input would be corked. When then the sink was suspended because
> of being idle, the source output was also corked. If you moved then away from the
> suspended source, module-loopback would not start the stream again, because sink
> input and source output were both corked. The same applied if the sink was suspended.
>
> This patch corrects this behavior. It also uncorks sink input or source output if the
> destination source or sink during a move is suspended because it is idle. This avoids
> unnecessary interruptions of the stream, which makes the latency reports used to
> correct the initial latency more reliable.
>
> The patch also takes profile switches into account, where sink and source become invalid
> at the same time. In this case, corking or uncorking must be delayed until the appropriate
> attach callback.
>
> ---
> src/modules/module-loopback.c | 98 +++++++++++++++++++++++++++++++++++--------
> 1 file changed, 81 insertions(+), 17 deletions(-)
> @@ -480,6 +487,15 @@ static void source_output_attach_cb(pa_source_output *o) {
> o->source->thread_info.rtpoll,
> PA_RTPOLL_LATE,
> u->asyncmsgq);
> +
> + /* Delayed state schange if necessary */
> + if (u->input_thread_info.delayed_source_output_state_change_required) {
> + u->input_thread_info.delayed_source_output_state_change_required = false;
> + if (u->input_thread_info.delayed_source_output_should_cork)
> + pa_source_output_set_state_within_thread(o, PA_SOURCE_OUTPUT_CORKED);
> + else
> + pa_source_output_set_state_within_thread(o, PA_SOURCE_OUTPUT_RUNNING);
> + }
pa_source_output_cork() does a bunch of things that
pa_source_output_set_state_within_thread() doesn't do, so it looks like
you can't replace the former with the latter.
Did you look into modifying pa_source_output_cork() so that it could be
called from the moving() callback? I had a look, and it seems that
there shouldn't be big problems with dealing with the case where o-
>source is NULL. Remember to update module-suspend-on-idle to deal with
that case in its PA_SOURCE_OUTPUT_STATE_CHANGED hook callback.
> @@ -598,11 +624,20 @@ static void source_output_suspend_cb(pa_source_output *o, bool suspended) {
> else
> u->output_thread_info.push_called = false;
>
> - } else
> + /* Do not cork the sink input if the source is suspended
> + * because the sink was suspended and the source output
> + * corked previously */
> + if (pa_source_output_get_state(u->source_output) != PA_SOURCE_OUTPUT_CORKED)
> + pa_sink_input_cork(u->sink_input, true);
I don't fully understand why the check is done before corking. Is it to
avoid corking the sink input if the source is idle-suspended? If so,
would it work if you changed the condition to checking the source's
suspend cause (that is, cork the sink input iff the source is idle-
suspended)?
> +
> + } else {
> /* Get effective source latency on unsuspend */
> update_effective_source_latency(u, u->source_output->source, u->sink_input->sink);
>
> - pa_sink_input_cork(u->sink_input, suspended);
> + /* Only uncork the sink input, if the sink is valid */
> + if (u->sink_input->sink)
> + pa_sink_input_cork(u->sink_input, false);
If the sink is not valid, what will trigger uncorking when the sink
becomes valid?
If it's possible to make the uncorking unconditional here, that would
make this simpler.
--
Tanu
https://www.patreon.com/tanuk
More information about the pulseaudio-discuss
mailing list