Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-08-04 11:00:24 +0300
committerPaul B Mahol <onemda@gmail.com>2021-08-04 11:04:58 +0300
commitb3117f376d1c50b3c39befe27cbba12d5c0f80da (patch)
tree9d97e08d3213eb07d48c9d76a44383cef941ab12 /libavfilter/vaf_spectrumsynth.c
parenta428d2a4871e9523bc3b59fdd1633ae7edfa9e24 (diff)
avfilter/vaf_spectrumsynth: switch to TX FFT from avutil
Diffstat (limited to 'libavfilter/vaf_spectrumsynth.c')
-rw-r--r--libavfilter/vaf_spectrumsynth.c80
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);
}