From: Paul B Mahol <onemda@gmail.com> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: [FFmpeg-devel] [PATCH] avfilter/af_firequalizer: switch to TX from lavu Date: Sun, 13 Nov 2022 14:35:24 +0100 Message-ID: <CAPYw7P5HqsjWDbMmoRfUE8SVS149m2D1h6Gboe=dwtK7Oi2p7w@mail.gmail.com> (raw) [-- Attachment #1: Type: text/plain, Size: 16 bytes --] Patch attached. [-- Attachment #2: 0001-avfilter-af_firequalizer-switch-to-TX-from-lavu.patch --] [-- Type: text/x-patch, Size: 14419 bytes --] From bf0c69dc29fa4a41de7e47308f6907adf1215df3 Mon Sep 17 00:00:00 2001 From: Paul B Mahol <onemda@gmail.com> Date: Sat, 12 Nov 2022 12:02:08 +0100 Subject: [PATCH] avfilter/af_firequalizer: switch to TX from lavu Signed-off-by: Paul B Mahol <onemda@gmail.com> --- configure | 3 - libavfilter/af_firequalizer.c | 119 +++++++++++++++++++--------------- 2 files changed, 66 insertions(+), 56 deletions(-) diff --git a/configure b/configure index e6470dc03b..d2c5ca64b1 100755 --- a/configure +++ b/configure @@ -3671,8 +3671,6 @@ elbg_filter_deps="avcodec" eq_filter_deps="gpl" erosion_opencl_filter_deps="opencl" find_rect_filter_deps="avcodec avformat gpl" -firequalizer_filter_deps="avcodec" -firequalizer_filter_select="rdft" flip_vulkan_filter_deps="vulkan spirv_compiler" flite_filter_deps="libflite" framerate_filter_select="scene_sad" @@ -7466,7 +7464,6 @@ enabled cover_rect_filter && prepend avfilter_deps "avformat avcodec" enabled ebur128_filter && enabled swresample && prepend avfilter_deps "swresample" enabled elbg_filter && prepend avfilter_deps "avcodec" enabled find_rect_filter && prepend avfilter_deps "avformat avcodec" -enabled firequalizer_filter && prepend avfilter_deps "avcodec" enabled mcdeint_filter && prepend avfilter_deps "avcodec" enabled movie_filter && prepend avfilter_deps "avformat avcodec" enabled pan_filter && prepend avfilter_deps "swresample" diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c index e0f35c139e..156e5e14d7 100644 --- a/libavfilter/af_firequalizer.c +++ b/libavfilter/af_firequalizer.c @@ -23,7 +23,7 @@ #include "libavutil/opt.h" #include "libavutil/eval.h" #include "libavutil/avassert.h" -#include "libavcodec/avfft.h" +#include "libavutil/tx.h" #include "avfilter.h" #include "internal.h" #include "audio.h" @@ -67,13 +67,20 @@ typedef struct OverlapIndex { typedef struct FIREqualizerContext { const AVClass *class; - RDFTContext *analysis_rdft; - RDFTContext *analysis_irdft; - RDFTContext *rdft; - RDFTContext *irdft; - FFTContext *fft_ctx; - RDFTContext *cepstrum_rdft; - RDFTContext *cepstrum_irdft; + AVTXContext *analysis_rdft; + av_tx_fn analysis_rdft_fn; + AVTXContext *analysis_irdft; + av_tx_fn analysis_irdft_fn; + AVTXContext *rdft; + av_tx_fn rdft_fn; + AVTXContext *irdft; + av_tx_fn irdft_fn; + AVTXContext *fft_ctx; + av_tx_fn fft_fn; + AVTXContext *cepstrum_rdft; + av_tx_fn cepstrum_rdft_fn; + AVTXContext *cepstrum_irdft; + av_tx_fn cepstrum_irdft_fn; int analysis_rdft_len; int rdft_len; int cepstrum_len; @@ -151,13 +158,13 @@ AVFILTER_DEFINE_CLASS(firequalizer); static void common_uninit(FIREqualizerContext *s) { - av_rdft_end(s->analysis_rdft); - av_rdft_end(s->analysis_irdft); - av_rdft_end(s->rdft); - av_rdft_end(s->irdft); - av_fft_end(s->fft_ctx); - av_rdft_end(s->cepstrum_rdft); - av_rdft_end(s->cepstrum_irdft); + av_tx_uninit(&s->analysis_rdft); + av_tx_uninit(&s->analysis_irdft); + av_tx_uninit(&s->rdft); + av_tx_uninit(&s->irdft); + av_tx_uninit(&s->fft_ctx); + av_tx_uninit(&s->cepstrum_rdft); + av_tx_uninit(&s->cepstrum_irdft); s->analysis_rdft = s->analysis_irdft = s->rdft = s->irdft = NULL; s->fft_ctx = NULL; s->cepstrum_rdft = NULL; @@ -193,16 +200,14 @@ static void fast_convolute(FIREqualizerContext *av_restrict s, const float *av_r memset(buf, 0, center * sizeof(*data)); memcpy(buf + center, data, nsamples * sizeof(*data)); memset(buf + center + nsamples, 0, (s->rdft_len - nsamples - center) * sizeof(*data)); - av_rdft_calc(s->rdft, buf); + s->rdft_fn(s->rdft, buf, buf, sizeof(float)); - buf[0] *= kernel_buf[0]; - buf[1] *= kernel_buf[s->rdft_len/2]; - for (k = 1; k < s->rdft_len/2; k++) { + for (k = 0; k <= s->rdft_len/2; k++) { buf[2*k] *= kernel_buf[k]; buf[2*k+1] *= kernel_buf[k]; } - av_rdft_calc(s->irdft, buf); + s->irdft_fn(s->irdft, buf, buf, sizeof(float)); for (k = 0; k < s->rdft_len - idx->overlap_idx; k++) buf[k] += obuf[k]; memcpy(data, buf, nsamples * sizeof(*data)); @@ -230,11 +235,9 @@ static void fast_convolute_nonlinear(FIREqualizerContext *av_restrict s, const f memcpy(buf, data, nsamples * sizeof(*data)); memset(buf + nsamples, 0, (s->rdft_len - nsamples) * sizeof(*data)); - av_rdft_calc(s->rdft, buf); + s->rdft_fn(s->rdft, buf, buf, sizeof(float)); - buf[0] *= kernel_buf[0]; - buf[1] *= kernel_buf[1]; - for (k = 2; k < s->rdft_len; k += 2) { + for (k = 0; k <= s->rdft_len; k += 2) { float re, im; re = buf[k] * kernel_buf[k] - buf[k+1] * kernel_buf[k+1]; im = buf[k] * kernel_buf[k+1] + buf[k+1] * kernel_buf[k]; @@ -242,7 +245,7 @@ static void fast_convolute_nonlinear(FIREqualizerContext *av_restrict s, const f buf[k+1] = im; } - av_rdft_calc(s->irdft, buf); + s->irdft_fn(s->irdft, buf, buf, sizeof(float)); for (k = 0; k < s->rdft_len - idx->overlap_idx; k++) buf[k] += obuf[k]; memcpy(data, buf, nsamples * sizeof(*data)); @@ -259,12 +262,12 @@ static void fast_convolute_nonlinear(FIREqualizerContext *av_restrict s, const f } } -static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, FFTComplex *av_restrict conv_buf, +static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, AVComplexFloat *av_restrict conv_buf, OverlapIndex *av_restrict idx, float *av_restrict data0, float *av_restrict data1, int nsamples) { if (nsamples <= s->nsamples_max) { - FFTComplex *buf = conv_buf + idx->buf_idx * s->rdft_len; - FFTComplex *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx; + AVComplexFloat *buf = conv_buf + idx->buf_idx * s->rdft_len; + AVComplexFloat *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx; int center = s->fir_len/2; int k; float tmp; @@ -275,8 +278,7 @@ static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_ buf[center+k].im = data1[k]; } memset(buf + center + nsamples, 0, (s->rdft_len - nsamples - center) * sizeof(*buf)); - av_fft_permute(s->fft_ctx, buf); - av_fft_calc(s->fft_ctx, buf); + s->fft_fn(s->fft_ctx, buf, buf, sizeof(float)); /* swap re <-> im, do backward fft using forward fft_ctx */ /* normalize with 0.5f */ @@ -296,8 +298,7 @@ static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_ buf[k].re = 0.5f * kernel_buf[k] * buf[k].im; buf[k].im = 0.5f * kernel_buf[k] * tmp; - av_fft_permute(s->fft_ctx, buf); - av_fft_calc(s->fft_ctx, buf); + s->fft_fn(s->fft_ctx, buf, buf, sizeof(float)); for (k = 0; k < s->rdft_len - idx->overlap_idx; k++) { buf[k].re += obuf[k].re; @@ -361,7 +362,7 @@ static void dump_fir(AVFilterContext *ctx, FILE *fp, int ch) fprintf(fp, "%15.10f %15.10f\n", (double)x / rate, (double) s->analysis_buf[x]); } - av_rdft_calc(s->analysis_rdft, s->analysis_buf); + s->analysis_rdft_fn(s->analysis_rdft, s->analysis_buf, s->analysis_buf, sizeof(float)); fprintf(fp, "\n\n# freq[%d] (frequency desired_gain actual_gain)\n", ch); @@ -533,7 +534,7 @@ static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf) memcpy(s->cepstrum_buf, rdft_buf, rdft_len/2 * sizeof(*rdft_buf)); memcpy(s->cepstrum_buf + cepstrum_len - rdft_len/2, rdft_buf + rdft_len/2, rdft_len/2 * sizeof(*rdft_buf)); - av_rdft_calc(s->cepstrum_rdft, s->cepstrum_buf); + s->cepstrum_rdft_fn(s->cepstrum_rdft, s->cepstrum_buf, s->cepstrum_buf, sizeof(float)); s->cepstrum_buf[0] = log(FFMAX(s->cepstrum_buf[0], minval)); s->cepstrum_buf[1] = log(FFMAX(s->cepstrum_buf[1], minval)); @@ -543,13 +544,13 @@ static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf) s->cepstrum_buf[k+1] = 0; } - av_rdft_calc(s->cepstrum_irdft, s->cepstrum_buf); + s->cepstrum_irdft_fn(s->cepstrum_irdft, s->cepstrum_buf, s->cepstrum_buf, sizeof(float)); memset(s->cepstrum_buf + cepstrum_len/2 + 1, 0, (cepstrum_len/2 - 1) * sizeof(*s->cepstrum_buf)); for (k = 1; k < cepstrum_len/2; k++) s->cepstrum_buf[k] *= 2; - av_rdft_calc(s->cepstrum_rdft, s->cepstrum_buf); + s->cepstrum_rdft_fn(s->cepstrum_rdft, s->cepstrum_buf, s->cepstrum_buf, sizeof(float)); s->cepstrum_buf[0] = exp(s->cepstrum_buf[0] * norm) * norm; s->cepstrum_buf[1] = exp(s->cepstrum_buf[1] * norm) * norm; @@ -560,7 +561,7 @@ static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf) s->cepstrum_buf[k+1] = mag * sin(ph); } - av_rdft_calc(s->cepstrum_irdft, s->cepstrum_buf); + s->cepstrum_irdft_fn(s->cepstrum_irdft, s->cepstrum_buf, s->cepstrum_buf, sizeof(float)); memset(rdft_buf, 0, s->rdft_len * sizeof(*rdft_buf)); memcpy(rdft_buf, s->cepstrum_buf, s->fir_len * sizeof(*rdft_buf)); @@ -568,7 +569,6 @@ static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf) memset(s->analysis_buf, 0, s->analysis_rdft_len * sizeof(*s->analysis_buf)); memcpy(s->analysis_buf, s->cepstrum_buf, s->fir_len * sizeof(*s->analysis_buf)); } - } static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *gain_entry) @@ -641,7 +641,7 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g if (s->dump_buf) memcpy(s->dump_buf, s->analysis_buf, s->analysis_rdft_len * sizeof(*s->analysis_buf)); - av_rdft_calc(s->analysis_irdft, s->analysis_buf); + s->analysis_irdft_fn(s->analysis_irdft, s->analysis_buf, s->analysis_buf, sizeof(float)); center = s->fir_len / 2; for (k = 0; k <= center; k++) { @@ -691,7 +691,7 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g memcpy(rdft_buf + s->rdft_len/2, s->analysis_buf + s->analysis_rdft_len - s->rdft_len/2, s->rdft_len/2 * sizeof(*s->analysis_buf)); if (s->min_phase) generate_min_phase_kernel(s, rdft_buf); - av_rdft_calc(s->rdft, rdft_buf); + s->rdft_fn(s->rdft, rdft_buf, rdft_buf, sizeof(float)); for (k = 0; k < s->rdft_len; k++) { if (isnan(rdft_buf[k]) || isinf(rdft_buf[k])) { @@ -731,7 +731,8 @@ static int config_input(AVFilterLink *inlink) { AVFilterContext *ctx = inlink->dst; FIREqualizerContext *s = ctx->priv; - int rdft_bits; + float iscale, scale = 1.f; + int rdft_bits, ret; common_uninit(s); @@ -753,11 +754,15 @@ static int config_input(AVFilterLink *inlink) return AVERROR(EINVAL); } - if (!(s->rdft = av_rdft_init(rdft_bits, DFT_R2C)) || !(s->irdft = av_rdft_init(rdft_bits, IDFT_C2R))) - return AVERROR(ENOMEM); + iscale = 0.5f; + if (((ret = av_tx_init(&s->rdft, &s->rdft_fn, AV_TX_FLOAT_RDFT, 0, 1 << rdft_bits, &scale, AV_TX_INPLACE)) < 0) || + ((ret = av_tx_init(&s->irdft, &s->irdft_fn, AV_TX_FLOAT_RDFT, 1, 1 << rdft_bits, &iscale, AV_TX_INPLACE)) < 0)) + return ret; - if (s->fft2 && !s->multi && inlink->ch_layout.nb_channels > 1 && !(s->fft_ctx = av_fft_init(rdft_bits, 0))) - return AVERROR(ENOMEM); + scale = 1.f; + if (s->fft2 && !s->multi && inlink->ch_layout.nb_channels > 1 && + ((ret = av_tx_init(&s->fft_ctx, &s->fft_fn, AV_TX_FLOAT_FFT, 0, 1 << rdft_bits, &scale, AV_TX_INPLACE)) < 0)) + return ret; if (s->min_phase) { int cepstrum_bits = rdft_bits + 2; @@ -767,10 +772,15 @@ static int config_input(AVFilterLink *inlink) } cepstrum_bits = FFMIN(RDFT_BITS_MAX, cepstrum_bits + 1); - s->cepstrum_rdft = av_rdft_init(cepstrum_bits, DFT_R2C); - s->cepstrum_irdft = av_rdft_init(cepstrum_bits, IDFT_C2R); - if (!s->cepstrum_rdft || !s->cepstrum_irdft) - return AVERROR(ENOMEM); + scale = 1.f; + ret = av_tx_init(&s->cepstrum_rdft, &s->cepstrum_rdft_fn, AV_TX_FLOAT_RDFT, 0, 1 << cepstrum_bits, &scale, AV_TX_INPLACE); + if (ret < 0) + return ret; + + iscale = 8.f / (1 << cepstrum_bits); + ret = av_tx_init(&s->cepstrum_irdft, &s->cepstrum_irdft_fn, AV_TX_FLOAT_RDFT, 1, 1 << cepstrum_bits, &iscale, AV_TX_INPLACE); + if (ret < 0) + return ret; s->cepstrum_len = 1 << cepstrum_bits; s->cepstrum_buf = av_malloc_array(s->cepstrum_len, sizeof(*s->cepstrum_buf)); @@ -789,11 +799,14 @@ static int config_input(AVFilterLink *inlink) return AVERROR(EINVAL); } - if (!(s->analysis_irdft = av_rdft_init(rdft_bits, IDFT_C2R))) - return AVERROR(ENOMEM); + iscale = 0.5f; + if ((ret = av_tx_init(&s->analysis_irdft, &s->analysis_irdft_fn, AV_TX_FLOAT_RDFT, 1, 1 << rdft_bits, &iscale, AV_TX_INPLACE)) < 0) + return ret; if (s->dumpfile) { - s->analysis_rdft = av_rdft_init(rdft_bits, DFT_R2C); + scale = 1.f; + if ((ret = av_tx_init(&s->analysis_rdft, &s->analysis_rdft_fn, AV_TX_FLOAT_RDFT, 0, 1 << rdft_bits, &scale, AV_TX_INPLACE)) < 0) + return ret; s->dump_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->dump_buf)); } @@ -822,7 +835,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) if (!s->min_phase) { for (ch = 0; ch + 1 < inlink->ch_layout.nb_channels && s->fft_ctx; ch += 2) { - fast_convolute2(s, s->kernel_buf, (FFTComplex *)(s->conv_buf + 2 * ch * s->rdft_len), + fast_convolute2(s, s->kernel_buf, (AVComplexFloat *)(s->conv_buf + 2 * ch * s->rdft_len), s->conv_idx + ch, (float *) frame->extended_data[ch], (float *) frame->extended_data[ch+1], frame->nb_samples); } -- 2.37.2 [-- Attachment #3: Type: text/plain, Size: 251 bytes --] _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
reply other threads:[~2022-11-13 13:35 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to='CAPYw7P5HqsjWDbMmoRfUE8SVS149m2D1h6Gboe=dwtK7Oi2p7w@mail.gmail.com' \ --to=onemda@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git