From patchwork Sun May 24 17:03:08 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: 19831 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 AC55244AF8B for ; Sun, 24 May 2020 20:10:16 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7B4526881F3; Sun, 24 May 2020 20:10:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f194.google.com (mail-lj1-f194.google.com [209.85.208.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 755076809A4 for ; Sun, 24 May 2020 20:10:10 +0300 (EEST) Received: by mail-lj1-f194.google.com with SMTP id m18so18333675ljo.5 for ; Sun, 24 May 2020 10:10:10 -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=GIRxnsp9AvUyVys7pPS8KpLFdu0Tsv9lqIcGwE9PNyM=; b=FOHgOOwKKfcdW3TsykelVtRFpE/LLJutLYrneLDwTOqCMkzavm/1pJSL/QblhHmJxc g1TeBc+so6KWGBFF4hrKmo3BYjQ2PWzT1Smb83kUYc4tpXh3KnEASL/QfIxX46NuQOcD kyT7ElYd/Bsf8+78MxBRfwMa4E9U+DNWQY2m2HC9mViXCXKZXOs8I3Kna8fVtwcFqpFI muXnq5MTYlsVUn+C6Hoch/jQevxgJ6XkfiushxVWYKPUUhNo+H4p6jqtUcsuhyeJ7iQi TjhpwSWEsCnLo1F+JDMPYofRZpUPxFdj/zeSef1Sz9koXwJGukTk9wmdqPac9ou4tM/W r8Iw== 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=GIRxnsp9AvUyVys7pPS8KpLFdu0Tsv9lqIcGwE9PNyM=; b=B829RB+ABnNLDVJcsrzcsxkTyqSPFDsVsCyAsw61PyuBi4j91IHUe02asqfXkdLDAd 18hhRJjO0O1DgvA07HCUcwo17ppgyfJFQxhD21YhfhXQCbntHWna9QspKBOvxiVMUd83 xYhq7v22w9dVsQhG1bEFZ80VgFW3zWIzL2ZbKPsv5idZc1cMJSr4e1R/uxrXUqSksPUv nwRfpskBNyMtZ3aPQn/wi1smBUmLpLbLIpRn4npdRsNeikhnGkmSLEBhObpr5ATrjdPj /XQMAGzDDBZeWyf+N2kUfgOS2BcLBe1exsHjNo2dD8+XA27NFuHdjeumDYBzEWesB/Dk x12A== X-Gm-Message-State: AOAM530gz9iwxyPg7DiSIOIj3W3TdYi0Yu0Kcy905hajLTHxdjOz/nUC 768q7MsLRE9nYzTAeXPNfkQoc8lSQMY= X-Google-Smtp-Source: ABdhPJwWuD1sCNvwZbED9Ni6dTaE2KNlHHW1uVnGsgRu/N1lUdEH11fb87kGZIxRSSgfg623041Ntw== X-Received: by 2002:aa7:d98f:: with SMTP id u15mr11486255eds.42.1590339801091; Sun, 24 May 2020 10:03:21 -0700 (PDT) Received: from localhost.localdomain ([109.227.32.69]) by smtp.gmail.com with ESMTPSA id u10sm13431059edb.65.2020.05.24.10.03.20 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2020 10:03:20 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sun, 24 May 2020 19:03:08 +0200 Message-Id: <20200524170308.9994-4-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200524170308.9994-1-onemda@gmail.com> References: <20200524170308.9994-1-onemda@gmail.com> Subject: [FFmpeg-devel] [PATCH 4/4] 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 5af4797b7e..773473f721 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2691,6 +2691,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 @@ -2754,6 +2763,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 @@ -2824,6 +2842,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 @@ -2882,6 +2909,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 @@ -3605,6 +3641,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 @@ -4082,6 +4127,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 @@ -4405,6 +4459,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 @@ -5525,6 +5588,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..a9dcc7658d 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 (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} };