From d8147c4e2d9111787319983d14889bc21705746f Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 28 Apr 2020 12:01:04 +0200 Subject: avfilter/af_amix: make weights option runtime configured --- libavfilter/af_amix.c | 69 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 20 deletions(-) (limited to 'libavfilter/af_amix.c') diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index c09f8b034b..0826fc118c 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,37 @@ 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; + 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 +559,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 +614,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 +652,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, }; -- cgit v1.2.3