From patchwork Sun May 24 17:03:05 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: 19834 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 E432444AC39 for ; Sun, 24 May 2020 20:29:28 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id BED7068980D; Sun, 24 May 2020 20:29:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f65.google.com (mail-ed1-f65.google.com [209.85.208.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AB822688069 for ; Sun, 24 May 2020 20:29:22 +0300 (EEST) Received: by mail-ed1-f65.google.com with SMTP id d24so13225019eds.11 for ; Sun, 24 May 2020 10:29:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=lDPbP3H8xHiqX8/OgRPZoXPOGXsHXqslxEUFb1G4RfE=; b=JBtz7frL+oNAQQAmxfwHfRPKYy04Zm2ID++gSLa/1aghGG7ZtjVibwjnrf6q0e1KXF dfMXxpKJ7RfHTgX8EhG34Q3c9wHj86tOYvzZ/gCtQn7fcX8VDZLKXYiejuJIB0nqD0Jk RxiRAgboLk1eK2888dEl9Tw5fS9gDkJ58PZTBc45mf6F/n8uHjIi7sYSZwIklc8BpNWv RZBmdbC4BpvaqZJ/8R2p2/1dlT2+NEcRa5X5FipB72HmRT8lj3cnOTYEQs1LP4bVauPf HFsUPuTxa5oVFUoeVGIvVauR7LMXdhjUallarwdGIq/P0tOdlKn1SYaNDgWnmgaFEgjd +Ksw== 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; bh=lDPbP3H8xHiqX8/OgRPZoXPOGXsHXqslxEUFb1G4RfE=; b=YwGJoKExO0y1TQufi9dFfX+4ERpZE2ljRkQRnoGVrMvjWQbYCGup6g9zsy9EfbtKV6 OPZJN5WzrRvRIGEJX/7tWGqvoT1l7ls4ZIigPDr3AOXfn70EwY09O9HX8AGIgReQu8Hp K7u55xSxjqWDDEkqi6rfhdMvAKVUwIuQUJn5GwNDtxnQej7bIzp3uo0HOEPnKLcS6RmK dmNuiCfk35/3U25xStUJ1KH3ZjLzQ1kyfBu7rqJWZ/zUEy2xevhNTj2AHQ5h4VHqgjqW CmAV1xDBEbkB2F1pU9FbbaqI/iaWnlmePG4sYnwK71DtFh0vFFeeVUJbSyRsk7qGq+G7 KOVg== X-Gm-Message-State: AOAM531nixFsTuhudwksxvVHiORG5xg5eouAPwmhXt3ipH4jL1jL0PY3 GR+EpcVGFZANZaMB+WvFinrRT128p8Q= X-Google-Smtp-Source: ABdhPJwYQRCOM51tYISVmc4H0Ra8JNqBHt20EP9SAPGlskxAK1BCLfHtZh4tI4buuwI4uqOJYGyGGw== X-Received: by 2002:a17:906:3095:: with SMTP id 21mr16047598ejv.32.1590339798028; Sun, 24 May 2020 10:03:18 -0700 (PDT) Received: from localhost.localdomain ([109.227.32.69]) by smtp.gmail.com with ESMTPSA id u10sm13431059edb.65.2020.05.24.10.03.16 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2020 10:03:17 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sun, 24 May 2020 19:03:05 +0200 Message-Id: <20200524170308.9994-1-onemda@gmail.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH 1/4] avfilter/af_biquads: implement 1st order allpass 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" Signed-off-by: Paul B Mahol --- doc/filters.texi | 3 +++ libavfilter/af_biquads.c | 28 ++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 85a511b205..5af4797b7e 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1568,6 +1568,9 @@ 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 order, o +Set the filter order, can be 1 or 2. Default is 2. @end table @subsection Commands diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c index a2f7e3f061..81cdb0c10e 100644 --- a/libavfilter/af_biquads.c +++ b/libavfilter/af_biquads.c @@ -113,6 +113,7 @@ typedef struct BiquadsContext { double mix; uint64_t channels; int normalize; + int order; double a0, a1, a2; double b0, b1, b2; @@ -264,6 +265,7 @@ static int config_filter(AVFilterLink *outlink, int reset) AVFilterLink *inlink = ctx->inputs[0]; double A = ff_exp10(s->gain / 40); double w0 = 2 * M_PI * s->frequency / inlink->sample_rate; + double K = tan(w0 / 2.); double alpha, beta; if (w0 > M_PI) { @@ -389,12 +391,24 @@ static int config_filter(AVFilterLink *outlink, int reset) } break; case allpass: - s->a0 = 1 + alpha; - s->a1 = -2 * cos(w0); - s->a2 = 1 - alpha; - s->b0 = 1 - alpha; - s->b1 = -2 * cos(w0); - s->b2 = 1 + alpha; + switch (s->order) { + case 1: + s->a0 = 1.; + s->a1 = -(1. - K) / (1. + K); + s->a2 = 0.; + s->b0 = s->a1; + s->b1 = s->a0; + s->b2 = 0.; + break; + case 2: + s->a0 = 1 + alpha; + s->a1 = -2 * cos(w0); + s->a2 = 1 - alpha; + s->b0 = 1 - alpha; + s->b1 = -2 * cos(w0); + s->b2 = 1 + alpha; + break; + } break; default: av_assert0(0); @@ -773,6 +787,8 @@ static const AVOption allpass_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}, + {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, + {"o", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS}, {NULL} }; From patchwork Sun May 24 17:03:06 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: 19832 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 ADEB444B11A for ; Sun, 24 May 2020 20:11:33 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 985C56881F3; Sun, 24 May 2020 20:11:33 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f65.google.com (mail-ed1-f65.google.com [209.85.208.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E0EAB687F0C for ; Sun, 24 May 2020 20:11:27 +0300 (EEST) Received: by mail-ed1-f65.google.com with SMTP id g9so13226953edw.10 for ; Sun, 24 May 2020 10:11:27 -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=jKXYaoc2LmJx9YYbKLGPSVW/H8CKAEd01u7TNMB/QDk=; b=XQtVK/f80k7vrGjA1J8xu+ww3m1ApNtECVaLeRmYbDMwcjQZfxuJtJdYJILPxlVGH8 4jY8QWlf9qmHkH2tojHyYCM03Q83NEAF6s/xawV4zKV9O/lxvfd8wy6fLonvVo4FTVte yCHB7AO0KuVzAfJ6hu18xsaY0P0XWBczKqHSGuDwJH1/gFfqLgwNdza+jWFtom3LAbZ4 eNA2KDFEXq10EP8WseOQHtLvqxwZ7j9AdjN01eWdm02sulkiwDMFc0CZm16gwmyzoQRI 6LeFQd1hZZDMBBxECS3THj/EfHF6VRmGEz/QQqWZPvNV09gs/X3Ybb4GhDsFx4yC3mDY bGYg== 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=jKXYaoc2LmJx9YYbKLGPSVW/H8CKAEd01u7TNMB/QDk=; b=Vga/fkqQfvhKkdHGWKpYT4bVOjl3X+JO8qz5hdJhlmSn6nbOSXEF0t5xsid1wBt7uB M07Gt9hfRYO98Nyui0kbwmPqoJ9mhaEJuP1ehlQMbCyUPYXWOLKxr/0361kol2Em4q9t rjms0KIKx859MROB9NajM5y3uVqkjMMGDUadt/rhSdQWFLWizT8sG6v0NooPm0EQ7AWg +4QRM1dtAANW1WEjQU7WXltmfPu4EKuzggBx2ILS6NnTtTLBA4jtiphf6BZc/XNvqPMF M/5JrFSd/7nTdxy01kqiqe4Jo5ZioFTtG17GZKUMhNhUpMEjeZ4WOo/viJ5GP1S/q9Cr ZAug== X-Gm-Message-State: AOAM531kfnHE8hSm7EE3T9erj8pcvSQFsJOXZ5O6XH+m46MAi3LdzHVB mAe6fZuC27dY3SorVKeH0FwV2Cdr0ZY= X-Google-Smtp-Source: ABdhPJwo/r4h7E+IqBNUmnx8mh97TeHlI1JDhJ3r7susdGMV5RvK7aMNHuTmbW3/6rmpJsJAHGhMeQ== X-Received: by 2002:a17:906:c7d1:: with SMTP id dc17mr16893998ejb.166.1590339798977; Sun, 24 May 2020 10:03:18 -0700 (PDT) Received: from localhost.localdomain ([109.227.32.69]) by smtp.gmail.com with ESMTPSA id u10sm13431059edb.65.2020.05.24.10.03.18 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2020 10:03:18 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sun, 24 May 2020 19:03:06 +0200 Message-Id: <20200524170308.9994-2-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 2/4] avfilter/af_biquads: switch to activate() 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" Needed by following commits. Signed-off-by: Paul B Mahol --- libavfilter/af_biquads.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c index 81cdb0c10e..ef28db741a 100644 --- a/libavfilter/af_biquads.c +++ b/libavfilter/af_biquads.c @@ -67,6 +67,7 @@ #include "libavutil/opt.h" #include "audio.h" #include "avfilter.h" +#include "filters.h" #include "internal.h" enum FilterType { @@ -523,6 +524,30 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) return ff_filter_frame(outlink, out_buf); } +static int activate(AVFilterContext *ctx) +{ + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *in = NULL; + int ret; + + 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 (ret < 0) + return ret; + } + + FF_FILTER_FORWARD_STATUS(inlink, outlink); + FF_FILTER_FORWARD_WANTED(outlink, inlink); + + return FFERROR_NOT_READY; +} + static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags) { @@ -547,7 +572,6 @@ static const AVFilterPad inputs[] = { { .name = "default", .type = AVMEDIA_TYPE_AUDIO, - .filter_frame = filter_frame, }, { NULL } }; @@ -567,19 +591,20 @@ static const AVFilterPad outputs[] = { #define DEFINE_BIQUAD_FILTER(name_, description_) \ AVFILTER_DEFINE_CLASS(name_); \ -static av_cold int name_##_init(AVFilterContext *ctx) \ +static av_cold int name_##_init(AVFilterContext *ctx) \ { \ BiquadsContext *s = ctx->priv; \ s->class = &name_##_class; \ s->filter_type = name_; \ - return init(ctx); \ + return init(ctx); \ } \ \ -AVFilter ff_af_##name_ = { \ +AVFilter ff_af_##name_ = { \ .name = #name_, \ .description = NULL_IF_CONFIG_SMALL(description_), \ .priv_size = sizeof(BiquadsContext), \ .init = name_##_init, \ + .activate = activate, \ .uninit = uninit, \ .query_formats = query_formats, \ .inputs = inputs, \ From patchwork Sun May 24 17:03:07 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: 19833 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 87E3844B11A for ; Sun, 24 May 2020 20:11:47 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6A89768A127; Sun, 24 May 2020 20:11:47 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f195.google.com (mail-lj1-f195.google.com [209.85.208.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 45EF36881F1 for ; Sun, 24 May 2020 20:11:41 +0300 (EEST) Received: by mail-lj1-f195.google.com with SMTP id w10so18393891ljo.0 for ; Sun, 24 May 2020 10:11:41 -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=woYoLZ0u/TjruyQIm15HNIwsEAThnq45JYwe4ZIVI6E=; b=nojFt72FizIyiErGpmIg3HHl62ZbjXMfR9i3rOw3HeJWm0bzwFWNnIbrGSKTYj7NT6 S5yY0xu74w6ynFNKyfzXjuQXhs8N9Kykh30HW4Ak+PtGcceH5ADP3MLYuRRWqXsrX/j8 A1jmGH1MeHdmWvIQxFXaj+OdeqTJkeovkJl4mmJUrTBEp6EP2wYO3QYV55wjbAC1Kgwv CAhKw7zxEEFhQYUpNOpplXYwgx46TvCg2h3QKdkex/yp+zv616DuMopFDJtu0HELHxj2 N89j1jCEHWSmgsPFFs9hGHecG2ZviPRewYGghHe4IxKiIWJJ2YgYVQ0wSpiGO28rekDi y6yA== 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=woYoLZ0u/TjruyQIm15HNIwsEAThnq45JYwe4ZIVI6E=; b=ewDhqvJVTS702ltZE0tcw5Jk5SwofKE1SR5lKMpyxK7uBxCp+PvGCLjSf5dYUaouY6 7rdhZd3e5fdpO/+0oR0J7Rl1RgX7tUFGPoTInlggICYwP7mP4ZbamLY2RLMMstwLrTV4 WQ+RYsYDvmwD8vj1jf2NMW61pWkpz2DsbIsHYjEG7JFtR86iUpTir8evLKdaDFbP7C7I BQ+Ax8Bby2NZvuKiyUuHfMVeAE1M/l5m+0JvbGcp0eUAmEHWl3sEX/N2oG5zoPa0l/vw eHc+hO+7U4ywrZUBTV+2wjz2Qa+369QqEAgoax7j6iCKotlEVVKHcupmUOee5gvRm3gq Lh9g== X-Gm-Message-State: AOAM532PhlEqbJvhzUrazaMxMKb8113uq/7pgHpRKPPavN5MJ/qamEaM 0FEwmbtZQTixDJdhxSW0daKzsiftBAk= X-Google-Smtp-Source: ABdhPJxAxVV1J3ocC4EqMgW2vqBuEqlhD/nCgCOcSG4Cku9wvL0PxKEt0DbsslukMsDq7UCfCOTr7g== X-Received: by 2002:a17:906:3ed3:: with SMTP id d19mr16898656ejj.404.1590339799944; Sun, 24 May 2020 10:03:19 -0700 (PDT) Received: from localhost.localdomain ([109.227.32.69]) by smtp.gmail.com with ESMTPSA id u10sm13431059edb.65.2020.05.24.10.03.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 24 May 2020 10:03:19 -0700 (PDT) From: Paul B Mahol To: ffmpeg-devel@ffmpeg.org Date: Sun, 24 May 2020 19:03:07 +0200 Message-Id: <20200524170308.9994-3-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 3/4] avfilter: add ff_inlink_peek_samples and ff_inlink_skip samples 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" Signed-off-by: Paul B Mahol --- libavfilter/avfilter.c | 61 +++++++++++++++++++++++++++++++++++++----- libavfilter/filters.h | 17 ++++++++++++ 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 394811916d..85010c88fe 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -1131,6 +1131,7 @@ static int samples_ready(AVFilterLink *link, unsigned min) } static int take_samples(AVFilterLink *link, unsigned min, unsigned max, + unsigned peek_samples, AVFrame **rframe) { AVFrame *frame0, *frame, *buf; @@ -1142,7 +1143,10 @@ static int take_samples(AVFilterLink *link, unsigned min, unsigned max, av_assert1(samples_ready(link, link->min_samples)); frame0 = frame = ff_framequeue_peek(&link->fifo, 0); if (!link->fifo.samples_skipped && frame->nb_samples >= min && frame->nb_samples <= max) { - *rframe = ff_framequeue_take(&link->fifo); + if (peek_samples) + *rframe = av_frame_clone(frame); + else + *rframe = ff_framequeue_take(&link->fifo); return 0; } nb_frames = 0; @@ -1172,18 +1176,20 @@ static int take_samples(AVFilterLink *link, unsigned min, unsigned max, p = 0; for (i = 0; i < nb_frames; i++) { - frame = ff_framequeue_take(&link->fifo); + frame = peek_samples ? ff_framequeue_peek(&link->fifo, i) : ff_framequeue_take(&link->fifo); av_samples_copy(buf->extended_data, frame->extended_data, p, 0, frame->nb_samples, link->channels, link->format); p += frame->nb_samples; - av_frame_free(&frame); + if (!peek_samples) + av_frame_free(&frame); } if (p < nb_samples) { unsigned n = nb_samples - p; - frame = ff_framequeue_peek(&link->fifo, 0); + frame = ff_framequeue_peek(&link->fifo, peek_samples ? i : 0); av_samples_copy(buf->extended_data, frame->extended_data, p, 0, n, link->channels, link->format); - ff_framequeue_skip_samples(&link->fifo, n, link->time_base); + if (!peek_samples) + ff_framequeue_skip_samples(&link->fifo, n, link->time_base); } *rframe = buf; @@ -1504,7 +1510,7 @@ int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, return 0; if (link->status_in) min = FFMIN(min, ff_framequeue_queued_samples(&link->fifo)); - ret = take_samples(link, min, max, &frame); + ret = take_samples(link, min, max, 0, &frame); if (ret < 0) return ret; consume_update(link, frame); @@ -1512,6 +1518,49 @@ int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, return 1; } +int ff_inlink_peek_samples(AVFilterLink *link, unsigned nb_samples, + AVFrame **rframe) +{ + AVFrame *frame; + int ret; + + av_assert1(nb_samples); + *rframe = NULL; + if (!ff_inlink_check_available_samples(link, nb_samples)) + return 0; + if (link->status_in) + nb_samples = FFMIN(nb_samples, ff_framequeue_queued_samples(&link->fifo)); + ret = take_samples(link, nb_samples, nb_samples, 1, &frame); + if (ret < 0) + return ret; + *rframe = frame; + return !!frame; +} + +void ff_inlink_skip_samples(AVFilterLink *link, unsigned skip_samples) +{ + skip_samples = FFMIN(skip_samples, ff_framequeue_queued_samples(&link->fifo)); + + while (skip_samples > 0) { + AVFrame *frame = ff_inlink_peek_frame(link, 0); + if (skip_samples >= frame->nb_samples) { + frame = ff_framequeue_take(&link->fifo); + skip_samples -= frame->nb_samples; + av_frame_free(&frame); + } else { + break; + } + } + + if (skip_samples) + ff_framequeue_skip_samples(&link->fifo, skip_samples, link->time_base); + + if (ff_inlink_queued_frames(link)) { + AVFrame *frame = ff_inlink_peek_frame(link, 0); + consume_update(link, frame); + } +} + AVFrame *ff_inlink_peek_frame(AVFilterLink *link, size_t idx) { return ff_framequeue_peek(&link->fifo, idx); diff --git a/libavfilter/filters.h b/libavfilter/filters.h index 1157755403..7dc0b35981 100644 --- a/libavfilter/filters.h +++ b/libavfilter/filters.h @@ -115,6 +115,23 @@ int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe); int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe); +/** + * Peek samples from the link's FIFO. + * + * @return >0 if a samples are available, + * 0 and set rframe to NULL if no samples are available, + * or AVERROR code + */ +int ff_inlink_peek_samples(AVFilterLink *link, unsigned nb_samples, + AVFrame **rframe); + +/** + * Skip samples from the link's FIFO. + * + * @note May trigger process_command() and/or update is_disabled. + */ +void ff_inlink_skip_samples(AVFilterLink *link, unsigned skip); + /** * Access a frame in the link fifo without consuming it. * The first frame is numbered 0; the designated frame must exist. 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} };