Showing the changes to libavfilter (1 of 2 files). Show all
Unified · Split
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <float.h> |
| 22 | 22 | #include <math.h> |
| 23 | 23 | |
| 24 | −#include "libavcodec/avfft.h" | |
| 24 | +#include "libavutil/tx.h" | |
| 25 | 25 | #include "libavutil/audio_fifo.h" |
| 26 | 26 | #include "libavutil/avassert.h" |
| 27 | 27 | #include "libavutil/avstring.h" |
| @@ -49,12 +49,13 @@ typedef struct ShowFreqsContext { · 21 unmodified lines | ||
| 49 | 49 | int data_mode; |
| 50 | 50 | int cmode; |
| 51 | 51 | int fft_size; |
| 52 | − int fft_bits; | |
| 53 | 52 | int ascale, fscale; |
| 54 | 53 | int avg; |
| 55 | 54 | int win_func; |
| 56 | − FFTContext *fft; | |
| 57 | − FFTComplex **fft_data; | |
| 55 | + AVTXContext *fft; | |
| 56 | + av_tx_fn tx_fn; | |
| 57 | + AVComplexFloat **fft_input; | |
| 58 | + AVComplexFloat **fft_data; | |
| 58 | 59 | float **avg_data; |
| 59 | 60 | float *window_func_lut; |
| 60 | 61 | float overlap; |
| @@ -171,32 +172,36 @@ static int config_output(AVFilterLink *outlink) · 110 unmodified lines | ||
| 171 | 172 | AVFilterContext *ctx = outlink->src; |
| 172 | 173 | AVFilterLink *inlink = ctx->inputs[0]; |
| 173 | 174 | ShowFreqsContext *s = ctx->priv; |
| 174 | − float overlap; | |
| 175 | − int i; | |
| 175 | + float overlap, scale; | |
| 176 | + int i, ret; | |
| 176 | 177 | |
| 177 | − s->fft_bits = av_log2(s->fft_size); | |
| 178 | − s->nb_freq = 1 << (s->fft_bits - 1); | |
| 179 | − s->win_size = s->nb_freq << 1; | |
| 178 | + s->nb_freq = s->fft_size / 2; | |
| 179 | + s->win_size = s->fft_size; | |
| 180 | 180 | av_audio_fifo_free(s->fifo); |
| 181 | − av_fft_end(s->fft); | |
| 182 | − s->fft = av_fft_init(s->fft_bits, 0); | |
| 183 | − if (!s->fft) { | |
| 181 | + av_tx_uninit(&s->fft); | |
| 182 | + ret = av_tx_init(&s->fft, &s->tx_fn, AV_TX_FLOAT_FFT, 0, s->fft_size, &scale, 0); | |
| 183 | + if (ret < 0) { | |
| 184 | 184 | av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. " |
| 185 | 185 | "The window size might be too high.\n"); |
| 186 | − return AVERROR(ENOMEM); | |
| 186 | + return ret; | |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | 189 | /* FFT buffers: x2 for each (display) channel buffer. |
| 190 | 190 | * Note: we use free and malloc instead of a realloc-like function to |
| 191 | 191 | * make sure the buffer is aligned in memory for the FFT functions. */ |
| 192 | 192 | for (i = 0; i < s->nb_channels; i++) { |
| 193 | + av_freep(&s->fft_input[i]); | |
| 193 | 194 | av_freep(&s->fft_data[i]); |
| 194 | 195 | av_freep(&s->avg_data[i]); |
| 195 | 196 | } |
| 197 | + av_freep(&s->fft_input); | |
| 196 | 198 | av_freep(&s->fft_data); |
| 197 | 199 | av_freep(&s->avg_data); |
| 198 | 200 | s->nb_channels = inlink->channels; |
| 199 | 201 | |
| 202 | + s->fft_input = av_calloc(s->nb_channels, sizeof(*s->fft_input)); | |
| 203 | + if (!s->fft_input) | |
| 204 | + return AVERROR(ENOMEM); | |
| 200 | 205 | s->fft_data = av_calloc(s->nb_channels, sizeof(*s->fft_data)); |
| 201 | 206 | if (!s->fft_data) |
| 202 | 207 | return AVERROR(ENOMEM); |
| @@ -204,9 +209,10 @@ static int config_output(AVFilterLink *outlink) · 1 unmodified line | ||
| 204 | 209 | if (!s->avg_data) |
| 205 | 210 | return AVERROR(ENOMEM); |
| 206 | 211 | for (i = 0; i < s->nb_channels; i++) { |
| 207 | − s->fft_data[i] = av_calloc(s->win_size, sizeof(**s->fft_data)); | |
| 212 | + s->fft_input[i] = av_calloc(FFALIGN(s->win_size, 512), sizeof(**s->fft_input)); | |
| 213 | + s->fft_data[i] = av_calloc(FFALIGN(s->win_size, 512), sizeof(**s->fft_data)); | |
| 208 | 214 | s->avg_data[i] = av_calloc(s->nb_freq, sizeof(**s->avg_data)); |
| 209 | − if (!s->fft_data[i] || !s->avg_data[i]) | |
| 215 | + if (!s->fft_data[i] || !s->avg_data[i] || !s->fft_input[i]) | |
| 210 | 216 | return AVERROR(ENOMEM); |
| 211 | 217 | } |
| 212 | 218 | |
| @@ -385,19 +391,18 @@ static int plot_freqs(AVFilterLink *inlink, AVFrame *in) · 172 unmodified lines | ||
| 385 | 391 | const float *p = (float *)in->extended_data[ch]; |
| 386 | 392 | |
| 387 | 393 | for (n = 0; n < in->nb_samples; n++) { |
| 388 | − s->fft_data[ch][n].re = p[n] * s->window_func_lut[n]; | |
| 389 | − s->fft_data[ch][n].im = 0; | |
| 394 | + s->fft_input[ch][n].re = p[n] * s->window_func_lut[n]; | |
| 395 | + s->fft_input[ch][n].im = 0; | |
| 390 | 396 | } |
| 391 | 397 | for (; n < win_size; n++) { |
| 392 | − s->fft_data[ch][n].re = 0; | |
| 393 | − s->fft_data[ch][n].im = 0; | |
| 398 | + s->fft_input[ch][n].re = 0; | |
| 399 | + s->fft_input[ch][n].im = 0; | |
| 394 | 400 | } |
| 395 | 401 | } |
| 396 | 402 | |
| 397 | 403 | /* run FFT on each samples set */ |
| 398 | 404 | for (ch = 0; ch < s->nb_channels; ch++) { |
| 399 | − av_fft_permute(s->fft, s->fft_data[ch]); | |
| 400 | − av_fft_calc(s->fft, s->fft_data[ch]); | |
| 405 | + s->tx_fn(s->fft, s->fft_data[ch], s->fft_input[ch], sizeof(float)); | |
| 401 | 406 | } |
| 402 | 407 | |
| 403 | 408 | #define RE(x, ch) s->fft_data[ch][x].re |
| @@ -526,13 +531,16 @@ static av_cold void uninit(AVFilterContext *ctx) · 122 unmodified lines | ||
| 526 | 531 | ShowFreqsContext *s = ctx->priv; |
| 527 | 532 | int i; |
| 528 | 533 | |
| 529 | − av_fft_end(s->fft); | |
| 534 | + av_tx_uninit(&s->fft); | |
| 530 | 535 | for (i = 0; i < s->nb_channels; i++) { |
| 536 | + if (s->fft_input) | |
| 537 | + av_freep(&s->fft_input[i]); | |
| 531 | 538 | if (s->fft_data) |
| 532 | 539 | av_freep(&s->fft_data[i]); |
| 533 | 540 | if (s->avg_data) |
| 534 | 541 | av_freep(&s->avg_data[i]); |
| 535 | 542 | } |
| 543 | + av_freep(&s->fft_input); | |
| 536 | 544 | av_freep(&s->fft_data); |
| 537 | 545 | av_freep(&s->avg_data); |
| 538 | 546 | av_freep(&s->window_func_lut); |