Mercurial > libavcodec.hg
annotate fft-test.c @ 9595:f9a7147cc9e6 libavcodec
Do not scan for MP3 header after the given buffer and return skipped
bytes along with consumed bytes on successful decoding.
patch by Zdenek Kabelac, zdenek.kabelac gmail com
author | diego |
---|---|
date | Mon, 04 May 2009 14:23:48 +0000 |
parents | 2313bf51945b |
children | 67a20f0eb42c |
rev | line source |
---|---|
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
1 /* |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
2 * (c) 2002 Fabrice Bellard |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
3 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
4 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
5 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
6 * FFmpeg is free software; you can redistribute it and/or |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
7 * modify it under the terms of the GNU Lesser General Public |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
8 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
9 * version 2.1 of the License, or (at your option) any later version. |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
10 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
11 * FFmpeg is distributed in the hope that it will be useful, |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
14 * Lesser General Public License for more details. |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
15 * |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
16 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3699
diff
changeset
|
17 * License along with FFmpeg; if not, write to the Free Software |
3699
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
19 */ |
c537a97eec66
Add official LGPL license headers to the files that were missing them.
diego
parents:
2967
diff
changeset
|
20 |
1106 | 21 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
7546
diff
changeset
|
22 * @file libavcodec/fft-test.c |
1106 | 23 * FFT and MDCT tests. |
24 */ | |
25 | |
9199
ea0e5e9a520f
Replace random() usage in test programs by av_lfg_*().
diego
parents:
8718
diff
changeset
|
26 #include "libavutil/lfg.h" |
781 | 27 #include "dsputil.h" |
28 #include <math.h> | |
980 | 29 #include <unistd.h> |
781 | 30 #include <sys/time.h> |
5118
3b190bc34546
Add some #includes to allow compilation without HAVE_AV_CONFIG_H.
diego
parents:
4760
diff
changeset
|
31 #include <stdlib.h> |
3b190bc34546
Add some #includes to allow compilation without HAVE_AV_CONFIG_H.
diego
parents:
4760
diff
changeset
|
32 #include <string.h> |
781 | 33 |
4760 | 34 #undef exit |
35 | |
781 | 36 /* reference fft */ |
37 | |
38 #define MUL16(a,b) ((a) * (b)) | |
39 | |
40 #define CMAC(pre, pim, are, aim, bre, bim) \ | |
41 {\ | |
42 pre += (MUL16(are, bre) - MUL16(aim, bim));\ | |
43 pim += (MUL16(are, bim) + MUL16(bre, aim));\ | |
44 } | |
45 | |
46 FFTComplex *exptab; | |
47 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9199
diff
changeset
|
48 static void fft_ref_init(int nbits, int inverse) |
781 | 49 { |
50 int n, i; | |
5418
95234f2e0bdd
make the reference code use double instead of float where it is easy
michael
parents:
5417
diff
changeset
|
51 double c1, s1, alpha; |
781 | 52 |
53 n = 1 << nbits; | |
54 exptab = av_malloc((n / 2) * sizeof(FFTComplex)); | |
55 | |
56 for(i=0;i<(n/2);i++) { | |
57 alpha = 2 * M_PI * (float)i / (float)n; | |
58 c1 = cos(alpha); | |
59 s1 = sin(alpha); | |
60 if (!inverse) | |
61 s1 = -s1; | |
62 exptab[i].re = c1; | |
63 exptab[i].im = s1; | |
64 } | |
65 } | |
66 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9199
diff
changeset
|
67 static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits) |
781 | 68 { |
69 int n, i, j, k, n2; | |
5418
95234f2e0bdd
make the reference code use double instead of float where it is easy
michael
parents:
5417
diff
changeset
|
70 double tmp_re, tmp_im, s, c; |
781 | 71 FFTComplex *q; |
72 | |
73 n = 1 << nbits; | |
74 n2 = n >> 1; | |
75 for(i=0;i<n;i++) { | |
76 tmp_re = 0; | |
77 tmp_im = 0; | |
78 q = tab; | |
79 for(j=0;j<n;j++) { | |
80 k = (i * j) & (n - 1); | |
81 if (k >= n2) { | |
82 c = -exptab[k - n2].re; | |
83 s = -exptab[k - n2].im; | |
84 } else { | |
85 c = exptab[k].re; | |
86 s = exptab[k].im; | |
87 } | |
88 CMAC(tmp_re, tmp_im, c, s, q->re, q->im); | |
89 q++; | |
90 } | |
91 tabr[i].re = tmp_re; | |
92 tabr[i].im = tmp_im; | |
93 } | |
94 } | |
95 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9199
diff
changeset
|
96 static void imdct_ref(float *out, float *in, int nbits) |
781 | 97 { |
5442 | 98 int n = 1<<nbits; |
781 | 99 int k, i, a; |
5418
95234f2e0bdd
make the reference code use double instead of float where it is easy
michael
parents:
5417
diff
changeset
|
100 double sum, f; |
781 | 101 |
102 for(i=0;i<n;i++) { | |
103 sum = 0; | |
104 for(k=0;k<n/2;k++) { | |
105 a = (2 * i + 1 + (n / 2)) * (2 * k + 1); | |
106 f = cos(M_PI * a / (double)(2 * n)); | |
107 sum += f * in[k]; | |
108 } | |
109 out[i] = -sum; | |
110 } | |
111 } | |
112 | |
113 /* NOTE: no normalisation by 1 / N is done */ | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9199
diff
changeset
|
114 static void mdct_ref(float *output, float *input, int nbits) |
781 | 115 { |
5442 | 116 int n = 1<<nbits; |
781 | 117 int k, i; |
5418
95234f2e0bdd
make the reference code use double instead of float where it is easy
michael
parents:
5417
diff
changeset
|
118 double a, s; |
781 | 119 |
120 /* do it by hand */ | |
121 for(k=0;k<n/2;k++) { | |
122 s = 0; | |
123 for(i=0;i<n;i++) { | |
124 a = (2*M_PI*(2*i+1+n/2)*(2*k+1) / (4 * n)); | |
125 s += input[i] * cos(a); | |
126 } | |
127 output[k] = s; | |
128 } | |
129 } | |
130 | |
131 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9199
diff
changeset
|
132 static float frandom(void) |
781 | 133 { |
9388
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
134 AVLFG prng; |
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
135 av_lfg_init(&prng, 1); |
2313bf51945b
cosmetics: Rename prn variable to prng (Pseudo Random Number Generator).
diego
parents:
9295
diff
changeset
|
136 return (float)((av_lfg_get(&prng) & 0xffff) - 32768) / 32768.0; |
781 | 137 } |
138 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9199
diff
changeset
|
139 static int64_t gettime(void) |
781 | 140 { |
141 struct timeval tv; | |
142 gettimeofday(&tv,NULL); | |
1064 | 143 return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; |
781 | 144 } |
145 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9199
diff
changeset
|
146 static void check_diff(float *tab1, float *tab2, int n) |
781 | 147 { |
148 int i; | |
5417 | 149 double max= 0; |
150 double error= 0; | |
781 | 151 |
152 for(i=0;i<n;i++) { | |
5417 | 153 double e= fabsf(tab1[i] - tab2[i]); |
154 if (e >= 1e-3) { | |
2967 | 155 av_log(NULL, AV_LOG_ERROR, "ERROR %d: %f %f\n", |
781 | 156 i, tab1[i], tab2[i]); |
157 } | |
5417 | 158 error+= e*e; |
159 if(e>max) max= e; | |
781 | 160 } |
5417 | 161 av_log(NULL, AV_LOG_INFO, "max:%f e:%g\n", max, sqrt(error)/n); |
781 | 162 } |
163 | |
164 | |
9295
b225f51903af
Mark non-exported functions in test and example programs as static.
diego
parents:
9199
diff
changeset
|
165 static void help(void) |
781 | 166 { |
2593
786ccf72ccd5
printf -> av_log patch by (Benjamin Larsson <>banan student.ltu se)
michael
parents:
1879
diff
changeset
|
167 av_log(NULL, AV_LOG_INFO,"usage: fft-test [-h] [-s] [-i] [-n b]\n" |
781 | 168 "-h print this help\n" |
169 "-s speed test\n" | |
170 "-m (I)MDCT test\n" | |
171 "-i inverse transform test\n" | |
172 "-n b set the transform size to 2^b\n" | |
173 ); | |
174 exit(1); | |
175 } | |
176 | |
177 | |
178 | |
179 int main(int argc, char **argv) | |
180 { | |
181 FFTComplex *tab, *tab1, *tab_ref; | |
7546 | 182 FFTSample *tab2; |
781 | 183 int it, i, c; |
184 int do_speed = 0; | |
185 int do_mdct = 0; | |
186 int do_inverse = 0; | |
187 FFTContext s1, *s = &s1; | |
188 MDCTContext m1, *m = &m1; | |
189 int fft_nbits, fft_size; | |
190 | |
191 fft_nbits = 9; | |
192 for(;;) { | |
193 c = getopt(argc, argv, "hsimn:"); | |
194 if (c == -1) | |
195 break; | |
196 switch(c) { | |
197 case 'h': | |
198 help(); | |
199 break; | |
200 case 's': | |
201 do_speed = 1; | |
202 break; | |
203 case 'i': | |
204 do_inverse = 1; | |
205 break; | |
206 case 'm': | |
207 do_mdct = 1; | |
208 break; | |
209 case 'n': | |
210 fft_nbits = atoi(optarg); | |
211 break; | |
212 } | |
213 } | |
214 | |
215 fft_size = 1 << fft_nbits; | |
216 tab = av_malloc(fft_size * sizeof(FFTComplex)); | |
217 tab1 = av_malloc(fft_size * sizeof(FFTComplex)); | |
218 tab_ref = av_malloc(fft_size * sizeof(FFTComplex)); | |
219 tab2 = av_malloc(fft_size * sizeof(FFTSample)); | |
220 | |
221 if (do_mdct) { | |
222 if (do_inverse) | |
2593
786ccf72ccd5
printf -> av_log patch by (Benjamin Larsson <>banan student.ltu se)
michael
parents:
1879
diff
changeset
|
223 av_log(NULL, AV_LOG_INFO,"IMDCT"); |
781 | 224 else |
2593
786ccf72ccd5
printf -> av_log patch by (Benjamin Larsson <>banan student.ltu se)
michael
parents:
1879
diff
changeset
|
225 av_log(NULL, AV_LOG_INFO,"MDCT"); |
969 | 226 ff_mdct_init(m, fft_nbits, do_inverse); |
781 | 227 } else { |
228 if (do_inverse) | |
2593
786ccf72ccd5
printf -> av_log patch by (Benjamin Larsson <>banan student.ltu se)
michael
parents:
1879
diff
changeset
|
229 av_log(NULL, AV_LOG_INFO,"IFFT"); |
781 | 230 else |
2593
786ccf72ccd5
printf -> av_log patch by (Benjamin Larsson <>banan student.ltu se)
michael
parents:
1879
diff
changeset
|
231 av_log(NULL, AV_LOG_INFO,"FFT"); |
1879
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
232 ff_fft_init(s, fft_nbits, do_inverse); |
781 | 233 fft_ref_init(fft_nbits, do_inverse); |
234 } | |
2593
786ccf72ccd5
printf -> av_log patch by (Benjamin Larsson <>banan student.ltu se)
michael
parents:
1879
diff
changeset
|
235 av_log(NULL, AV_LOG_INFO," %d test\n", fft_size); |
781 | 236 |
237 /* generate random data */ | |
238 | |
239 for(i=0;i<fft_size;i++) { | |
240 tab1[i].re = frandom(); | |
241 tab1[i].im = frandom(); | |
242 } | |
243 | |
244 /* checking result */ | |
2593
786ccf72ccd5
printf -> av_log patch by (Benjamin Larsson <>banan student.ltu se)
michael
parents:
1879
diff
changeset
|
245 av_log(NULL, AV_LOG_INFO,"Checking...\n"); |
781 | 246 |
247 if (do_mdct) { | |
248 if (do_inverse) { | |
5442 | 249 imdct_ref((float *)tab_ref, (float *)tab1, fft_nbits); |
7546 | 250 ff_imdct_calc(m, tab2, (float *)tab1); |
781 | 251 check_diff((float *)tab_ref, tab2, fft_size); |
252 } else { | |
5442 | 253 mdct_ref((float *)tab_ref, (float *)tab1, fft_nbits); |
2967 | 254 |
7546 | 255 ff_mdct_calc(m, tab2, (float *)tab1); |
781 | 256 |
257 check_diff((float *)tab_ref, tab2, fft_size / 2); | |
258 } | |
259 } else { | |
260 memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); | |
1879
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
261 ff_fft_permute(s, tab); |
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
262 ff_fft_calc(s, tab); |
2967 | 263 |
781 | 264 fft_ref(tab_ref, tab1, fft_nbits); |
265 check_diff((float *)tab_ref, (float *)tab, fft_size * 2); | |
266 } | |
267 | |
268 /* do a speed test */ | |
269 | |
270 if (do_speed) { | |
1064 | 271 int64_t time_start, duration; |
781 | 272 int nb_its; |
273 | |
2593
786ccf72ccd5
printf -> av_log patch by (Benjamin Larsson <>banan student.ltu se)
michael
parents:
1879
diff
changeset
|
274 av_log(NULL, AV_LOG_INFO,"Speed test...\n"); |
781 | 275 /* we measure during about 1 seconds */ |
276 nb_its = 1; | |
277 for(;;) { | |
278 time_start = gettime(); | |
279 for(it=0;it<nb_its;it++) { | |
280 if (do_mdct) { | |
281 if (do_inverse) { | |
7546 | 282 ff_imdct_calc(m, (float *)tab, (float *)tab1); |
781 | 283 } else { |
7546 | 284 ff_mdct_calc(m, (float *)tab, (float *)tab1); |
781 | 285 } |
286 } else { | |
287 memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); | |
1879
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
288 ff_fft_calc(s, tab); |
781 | 289 } |
290 } | |
291 duration = gettime() - time_start; | |
292 if (duration >= 1000000) | |
293 break; | |
294 nb_its *= 2; | |
295 } | |
2967 | 296 av_log(NULL, AV_LOG_INFO,"time: %0.1f us/transform [total time=%0.2f s its=%d]\n", |
297 (double)duration / nb_its, | |
781 | 298 (double)duration / 1000000.0, |
299 nb_its); | |
300 } | |
2967 | 301 |
781 | 302 if (do_mdct) { |
969 | 303 ff_mdct_end(m); |
781 | 304 } else { |
1879
dd63cb7e5080
fft_*() renamed into ff_fft_*() patch by (Gildas Bazin <gbazin at altern dot org>)
michael
parents:
1106
diff
changeset
|
305 ff_fft_end(s); |
781 | 306 } |
307 return 0; | |
308 } |