From 010c9f1b93da84bb66a42e10d82be5f3a498da6a Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 16 Jan 2024 13:29:57 +0100 Subject: [PATCH] audioconvert: also place resample output in rate_io We can also place the estimated size that the resampler will produce in the rate_io for output streams. See #3750 --- spa/plugins/audioconvert/audioconvert.c | 107 +++++++++++++----------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c index 6725a62e6..558df89ca 100644 --- a/spa/plugins/audioconvert/audioconvert.c +++ b/spa/plugins/audioconvert/audioconvert.c @@ -1826,6 +1826,52 @@ static int ensure_tmp(struct impl *this, uint32_t maxsize, uint32_t maxports) return 0; } +static uint32_t resample_update_rate_match(struct impl *this, bool passthrough, uint32_t size, uint32_t queued) +{ + uint32_t delay, match_size; + + if (passthrough) { + delay = 0; + match_size = size; + } else { + double rate = this->rate_scale / this->props.rate; + if (this->io_rate_match && + SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE)) + rate *= this->io_rate_match->rate; + resample_update_rate(&this->resample, rate); + delay = resample_delay(&this->resample); + if (this->direction == SPA_DIRECTION_INPUT) + match_size = resample_in_len(&this->resample, size); + else + match_size = resample_out_len(&this->resample, size); + } + match_size -= SPA_MIN(match_size, queued); + + spa_log_trace_fp(this->log, "%p: next match %u", this, match_size); + + if (this->io_rate_match) { + this->io_rate_match->delay = delay + queued; + this->io_rate_match->size = match_size; + } + return match_size; +} + +static inline bool resample_is_passthrough(struct impl *this) +{ + if (this->props.resample_disabled) + return true; + if (this->resample.i_rate != this->resample.o_rate) + return false; + if (this->rate_scale != 1.0) + return false; + if (this->rate_adjust) + return false; + if (this->io_rate_match != NULL && + SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE)) + return false; + return true; +} + static int setup_convert(struct impl *this) { struct dir *in, *out; @@ -2765,49 +2811,6 @@ static inline uint32_t resample_get_in_size(struct impl *this, bool passthrough, return match_size; } -static uint32_t resample_update_rate_match(struct impl *this, bool passthrough, uint32_t out_size, uint32_t in_queued) -{ - uint32_t delay, match_size; - - if (passthrough) { - delay = 0; - match_size = out_size; - } else { - double rate = this->rate_scale / this->props.rate; - if (this->io_rate_match && - SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE)) - rate *= this->io_rate_match->rate; - resample_update_rate(&this->resample, rate); - delay = resample_delay(&this->resample); - match_size = resample_in_len(&this->resample, out_size); - } - match_size -= SPA_MIN(match_size, in_queued); - - spa_log_trace_fp(this->log, "%p: next match %u", this, match_size); - - if (this->io_rate_match) { - this->io_rate_match->delay = delay + in_queued; - this->io_rate_match->size = match_size; - } - return match_size; -} - -static inline bool resample_is_passthrough(struct impl *this) -{ - if (this->props.resample_disabled) - return true; - if (this->resample.i_rate != this->resample.o_rate) - return false; - if (this->rate_scale != 1.0) - return false; - if (this->rate_adjust) - return false; - if (this->io_rate_match != NULL && - SPA_FLAG_IS_SET(this->io_rate_match->flags, SPA_IO_RATE_MATCH_FLAG_ACTIVE)) - return false; - return true; -} - static uint64_t get_time_ns(struct impl *impl) { struct timespec now; @@ -3272,10 +3275,20 @@ static int impl_node_process(void *object) spa_log_trace_fp(this->log, "%p: no output buffer", this); } } - if (resample_update_rate_match(this, resample_passthrough, - max_out - this->out_offset, - max_in - this->in_offset) > 0) - res |= SPA_STATUS_NEED_DATA; + { + uint32_t size, queued; + + if (this->direction == SPA_DIRECTION_INPUT) { + size = max_out - this->out_offset; + queued = max_in - this->in_offset; + } else { + size = quant_samples; + queued = 0; + } + if (resample_update_rate_match(this, resample_passthrough, + size, queued) > 0) + res |= SPA_STATUS_NEED_DATA; + } return res; }