stream: clear buffer from io when clearing buffers

If a provider uses the stream API and pushes a buffer to the stream
after the stream is set to paused, the buffer_id of the last buffer
remains in the io.

If a consumer starts streaming in this state, the buffer_id of the old
buffer is still in the io. The consumer receives a stale buffer_id and
may discard the buffer. Now the buffer is lost, since it is still marked
as busy on the producer.

This can be reproduced by starting Weston with the PipeWire backend and
repeatedly restarting a GStreamer pipeline that connects to the Weston
output. Eventually Weston won't be able to dequeue buffers since the
lost buffer is still busy.

Clear the buffers in the io when the buffers are cleared to avoid
sending an old buffer_id to the consumer.
This commit is contained in:
Michael Tretter 2025-01-28 11:39:35 +01:00 committed by Wim Taymans
parent 5ac432e5be
commit aca566a02d

View file

@ -819,8 +819,14 @@ static void clear_buffers(struct pw_stream *stream)
if (b->busy)
SPA_ATOMIC_DEC(b->busy->count);
}
} else
} else {
clear_queue(impl, &impl->dequeued);
struct spa_io_buffers *io = impl->io;
if (io && io->status == SPA_STATUS_HAVE_DATA) {
io->status = SPA_ID_INVALID;
io->buffer_id = SPA_STATUS_OK;
}
}
clear_queue(impl, &impl->queued);
}