[FFmpeg-cvslog] avfilter/af_afreqshift: add fltp sample format support

Paul B Mahol git at videolan.org
Sun Dec 13 12:17:23 EET 2020


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sun Dec 13 11:11:49 2020 +0100| [bf4b9e933fbd01591bb75e8adf54b8d6d19273f1] | committer: Paul B Mahol

avfilter/af_afreqshift: add fltp sample format support

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

 libavfilter/af_afreqshift.c | 224 ++++++++++++++++++++++++--------------------
 1 file changed, 121 insertions(+), 103 deletions(-)

diff --git a/libavfilter/af_afreqshift.c b/libavfilter/af_afreqshift.c
index 4cc4e27c1c..6141730e03 100644
--- a/libavfilter/af_afreqshift.c
+++ b/libavfilter/af_afreqshift.c
@@ -34,7 +34,8 @@ typedef struct AFreqShift {
     double shift;
     double level;
 
-    double c[NB_COEFS];
+    double cd[NB_COEFS];
+    float cf[NB_COEFS];
 
     int64_t in_samples;
 
@@ -42,11 +43,8 @@ typedef struct AFreqShift {
     AVFrame *i2, *o2;
 
     void (*filter_channel)(AVFilterContext *ctx,
-                           int nb_samples,
-                           int sample_rate,
-                           const double *src, double *dst,
-                           double *i1, double *o1,
-                           double *i2, double *o2);
+                           int channel,
+                           AVFrame *in, AVFrame *out);
 } AFreqShift;
 
 static int query_formats(AVFilterContext *ctx)
@@ -54,6 +52,7 @@ static int query_formats(AVFilterContext *ctx)
     AVFilterFormats *formats = NULL;
     AVFilterChannelLayouts *layouts = NULL;
     static const enum AVSampleFormat sample_fmts[] = {
+        AV_SAMPLE_FMT_FLTP,
         AV_SAMPLE_FMT_DBLP,
         AV_SAMPLE_FMT_NONE
     };
@@ -78,89 +77,105 @@ static int query_formats(AVFilterContext *ctx)
     return ff_set_common_samplerates(ctx, formats);
 }
 
-static void pfilter_channel(AVFilterContext *ctx,
-                            int nb_samples,
-                            int sample_rate,
-                            const double *src, double *dst,
-                            double *i1, double *o1,
-                            double *i2, double *o2)
-{
-    AFreqShift *s = ctx->priv;
-    const double *c = s->c;
-    const double level = s->level;
-    double shift = s->shift * M_PI;
-    double cos_theta = cos(shift);
-    double sin_theta = sin(shift);
-
-    for (int n = 0; n < nb_samples; n++) {
-        double xn1 = src[n], xn2 = src[n];
-        double I, Q;
-
-        for (int j = 0; j < NB_COEFS / 2; j++) {
-            I = c[j] * (xn1 + o2[j]) - i2[j];
-            i2[j] = i1[j];
-            i1[j] = xn1;
-            o2[j] = o1[j];
-            o1[j] = I;
-            xn1 = I;
-        }
-
-        for (int j = NB_COEFS / 2; j < NB_COEFS; j++) {
-            Q = c[j] * (xn2 + o2[j]) - i2[j];
-            i2[j] = i1[j];
-            i1[j] = xn2;
-            o2[j] = o1[j];
-            o1[j] = Q;
-            xn2 = Q;
-        }
-        Q = o2[NB_COEFS - 1];
-
-        dst[n] = (I * cos_theta - Q * sin_theta) * level;
-    }
+#define PFILTER(name, type, sin, cos, cc)                     \
+static void pfilter_channel_## name(AVFilterContext *ctx,     \
+                            int ch,                           \
+                            AVFrame *in, AVFrame *out)        \
+{                                                             \
+    AFreqShift *s = ctx->priv;                                \
+    const int nb_samples = in->nb_samples;                    \
+    const type *src = (const type *)in->extended_data[ch];    \
+    type *dst = (type *)out->extended_data[ch];               \
+    type *i1 = (type *)s->i1->extended_data[ch];              \
+    type *o1 = (type *)s->o1->extended_data[ch];              \
+    type *i2 = (type *)s->i2->extended_data[ch];              \
+    type *o2 = (type *)s->o2->extended_data[ch];              \
+    const type *c = s->cc;                                    \
+    const type level = s->level;                              \
+    type shift = s->shift * M_PI;                             \
+    type cos_theta = cos(shift);                              \
+    type sin_theta = sin(shift);                              \
+                                                              \
+    for (int n = 0; n < nb_samples; n++) {                    \
+        type xn1 = src[n], xn2 = src[n];                      \
+        type I, Q;                                            \
+                                                              \
+        for (int j = 0; j < NB_COEFS / 2; j++) {              \
+            I = c[j] * (xn1 + o2[j]) - i2[j];                 \
+            i2[j] = i1[j];                                    \
+            i1[j] = xn1;                                      \
+            o2[j] = o1[j];                                    \
+            o1[j] = I;                                        \
+            xn1 = I;                                          \
+        }                                                     \
+                                                              \
+        for (int j = NB_COEFS / 2; j < NB_COEFS; j++) {       \
+            Q = c[j] * (xn2 + o2[j]) - i2[j];                 \
+            i2[j] = i1[j];                                    \
+            i1[j] = xn2;                                      \
+            o2[j] = o1[j];                                    \
+            o1[j] = Q;                                        \
+            xn2 = Q;                                          \
+        }                                                     \
+        Q = o2[NB_COEFS - 1];                                 \
+                                                              \
+        dst[n] = (I * cos_theta - Q * sin_theta) * level;     \
+    }                                                         \
 }
 
-static void ffilter_channel(AVFilterContext *ctx,
-                            int nb_samples,
-                            int sample_rate,
-                            const double *src, double *dst,
-                            double *i1, double *o1,
-                            double *i2, double *o2)
-{
-    AFreqShift *s = ctx->priv;
-    const double *c = s->c;
-    const double level = s->level;
-    double ts = 1. / sample_rate;
-    double shift = s->shift;
-    int64_t N = s->in_samples;
-
-    for (int n = 0; n < nb_samples; n++) {
-        double xn1 = src[n], xn2 = src[n];
-        double I, Q, theta;
-
-        for (int j = 0; j < NB_COEFS / 2; j++) {
-            I = c[j] * (xn1 + o2[j]) - i2[j];
-            i2[j] = i1[j];
-            i1[j] = xn1;
-            o2[j] = o1[j];
-            o1[j] = I;
-            xn1 = I;
-        }
-
-        for (int j = NB_COEFS / 2; j < NB_COEFS; j++) {
-            Q = c[j] * (xn2 + o2[j]) - i2[j];
-            i2[j] = i1[j];
-            i1[j] = xn2;
-            o2[j] = o1[j];
-            o1[j] = Q;
-            xn2 = Q;
-        }
-        Q = o2[NB_COEFS - 1];
-
-        theta = 2. * M_PI * fmod(shift * (N + n) * ts, 1.);
-        dst[n] = (I * cos(theta) - Q * sin(theta)) * level;
-    }
+PFILTER(flt, float, sin, cos, cf)
+PFILTER(dbl, double, sin, cos, cd)
+
+#define FFILTER(name, type, sin, cos, fmod, cc)               \
+static void ffilter_channel_## name(AVFilterContext *ctx,     \
+                            int ch,                           \
+                            AVFrame *in, AVFrame *out)        \
+{                                                             \
+    AFreqShift *s = ctx->priv;                                \
+    const int nb_samples = in->nb_samples;                    \
+    const type *src = (const type *)in->extended_data[ch];    \
+    type *dst = (type *)out->extended_data[ch];               \
+    type *i1 = (type *)s->i1->extended_data[ch];              \
+    type *o1 = (type *)s->o1->extended_data[ch];              \
+    type *i2 = (type *)s->i2->extended_data[ch];              \
+    type *o2 = (type *)s->o2->extended_data[ch];              \
+    const type *c = s->cc;                                    \
+    const type level = s->level;                              \
+    type ts = 1. / in->sample_rate;                           \
+    type shift = s->shift;                                    \
+    int64_t N = s->in_samples;                                \
+                                                              \
+    for (int n = 0; n < nb_samples; n++) {                    \
+        type xn1 = src[n], xn2 = src[n];                      \
+        type I, Q, theta;                                     \
+                                                              \
+        for (int j = 0; j < NB_COEFS / 2; j++) {              \
+            I = c[j] * (xn1 + o2[j]) - i2[j];                 \
+            i2[j] = i1[j];                                    \
+            i1[j] = xn1;                                      \
+            o2[j] = o1[j];                                    \
+            o1[j] = I;                                        \
+            xn1 = I;                                          \
+        }                                                     \
+                                                              \
+        for (int j = NB_COEFS / 2; j < NB_COEFS; j++) {       \
+            Q = c[j] * (xn2 + o2[j]) - i2[j];                 \
+            i2[j] = i1[j];                                    \
+            i1[j] = xn2;                                      \
+            o2[j] = o1[j];                                    \
+            o1[j] = Q;                                        \
+            xn2 = Q;                                          \
+        }                                                     \
+        Q = o2[NB_COEFS - 1];                                 \
+                                                              \
+        theta = 2. * M_PI * fmod(shift * (N + n) * ts, 1.);   \
+        dst[n] = (I * cos(theta) - Q * sin(theta)) * level;   \
+    }                                                         \
 }
 
+FFILTER(flt, float, sinf, cosf, fmodf, cf)
+FFILTER(dbl, double, sin, cos, fmod, cd)
+
 static void compute_transition_param(double *K, double *Q, double transition)
 {
     double kksqrt, e, e2, e4, k, q;
@@ -243,15 +258,19 @@ static double compute_coef(int index, double k, double q, int order)
     return coef;
 }
 
-static void compute_coefs(double *coef_arr, int nbr_coefs, double transition)
+static void compute_coefs(double *coef_arrd, float *coef_arrf, int nbr_coefs, double transition)
 {
     const int order = nbr_coefs * 2 + 1;
     double k, q;
 
     compute_transition_param(&k, &q, transition);
 
-    for (int n = 0; n < nbr_coefs; n++)
-        coef_arr[(n / 2) + (n & 1) * nbr_coefs / 2] = compute_coef(n, k, q, order);
+    for (int n = 0; n < nbr_coefs; n++) {
+        const int idx = (n / 2) + (n & 1) * nbr_coefs / 2;
+
+        coef_arrd[idx] = compute_coef(n, k, q, order);
+        coef_arrf[idx] = coef_arrd[idx];
+    }
 }
 
 static int config_input(AVFilterLink *inlink)
@@ -259,7 +278,7 @@ static int config_input(AVFilterLink *inlink)
     AVFilterContext *ctx = inlink->dst;
     AFreqShift *s = ctx->priv;
 
-    compute_coefs(s->c, NB_COEFS, 2. * 20. / inlink->sample_rate);
+    compute_coefs(s->cd, s->cf, NB_COEFS, 2. * 20. / inlink->sample_rate);
 
     s->i1 = ff_get_audio_buffer(inlink, NB_COEFS);
     s->o1 = ff_get_audio_buffer(inlink, NB_COEFS);
@@ -268,10 +287,17 @@ static int config_input(AVFilterLink *inlink)
     if (!s->i1 || !s->o1 || !s->i2 || !s->o2)
         return AVERROR(ENOMEM);
 
-    if (!strcmp(ctx->filter->name, "afreqshift"))
-        s->filter_channel = ffilter_channel;
-    else
-        s->filter_channel = pfilter_channel;
+    if (inlink->format == AV_SAMPLE_FMT_DBLP) {
+        if (!strcmp(ctx->filter->name, "afreqshift"))
+            s->filter_channel = ffilter_channel_dbl;
+        else
+            s->filter_channel = pfilter_channel_dbl;
+    } else {
+        if (!strcmp(ctx->filter->name, "afreqshift"))
+            s->filter_channel = ffilter_channel_flt;
+        else
+            s->filter_channel = pfilter_channel_flt;
+    }
 
     return 0;
 }
@@ -289,16 +315,8 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
     const int start = (in->channels * jobnr) / nb_jobs;
     const int end = (in->channels * (jobnr+1)) / nb_jobs;
 
-    for (int ch = start; ch < end; ch++) {
-        s->filter_channel(ctx, in->nb_samples,
-                          in->sample_rate,
-                          (const double *)in->extended_data[ch],
-                          (double *)out->extended_data[ch],
-                          (double *)s->i1->extended_data[ch],
-                          (double *)s->o1->extended_data[ch],
-                          (double *)s->i2->extended_data[ch],
-                          (double *)s->o2->extended_data[ch]);
-    }
+    for (int ch = start; ch < end; ch++)
+        s->filter_channel(ctx, ch, in, out);
 
     return 0;
 }



More information about the ffmpeg-cvslog mailing list