From 79fb95bf9028cc7cc30f6dfed0cf031e570b7c16 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 17 Nov 2020 17:15:26 +0100 Subject: [PATCH] stream: implement Flush Flush out pending samples in the resampler Set the io area status to _OK so that buffers are recycled and new buffers produced. --- spa/plugins/audioconvert/audioadapter.c | 3 +++ spa/plugins/audioconvert/audioconvert.c | 11 +++++++++++ spa/plugins/audioconvert/channelmix.c | 2 +- spa/plugins/audioconvert/fmtconvert.c | 2 +- spa/plugins/audioconvert/merger.c | 2 +- spa/plugins/audioconvert/resample.c | 16 ++++++++++++++-- spa/plugins/audioconvert/splitter.c | 2 +- src/pipewire/stream.c | 4 ++++ 8 files changed, 36 insertions(+), 6 deletions(-) diff --git a/spa/plugins/audioconvert/audioadapter.c b/spa/plugins/audioconvert/audioadapter.c index 0967f436a..42ed92111 100644 --- a/spa/plugins/audioconvert/audioadapter.c +++ b/spa/plugins/audioconvert/audioadapter.c @@ -517,6 +517,9 @@ static int impl_node_send_command(void *object, const struct spa_command *comman case SPA_NODE_COMMAND_Suspend: configure_format(this, 0, NULL); SPA_FALLTHROUGH + case SPA_NODE_COMMAND_Flush: + this->io_buffers.status = SPA_STATUS_OK; + SPA_FALLTHROUGH case SPA_NODE_COMMAND_Pause: this->started = false; break; diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c index 618f96afa..dbeeccf0f 100644 --- a/spa/plugins/audioconvert/audioconvert.c +++ b/spa/plugins/audioconvert/audioconvert.c @@ -388,6 +388,14 @@ static int negotiate_link_buffers(struct impl *this, struct link *link) return 0; } +static void flush_convert(struct impl *this) +{ + int i; + spa_log_debug(this->log, NAME " %p: %d", this, this->n_links); + for (i = 0; i < this->n_links; i++) + this->links[i].io.status = SPA_STATUS_OK; +} + static void clean_convert(struct impl *this) { int i; @@ -809,6 +817,9 @@ static int impl_node_send_command(void *object, const struct spa_command *comman case SPA_NODE_COMMAND_Suspend: clean_convert(this); SPA_FALLTHROUGH + case SPA_NODE_COMMAND_Flush: + flush_convert(this); + SPA_FALLTHROUGH case SPA_NODE_COMMAND_Pause: this->started = false; break; diff --git a/spa/plugins/audioconvert/channelmix.c b/spa/plugins/audioconvert/channelmix.c index 674981d23..f22a41226 100644 --- a/spa/plugins/audioconvert/channelmix.c +++ b/spa/plugins/audioconvert/channelmix.c @@ -466,7 +466,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman this->started = true; break; case SPA_NODE_COMMAND_Suspend: - SPA_FALLTHROUGH + case SPA_NODE_COMMAND_Flush: case SPA_NODE_COMMAND_Pause: this->started = false; break; diff --git a/spa/plugins/audioconvert/fmtconvert.c b/spa/plugins/audioconvert/fmtconvert.c index 9c7fb42aa..5c17c9848 100644 --- a/spa/plugins/audioconvert/fmtconvert.c +++ b/spa/plugins/audioconvert/fmtconvert.c @@ -248,7 +248,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman this->started = true; break; case SPA_NODE_COMMAND_Suspend: - SPA_FALLTHROUGH + case SPA_NODE_COMMAND_Flush: case SPA_NODE_COMMAND_Pause: this->started = false; break; diff --git a/spa/plugins/audioconvert/merger.c b/spa/plugins/audioconvert/merger.c index 6c3007b81..5442318e3 100644 --- a/spa/plugins/audioconvert/merger.c +++ b/spa/plugins/audioconvert/merger.c @@ -348,7 +348,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman this->started = true; break; case SPA_NODE_COMMAND_Suspend: - SPA_FALLTHROUGH + case SPA_NODE_COMMAND_Flush: case SPA_NODE_COMMAND_Pause: this->started = false; break; diff --git a/spa/plugins/audioconvert/resample.c b/spa/plugins/audioconvert/resample.c index 5751a4838..4d62a418a 100644 --- a/spa/plugins/audioconvert/resample.c +++ b/spa/plugins/audioconvert/resample.c @@ -248,6 +248,17 @@ static void update_rate_match(struct impl *this) } } +static void reset_node(struct impl *this) +{ + struct port *outport, *inport; + outport = GET_OUT_PORT(this, 0); + inport = GET_IN_PORT(this, 0); + + resample_reset(&this->resample); + outport->offset = 0; + inport->offset = 0; +} + static int impl_node_send_command(void *object, const struct spa_command *command) { struct impl *this = object; @@ -262,9 +273,10 @@ static int impl_node_send_command(void *object, const struct spa_command *comman update_rate_match(this); break; case SPA_NODE_COMMAND_Suspend: - SPA_FALLTHROUGH + case SPA_NODE_COMMAND_Flush: + reset_node(this); + SPA_FALLTHROUGH; case SPA_NODE_COMMAND_Pause: - resample_reset(&this->resample); this->started = false; break; default: diff --git a/spa/plugins/audioconvert/splitter.c b/spa/plugins/audioconvert/splitter.c index 797b90200..950fecb4e 100644 --- a/spa/plugins/audioconvert/splitter.c +++ b/spa/plugins/audioconvert/splitter.c @@ -330,7 +330,7 @@ static int impl_node_send_command(void *object, const struct spa_command *comman this->started = true; break; case SPA_NODE_COMMAND_Suspend: - SPA_FALLTHROUGH + case SPA_NODE_COMMAND_Flush: case SPA_NODE_COMMAND_Pause: this->started = false; break; diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 3c7593317..bc5503701 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -388,6 +388,7 @@ static int impl_send_command(void *object, const struct spa_command *command) switch (SPA_NODE_COMMAND_ID(command)) { case SPA_NODE_COMMAND_Suspend: + case SPA_NODE_COMMAND_Flush: case SPA_NODE_COMMAND_Pause: pw_loop_invoke(impl->context->main_loop, NULL, 0, NULL, 0, false, impl); @@ -1897,5 +1898,8 @@ int pw_stream_flush(struct pw_stream *stream, bool drain) struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); pw_loop_invoke(impl->context->data_loop, drain ? do_drain : do_flush, 1, NULL, 0, true, impl); + if (!drain) + spa_node_send_command(impl->node->node, + &SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Flush)); return 0; }