mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 12:02:23 +02:00
audio/filter: fix mul/delay scale and values
Before this commit, the af_instance->mul/delay values were in bytes. Using bytes is confusing for non-interleaved audio, so switch mul to samples, and delay to seconds. For delay, seconds are more intuitive than bytes or samples, because it's used for the latency calculation. We also might want to replace the delay mechanism with real PTS tracking inside the filter chain some time in the future, and PTS will also require time-adjustments to be done in seconds. For most filters, we just remove the redundant mul=1 initialization. (Setting this used to be required, but not anymore.)
This commit is contained in:
parent
7510caa0c5
commit
824e6550f8
@ -312,10 +312,9 @@ int decode_audio(sh_audio_t *sh_audio, struct mp_audio_buffer *outbuf,
|
||||
max_decode_len -= max_decode_len % unitsize;
|
||||
|
||||
while (minsamples >= 0 && mp_audio_buffer_samples(outbuf) < minsamples) {
|
||||
struct af_stream *afs = sh_audio->afilter;
|
||||
int out_sstride = afs->output.sstride;
|
||||
int declen = (minsamples - mp_audio_buffer_samples(outbuf))
|
||||
* out_sstride / filter_multiplier;
|
||||
int decsamples = (minsamples - mp_audio_buffer_samples(outbuf))
|
||||
/ filter_multiplier;
|
||||
int declen = decsamples * sstride;
|
||||
// + some extra for possible filter buffering
|
||||
declen += unitsize << 5;
|
||||
if (huge_filter_buffer)
|
||||
|
@ -703,12 +703,12 @@ struct mp_audio *af_play(struct af_stream *s, struct mp_audio *data)
|
||||
return data;
|
||||
}
|
||||
|
||||
// Calculate average ratio of filter output size to input size
|
||||
// Calculate average ratio of filter output samples to input samples.
|
||||
// e.g: num_output_samples = mul * num_input_samples
|
||||
double af_calc_filter_multiplier(struct af_stream *s)
|
||||
{
|
||||
struct af_instance *af = s->first;
|
||||
double mul = 1;
|
||||
// Iterate through all filters and calculate total multiplication factor
|
||||
do {
|
||||
mul *= af->mul;
|
||||
af = af->next;
|
||||
@ -721,11 +721,9 @@ double af_calc_filter_multiplier(struct af_stream *s)
|
||||
double af_calc_delay(struct af_stream *s)
|
||||
{
|
||||
struct af_instance *af = s->first;
|
||||
register double delay = 0.0;
|
||||
// Iterate through all filters
|
||||
double delay = 0.0;
|
||||
while (af) {
|
||||
delay += af->delay;
|
||||
delay *= af->mul;
|
||||
af = af->next;
|
||||
}
|
||||
return delay;
|
||||
|
@ -64,10 +64,11 @@ struct af_instance {
|
||||
struct mp_audio *data; // configuration and buffer for outgoing data stream
|
||||
struct af_instance *next;
|
||||
struct af_instance *prev;
|
||||
double delay; /* Delay caused by the filter, in units of bytes read without
|
||||
* corresponding output */
|
||||
double delay; /* Delay caused by the filter, in seconds of audio consumed
|
||||
* without corresponding output */
|
||||
double mul; /* length multiplier: how much does this instance change
|
||||
the length of the buffer. */
|
||||
* the number of samples passed though. (Ratio of input
|
||||
* and output, e.g. mul=4 => 1 sample becomes 4 samples) .*/
|
||||
bool auto_inserted; // inserted by af.c, such as conversion filters
|
||||
};
|
||||
|
||||
|
@ -171,7 +171,6 @@ static int af_open(struct af_instance *af)
|
||||
struct af_bs2b *s = af->priv;
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->mul = 1;
|
||||
|
||||
// NULL means failed initialization
|
||||
if (!(s->filter = bs2b_open())) {
|
||||
|
@ -107,7 +107,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=s=calloc(1,sizeof(af_center_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -168,7 +168,6 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
|
||||
af->data->rate = ((struct mp_audio*)arg)->rate;
|
||||
mp_audio_set_format(af->data, ((struct mp_audio*)arg)->format);
|
||||
af->mul = (double)af->data->nch / ((struct mp_audio*)arg)->nch;
|
||||
mp_audio_force_interleaved_format(af->data);
|
||||
int r = af_test_output(af,(struct mp_audio*)arg);
|
||||
if (r != AF_OK)
|
||||
@ -255,7 +254,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=calloc(1,sizeof(af_channels_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -53,8 +53,6 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
|
||||
assert(test_conversion(in->format, out->format));
|
||||
|
||||
af->mul = (double)out->bps / in->bps;
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET: {
|
||||
|
@ -120,7 +120,6 @@ static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=calloc(1,sizeof(af_delay_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -319,7 +319,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=calloc(1,sizeof(af_drc_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -53,7 +53,6 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data)
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
bp2(s->a[k],s->b[k],F[k]/((float)af->data->rate),Q);
|
||||
|
||||
// Calculate how much this plugin adds to the overall time delay
|
||||
af->delay = 2 * af->data->nch * af->data->bps;
|
||||
af->delay = 2.0 / (double)af->data->rate;
|
||||
|
||||
// Calculate gain factor to prevent clipping at output
|
||||
for(k=0;k<AF_NCH;k++)
|
||||
@ -203,7 +203,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=calloc(1,sizeof(af_equalizer_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -256,7 +256,6 @@ static int af_open( struct af_instance* af )
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->play = play;
|
||||
af->mul=1;
|
||||
af->setup = calloc(1, sizeof(af_export_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -128,7 +128,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play_s16;
|
||||
af->mul=1;
|
||||
af->setup=calloc(1,sizeof(af_extrastereo_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -106,7 +106,6 @@ static int af_open(struct af_instance *af)
|
||||
{
|
||||
af->control = control;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
|
||||
force_in_params(af, af->data);
|
||||
force_out_params(af, af->data);
|
||||
|
@ -313,7 +313,6 @@ static int control(struct af_instance *af, int cmd, void* arg)
|
||||
mp_audio_set_channels_old(af->data, 5);
|
||||
mp_audio_set_format(af->data, AF_FORMAT_S16_NE);
|
||||
test_output_res = af_test_output(af, (struct mp_audio*)arg);
|
||||
af->mul = 2.0 / af->data->nch;
|
||||
// after testing input set the real output format
|
||||
mp_audio_set_num_channels(af->data, 2);
|
||||
s->print_flag = 1;
|
||||
@ -598,7 +597,6 @@ static int af_open(struct af_instance* af)
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
af->setup = calloc(1, sizeof(af_hrtf_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -69,7 +69,6 @@ static struct mp_audio* play(struct af_instance* af, struct mp_audio* data)
|
||||
static int af_open(struct af_instance* af){
|
||||
af->control = control;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
return AF_OK;
|
||||
}
|
||||
|
||||
|
@ -875,7 +875,6 @@ static int af_open(struct af_instance *af) {
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
|
||||
af->setup = calloc(1, sizeof(af_ladspa_t));
|
||||
if (af->setup == NULL) {
|
||||
|
@ -88,12 +88,13 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
test_output_res = af_test_output(af, data);
|
||||
|
||||
s->pending_len = 0;
|
||||
s->expect_len = AC3_FRAME_SIZE * data->nch * af->data->bps;
|
||||
int expect_samples = AC3_FRAME_SIZE;
|
||||
s->expect_len = expect_samples * data->nch * af->data->bps;
|
||||
assert(s->expect_len <= s->pending_data_size);
|
||||
if (s->add_iec61937_header)
|
||||
af->mul = (double)AC3_FRAME_SIZE * 2 * 2 / s->expect_len;
|
||||
af->mul = 1;
|
||||
else
|
||||
af->mul = (double)AC3_MAX_CODED_FRAME_SIZE / s->expect_len;
|
||||
af->mul = (double)(AC3_MAX_CODED_FRAME_SIZE / (2 * 2)) / expect_samples;
|
||||
|
||||
mp_msg(MSGT_AFILTER, MSGL_DBG2, "af_lavcac3enc reinit: %d, %d, %f, %d.\n",
|
||||
data->nch, data->rate, af->mul, s->expect_len);
|
||||
@ -306,7 +307,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=s;
|
||||
|
||||
s->lavc_acodec = avcodec_find_encoder_by_name("ac3");
|
||||
|
@ -197,7 +197,8 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
|
||||
p->timebase_out = l_out->time_base;
|
||||
|
||||
af->mul = (double) (out->rate * out->nch) / (in->rate * in->nch);
|
||||
// Blatantly incorrect; we don't know what the filters do.
|
||||
af->mul = out->rate / (double)in->rate;
|
||||
|
||||
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
|
||||
}
|
||||
@ -270,7 +271,7 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
|
||||
// Need pts past the last output sample.
|
||||
out_time += r->samples / (double)r->rate;
|
||||
|
||||
af->delay = (in_time - out_time) * r->rate * r->sstride;
|
||||
af->delay = in_time - out_time;
|
||||
}
|
||||
|
||||
*data = *r;
|
||||
@ -286,7 +287,6 @@ static int af_open(struct af_instance *af)
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
struct priv *priv = af->priv;
|
||||
af->data = talloc_zero(priv, struct mp_audio),
|
||||
// Removing this requires fixing AVFrame.data vs. AVFrame.extended_data
|
||||
|
@ -249,8 +249,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
if (af_to_avformat(out->format) == AV_SAMPLE_FMT_NONE)
|
||||
mp_audio_set_format(out, in->format);
|
||||
|
||||
af->mul = (double) (out->rate * out->nch) / (in->rate * in->nch);
|
||||
af->delay = out->nch * s->opts.filter_size / FFMIN(af->mul, 1);
|
||||
af->mul = out->rate / (double)in->rate;
|
||||
|
||||
int r = ((in->format == orig_in.format) &&
|
||||
mp_chmap_equals(&in->channels, &orig_in.channels))
|
||||
@ -333,9 +332,7 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
|
||||
|
||||
mp_audio_realloc_min(out, out->samples);
|
||||
|
||||
af->delay = out->bps * av_rescale_rnd(get_delay(s),
|
||||
s->ctx.out_rate, s->ctx.in_rate,
|
||||
AV_ROUND_UP);
|
||||
af->delay = get_delay(s) / (double)s->ctx.in_rate;
|
||||
|
||||
#if !USE_SET_CHANNEL_MAPPING
|
||||
do_reorder(in, s->reorder_in);
|
||||
@ -380,7 +377,6 @@ static int af_open(struct af_instance *af)
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
|
||||
if (s->opts.cutoff <= 0.0)
|
||||
s->opts.cutoff = af_resample_default_cutoff(s->opts.filter_size);
|
||||
|
@ -57,7 +57,6 @@ static int control(struct af_instance* af, int cmd, void* arg)
|
||||
af->data->rate = ((struct mp_audio*)arg)->rate;
|
||||
mp_audio_set_format(af->data, AF_FORMAT_FLOAT_NE);
|
||||
set_channels(af->data, s->nch ? s->nch: ((struct mp_audio*)arg)->nch);
|
||||
af->mul = (double)af->data->nch / ((struct mp_audio*)arg)->nch;
|
||||
|
||||
if((af->data->format != ((struct mp_audio*)arg)->format) ||
|
||||
(af->data->bps != ((struct mp_audio*)arg)->bps)){
|
||||
@ -191,7 +190,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=calloc(1,sizeof(af_pan_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -256,7 +256,8 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
|
||||
// This filter can have a negative delay when scale > 1:
|
||||
// output corresponding to some length of input can be decided and written
|
||||
// after receiving only a part of that input.
|
||||
af->delay = s->bytes_queued - s->bytes_to_slide;
|
||||
af->delay = (s->bytes_queued - s->bytes_to_slide) / s->scale
|
||||
/ af->data->sstride / af->data->rate;
|
||||
|
||||
data->planes[0] = af->data->planes[0];
|
||||
data->samples = (pout - (int8_t *)af->data->planes[0]) / af->data->sstride;
|
||||
@ -299,9 +300,8 @@ static int control(struct af_instance *af, int cmd, void *arg)
|
||||
s->frames_stride = srate * s->ms_stride;
|
||||
s->bytes_stride = s->frames_stride * bps * nch;
|
||||
s->frames_stride_scaled = s->scale * s->frames_stride;
|
||||
int bytes_stride_scaled = s->scale * s->bytes_stride;
|
||||
s->frames_stride_error = 0;
|
||||
af->mul = (double)s->bytes_stride / bytes_stride_scaled;
|
||||
af->mul = 1.0 / s->scale;
|
||||
af->delay = 0;
|
||||
|
||||
int frames_overlap = s->frames_stride * s->percent_overlap;
|
||||
@ -462,7 +462,6 @@ static int af_open(struct af_instance *af)
|
||||
af->control = control;
|
||||
af->uninit = uninit;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
|
||||
s->speed_tempo = !!(s->speed_opt & SCALE_TEMPO);
|
||||
s->speed_pitch = !!(s->speed_opt & SCALE_PITCH);
|
||||
|
@ -148,7 +148,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play_s16;
|
||||
af->mul=1;
|
||||
af->setup=calloc(1,sizeof(af_sinesuppress_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -165,7 +165,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=s=calloc(1,sizeof(af_sub_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -243,7 +243,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=2;
|
||||
af->setup=calloc(1,sizeof(af_surround_t));
|
||||
if(af->setup == NULL)
|
||||
return AF_ERROR;
|
||||
|
@ -84,7 +84,6 @@ static int af_open(struct af_instance* af){
|
||||
af->control=control;
|
||||
af->uninit=uninit;
|
||||
af->play=play;
|
||||
af->mul=1;
|
||||
af->setup=calloc(1,sizeof(af_sweept));
|
||||
return AF_OK;
|
||||
}
|
||||
|
@ -104,7 +104,6 @@ static int af_open(struct af_instance *af)
|
||||
struct priv *s = af->priv;
|
||||
af->control = control;
|
||||
af->play = play;
|
||||
af->mul = 1;
|
||||
af_from_dB(1, &s->cfg_volume, &s->level, 20.0, -200.0, 60.0);
|
||||
return AF_OK;
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ double written_audio_pts(struct MPContext *mpctx)
|
||||
a_pts -= sh_audio->a_buffer_len / bps;
|
||||
|
||||
// Data buffered in audio filters, measured in seconds of "missing" output
|
||||
double buffered_output = af_calc_delay(sh_audio->afilter) / mpctx->ao->bps;
|
||||
double buffered_output = af_calc_delay(sh_audio->afilter);
|
||||
|
||||
// Data that was ready for ao but was buffered because ao didn't fully
|
||||
// accept everything to internal buffers yet
|
||||
|
Loading…
Reference in New Issue
Block a user