From 3804376ccce6d7b3b9a93cbc53b490705d2b6f3e Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 12 Oct 2015 21:12:05 +0200 Subject: af_lavrresample: reinit resampler on large speed changes swr/avresample_set_compensation() was made for small speed adjustments. Non-documentation says it should be used for changes not larger than 1%, so reinitialize the sampler if the change is larger than that. --- audio/filter/af_lavrresample.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'audio') diff --git a/audio/filter/af_lavrresample.c b/audio/filter/af_lavrresample.c index b21b4d84c1..b73f0d8d0e 100644 --- a/audio/filter/af_lavrresample.c +++ b/audio/filter/af_lavrresample.c @@ -513,21 +513,25 @@ static int filter(struct af_instance *af, struct mp_audio *in) { struct af_resample *s = af->priv; - int in_samples = in ? in->samples : 0; - int wanted_samples = lrint(in_samples / s->playback_speed); - - if (avresample_set_compensation(s->avrctx, - (wanted_samples - in_samples) * s->out_rate / s->in_rate, - wanted_samples * s->out_rate / s->in_rate) < 0) - { - int new_rate = rate_from_speed(s->in_rate_af, s->playback_speed); - if (new_rate != s->in_rate && s->avrctx && af->fmt_out.format) { - // Before reconfiguring, drain the audio that is still buffered - // in the resampler. - filter_resample(af, NULL); - // Reinitialize resampler. - configure_lavrr(af, &af->fmt_in, &af->fmt_out, false); - } + int new_rate = rate_from_speed(s->in_rate_af, s->playback_speed); + bool need_reinit = fabs(new_rate / (double)s->in_rate - 1) > 0.01; + + if (!need_reinit && s->avrctx) { + double speed_factor = s->playback_speed * s->in_rate_af / s->in_rate; + int in_samples = in ? in->samples : 0; + int wanted_samples = lrint(in_samples / speed_factor); + if (avresample_set_compensation(s->avrctx, + (wanted_samples - in_samples) * s->out_rate / s->in_rate, + wanted_samples * s->out_rate / s->in_rate) < 0) + need_reinit = true; + } + + if (need_reinit && new_rate != s->in_rate) { + // Before reconfiguring, drain the audio that is still buffered + // in the resampler. + filter_resample(af, NULL); + // Reinitialize resampler. + configure_lavrr(af, &af->fmt_in, &af->fmt_out, false); } return filter_resample(af, in); -- cgit v1.2.3