diff --git a/doc/filters.texi b/doc/filters.texi index 1c51e42388..19004f233f 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1193,6 +1193,10 @@ select gain to noise approach, this is most popular one. Set gain to be applied to IR coefficients before filtering. Allowed range is 0 to 1. This can be set even with @var{again} used. +@item irfmt +Set format of IR stream. Can be @code{mono} or @code{input}. +Default is @code{input}. + @item maxir Set max allowed Impulse Response filter duration in seconds. Default is 30 seconds. Allowed range is 0.1 to 60 seconds. diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c index 344905ad5a..b2d158c17e 100644 --- a/libavfilter/af_afir.c +++ b/libavfilter/af_afir.c @@ -533,7 +533,7 @@ static int query_formats(AVFilterContext *ctx) AV_PIX_FMT_RGB0, AV_PIX_FMT_NONE }; - int ret, i; + int ret; if (s->response) { AVFilterLink *videolink = ctx->outputs[1]; @@ -543,12 +543,25 @@ static int query_formats(AVFilterContext *ctx) } layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0) - return ret; + if (!layouts) + return AVERROR(ENOMEM); + + if (s->ir_format) { + ret = ff_set_common_channel_layouts(ctx, layouts); + if (ret < 0) + return ret; + } else { + AVFilterChannelLayouts *mono = NULL; - for (i = 0; i < 2; i++) { - layouts = ff_all_channel_counts(); - if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts)) < 0) + ret = ff_add_channel_layout(&mono, AV_CH_LAYOUT_MONO); + if (ret) + return ret; + + if ((ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts)) < 0) + return ret; + if ((ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts)) < 0) + return ret; + if ((ret = ff_channel_layouts_ref(mono, &ctx->inputs[1]->out_channel_layouts)) < 0) return ret; } @@ -565,14 +578,6 @@ static int config_output(AVFilterLink *outlink) AVFilterContext *ctx = outlink->src; AudioFIRContext *s = ctx->priv; - if (ctx->inputs[0]->channels != ctx->inputs[1]->channels && - ctx->inputs[1]->channels != 1) { - av_log(ctx, AV_LOG_ERROR, - "Second input must have same number of channels as first input or " - "exactly 1 channel.\n"); - return AVERROR(EINVAL); - } - s->one2many = ctx->inputs[1]->channels == 1; outlink->sample_rate = ctx->inputs[0]->sample_rate; outlink->time_base = ctx->inputs[0]->time_base; @@ -739,6 +744,9 @@ static const AVOption afir_options[] = { { "dc", "DC gain", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "gtype" }, { "gn", "gain to noise", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "gtype" }, { "irgain", "set IR gain", OFFSET(ir_gain), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, AF }, + { "irfmt", "set IR format", OFFSET(ir_format), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "irfmt" }, + { "mono", "single channel", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "irfmt" }, + { "input", "same as input", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "irfmt" }, { "maxir", "set max IR length", OFFSET(max_ir_len), AV_OPT_TYPE_FLOAT, {.dbl=30}, 0.1, 60, AF }, { "response", "show IR frequency response", OFFSET(response), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, VF }, { "channel", "set IR channel to display frequency response", OFFSET(ir_channel), AV_OPT_TYPE_INT, {.i64=0}, 0, 1024, VF }, diff --git a/libavfilter/af_afir.h b/libavfilter/af_afir.h index 9e6f957a8d..ecc0d60641 100644 --- a/libavfilter/af_afir.h +++ b/libavfilter/af_afir.h @@ -41,6 +41,7 @@ typedef struct AudioFIRContext { int again; int gtype; float ir_gain; + int ir_format; float max_ir_len; int response; int w, h;