From ce626f26959a1ab56c99fc3fe224c91d14f5b4c8 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Sun, 17 Dec 2017 16:37:12 +0100 Subject: avfilter/av_biquads: add support for commands Signed-off-by: Paul B Mahol --- libavfilter/af_biquads.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) (limited to 'libavfilter/af_biquads.c') 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 -- cgit v1.2.3