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
This commit is contained in:
Wim Taymans 2025-01-16 16:16:57 +01:00
parent cf7e917024
commit c62905d911

View file

@ -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;