diff options
author | Paul B Mahol <onemda@gmail.com> | 2021-08-04 11:00:24 +0300 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2021-08-04 11:04:58 +0300 |
commit | b3117f376d1c50b3c39befe27cbba12d5c0f80da (patch) | |
tree | 9d97e08d3213eb07d48c9d76a44383cef941ab12 /libavfilter/vaf_spectrumsynth.c | |
parent | a428d2a4871e9523bc3b59fdd1633ae7edfa9e24 (diff) |
avfilter/vaf_spectrumsynth: switch to TX FFT from avutil
Diffstat (limited to 'libavfilter/vaf_spectrumsynth.c')
-rw-r--r-- | libavfilter/vaf_spectrumsynth.c | 80 |
1 files changed, 47 insertions, 33 deletions
diff --git a/libavfilter/vaf_spectrumsynth.c b/libavfilter/vaf_spectrumsynth.c index 36fb48c630..cf76f4e4c7 100644 --- a/libavfilter/vaf_spectrumsynth.c +++ b/libavfilter/vaf_spectrumsynth.c @@ -24,7 +24,7 @@ * @todo support float pixel format */ -#include "libavcodec/avfft.h" +#include "libavutil/tx.h" #include "libavutil/avassert.h" #include "libavutil/channel_layout.h" #include "libavutil/ffmath.h" @@ -53,9 +53,10 @@ typedef struct SpectrumSynthContext { int orientation; AVFrame *magnitude, *phase; - FFTContext *fft; ///< Fast Fourier Transform context - int fft_bits; ///< number of bits (FFT window size = 1<<fft_bits) - FFTComplex **fft_data; ///< bins holder for each (displayed) channels + AVTXContext *fft; ///< Fast Fourier Transform context + av_tx_fn tx_fn; + AVComplexFloat **fft_in; ///< bins holder for each (displayed) channels + AVComplexFloat **fft_out; ///< bins holder for each (displayed) channels int win_size; int size; int nb_freq; @@ -150,8 +151,8 @@ static int config_output(AVFilterLink *outlink) int height = ctx->inputs[0]->h; AVRational time_base = ctx->inputs[0]->time_base; AVRational frame_rate = ctx->inputs[0]->frame_rate; - int i, ch, fft_bits; - float factor, overlap; + float factor, overlap, scale; + int i, ch, ret; outlink->sample_rate = s->sample_rate; outlink->time_base = (AVRational){1, s->sample_rate}; @@ -182,23 +183,30 @@ static int config_output(AVFilterLink *outlink) s->size = s->orientation == VERTICAL ? height / s->channels : width / s->channels; s->xend = s->orientation == VERTICAL ? width : height; - for (fft_bits = 1; 1 << fft_bits < 2 * s->size; fft_bits++); + s->win_size = s->size * 2; + s->nb_freq = s->size; - s->win_size = 1 << fft_bits; - s->nb_freq = 1 << (fft_bits - 1); - - s->fft = av_fft_init(fft_bits, 1); - if (!s->fft) { + ret = av_tx_init(&s->fft, &s->tx_fn, AV_TX_FLOAT_FFT, 1, s->win_size, &scale, 0); + if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. " "The window size might be too high.\n"); - return AVERROR(EINVAL); + return ret; } - s->fft_data = av_calloc(s->channels, sizeof(*s->fft_data)); - if (!s->fft_data) + + s->fft_in = av_calloc(s->channels, sizeof(*s->fft_in)); + if (!s->fft_in) return AVERROR(ENOMEM); + s->fft_out = av_calloc(s->channels, sizeof(*s->fft_out)); + if (!s->fft_out) + return AVERROR(ENOMEM); + for (ch = 0; ch < s->channels; ch++) { - s->fft_data[ch] = av_calloc(s->win_size, sizeof(**s->fft_data)); - if (!s->fft_data[ch]) + s->fft_in[ch] = av_calloc(FFALIGN(s->win_size, av_cpu_max_align()), sizeof(**s->fft_in)); + if (!s->fft_in[ch]) + return AVERROR(ENOMEM); + + s->fft_out[ch] = av_calloc(FFALIGN(s->win_size, av_cpu_max_align()), sizeof(**s->fft_out)); + if (!s->fft_out[ch]) return AVERROR(ENOMEM); } @@ -244,8 +252,8 @@ static void read16_fft_bin(SpectrumSynthContext *s, } phase = ((p[x] / (double)UINT16_MAX) * 2. - 1.) * M_PI; - s->fft_data[ch][f].re = magnitude * cos(phase); - s->fft_data[ch][f].im = magnitude * sin(phase); + s->fft_in[ch][f].re = magnitude * cos(phase); + s->fft_in[ch][f].im = magnitude * sin(phase); } static void read8_fft_bin(SpectrumSynthContext *s, @@ -269,8 +277,8 @@ static void read8_fft_bin(SpectrumSynthContext *s, } phase = ((p[x] / (double)UINT8_MAX) * 2. - 1.) * M_PI; - s->fft_data[ch][f].re = magnitude * cos(phase); - s->fft_data[ch][f].im = magnitude * sin(phase); + s->fft_in[ch][f].re = magnitude * cos(phase); + s->fft_in[ch][f].im = magnitude * sin(phase); } static void read_fft_data(AVFilterContext *ctx, int x, int h, int ch) @@ -330,17 +338,16 @@ static void synth_window(AVFilterContext *ctx, int x) read_fft_data(ctx, x, h, ch); for (y = h; y <= s->nb_freq; y++) { - s->fft_data[ch][y].re = 0; - s->fft_data[ch][y].im = 0; + s->fft_in[ch][y].re = 0; + s->fft_in[ch][y].im = 0; } for (y = s->nb_freq + 1, f = s->nb_freq - 1; y < nb; y++, f--) { - s->fft_data[ch][y].re = s->fft_data[ch][f].re; - s->fft_data[ch][y].im = -s->fft_data[ch][f].im; + s->fft_in[ch][y].re = s->fft_in[ch][f].re; + s->fft_in[ch][y].im = -s->fft_in[ch][f].im; } - av_fft_permute(s->fft, s->fft_data[ch]); - av_fft_calc(s->fft, s->fft_data[ch]); + s->tx_fn(s->fft, s->fft_out[ch], s->fft_in[ch], sizeof(float)); } } @@ -363,11 +370,11 @@ static int try_push_frame(AVFilterContext *ctx, int x) end = s->end; k = end; for (i = 0, j = start; j < k && i < s->win_size; i++, j++) { - buf[j] += s->fft_data[ch][i].re; + buf[j] += s->fft_out[ch][i].re; } for (; i < s->win_size; i++, j++) { - buf[j] = s->fft_data[ch][i].re; + buf[j] = s->fft_out[ch][i].re; } start += s->hop_size; @@ -499,12 +506,19 @@ static av_cold void uninit(AVFilterContext *ctx) av_frame_free(&s->magnitude); av_frame_free(&s->phase); av_frame_free(&s->buffer); - av_fft_end(s->fft); - if (s->fft_data) { + + av_tx_uninit(&s->fft); + + if (s->fft_in) { + for (i = 0; i < s->channels; i++) + av_freep(&s->fft_in[i]); + } + if (s->fft_out) { for (i = 0; i < s->channels; i++) - av_freep(&s->fft_data[i]); + av_freep(&s->fft_out[i]); } - av_freep(&s->fft_data); + av_freep(&s->fft_in); + av_freep(&s->fft_out); av_freep(&s->window_func_lut); } |