]> git.sesse.net Git - ffmpeg/commitdiff
avfilter/af_acrossover: rewrite code so it performs faster
authorPaul B Mahol <onemda@gmail.com>
Wed, 25 Nov 2020 21:01:53 +0000 (22:01 +0100)
committerPaul B Mahol <onemda@gmail.com>
Thu, 26 Nov 2020 12:17:20 +0000 (13:17 +0100)
libavfilter/af_acrossover.c

index 4c4bbbc76ef4ce2b2bde7fe603805fbb92fde80e..bd84223681e50d39348d8efadb7ef2fc07d35a9c 100644 (file)
@@ -237,16 +237,35 @@ static int query_formats(AVFilterContext *ctx)
     return ff_set_common_samplerates(ctx, formats);
 }
 
-static double biquad_process(BiquadContext *b, double in)
+static void biquad_process(BiquadContext *b,
+                           double *dst, const double *src,
+                           int nb_samples)
 {
-    double out = in * b->a0 + b->i1 * b->a1 + b->i2 * b->a2 - b->o1 * b->b1 - b->o2 * b->b2;
-
-    b->i2 = b->i1;
-    b->o2 = b->o1;
-    b->i1 = in;
-    b->o1 = out;
+    const double a0 = b->a0;
+    const double a1 = b->a1;
+    const double a2 = b->a2;
+    const double b1 = b->b1;
+    const double b2 = b->b2;
+    double i1 = b->i1;
+    double i2 = b->i2;
+    double o1 = b->o1;
+    double o2 = b->o2;
+
+    for (int n = 0; n < nb_samples; n++) {
+        const double in = src[n];
+        double out;
+
+        out = in * a0 + i1 * a1 + i2 * a2 - o1 * b1 - o2 * b2;
+        i2 = i1;
+        o2 = o1;
+        i1 = in;
+        o1 = dst[n] = out;
+    }
 
-    return out;
+    b->i1 = i1;
+    b->i2 = i2;
+    b->o1 = o1;
+    b->o2 = o2;
 }
 
 static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
@@ -256,33 +275,28 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
     AVFrame **frames = s->frames;
     const int start = (in->channels * jobnr) / nb_jobs;
     const int end = (in->channels * (jobnr+1)) / nb_jobs;
-    int f, band;
+    const int nb_samples = in->nb_samples;
 
     for (int ch = start; ch < end; ch++) {
-        const double *src = (const double *)in->extended_data[ch];
         CrossoverChannel *xover = &s->xover[ch];
 
-        for (int i = 0; i < in->nb_samples; i++) {
-            double sample = src[i], lo, hi;
-
-            for (band = 0; band < ctx->nb_outputs; band++) {
-                double *dst = (double *)frames[band]->extended_data[ch];
+        for (int band = 0; band < ctx->nb_outputs; band++) {
+            for (int f = 0; band + 1 < ctx->nb_outputs && f < s->filter_count; f++) {
+                const double *src = band == 0 ? (const double *)in->extended_data[ch] : (const double *)frames[band]->extended_data[ch];
+                double *dst = (double *)frames[band + 1]->extended_data[ch];
+                const double *hsrc = f == 0 ? src : dst;
+                BiquadContext *hp = &xover->hp[band][f];
 
-                lo = sample;
-                hi = sample;
-                for (f = 0; band + 1 < ctx->nb_outputs && f < s->filter_count; f++) {
-                    BiquadContext *lp = &xover->lp[band][f];
-                    lo = biquad_process(lp, lo);
-                }
-
-                for (f = 0; band + 1 < ctx->nb_outputs && f < s->filter_count; f++) {
-                    BiquadContext *hp = &xover->hp[band][f];
-                    hi = biquad_process(hp, hi);
-                }
+                biquad_process(hp, dst, hsrc, nb_samples);
+            }
 
-                dst[i] = lo;
+            for (int f = 0; band + 1 < ctx->nb_outputs && f < s->filter_count; f++) {
+                const double *src = band == 0 ? (const double *)in->extended_data[ch] : (const double *)frames[band]->extended_data[ch];
+                double *dst = (double *)frames[band]->extended_data[ch];
+                const double *lsrc = f == 0 ? src : dst;
+                BiquadContext *lp = &xover->lp[band][f];
 
-                sample = hi;
+                biquad_process(lp, dst, lsrc, nb_samples);
             }
         }
     }