mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 20:03:10 +02:00
af_lavrresample: use libswsresample dynamic rate adjustment feature
swr_set_compensation() changes the apparent sample rate on the fly (who would have guessed). It is thus very well-suited for adjusting audio speed on the fly during playback (like needed by the display-sync mode). It skips the relatively slow resampler reinitialization. If this doesn't work (libswresample soxr backend), then fall back to the old method.
This commit is contained in:
parent
aa796c23db
commit
280251656c
@ -49,6 +49,7 @@
|
||||
#define avresample_convert(ctx, out, out_planesize, out_samples, in, in_planesize, in_samples) \
|
||||
swr_convert(ctx, out, out_samples, (const uint8_t**)(in), in_samples)
|
||||
#define avresample_set_channel_mapping swr_set_channel_mapping
|
||||
#define avresample_set_compensation swr_set_compensation
|
||||
#else
|
||||
#error "config.h broken or no resampler found"
|
||||
#endif
|
||||
@ -386,14 +387,6 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
return AF_OK;
|
||||
case AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE: {
|
||||
s->playback_speed = *(double *)arg;
|
||||
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.
|
||||
af->filter_frame(af, NULL);
|
||||
// Reinitialize resampler.
|
||||
configure_lavrr(af, &af->fmt_in, &af->fmt_out, false);
|
||||
}
|
||||
return AF_OK;
|
||||
}
|
||||
case AF_CONTROL_RESET:
|
||||
@ -455,7 +448,7 @@ static void reorder_planes(struct mp_audio *mpa, int *reorder,
|
||||
}
|
||||
}
|
||||
|
||||
static int filter(struct af_instance *af, struct mp_audio *in)
|
||||
static int filter_resample(struct af_instance *af, struct mp_audio *in)
|
||||
{
|
||||
struct af_resample *s = af->priv;
|
||||
|
||||
@ -516,6 +509,30 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return filter_resample(af, in);
|
||||
}
|
||||
|
||||
static int af_open(struct af_instance *af)
|
||||
{
|
||||
struct af_resample *s = af->priv;
|
||||
|
Loading…
Reference in New Issue
Block a user