[FFmpeg-devel] [PATCH] avfilter/af_amix: make weights option runtime configured

Paul B Mahol onemda at gmail.com
Tue Apr 28 13:05:24 EEST 2020


Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 doc/filters.texi      |  8 +++++
 libavfilter/af_amix.c | 70 ++++++++++++++++++++++++++++++-------------
 2 files changed, 58 insertions(+), 20 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 55edd564bf..fe661c0b4b 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1703,6 +1703,14 @@ Specify weight of each input audio stream as sequence.
 Each weight is separated by space. By default all inputs have same weight.
 @end table
 
+ at subsection Commands
+
+This filter supports the following commands:
+ at table @option
+ at item weights
+Syntax is same as option with same name.
+ at end table
+
 @section amultiply
 
 Multiply first audio stream with second audio stream and store result
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c
index c09f8b034b..32aa80e112 100644
--- a/libavfilter/af_amix.c
+++ b/libavfilter/af_amix.c
@@ -181,6 +181,7 @@ typedef struct MixContext {
 #define OFFSET(x) offsetof(MixContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
 #define F AV_OPT_FLAG_FILTERING_PARAM
+#define T AV_OPT_FLAG_RUNTIME_PARAM
 static const AVOption amix_options[] = {
     { "inputs", "Number of inputs.",
             OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT16_MAX, A|F },
@@ -193,7 +194,7 @@ static const AVOption amix_options[] = {
                             "renormalization when an input stream ends.",
             OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A|F },
     { "weights", "Set weight for each input.",
-            OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, A|F },
+            OFFSET(weights_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, A|F|T },
     { NULL }
 };
 
@@ -504,12 +505,38 @@ static int activate(AVFilterContext *ctx)
     return 0;
 }
 
-static av_cold int init(AVFilterContext *ctx)
+static void parse_weights(AVFilterContext *ctx)
 {
     MixContext *s = ctx->priv;
     float last_weight = 1.f;
-    int i, ret;
     char *p;
+    int i;
+
+    s->weight_sum = 0.f;
+    p = s->weights_str;
+    for (i = 0; i < s->nb_inputs; i++) {
+        last_weight = av_strtod(p, &p);
+        s->weights[i] = last_weight;
+        printf("%g\n", last_weight);
+        s->weight_sum += FFABS(last_weight);
+        if (p && *p) {
+            p++;
+        } else {
+            i++;
+            break;
+        }
+    }
+
+    for (; i < s->nb_inputs; i++) {
+        s->weights[i] = last_weight;
+        s->weight_sum += FFABS(last_weight);
+    }
+}
+
+static av_cold int init(AVFilterContext *ctx)
+{
+    MixContext *s = ctx->priv;
+    int i, ret;
 
     for (i = 0; i < s->nb_inputs; i++) {
         AVFilterPad pad = { 0 };
@@ -533,23 +560,7 @@ static av_cold int init(AVFilterContext *ctx)
     if (!s->weights)
         return AVERROR(ENOMEM);
 
-    p = s->weights_str;
-    for (i = 0; i < s->nb_inputs; i++) {
-        last_weight = av_strtod(p, &p);
-        s->weights[i] = last_weight;
-        s->weight_sum += FFABS(last_weight);
-        if (p && *p) {
-            p++;
-        } else {
-            i++;
-            break;
-        }
-    }
-
-    for (; i < s->nb_inputs; i++) {
-        s->weights[i] = last_weight;
-        s->weight_sum += FFABS(last_weight);
-    }
+    parse_weights(ctx);
 
     return 0;
 }
@@ -604,6 +615,24 @@ fail:
     return ret;
 }
 
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    MixContext *s = ctx->priv;
+    int ret;
+
+    ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
+    if (ret < 0)
+        return ret;
+
+    parse_weights(ctx);
+    for (int i = 0; i < s->nb_inputs; i++)
+        s->scale_norm[i] = s->weight_sum / FFABS(s->weights[i]);
+    calculate_scales(s, 0);
+
+    return 0;
+}
+
 static const AVFilterPad avfilter_af_amix_outputs[] = {
     {
         .name          = "default",
@@ -624,5 +653,6 @@ AVFilter ff_af_amix = {
     .query_formats  = query_formats,
     .inputs         = NULL,
     .outputs        = avfilter_af_amix_outputs,
+    .process_command = process_command,
     .flags          = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
-- 
2.17.1



More information about the ffmpeg-devel mailing list