[FFmpeg-cvslog] avfilter/vaf_spectrumsynth: switch to TX FFT from avutil

Paul B Mahol git at videolan.org
Wed Aug 4 11:17:25 EEST 2021


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed Aug  4 10:00:24 2021 +0200| [b3117f376d1c50b3c39befe27cbba12d5c0f80da] | committer: Paul B Mahol

avfilter/vaf_spectrumsynth: switch to TX FFT from avutil

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b3117f376d1c50b3c39befe27cbba12d5c0f80da
---

 configure                       |  3 --
 libavfilter/vaf_spectrumsynth.c | 80 ++++++++++++++++++++++++-----------------
 2 files changed, 47 insertions(+), 36 deletions(-)

diff --git a/configure b/configure
index 5c4ca62fb4..f9fdf58bc3 100755
--- a/configure
+++ b/configure
@@ -3660,8 +3660,6 @@ sinc_filter_select="rdft"
 smartblur_filter_deps="gpl swscale"
 sobel_opencl_filter_deps="opencl"
 sofalizer_filter_deps="libmysofa"
-spectrumsynth_filter_deps="avcodec"
-spectrumsynth_filter_select="fft"
 spp_filter_deps="gpl avcodec"
 spp_filter_select="fft idctdsp fdctdsp me_cmp pixblockdsp"
 sr_filter_deps="avformat swscale"
@@ -7278,7 +7276,6 @@ enabled scale2ref_filter    && prepend avfilter_deps "swscale"
 enabled showcqt_filter      && prepend avfilter_deps "avformat swscale"
 enabled signature_filter    && prepend avfilter_deps "avcodec avformat"
 enabled smartblur_filter    && prepend avfilter_deps "swscale"
-enabled spectrumsynth_filter && prepend avfilter_deps "avcodec"
 enabled spp_filter          && prepend avfilter_deps "avcodec"
 enabled sr_filter           && prepend avfilter_deps "avformat swscale"
 enabled subtitles_filter    && prepend avfilter_deps "avformat avcodec"
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);
 }
 



More information about the ffmpeg-cvslog mailing list