resample: limit the amount of phases

If we have in and out rates with a very small GCD, we might end up with
a lot of phases. Limit the number of phases to 1024 and switch to
interpolating mode. 1024 phases is enough to accurately interpolate
from.

Together with the MAX_TAPS limit we will never create a filter
size that overflows 32 bits.

Fixes #5073
This commit is contained in:
Wim Taymans 2026-01-15 12:05:07 +01:00
parent f055cf398d
commit 9fdbe98330

View File

@ -13,6 +13,9 @@
SPA_LOG_TOPIC_DEFINE(resample_log_topic, "spa.resample");
#define MAX_TAPS (1u<<18)
#define MAX_PHASES 1024u
#define INHERIT_PARAM(c,q,p) if ((c)->params[p] == 0.0) (c)->params[p] = (q)->params[p];
struct quality {
@ -263,7 +266,7 @@ static void impl_native_update_rate(struct resample *r, double rate)
in_rate = UINT32_TO_FIXP(r->i_rate);
out_rate = r->o_rate;
if (rate != 1.0) {
if (rate != 1.0 || out_rate > data->n_phases) {
in_rate.value = (uint64_t)round(in_rate.value / rate);
data->func = data->info->process_inter;
}
@ -503,16 +506,17 @@ int resample_native_init(struct resample *r)
/* multiple of 8 taps to ease simd optimizations */
n_taps = SPA_ROUND_UP_N((uint32_t)ceil(n_taps / scale), 8);
n_taps = SPA_MIN(n_taps, 1u << 18);
n_taps = SPA_MIN(n_taps, MAX_TAPS);
/* try to get at least 256 phases so that interpolation is
* accurate enough when activated */
n_phases = out_rate;
n_phases = SPA_MIN(MAX_PHASES, out_rate);
oversample = (255 + n_phases) / n_phases;
n_phases *= oversample;
filter_stride = SPA_ROUND_UP_N(n_taps * sizeof(float), 64);
filter_size = filter_stride * (n_phases + 1);
history_stride = SPA_ROUND_UP_N(2 * n_taps * sizeof(float), 64);
history_size = r->channels * history_stride;