From patchwork Thu Jun 11 16:12:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul B Mahol X-Patchwork-Id: 20288 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id DB088449671 for ; Thu, 11 Jun 2020 19:18:14 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id ACE4468B5D0; Thu, 11 Jun 2020 19:18:14 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5F347687FC7 for ; Thu, 11 Jun 2020 19:18:08 +0300 (EEST) Received: by mail-wm1-f66.google.com with SMTP id k26so5617318wmi.4 for ; Thu, 11 Jun 2020 09:18:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=P0wJtKu/OIcRpY3iSL62nUTFdbRh5txVQseEPH5+6ps=; b=Khp9/vViOkpco/yVR7S7N7TDwHORuBFIoVO02xGu+S9jKHKePqA+xoWTe+E4zNetMA NkugEa+2+NXhK2lhUMi9yhfq+PzVn1ZO4x0DPWSknWAbWZZ8LfC4DaBj4j9YbGdhvU9Q dx+bOYKLOaZu3qazpwLy6KkTqebAK3luoDOgWOdQDPMiIohHtcCMwNV/Ju7M9pqY3EGU 583G8GZbnMcjg08yB5D4CQm6Mnomlxd9nwR0VwcHiAbjR5xG5c9ocvVDKFuyDzwsu3aj NXe83bs8k/p/WRMIRkp7whcwxBPMgfIG4voj7Tr+daVp7VDUBPJY6XLwR5AsOtsbO2P7 LpRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=P0wJtKu/OIcRpY3iSL62nUTFdbRh5txVQseEPH5+6ps=; b=oGMiPwsnrl4tXN90h8Cx2Hp9XCbmBUzpQgYYLMMn2xdSYhdE7+jI21AgmDMIehT1W8 0RjehslvfOmMpMiXA/B4BIYCSzX2EZcu4/NQrIjfb12Rwwd3nGtFVf5GYGcpfwmhZrGA 8eCOxRQJL1jB4aYHVD3eGOONorU3RMEED6/aJAALu2Ev+3i8jYQkvPDX0iiaAeI4ApLq x9pNbtGgy3iefHOySwXFxf0n131ZUdUi/1hnxsWGvhLTSg/z5VkLnCCFsLCGNN3Zp+hy hDYRiKX5Dwjr2usbltmJmJLEiBcnzk+HvHlQHeu9A13p5AYnroPoiLGV5imWx/I0oyoh iUew== X-Gm-Message-State: AOAM530PCO4/41w03oE42gPiFNgKWEipvl6FeXp78p0wwHoK2LOSL+LE aqXHlobSBDFnAhRgQB245oBGAqgWYgM= X-Google-Smtp-Source: ABdhPJzcLss4567ttUAM8golW67X7B7l+78Jhcw27nCZTGBGDDy/HvvopdRc64xVJkUDghM7bOGJyQ== X-Received: by 2002:a7b:cf35:: with SMTP id m21mr9208047wmg.181.1591891959964; Thu, 11 Jun 2020 09:12:39 -0700 (PDT) Received: from localhost.localdomain ([37.244.249.74]) by smtp.gmail.com with ESMTPSA id 104sm6074960wrl.25.2020.06.11.09.12.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Jun 2020 09:12:39 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Thu, 11 Jun 2020 18:12:23 +0200 Message-Id: <20200611161227.5622-3-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200611161227.5622-1-onemda@gmail.com> References: <20200611161227.5622-1-onemda@gmail.com> Subject: [FFmpeg-devel] [PATCH 3/7] avfilter/af_biquads: add reverse filtering support X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Add it to all filters, except allpass as it does not make sense to use it in such case. Signed-off-by: Paul B Mahol --- doc/filters.texi | 72 +++++++++++ libavfilter/af_biquads.c | 271 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 333 insertions(+), 10 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 84567dec16..c2960e33c7 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2693,6 +2693,15 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item reverse, r +Enable reverse filter processing. Makes filter's phase response +linear at cost of introduced latency. + +@item size, s +Set size of window for reverse filter processing. +Allowed range is from 256 to 32768. +Default value is 2048. @end table @subsection Commands @@ -2756,6 +2765,15 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item reverse, r +Enable reverse filter processing. Makes filter's phase response +linear at cost of introduced latency. + +@item size, s +Set size of window for reverse filter processing. +Allowed range is from 256 to 32768. +Default value is 2048. @end table @subsection Commands @@ -2826,6 +2844,15 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item reverse, r +Enable reverse filter processing. Makes filter's phase response +linear at cost of introduced latency. + +@item size, s +Set size of window for reverse filter processing. +Allowed range is from 256 to 32768. +Default value is 2048. @end table @subsection Commands @@ -2884,6 +2911,15 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item reverse, r +Enable reverse filter processing. Makes filter's phase response +linear at cost of introduced latency. + +@item size, s +Set size of window for reverse filter processing. +Allowed range is from 256 to 32768. +Default value is 2048. @end table @section bs2b @@ -3607,6 +3643,15 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item reverse, r +Enable reverse filter processing. Makes filter's phase response +linear at cost of introduced latency. + +@item size, s +Set size of window for reverse filter processing. +Allowed range is from 256 to 32768. +Default value is 2048. @end table @subsection Examples @@ -4084,6 +4129,15 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item reverse, r +Enable reverse filter processing. Makes filter's phase response +linear at cost of introduced latency. + +@item size, s +Set size of window for reverse filter processing. +Allowed range is from 256 to 32768. +Default value is 2048. @end table @subsection Commands @@ -4407,6 +4461,15 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item reverse, r +Enable reverse filter processing. Makes filter's phase response +linear at cost of introduced latency. + +@item size, s +Set size of window for reverse filter processing. +Allowed range is from 256 to 32768. +Default value is 2048. @end table @subsection Examples @@ -5527,6 +5590,15 @@ Specify which channels to filter, by default all available are filtered. @item normalize, n Normalize biquad coefficients, by default is disabled. Enabling it will normalize magnitude response at DC to 0dB. + +@item reverse, r +Enable reverse filter processing. Makes filter's phase response +linear at cost of introduced latency. + +@item size, s +Set size of window for reverse filter processing. +Allowed range is from 256 to 32768. +Default value is 2048. @end table @subsection Commands diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c index ef28db741a..5e2d74f8f9 100644 --- a/libavfilter/af_biquads.c +++ b/libavfilter/af_biquads.c @@ -97,6 +97,8 @@ enum WidthType { typedef struct ChanCache { double i1, i2; double o1, o2; + double ri1, ri2; + double ro1, ro2; int clippings; } ChanCache; @@ -107,6 +109,7 @@ typedef struct BiquadsContext { int width_type; int poles; int csg; + int reverse; double gain; double frequency; @@ -122,10 +125,18 @@ typedef struct BiquadsContext { ChanCache *cache; int block_align; + AVFrame *frame; + int window_size; + int hop_size; + double *window_func_lut; + void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len, double *i1, double *i2, double *o1, double *o2, double b0, double b1, double b2, double a1, double a2, int *clippings, int disabled); + void (*reverse_filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, void *dst, + int len, double *i1, double *i2, double *o1, double *o2, + double b0, double b1, double b2, double a1, double a2, int *clippings); } BiquadsContext; static av_cold int init(AVFilterContext *ctx) @@ -259,6 +270,99 @@ BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) BIQUAD_FILTER(flt, float, -1., 1., 0) BIQUAD_FILTER(dbl, double, -1., 1., 0) +#define BIQUAD_FILTER_REVERSE(name, type, min, max, need_clipping) \ +static void biquad_reverse_## name (BiquadsContext *s, \ + const void *input, void *output, void *dst, \ + int len, \ + double *in1, double *in2, \ + double *out1, double *out2, \ + double b0, double b1, double b2, \ + double a1, double a2, int *clippings) \ +{ \ + const type *ibuf = input; \ + type *obuf = output; \ + type *dbuf = dst; \ + double o0; \ + double i1 = *in1; \ + double i2 = *in2; \ + double o1 = *out1; \ + double o2 = *out2; \ + double wet = s->mix; \ + double dry = 1. - wet; \ + double out; \ + int i, j; \ + const double *w = s->window_func_lut; \ + \ + a1 = -a1; \ + a2 = -a2; \ + \ + for (i = 0; i+1 < len; i++) { \ + j = len - 1 - i; \ + o2 = i2 * b2 + i1 * b1 + ibuf[j] * b0 + o2 * a2 + o1 * a1; \ + i2 = ibuf[j]; \ + out = o2 * wet + i2 * dry; \ + if (need_clipping && out < min) { \ + (*clippings)++; \ + obuf[j] = min; \ + } else if (need_clipping && out > max) { \ + (*clippings)++; \ + obuf[j] = max; \ + } else { \ + obuf[j] = out; \ + } \ + i++; \ + j = len - 1 - i; \ + o1 = i1 * b2 + i2 * b1 + ibuf[j] * b0 + o1 * a2 + o2 * a1; \ + i1 = ibuf[j]; \ + out = o1 * wet + i1 * dry; \ + if (need_clipping && out < min) { \ + (*clippings)++; \ + obuf[j] = min; \ + } else if (need_clipping && out > max) { \ + (*clippings)++; \ + obuf[j] = max; \ + } else { \ + obuf[j] = out; \ + } \ + } \ + if (i < len) { \ + j = len - 1 - i; \ + o0 = ibuf[j] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \ + i2 = i1; \ + i1 = ibuf[j]; \ + o2 = o1; \ + o1 = o0; \ + out = o0 * wet + i1 * dry; \ + if (need_clipping && out < min) { \ + (*clippings)++; \ + obuf[j] = min; \ + } else if (need_clipping && out > max) { \ + (*clippings)++; \ + obuf[j] = max; \ + } else { \ + obuf[j] = out; \ + } \ + } \ + *in1 = i1; \ + *in2 = i2; \ + *out1 = o1; \ + *out2 = o2; \ + \ + for (i = 0; i < len; i++) \ + dbuf[i] += obuf[i] * w[i]; \ + for (i = 0; i < s->hop_size; i++) \ + obuf[i] = dbuf[i]; \ + memmove(dbuf, dbuf + s->hop_size, \ + (s->window_size * 2 - s->hop_size) * s->block_align); \ + memset(dbuf + s->window_size * 2 - s->hop_size, 0, \ + s->hop_size * s->block_align); \ +} + +BIQUAD_FILTER_REVERSE(s16, int16_t, INT16_MIN, INT16_MAX, 1) +BIQUAD_FILTER_REVERSE(s32, int32_t, INT32_MIN, INT32_MAX, 1) +BIQUAD_FILTER_REVERSE(flt, float, -1., 1., 0) +BIQUAD_FILTER_REVERSE(dbl, double, -1., 1., 0) + static int config_filter(AVFilterLink *outlink, int reset) { AVFilterContext *ctx = outlink->src; @@ -269,6 +373,18 @@ static int config_filter(AVFilterLink *outlink, int reset) double K = tan(w0 / 2.); double alpha, beta; + if (s->reverse && reset) { + s->window_size = s->hop_size * 2; + s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut)); + if (!s->window_func_lut) + return AVERROR(ENOMEM); + for (int i = 0; i < s->window_size; i++) + s->window_func_lut[i] = .5*(1-cos(2*M_PI*i/(s->window_size-1))); + s->frame = ff_get_audio_buffer(outlink, s->window_size * 2); + if (!s->frame) + return AVERROR(ENOMEM); + } + if (w0 > M_PI) { av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n", @@ -439,10 +555,22 @@ static int config_filter(AVFilterLink *outlink, int reset) memset(s->cache, 0, sizeof(ChanCache) * inlink->channels); switch (inlink->format) { - case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break; - case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break; - case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break; - case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break; + case AV_SAMPLE_FMT_S16P: + s->filter = biquad_s16; + s->reverse_filter = biquad_reverse_s16; + break; + case AV_SAMPLE_FMT_S32P: + s->filter = biquad_s32; + s->reverse_filter = biquad_reverse_s32; + break; + case AV_SAMPLE_FMT_FLTP: + s->filter = biquad_flt; + s->reverse_filter = biquad_reverse_flt; + break; + case AV_SAMPLE_FMT_DBLP: + s->filter = biquad_dbl; + s->reverse_filter = biquad_reverse_dbl; + break; default: av_assert0(0); } @@ -457,9 +585,44 @@ static int config_output(AVFilterLink *outlink) } typedef struct ThreadData { - AVFrame *in, *out; + AVFrame *in, *out, *tmp; } ThreadData; +static int reverse_filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + BiquadsContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + ThreadData *td = arg; + AVFrame *buf = td->in; + AVFrame *out_buf = td->out; + AVFrame *tmp_buf = td->tmp; + AVFrame *dst_buf = s->frame; + const int start = (buf->channels * jobnr) / nb_jobs; + const int end = (buf->channels * (jobnr+1)) / nb_jobs; + int ch; + + for (ch = start; ch < end; ch++) { + if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) { + if (buf != out_buf) + memcpy(out_buf->extended_data[ch], buf->extended_data[ch], + buf->nb_samples * s->block_align); + continue; + } + + s->filter(s, buf->extended_data[ch], tmp_buf->extended_data[ch], buf->nb_samples, + &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2, + s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); + s->reverse_filter(s, tmp_buf->extended_data[ch], out_buf->extended_data[ch], + dst_buf->extended_data[ch], + tmp_buf->nb_samples, &s->cache[ch].ri1, &s->cache[ch].ri2, + &s->cache[ch].ro1, &s->cache[ch].ro2, + s->b0, s->b1, s->b2, s->a1, s->a2, + &s->cache[ch].clippings); + } + + return 0; +} + static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { AVFilterLink *inlink = ctx->inputs[0]; @@ -487,6 +650,46 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job return 0; } +static int reverse_filter_frame(AVFilterLink *inlink, AVFrame *buf) +{ + AVFilterContext *ctx = inlink->dst; + BiquadsContext *s = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out_buf, *tmp_buf; + ThreadData td; + int ch; + + out_buf = ff_get_audio_buffer(outlink, buf->nb_samples); + tmp_buf = ff_get_audio_buffer(outlink, buf->nb_samples); + if (!out_buf || !tmp_buf) { + av_frame_free(&out_buf); + av_frame_free(&tmp_buf); + av_frame_free(&buf); + return AVERROR(ENOMEM); + } + av_frame_copy_props(out_buf, buf); + + td.in = buf; + td.out = out_buf; + td.tmp = tmp_buf; + ctx->internal->execute(ctx, reverse_filter_channel, &td, NULL, + FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx))); + + for (ch = 0; ch < outlink->channels; ch++) { + if (s->cache[ch].clippings > 0) + av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n", + ch, s->cache[ch].clippings); + s->cache[ch].clippings = 0; + } + + out_buf->nb_samples = FFMIN(buf->nb_samples, s->hop_size); + av_frame_free(&buf); + av_frame_free(&tmp_buf); + ff_inlink_skip_samples(inlink, s->hop_size); + + return ff_filter_frame(outlink, out_buf); +} + static int filter_frame(AVFilterLink *inlink, AVFrame *buf) { AVFilterContext *ctx = inlink->dst; @@ -526,6 +729,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) static int activate(AVFilterContext *ctx) { + BiquadsContext *s = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; AVFilterLink *outlink = ctx->outputs[0]; AVFrame *in = NULL; @@ -533,13 +737,18 @@ static int activate(AVFilterContext *ctx) FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); - ret = ff_inlink_consume_frame(inlink, &in); - if (ret < 0) - return ret; - if (ret > 0) { - ret = filter_frame(inlink, in); + if (s->reverse) { + ret = ff_inlink_peek_samples(inlink, s->window_size, &in); + if (ret < 0) + return ret; + if (ret > 0) + return reverse_filter_frame(inlink, in); + } else { + ret = ff_inlink_consume_frame(inlink, &in); if (ret < 0) return ret; + if (ret > 0) + return filter_frame(inlink, in); } FF_FILTER_FORWARD_STATUS(inlink, outlink); @@ -566,6 +775,8 @@ static av_cold void uninit(AVFilterContext *ctx) BiquadsContext *s = ctx->priv; av_freep(&s->cache); + av_freep(&s->window_func_lut); + av_frame_free(&s->frame); } static const AVFilterPad inputs[] = { @@ -635,6 +846,10 @@ static const AVOption equalizer_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -661,6 +876,10 @@ static const AVOption bass_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -687,6 +906,10 @@ static const AVOption treble_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -712,6 +935,10 @@ static const AVOption bandpass_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -736,6 +963,10 @@ static const AVOption bandreject_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -762,6 +993,10 @@ static const AVOption lowpass_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -788,6 +1023,10 @@ static const AVOption highpass_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -840,6 +1079,10 @@ static const AVOption lowshelf_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -866,6 +1109,10 @@ static const AVOption highshelf_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} }; @@ -885,6 +1132,10 @@ static const AVOption biquad_options[] = { {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS}, + {"reverse", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"r", "reverse filtering", OFFSET(reverse), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, AF}, + {"size", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, + {"s", "set window size for reverse filtering", OFFSET(hop_size), AV_OPT_TYPE_INT, {.i64=2048}, 256, 32768, AF}, {NULL} };