summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor V. Kovalenko <igor.v.kovalenko@gmail.com>2021-11-03 01:14:26 +0300
committerPulseAudio Marge Bot <pulseaudio-maintainers@lists.freedesktop.org>2021-11-03 15:59:22 +0000
commit90ccfc1688cdf0b80c168702c43340581674ae54 (patch)
tree8959202173c04c298ebecc1ac701787f7fc3a195
parent15c9ee5fecd711cde63c2eb7ea386222a57bbef0 (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.c40
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) {