diff options
author | Igor V. Kovalenko <igor.v.kovalenko@gmail.com> | 2021-11-03 01:14:26 +0300 |
---|---|---|
committer | PulseAudio Marge Bot <pulseaudio-maintainers@lists.freedesktop.org> | 2021-11-03 15:59:22 +0000 |
commit | 90ccfc1688cdf0b80c168702c43340581674ae54 (patch) | |
tree | 8959202173c04c298ebecc1ac701787f7fc3a195 | |
parent | 15c9ee5fecd711cde63c2eb7ea386222a57bbef0 (diff) |
null-sink: Recalculate max_request and max_rewind while resuming sink
When sink is suspended for reconfiguration changing sample spec, upon resume
internal thread_info max_request and max_rewind are out of date and possibly
not aligned to frame size anymore.
Recalculate thread max_request and max_rewind before resuming sink.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/658>
-rw-r--r-- | src/modules/module-null-sink.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 7cb52cbaf..714a81a63 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -113,6 +113,25 @@ static int sink_process_msg( } /* Called from the IO thread. */ +static void sink_recalculate_max_request_and_rewind(pa_sink *s) { + struct userdata *u; + size_t nbytes; + + pa_sink_assert_ref(s); + pa_assert_se(u = s->userdata); + + nbytes = pa_usec_to_bytes(u->block_usec, &s->sample_spec); + + if (u->norewinds) { + pa_sink_set_max_rewind_within_thread(s, 0); + } else { + pa_sink_set_max_rewind_within_thread(s, nbytes); + } + + pa_sink_set_max_request_within_thread(s, nbytes); +} + +/* Called from the IO thread. */ static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_suspend_cause_t new_suspend_cause) { struct userdata *u; @@ -120,16 +139,23 @@ static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state, pa_assert_se(u = s->userdata); if (s->thread_info.state == PA_SINK_SUSPENDED || s->thread_info.state == PA_SINK_INIT) { - if (PA_SINK_IS_OPENED(new_state)) + if (PA_SINK_IS_OPENED(new_state)) { u->timestamp = pa_rtclock_now(); + + /* If sink was suspended to change sample formats, both + * thread_info.max_request and thread_info.max_rewind + * must be updated before first block is rendered + */ + sink_recalculate_max_request_and_rewind(s); + } } return 0; } +/* Called from the IO thread. */ static void sink_update_requested_latency_cb(pa_sink *s) { struct userdata *u; - size_t nbytes; pa_sink_assert_ref(s); pa_assert_se(u = s->userdata); @@ -139,15 +165,7 @@ static void sink_update_requested_latency_cb(pa_sink *s) { if (u->block_usec == (pa_usec_t) -1) u->block_usec = s->thread_info.max_latency; - nbytes = pa_usec_to_bytes(u->block_usec, &s->sample_spec); - - if(u->norewinds){ - pa_sink_set_max_rewind_within_thread(s, 0); - } else { - pa_sink_set_max_rewind_within_thread(s, nbytes); - } - - pa_sink_set_max_request_within_thread(s, nbytes); + sink_recalculate_max_request_and_rewind(s); } static void sink_reconfigure_cb(pa_sink *s, pa_sample_spec *spec, bool passthrough) { |