summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-10-12 21:12:05 +0200
committerwm4 <wm4@nowhere>2015-10-12 21:12:05 +0200
commit3804376ccce6d7b3b9a93cbc53b490705d2b6f3e (patch)
tree904096e3e1216e5da3bb1629363d5520886d9784 /audio
parentbddd1e9e3b5907a1f6b50d8363ac0ca16bd1513f (diff)
downloadmpv-3804376ccce6d7b3b9a93cbc53b490705d2b6f3e.tar.bz2
mpv-3804376ccce6d7b3b9a93cbc53b490705d2b6f3e.tar.xz
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.
Diffstat (limited to 'audio')
-rw-r--r--audio/filter/af_lavrresample.c34
1 files changed, 19 insertions, 15 deletions
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);