From 09a2b32d1e15038fc9ea248f9e000edf34429af8 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 16 Jan 2025 16:16:57 +0100 Subject: [PATCH] pulse-server: clear old data when jumping forwards When we write samples, check if we make a jump in the ringbuffer and clear the samples we jumped over. If we don't do this, the reader side might pick up old samples that we didn't write or clear but that are now available for reading after we made a jump in the ringbuffer. This migh not be exactly what pulseaudio does but it is good for now. Fixes #4464 --- src/modules/module-protocol-pulse/server.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/modules/module-protocol-pulse/server.c b/src/modules/module-protocol-pulse/server.c index 3e25eaad2..196e85d91 100644 --- a/src/modules/module-protocol-pulse/server.c +++ b/src/modules/module-protocol-pulse/server.c @@ -103,6 +103,15 @@ finish: return 0; } +static void stream_clear_data(struct stream *stream, + uint32_t offset, uint32_t len) +{ + uint32_t l0 = SPA_MIN(len, MAXLENGTH - offset), l1 = len - l0; + sample_spec_silence(&stream->ss, SPA_PTROFF(stream->buffer, offset, void), l0); + if (SPA_UNLIKELY(l1 > 0)) + sample_spec_silence(&stream->ss, stream->buffer, l1); +} + static int handle_memblock(struct client *client, struct message *msg) { struct stream *stream; @@ -149,6 +158,15 @@ static int handle_memblock(struct client *client, struct message *msg) goto finish; } + if (diff > 0) { + pw_log_debug("clear gap of %"PRIu64, diff); + /* if we jump forwards, clear the data we skipped because we might otherwise + * play back old data. FIXME, if the write pointer goes backwards and + * forwards, this might clear valid data. We should probably keep track of + * the highest write pointer and only clear when we go past that one. */ + stream_clear_data(stream, index % MAXLENGTH, SPA_MIN(diff, MAXLENGTH)); + } + index += diff; filled += diff; stream->write_index += diff;