1 /*
2  * DSP utils
3  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file libavcodec/dsputil.h
25  * DSP utils.
26  * note, many functions in here may use MMX which trashes the FPU state, it is
27  * absolutely necessary to call emms_c() between dsp & float/double code
28  */
29 
30 #ifndef AVCODEC_DSPUTIL_H
31 #define AVCODEC_DSPUTIL_H
32 
33 #include "common.h"
34 
35 /* dct code */
36 typedef short DCTELEM;
37 typedef int DWTELEM;
38 typedef short IDWTELEM;
39 
40 /**
41  * Scantable.
42  */
43 typedef struct ScanTable{
44     const uint8_t *scantable;
45     uint8_t permutated[64];
46     uint8_t raster_end[64];
47 } ScanTable;
48 
49 void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable);
50 
51 /**
52  * Empty mmx state.
53  * this must be called between any dsp function and float/double code.
54  * for example sin(); dsp->idct_put(); emms_c(); cos()
55  */
56 #define emms_c()
57 
58 /* should be defined by architectures supporting
59    one or more MultiMedia extension */
60 int mm_support(void);
61 extern int mm_flags;
62 
63 #define DECLARE_ALIGNED_16(t, v) DECLARE_ALIGNED(16, t, v)
64 #define DECLARE_ALIGNED_8(t, v)  DECLARE_ALIGNED(8, t, v)
65 
66 #define mm_flags 0
67 #define mm_support() 0
68 
69 #ifndef STRIDE_ALIGN
70 #   define STRIDE_ALIGN 8
71 #endif
72 
73 /* FFT computation */
74 
75 /* NOTE: soon integer code will be added, so you must use the
76    FFTSample type */
77 typedef float FFTSample;
78 
79 struct MDCTContext;
80 
81 typedef struct FFTComplex {
82     FFTSample re, im;
83 } FFTComplex;
84 
85 typedef struct FFTContext {
86     int nbits;
87     int inverse;
88     uint16_t *revtab;
89     FFTComplex *exptab;
90     FFTComplex *exptab1; /* only used by SSE code */
91     FFTComplex *tmp_buf;
92     void (*fft_permute)(struct FFTContext *s, FFTComplex *z);
93     void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
94     int split_radix;
95     int permutation;
96 #define FF_MDCT_PERM_NONE       0
97 #define FF_MDCT_PERM_INTERLEAVE 1
98 } FFTContext;
99 
100 extern FFTSample* const ff_cos_tabs[17];
101 
102 #define COSTABLE_CONST
103 #define SINTABLE_CONST
104 
105 #define COSTABLE(size) COSTABLE_CONST FFTSample ff_cos_##size[size/2]
106 
107 #define SINTABLE(size) SINTABLE_CONST FFTSample ff_sin_##size[size/2]
108 
109 extern COSTABLE(16);
110 extern COSTABLE(32);
111 extern COSTABLE(64);
112 extern COSTABLE(128);
113 extern COSTABLE(256);
114 extern COSTABLE(512);
115 extern COSTABLE(1024);
116 extern COSTABLE(2048);
117 extern COSTABLE(4096);
118 extern COSTABLE(8192);
119 extern COSTABLE(16384);
120 extern COSTABLE(32768);
121 extern COSTABLE(65536);
122 
123 /**
124  * Initializes the cosine table in ff_cos_tabs[index]
125  * \param index index in ff_cos_tabs array of the table to initialize
126  */
127 void ff_init_ff_cos_tabs(int index);
128 
129 extern SINTABLE(16);
130 extern SINTABLE(32);
131 extern SINTABLE(64);
132 extern SINTABLE(128);
133 extern SINTABLE(256);
134 extern SINTABLE(512);
135 extern SINTABLE(1024);
136 extern SINTABLE(2048);
137 extern SINTABLE(4096);
138 extern SINTABLE(8192);
139 extern SINTABLE(16384);
140 extern SINTABLE(32768);
141 extern SINTABLE(65536);
142 
143 /**
144  * Sets up a complex FFT.
145  * @param nbits           log2 of the length of the input array
146  * @param inverse         if 0 perform the forward transform, if 1 perform the inverse
147  */
148 int ff_fft_init(FFTContext *s, int nbits, int inverse);
149 void ff_fft_permute_c(FFTContext *s, FFTComplex *z);
150 void ff_fft_calc_c(FFTContext *s, FFTComplex *z);
151 
152 /**
153  * Do the permutation needed BEFORE calling ff_fft_calc().
154  */
ff_fft_permute(FFTContext * s,FFTComplex * z)155 static inline void ff_fft_permute(FFTContext *s, FFTComplex *z)
156 {
157     s->fft_permute(s, z);
158 }
159 /**
160  * Do a complex FFT with the parameters defined in ff_fft_init(). The
161  * input data must be permuted before. No 1.0/sqrt(n) normalization is done.
162  */
ff_fft_calc(FFTContext * s,FFTComplex * z)163 static inline void ff_fft_calc(FFTContext *s, FFTComplex *z)
164 {
165     s->fft_calc(s, z);
166 }
167 void ff_fft_end(FFTContext *s);
168 
169 /**
170  * Generate a sine window.
171  * @param   window  pointer to half window
172  * @param   n       size of half window
173  */
174 void ff_sine_window_init(float *window, int n);
175 extern float ff_sine_128 [ 128];
176 extern float ff_sine_256 [ 256];
177 extern float ff_sine_512 [ 512];
178 extern float ff_sine_1024[1024];
179 extern float ff_sine_2048[2048];
180 extern float ff_sine_4096[4096];
181 extern float * const ff_sine_windows[6];
182 
183 /* Real Discrete Fourier Transform */
184 
185 enum RDFTransformType {
186     RDFT,
187     IRDFT,
188     RIDFT,
189     IRIDFT
190 };
191 
192 typedef struct {
193     int nbits;
194     int inverse;
195     int sign_convention;
196 
197     /* pre/post rotation tables */
198     FFTSample *tcos;
199     FFTSample *tsin;
200     FFTContext fft;
201 } RDFTContext;
202 
203 /**
204  * Sets up a real FFT.
205  * @param nbits           log2 of the length of the input array
206  * @param trans           the type of transform
207  */
208 int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans);
209 void ff_rdft_calc(RDFTContext *s, FFTSample *data);
210 void ff_rdft_end(RDFTContext *s);
211 
212 /* Discrete Cosine Transform */
213 
214 typedef struct {
215     int nbits;
216     int inverse;
217     FFTComplex *data;
218     FFTContext fft;
219 } DCTContext;
220 
221 /**
222  * Sets up (Inverse)DCT.
223  * @param nbits           log2 of the length of the input array
224  * @param inverse         >0 forward transform, <0 inverse transform
225  */
226 int ff_dct_init(DCTContext *s, int nbits, int inverse);
227 void ff_dct_calc(DCTContext *s, FFTSample *data);
228 void ff_dct_end(DCTContext *s);
229 
230 #endif /* AVCODEC_DSPUTIL_H */
231