diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c index fab751cb9f..4acc24ccac 100644 --- a/libavfilter/af_afir.c +++ b/libavfilter/af_afir.c @@ -298,8 +298,6 @@ static int convert_coeffs(AVFilterContext *ctx, int selir) part_size = 1 << av_log2(s->minp); max_part_size = 1 << av_log2(s->maxp); - s->min_part_size = part_size; - for (int i = 0; left > 0; i++) { int step = part_size == max_part_size ? INT_MAX : 1 + (i == 0); int nb_partitions = FFMIN(step, (left + part_size - 1) / part_size); @@ -592,6 +590,36 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!s->loading) return AVERROR(ENOMEM); + s->xfade[0] = ff_get_audio_buffer(outlink, s->min_part_size); + s->xfade[1] = ff_get_audio_buffer(outlink, s->min_part_size); + if (!s->xfade[0] || !s->xfade[1]) + return AVERROR(ENOMEM); + + switch (s->format) { + case AV_SAMPLE_FMT_FLTP: + for (int ch = 0; ch < s->nb_channels; ch++) { + float *dst0 = (float *)s->xfade[0]->extended_data[ch]; + float *dst1 = (float *)s->xfade[1]->extended_data[ch]; + + for (int n = 0; n < s->min_part_size; n++) { + dst0[n] = (n + 1.f) / s->min_part_size; + dst1[n] = 1.f - dst0[n]; + } + } + break; + case AV_SAMPLE_FMT_DBLP: + for (int ch = 0; ch < s->nb_channels; ch++) { + double *dst0 = (double *)s->xfade[0]->extended_data[ch]; + double *dst1 = (double *)s->xfade[1]->extended_data[ch]; + + for (int n = 0; n < s->min_part_size; n++) { + dst0[n] = (n + 1.0) / s->min_part_size; + dst1[n] = 1.0 - dst0[n]; + } + } + break; + } + return 0; } @@ -610,6 +638,9 @@ static av_cold void uninit(AVFilterContext *ctx) av_frame_free(&s->norm_ir[i]); } + av_frame_free(&s->xfade[0]); + av_frame_free(&s->xfade[1]); + av_frame_free(&s->video); } @@ -691,6 +722,8 @@ static av_cold int init(AVFilterContext *ctx) ff_afir_init(&s->afirdsp); + s->min_part_size = 1 << av_log2(s->minp); + return 0; } diff --git a/libavfilter/af_afir.h b/libavfilter/af_afir.h index 11564d5b12..5f2c68c5c6 100644 --- a/libavfilter/af_afir.h +++ b/libavfilter/af_afir.h @@ -90,6 +90,7 @@ typedef struct AudioFIRContext { AudioFIRSegment seg[MAX_IR_STREAMS][1024]; AVFrame *in; + AVFrame *xfade[2]; AVFrame *ir[MAX_IR_STREAMS]; AVFrame *norm_ir[MAX_IR_STREAMS]; AVFrame *video; diff --git a/libavfilter/afir_template.c b/libavfilter/afir_template.c index 63d95de900..5ddc79f6c1 100644 --- a/libavfilter/afir_template.c +++ b/libavfilter/afir_template.c @@ -292,6 +292,8 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse ftype *blockout, *ptr = (ftype *)out->extended_data[ch] + offset; const int min_part_size = s->min_part_size; const int nb_samples = FFMIN(min_part_size, out->nb_samples - offset); + const ftype *xfade0 = (const ftype *)s->xfade[0]->extended_data[ch]; + const ftype *xfade1 = (const ftype *)s->xfade[1]->extended_data[ch]; const int nb_segments = s->nb_segments[selir]; const float dry_gain = s->dry_gain; @@ -370,7 +372,7 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse if (selir == s->selir) { if (s->loading[ch] <= min_part_size) { for (int n = 0; n < nb_samples; n++) - ptr[n] += dst[n] * ((n + 1.f) / nb_samples); + ptr[n] += dst[n] * xfade0[n]; } } else { fn(fir_fadd)(s, ptr, dst, nb_samples); @@ -388,7 +390,7 @@ static int fn(fir_quantum)(AVFilterContext *ctx, AVFrame *out, int ch, int offse if (selir != s->selir) { if (s->loading[ch] <= min_part_size) { for (int n = 0; n < nb_samples; n++) - ptr[n] *= (nb_samples - n * 1.f) / nb_samples; + ptr[n] *= xfade1[n]; } return 0; }