[FFmpeg-cvslog] avfilter/af_afir: cache xfade coefficients

Paul B Mahol git at videolan.org
Mon Apr 24 23:33:51 EEST 2023


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Mon Apr 24 17:31:18 2023 +0200| [a0cb29261cddb2b62ee57fbeb689a0234f0cc735] | committer: Paul B Mahol

avfilter/af_afir: cache xfade coefficients

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a0cb29261cddb2b62ee57fbeb689a0234f0cc735
---

 libavfilter/af_afir.c       | 37 +++++++++++++++++++++++++++++++++++--
 libavfilter/af_afir.h       |  1 +
 libavfilter/afir_template.c |  6 ++++--
 3 files changed, 40 insertions(+), 4 deletions(-)

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;
     }



More information about the ffmpeg-cvslog mailing list