From e6019ebc94676a79d16bc53a5b5586e69de7a5a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= Date: Thu, 26 Mar 2026 15:44:35 +0100 Subject: [PATCH] spa: videotestsrc: recycle when triggered It is expected that the current buffer is recycled if the status is not `SPA_STATUS_HAVE_DATA` when the driving node is triggered. See #5190 See !2760 --- spa/plugins/videotestsrc/videotestsrc.c | 40 ++++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c index a8d7059c8..a85b818f5 100644 --- a/spa/plugins/videotestsrc/videotestsrc.c +++ b/spa/plugins/videotestsrc/videotestsrc.c @@ -263,7 +263,6 @@ static int make_buffer(struct impl *this) uint32_t n_bytes; if (spa_list_is_empty(&port->empty)) { - set_timer(this, false); spa_log_error(this->log, "%p: out of buffers", this); return -EPIPE; } @@ -289,7 +288,6 @@ static int make_buffer(struct impl *this) this->frame_count++; this->elapsed_time = FRAMES_TO_TIME(port, this->frame_count); - set_timer(this, true); io->buffer_id = b->id; io->status = SPA_STATUS_HAVE_DATA; @@ -297,15 +295,40 @@ static int make_buffer(struct impl *this) return io->status; } +static inline void reuse_buffer(struct impl *this, struct port *port, uint32_t id) +{ + struct buffer *b = &port->buffers[id]; + spa_return_if_fail(b->outstanding); + + spa_log_trace(this->log, "%p: reuse buffer %d", this, id); + + b->outstanding = false; + spa_list_append(&port->empty, &b->link); +} + static void on_output(void* data, uint64_t expirations) { struct impl *this = data; - int res; + struct port *port = &this->port; + struct spa_io_buffers *io = port->io; + int res = SPA_STATUS_OK; + + if (!io || io->status == SPA_STATUS_HAVE_DATA) + goto out; + + if (io->buffer_id < port->n_buffers) { + reuse_buffer(this, port, io->buffer_id); + io->buffer_id = SPA_ID_INVALID; + } res = make_buffer(this); if (res == SPA_STATUS_HAVE_DATA) spa_node_call_ready(&this->callbacks, res); + +out: + if (res >= 0) + set_timer(this, true); } static int impl_node_send_command(void *object, const struct spa_command *command) @@ -717,17 +740,6 @@ impl_node_port_set_io(void *object, return 0; } -static inline void reuse_buffer(struct impl *this, struct port *port, uint32_t id) -{ - struct buffer *b = &port->buffers[id]; - spa_return_if_fail(b->outstanding); - - spa_log_trace(this->log, "%p: reuse buffer %d", this, id); - - b->outstanding = false; - spa_list_append(&port->empty, &b->link); -} - static int impl_node_port_reuse_buffer(void *object, uint32_t port_id, uint32_t buffer_id) { struct impl *this = object;