History

avfilter/vaf_spectrumsynth: switch to TX FFT from avutil

Paul B Mahol committed 5 years ago

Commit b3117f31 parent a428d2a2 files · +47 −36Browse files

Showing the changes to libavfilter (1 of 2 files). Show all

Unified · Split

libavfilter/vaf_spectrumsynth.c+47−33
@@ -24,7 +24,7 @@ · 23 unmodified lines
24 * @todo support float pixel format24 * @todo support float pixel format
25 */25 */
26 26
27#include "libavcodec/avfft.h"27#include "libavutil/tx.h"
28#include "libavutil/avassert.h"28#include "libavutil/avassert.h"
29#include "libavutil/channel_layout.h"29#include "libavutil/channel_layout.h"
30#include "libavutil/ffmath.h"30#include "libavutil/ffmath.h"
@@ -53,9 +53,10 @@ typedef struct SpectrumSynthContext { · 22 unmodified lines
53 int orientation;53 int orientation;
54 54
55 AVFrame *magnitude, *phase;55 AVFrame *magnitude, *phase;
56 FFTContext *fft; ///< Fast Fourier Transform context56 AVTXContext *fft; ///< Fast Fourier Transform context
57 int fft_bits; ///< number of bits (FFT window size = 1<<fft_bits)57 av_tx_fn tx_fn;
58 FFTComplex **fft_data; ///< bins holder for each (displayed) channels58 AVComplexFloat **fft_in; ///< bins holder for each (displayed) channels
59 AVComplexFloat **fft_out; ///< bins holder for each (displayed) channels
59 int win_size;60 int win_size;
60 int size;61 int size;
61 int nb_freq;62 int nb_freq;
@@ -150,8 +151,8 @@ static int config_output(AVFilterLink *outlink) · 88 unmodified lines
150 int height = ctx->inputs[0]->h;151 int height = ctx->inputs[0]->h;
151 AVRational time_base = ctx->inputs[0]->time_base;152 AVRational time_base = ctx->inputs[0]->time_base;
152 AVRational frame_rate = ctx->inputs[0]->frame_rate;153 AVRational frame_rate = ctx->inputs[0]->frame_rate;
153 int i, ch, fft_bits;154 float factor, overlap, scale;
154 float factor, overlap;155 int i, ch, ret;
155 156
156 outlink->sample_rate = s->sample_rate;157 outlink->sample_rate = s->sample_rate;
157 outlink->time_base = (AVRational){1, s->sample_rate};158 outlink->time_base = (AVRational){1, s->sample_rate};
@@ -182,23 +183,30 @@ static int config_output(AVFilterLink *outlink) · 24 unmodified lines
182 s->size = s->orientation == VERTICAL ? height / s->channels : width / s->channels;183 s->size = s->orientation == VERTICAL ? height / s->channels : width / s->channels;
183 s->xend = s->orientation == VERTICAL ? width : height;184 s->xend = s->orientation == VERTICAL ? width : height;
184 185
185 for (fft_bits = 1; 1 << fft_bits < 2 * s->size; fft_bits++);186 s->win_size = s->size * 2;
187 s->nb_freq = s->size;
186 188
187 s->win_size = 1 << fft_bits;189 ret = av_tx_init(&s->fft, &s->tx_fn, AV_TX_FLOAT_FFT, 1, s->win_size, &scale, 0);
188 s->nb_freq = 1 << (fft_bits - 1);190 if (ret < 0) {
189
190 s->fft = av_fft_init(fft_bits, 1);
191 if (!s->fft) {
192 av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. "191 av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. "
193 "The window size might be too high.\n");192 "The window size might be too high.\n");
194 return AVERROR(EINVAL);193 return ret;
195 }194 }
196 s->fft_data = av_calloc(s->channels, sizeof(*s->fft_data));195
197 if (!s->fft_data)196 s->fft_in = av_calloc(s->channels, sizeof(*s->fft_in));
197 if (!s->fft_in)
198 return AVERROR(ENOMEM);198 return AVERROR(ENOMEM);
199 s->fft_out = av_calloc(s->channels, sizeof(*s->fft_out));
200 if (!s->fft_out)
201 return AVERROR(ENOMEM);
202
199 for (ch = 0; ch < s->channels; ch++) {203 for (ch = 0; ch < s->channels; ch++) {
200 s->fft_data[ch] = av_calloc(s->win_size, sizeof(**s->fft_data));204 s->fft_in[ch] = av_calloc(FFALIGN(s->win_size, av_cpu_max_align()), sizeof(**s->fft_in));
201 if (!s->fft_data[ch])205 if (!s->fft_in[ch])
206 return AVERROR(ENOMEM);
207
208 s->fft_out[ch] = av_calloc(FFALIGN(s->win_size, av_cpu_max_align()), sizeof(**s->fft_out));
209 if (!s->fft_out[ch])
202 return AVERROR(ENOMEM);210 return AVERROR(ENOMEM);
203 }211 }
204 212
@@ -244,8 +252,8 @@ static void read16_fft_bin(SpectrumSynthContext *s, · 39 unmodified lines
244 }252 }
245 phase = ((p[x] / (double)UINT16_MAX) * 2. - 1.) * M_PI;253 phase = ((p[x] / (double)UINT16_MAX) * 2. - 1.) * M_PI;
246 254
247 s->fft_data[ch][f].re = magnitude * cos(phase);255 s->fft_in[ch][f].re = magnitude * cos(phase);
248 s->fft_data[ch][f].im = magnitude * sin(phase);256 s->fft_in[ch][f].im = magnitude * sin(phase);
249}257}
250 258
251static void read8_fft_bin(SpectrumSynthContext *s,259static void read8_fft_bin(SpectrumSynthContext *s,
@@ -269,8 +277,8 @@ static void read8_fft_bin(SpectrumSynthContext *s, · 17 unmodified lines
269 }277 }
270 phase = ((p[x] / (double)UINT8_MAX) * 2. - 1.) * M_PI;278 phase = ((p[x] / (double)UINT8_MAX) * 2. - 1.) * M_PI;
271 279
272 s->fft_data[ch][f].re = magnitude * cos(phase);280 s->fft_in[ch][f].re = magnitude * cos(phase);
273 s->fft_data[ch][f].im = magnitude * sin(phase);281 s->fft_in[ch][f].im = magnitude * sin(phase);
274}282}
275 283
276static void read_fft_data(AVFilterContext *ctx, int x, int h, int ch)284static void read_fft_data(AVFilterContext *ctx, int x, int h, int ch)
@@ -330,17 +338,16 @@ static void synth_window(AVFilterContext *ctx, int x) · 53 unmodified lines
330 read_fft_data(ctx, x, h, ch);338 read_fft_data(ctx, x, h, ch);
331 339
332 for (y = h; y <= s->nb_freq; y++) {340 for (y = h; y <= s->nb_freq; y++) {
333 s->fft_data[ch][y].re = 0;341 s->fft_in[ch][y].re = 0;
334 s->fft_data[ch][y].im = 0;342 s->fft_in[ch][y].im = 0;
335 }343 }
336 344
337 for (y = s->nb_freq + 1, f = s->nb_freq - 1; y < nb; y++, f--) {345 for (y = s->nb_freq + 1, f = s->nb_freq - 1; y < nb; y++, f--) {
338 s->fft_data[ch][y].re = s->fft_data[ch][f].re;346 s->fft_in[ch][y].re = s->fft_in[ch][f].re;
339 s->fft_data[ch][y].im = -s->fft_data[ch][f].im;347 s->fft_in[ch][y].im = -s->fft_in[ch][f].im;
340 }348 }
341 349
342 av_fft_permute(s->fft, s->fft_data[ch]);350 s->tx_fn(s->fft, s->fft_out[ch], s->fft_in[ch], sizeof(float));
343 av_fft_calc(s->fft, s->fft_data[ch]);
344 }351 }
345}352}
346 353
@@ -363,11 +370,11 @@ static int try_push_frame(AVFilterContext *ctx, int x) · 16 unmodified lines
363 end = s->end;370 end = s->end;
364 k = end;371 k = end;
365 for (i = 0, j = start; j < k && i < s->win_size; i++, j++) {372 for (i = 0, j = start; j < k && i < s->win_size; i++, j++) {
366 buf[j] += s->fft_data[ch][i].re;373 buf[j] += s->fft_out[ch][i].re;
367 }374 }
368 375
369 for (; i < s->win_size; i++, j++) {376 for (; i < s->win_size; i++, j++) {
370 buf[j] = s->fft_data[ch][i].re;377 buf[j] = s->fft_out[ch][i].re;
371 }378 }
372 379
373 start += s->hop_size;380 start += s->hop_size;
@@ -499,12 +506,19 @@ static av_cold void uninit(AVFilterContext *ctx) · 125 unmodified lines
499 av_frame_free(&s->magnitude);506 av_frame_free(&s->magnitude);
500 av_frame_free(&s->phase);507 av_frame_free(&s->phase);
501 av_frame_free(&s->buffer);508 av_frame_free(&s->buffer);
502 av_fft_end(s->fft);509
503 if (s->fft_data) {510 av_tx_uninit(&s->fft);
511
512 if (s->fft_in) {
513 for (i = 0; i < s->channels; i++)
514 av_freep(&s->fft_in[i]);
515 }
516 if (s->fft_out) {
504 for (i = 0; i < s->channels; i++)517 for (i = 0; i < s->channels; i++)
505 av_freep(&s->fft_data[i]);518 av_freep(&s->fft_out[i]);
506 }519 }
507 av_freep(&s->fft_data);520 av_freep(&s->fft_in);
521 av_freep(&s->fft_out);
508 av_freep(&s->window_func_lut);522 av_freep(&s->window_func_lut);
509}523}
510 524

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t