mirror of https://git.ffmpeg.org/ffmpeg.git
avfilter/av_biquads: add support for commands
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
387ee1d6aa
commit
ce626f2695
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue