From c62905d911485369556b68e074b1ec73162ef545 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 6ef6b71d4..fe7d47ab0 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;