[FFmpeg-cvslog] avfilter/av_biquads: add support for commands

Paul B Mahol git at videolan.org
Sun Dec 17 17:48:08 EET 2017


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sun Dec 17 16:37:12 2017 +0100| [ce626f26959a1ab56c99fc3fe224c91d14f5b4c8] | committer: Paul B Mahol

avfilter/av_biquads: add support for commands

Signed-off-by: Paul B Mahol <onemda at gmail.com>

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

 libavfilter/af_biquads.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 119 insertions(+), 2 deletions(-)

diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c
index c4f619a423..e1a0339fa5 100644
--- a/libavfilter/af_biquads.c
+++ b/libavfilter/af_biquads.c
@@ -237,7 +237,7 @@ BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
 BIQUAD_FILTER(flt, float,   -1., 1., 0)
 BIQUAD_FILTER(dbl, double,  -1., 1., 0)
 
-static int config_output(AVFilterLink *outlink)
+static int config_filter(AVFilterLink *outlink, int reset)
 {
     AVFilterContext *ctx    = outlink->src;
     BiquadsContext *s       = ctx->priv;
@@ -380,7 +380,8 @@ static int config_output(AVFilterLink *outlink)
     s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
     if (!s->cache)
         return AVERROR(ENOMEM);
-    memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
+    if (reset)
+        memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
 
     switch (inlink->format) {
     case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break;
@@ -395,6 +396,11 @@ static int config_output(AVFilterLink *outlink)
     return 0;
 }
 
+static int config_output(AVFilterLink *outlink)
+{
+    return config_filter(outlink, 1);
+}
+
 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
 {
     AVFilterContext  *ctx = inlink->dst;
@@ -438,6 +444,116 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
     return ff_filter_frame(outlink, out_buf);
 }
 
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    BiquadsContext *s = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+
+    if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) &&
+        (s->filter_type == equalizer ||
+         s->filter_type == bass      ||
+         s->filter_type == treble    ||
+         s->filter_type == bandpass  ||
+         s->filter_type == bandreject||
+         s->filter_type == lowpass   ||
+         s->filter_type == highpass  ||
+         s->filter_type == allpass)) {
+        double freq;
+
+        if (sscanf(args, "%lf", &freq) != 1) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid frequency value.\n");
+            return AVERROR(EINVAL);
+        }
+
+        s->frequency = freq;
+    } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) &&
+        (s->filter_type == equalizer ||
+         s->filter_type == bass      ||
+         s->filter_type == treble)) {
+        double gain;
+
+        if (sscanf(args, "%lf", &gain) != 1) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid gain value.\n");
+            return AVERROR(EINVAL);
+        }
+
+        s->gain = gain;
+    } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) &&
+        (s->filter_type == equalizer ||
+         s->filter_type == bass      ||
+         s->filter_type == treble    ||
+         s->filter_type == bandpass  ||
+         s->filter_type == bandreject||
+         s->filter_type == lowpass   ||
+         s->filter_type == highpass  ||
+         s->filter_type == allpass)) {
+        double width;
+
+        if (sscanf(args, "%lf", &width) != 1) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid width value.\n");
+            return AVERROR(EINVAL);
+        }
+
+        s->width = width;
+    } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) &&
+        (s->filter_type == equalizer ||
+         s->filter_type == bass      ||
+         s->filter_type == treble    ||
+         s->filter_type == bandpass  ||
+         s->filter_type == bandreject||
+         s->filter_type == lowpass   ||
+         s->filter_type == highpass  ||
+         s->filter_type == allpass)) {
+        char width_type;
+
+        if (sscanf(args, "%c", &width_type) != 1) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid width_type value.\n");
+            return AVERROR(EINVAL);
+        }
+
+        switch (width_type) {
+        case 'h': width_type = HERTZ;
+        case 'q': width_type = QFACTOR;
+        case 'o': width_type = OCTAVE;
+        case 's': width_type = SLOPE;
+        default:
+            av_log(ctx, AV_LOG_ERROR, "Invalid width_type value: %c\n", width_type);
+            return AVERROR(EINVAL);
+        }
+
+        s->width_type = width_type;
+    } else if ((!strcmp(cmd, "a0") ||
+                !strcmp(cmd, "a1") ||
+                !strcmp(cmd, "a2") ||
+                !strcmp(cmd, "b0") ||
+                !strcmp(cmd, "b1") ||
+                !strcmp(cmd, "b2")) &&
+               s->filter_type == biquad) {
+        double value;
+
+        if (sscanf(args, "%lf", &value) != 1) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid biquad value.\n");
+            return AVERROR(EINVAL);
+        }
+
+        if (!strcmp(cmd, "a0"))
+            s->a0 = value;
+        else if (!strcmp(cmd, "a1"))
+            s->a1 = value;
+        else if (!strcmp(cmd, "a2"))
+            s->a2 = value;
+        else if (!strcmp(cmd, "b0"))
+            s->b0 = value;
+        else if (!strcmp(cmd, "b1"))
+            s->b1 = value;
+        else if (!strcmp(cmd, "b2"))
+            s->b2 = value;
+    }
+
+    return config_filter(outlink, 0);
+}
+
 static av_cold void uninit(AVFilterContext *ctx)
 {
     BiquadsContext *s = ctx->priv;
@@ -486,6 +602,7 @@ AVFilter ff_af_##name_ = {                         \
     .inputs        = inputs,                             \
     .outputs       = outputs,                            \
     .priv_class    = &name_##_class,                     \
+    .process_command = process_command,                  \
 }
 
 #if CONFIG_EQUALIZER_FILTER



More information about the ffmpeg-cvslog mailing list