2014-04-28 18:56:43 +03:00
|
|
|
/*
|
2017-02-01 05:13:06 +02:00
|
|
|
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
|
|
|
|
*
|
2014-05-15 22:13:31 +03:00
|
|
|
* This file is part of FFmpeg.
|
2014-04-28 18:56:43 +03:00
|
|
|
*
|
2014-05-15 22:13:31 +03:00
|
|
|
* FFmpeg is free software; you can redistribute it and/or
|
2014-04-28 18:56:43 +03:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
2014-05-15 22:13:31 +03:00
|
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
2014-04-28 18:56:43 +03:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2014-05-15 22:13:31 +03:00
|
|
|
* License along with FFmpeg; if not, write to the Free Software
|
2014-04-28 18:56:43 +03:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
2017-02-01 05:13:06 +02:00
|
|
|
#ifndef AVCODEC_MDCT15_H
|
|
|
|
#define AVCODEC_MDCT15_H
|
2014-04-28 18:56:43 +03:00
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
imdct15: replace the FFT with a faster PFA FFT algorithm
This commit replaces the current inefficient non-power-of-two FFT with a
much faster FFT based on the Prime Factor Algorithm.
Although it is already much faster than the old algorithm without SIMD,
the new algorithm makes use of the already very throughouly SIMD'd power
of two FFT, which improves performance even more across all platforms
which we have SIMD support for.
Most of the work was done by Peter Barfuss, who passed the code to me to
implement into the iMDCT and the current codebase. The code for a
5-point and 15-point FFT was derived from the previous implementation,
although it was optimized and simplified, which will make its future
SIMD easier. The 15-point FFT is currently using 6% of the current
overall decoder overhead.
The FFT can now easily be used as a forward transform by simply not
multiplying the 5-point FFT's imaginary component by -1 (which comes
from the fact that changing the complex exponential's angle by -1 also
changes the output by that) and by multiplying the "theta" angle of the
main exptab by -1. Hence the deliberately left multiplication by -1 at
the end.
FATE passes, and performance reports on other platforms/CPUs are
welcome.
Performance comparisons:
iMDCT, PFA:
101127 decicycles in speed, 32765 runs, 3 skips
iMDCT, Old:
211022 decicycles in speed, 32768 runs, 0 skips
Standalone FFT, 300000 transforms of size 960:
PFA Old FFT kiss_fft libfftw3f
3.659695s, 15.726912s, 13.300789s, 1.182222s
Being only 3x slower than libfftw3f is a big achievement by itself.
There appears to be something capping the performance in the iMDCT side
of things, possibly during the pre-stage reindexing. However, it is
certainly fast enough for now.
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2017-01-04 11:23:24 +02:00
|
|
|
#include "fft.h"
|
2014-04-28 18:56:43 +03:00
|
|
|
|
2017-02-01 05:13:06 +02:00
|
|
|
typedef struct MDCT15Context {
|
2014-04-28 18:56:43 +03:00
|
|
|
int fft_n;
|
|
|
|
int len2;
|
|
|
|
int len4;
|
2017-02-01 05:13:06 +02:00
|
|
|
int inverse;
|
imdct15: replace the FFT with a faster PFA FFT algorithm
This commit replaces the current inefficient non-power-of-two FFT with a
much faster FFT based on the Prime Factor Algorithm.
Although it is already much faster than the old algorithm without SIMD,
the new algorithm makes use of the already very throughouly SIMD'd power
of two FFT, which improves performance even more across all platforms
which we have SIMD support for.
Most of the work was done by Peter Barfuss, who passed the code to me to
implement into the iMDCT and the current codebase. The code for a
5-point and 15-point FFT was derived from the previous implementation,
although it was optimized and simplified, which will make its future
SIMD easier. The 15-point FFT is currently using 6% of the current
overall decoder overhead.
The FFT can now easily be used as a forward transform by simply not
multiplying the 5-point FFT's imaginary component by -1 (which comes
from the fact that changing the complex exponential's angle by -1 also
changes the output by that) and by multiplying the "theta" angle of the
main exptab by -1. Hence the deliberately left multiplication by -1 at
the end.
FATE passes, and performance reports on other platforms/CPUs are
welcome.
Performance comparisons:
iMDCT, PFA:
101127 decicycles in speed, 32765 runs, 3 skips
iMDCT, Old:
211022 decicycles in speed, 32768 runs, 0 skips
Standalone FFT, 300000 transforms of size 960:
PFA Old FFT kiss_fft libfftw3f
3.659695s, 15.726912s, 13.300789s, 1.182222s
Being only 3x slower than libfftw3f is a big achievement by itself.
There appears to be something capping the performance in the iMDCT side
of things, possibly during the pre-stage reindexing. However, it is
certainly fast enough for now.
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2017-01-04 11:23:24 +02:00
|
|
|
int *pfa_prereindex;
|
|
|
|
int *pfa_postreindex;
|
|
|
|
|
|
|
|
FFTContext ptwo_fft;
|
2014-04-28 18:56:43 +03:00
|
|
|
|
|
|
|
FFTComplex *tmp;
|
|
|
|
|
|
|
|
FFTComplex *twiddle_exptab;
|
|
|
|
|
imdct15: replace the FFT with a faster PFA FFT algorithm
This commit replaces the current inefficient non-power-of-two FFT with a
much faster FFT based on the Prime Factor Algorithm.
Although it is already much faster than the old algorithm without SIMD,
the new algorithm makes use of the already very throughouly SIMD'd power
of two FFT, which improves performance even more across all platforms
which we have SIMD support for.
Most of the work was done by Peter Barfuss, who passed the code to me to
implement into the iMDCT and the current codebase. The code for a
5-point and 15-point FFT was derived from the previous implementation,
although it was optimized and simplified, which will make its future
SIMD easier. The 15-point FFT is currently using 6% of the current
overall decoder overhead.
The FFT can now easily be used as a forward transform by simply not
multiplying the 5-point FFT's imaginary component by -1 (which comes
from the fact that changing the complex exponential's angle by -1 also
changes the output by that) and by multiplying the "theta" angle of the
main exptab by -1. Hence the deliberately left multiplication by -1 at
the end.
FATE passes, and performance reports on other platforms/CPUs are
welcome.
Performance comparisons:
iMDCT, PFA:
101127 decicycles in speed, 32765 runs, 3 skips
iMDCT, Old:
211022 decicycles in speed, 32768 runs, 0 skips
Standalone FFT, 300000 transforms of size 960:
PFA Old FFT kiss_fft libfftw3f
3.659695s, 15.726912s, 13.300789s, 1.182222s
Being only 3x slower than libfftw3f is a big achievement by itself.
There appears to be something capping the performance in the iMDCT side
of things, possibly during the pre-stage reindexing. However, it is
certainly fast enough for now.
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
2017-01-04 11:23:24 +02:00
|
|
|
/* 0 - 18: fft15 twiddles, 19 - 20: fft5 twiddles */
|
|
|
|
FFTComplex exptab[21];
|
2014-04-28 18:56:43 +03:00
|
|
|
|
2017-02-01 05:13:06 +02:00
|
|
|
/**
|
|
|
|
* Calculate a full 2N -> N MDCT
|
|
|
|
*/
|
|
|
|
void (*mdct)(struct MDCT15Context *s, float *dst, const float *src, ptrdiff_t stride);
|
|
|
|
|
2014-04-28 18:56:43 +03:00
|
|
|
/**
|
|
|
|
* Calculate the middle half of the iMDCT
|
|
|
|
*/
|
2017-02-01 05:13:06 +02:00
|
|
|
void (*imdct_half)(struct MDCT15Context *s, float *dst, const float *src,
|
2014-04-28 18:56:43 +03:00
|
|
|
ptrdiff_t src_stride, float scale);
|
2017-02-01 05:13:06 +02:00
|
|
|
} MDCT15Context;
|
2014-04-28 18:56:43 +03:00
|
|
|
|
|
|
|
/**
|
2017-02-01 05:13:06 +02:00
|
|
|
* Init an (i)MDCT of the length 2 * 15 * (2^N)
|
2014-04-28 18:56:43 +03:00
|
|
|
*/
|
2017-02-01 05:13:06 +02:00
|
|
|
int ff_mdct15_init(MDCT15Context **ps, int inverse, int N, double scale);
|
2014-04-28 18:56:43 +03:00
|
|
|
|
|
|
|
/**
|
2017-02-01 05:13:06 +02:00
|
|
|
* Frees a context
|
2014-04-28 18:56:43 +03:00
|
|
|
*/
|
2017-02-01 05:13:06 +02:00
|
|
|
void ff_mdct15_uninit(MDCT15Context **ps);
|
2014-04-28 18:56:43 +03:00
|
|
|
|
2017-02-01 05:13:06 +02:00
|
|
|
#endif /* AVCODEC_MDCT15_H */
|