stream: Only request more data when needed

When we are not working RT, only request a buffer when we recycled one
or when we had no buffers in the queue.

The reason is that we only want to request a new buffer when the
converter recycled a buffer and thus when the resampler has a new
input size suggestion.

We also want to request a new buffer when there is no new buffer to
queue. This would be an underrun but we need to keep on requesting
buffers in this case or else we stall forever.
This commit is contained in:
Wim Taymans 2022-03-28 15:04:52 +02:00
parent 7b845aa732
commit 31b31a6f97

View file

@ -987,16 +987,19 @@ static int impl_node_process_output(void *object)
struct buffer *b; struct buffer *b;
int res; int res;
uint32_t index; uint32_t index;
bool recycled;
again: again:
pw_log_trace("%p: process out status:%d id:%d", stream, pw_log_trace("%p: process out status:%d id:%d", stream,
io->status, io->buffer_id); io->status, io->buffer_id);
recycled = false;
if ((res = io->status) != SPA_STATUS_HAVE_DATA) { if ((res = io->status) != SPA_STATUS_HAVE_DATA) {
/* recycle old buffer */ /* recycle old buffer */
if ((b = get_buffer(stream, io->buffer_id)) != NULL) { if ((b = get_buffer(stream, io->buffer_id)) != NULL) {
pw_log_trace("%p: recycle buffer %d", stream, b->id); pw_log_trace("%p: recycle buffer %d", stream, b->id);
push_queue(impl, &impl->dequeued, b); push_queue(impl, &impl->dequeued, b);
recycled = true;
} }
/* pop new buffer */ /* pop new buffer */
@ -1023,12 +1026,12 @@ again:
if (!impl->draining && !impl->driving) { if (!impl->draining && !impl->driving) {
/* we're not draining, not a driver check if we need to get /* we're not draining, not a driver check if we need to get
* more buffers */ * more buffers */
if (!impl->process_rt) { if (!impl->process_rt && (recycled || res == SPA_STATUS_NEED_DATA)) {
/* not realtime and we have a free buffer, trigger process so that we have /* not realtime and we have a free buffer, trigger process so that we have
* data in the next round. */ * data in the next round. */
if (spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index) > 0) if (spa_ringbuffer_get_read_index(&impl->dequeued.ring, &index) > 0)
call_process(impl); call_process(impl);
} else if (io->status == SPA_STATUS_NEED_DATA) { } else if (res == SPA_STATUS_NEED_DATA) {
/* realtime and we don't have a buffer, trigger process and try /* realtime and we don't have a buffer, trigger process and try
* again when there is something in the queue now */ * again when there is something in the queue now */
call_process(impl); call_process(impl);