From cfaf424ed81a71dbf781875bb7ea0b7f9b6a8c7c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 16 Jun 2023 11:12:51 +0200 Subject: [PATCH] module-loopback: always dequeue the last capture buffer Because the capture triggers the playback stream, the playback stream might not be actually triggered when the stream is not running. This can cause a buffer to be queued in the capture side that is never dequeued from the playback side. If 2 buffers are queued (and 2 buffers are available on the stream), the capture source has no more buffers and starts to drop/stutter. Fix this problem by always dequeueing/queuing all the queued buffers so that we always use the last one. See #3276 --- src/modules/module-filter-chain.c | 11 ++++++++++- src/modules/module-loopback.c | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/modules/module-filter-chain.c b/src/modules/module-filter-chain.c index 3550871c3..ae42ba974 100644 --- a/src/modules/module-filter-chain.c +++ b/src/modules/module-filter-chain.c @@ -685,7 +685,16 @@ static void playback_process(void *d) struct graph_port *port; struct spa_data *bd; - if ((in = pw_stream_dequeue_buffer(impl->capture)) == NULL) + in = NULL; + while (true) { + struct pw_buffer *t; + if ((t = pw_stream_dequeue_buffer(impl->capture)) == NULL) + break; + if (in) + pw_stream_queue_buffer(impl->capture, in); + in = t; + } + if (in == NULL) pw_log_debug("%p: out of capture buffers: %m", impl); if ((out = pw_stream_dequeue_buffer(impl->playback)) == NULL) diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c index 9e9b3d926..a2328086b 100644 --- a/src/modules/module-loopback.c +++ b/src/modules/module-loopback.c @@ -233,11 +233,20 @@ static void playback_process(void *d) impl->recalc_delay = false; } - if ((in = pw_stream_dequeue_buffer(impl->capture)) == NULL) - pw_log_debug("out of capture buffers: %m"); + in = NULL; + while (true) { + struct pw_buffer *t; + if ((t = pw_stream_dequeue_buffer(impl->capture)) == NULL) + break; + if (in) + pw_stream_queue_buffer(impl->capture, in); + in = t; + } + if (in == NULL) + pw_log_debug("%p: out of capture buffers: %m", impl); if ((out = pw_stream_dequeue_buffer(impl->playback)) == NULL) - pw_log_debug("out of playback buffers: %m"); + pw_log_debug("%p: out of playback buffers: %m", impl); if (in != NULL && out != NULL) { uint32_t outsize = UINT32_MAX;