Showing the changes to libavfilter (1 of 2 files). Show all
Unified · Split
| @@ -24,7 +24,7 @@ · 23 unmodified lines | |||
| 24 | * @todo support float pixel format | 24 | * @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 context | 56 | 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) channels | 58 | 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 | ||
| 251 | static void read8_fft_bin(SpectrumSynthContext *s, | 259 | static 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 | ||
| 276 | static void read_fft_data(AVFilterContext *ctx, int x, int h, int ch) | 284 | 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) · 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 | ||