Commit d8147c4e authored by Paul B Mahol's avatar Paul B Mahol

avfilter/af_amix: make weights option runtime configured

parent a124f4eb
...@@ -1703,6 +1703,14 @@ Specify weight of each input audio stream as sequence. ...@@ -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. Each weight is separated by space. By default all inputs have same weight.
@end table @end table
@subsection Commands
This filter supports the following commands:
@table @option
@item weights
Syntax is same as option with same name.
@end table
@section amultiply @section amultiply
Multiply first audio stream with second audio stream and store result Multiply first audio stream with second audio stream and store result
......
...@@ -181,6 +181,7 @@ typedef struct MixContext { ...@@ -181,6 +181,7 @@ typedef struct MixContext {
#define OFFSET(x) offsetof(MixContext, x) #define OFFSET(x) offsetof(MixContext, x)
#define A AV_OPT_FLAG_AUDIO_PARAM #define A AV_OPT_FLAG_AUDIO_PARAM
#define F AV_OPT_FLAG_FILTERING_PARAM #define F AV_OPT_FLAG_FILTERING_PARAM
#define T AV_OPT_FLAG_RUNTIME_PARAM
static const AVOption amix_options[] = { static const AVOption amix_options[] = {
{ "inputs", "Number of inputs.", { "inputs", "Number of inputs.",
OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT16_MAX, A|F }, OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, INT16_MAX, A|F },
...@@ -193,7 +194,7 @@ static const AVOption amix_options[] = { ...@@ -193,7 +194,7 @@ static const AVOption amix_options[] = {
"renormalization when an input stream ends.", "renormalization when an input stream ends.",
OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A|F }, OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A|F },
{ "weights", "Set weight for each input.", { "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 } { NULL }
}; };
...@@ -504,12 +505,37 @@ static int activate(AVFilterContext *ctx) ...@@ -504,12 +505,37 @@ static int activate(AVFilterContext *ctx)
return 0; return 0;
} }
static av_cold int init(AVFilterContext *ctx) static void parse_weights(AVFilterContext *ctx)
{ {
MixContext *s = ctx->priv; MixContext *s = ctx->priv;
float last_weight = 1.f; float last_weight = 1.f;
int i, ret;
char *p; 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++) { for (i = 0; i < s->nb_inputs; i++) {
AVFilterPad pad = { 0 }; AVFilterPad pad = { 0 };
...@@ -533,23 +559,7 @@ static av_cold int init(AVFilterContext *ctx) ...@@ -533,23 +559,7 @@ static av_cold int init(AVFilterContext *ctx)
if (!s->weights) if (!s->weights)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
p = s->weights_str; parse_weights(ctx);
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);
}
return 0; return 0;
} }
...@@ -604,6 +614,24 @@ fail: ...@@ -604,6 +614,24 @@ fail:
return ret; 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[] = { static const AVFilterPad avfilter_af_amix_outputs[] = {
{ {
.name = "default", .name = "default",
...@@ -624,5 +652,6 @@ AVFilter ff_af_amix = { ...@@ -624,5 +652,6 @@ AVFilter ff_af_amix = {
.query_formats = query_formats, .query_formats = query_formats,
.inputs = NULL, .inputs = NULL,
.outputs = avfilter_af_amix_outputs, .outputs = avfilter_af_amix_outputs,
.process_command = process_command,
.flags = AVFILTER_FLAG_DYNAMIC_INPUTS, .flags = AVFILTER_FLAG_DYNAMIC_INPUTS,
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment