doc: library versions need to be bumped in version.h
[libav.git] / libavcodec / dct-test.c
CommitLineData
04d7f601
DB
1/*
2 * (c) 2001 Fabrice Bellard
3ac35bdb 3 * 2007 Marc Hoffman <marc.hoffman@analog.com>
04d7f601 4 *
2912e87a 5 * This file is part of Libav.
b78e7197 6 *
2912e87a 7 * Libav is free software; you can redistribute it and/or
04d7f601
DB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
04d7f601 11 *
2912e87a 12 * Libav is distributed in the hope that it will be useful,
04d7f601
DB
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
2912e87a 18 * License along with Libav; if not, write to the Free Software
04d7f601
DB
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
983e3246 22/**
ba87f080 23 * @file
94f694a4 24 * DCT test (c) 2001 Fabrice Bellard
983e3246
MN
25 * Started from sample code by Juan J. Sierralta P.
26 */
27
de6d9b64
FB
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <sys/time.h>
32#include <unistd.h>
12807c8d 33#include <math.h>
de6d9b64 34
c6c98d08 35#include "libavutil/cpu.h"
ae32e509 36#include "libavutil/common.h"
294eaa26 37#include "libavutil/lfg.h"
de6d9b64 38
86748dbc 39#include "simple_idct.h"
10ac3618 40#include "aandcttab.h"
65e4c8c9 41#include "faandct.h"
6f08c541 42#include "faanidct.h"
a6493a8f 43#include "x86/idct_xvid.h"
6a813295 44#include "dctref.h"
9e1586fc 45
434df899
MN
46#undef printf
47
9686df2b
DB
48void ff_mmx_idct(DCTELEM *data);
49void ff_mmxext_idct(DCTELEM *data);
9e1586fc 50
9686df2b 51void odivx_idct_c(short *block);
86748dbc 52
3ac35bdb 53// BFIN
9686df2b
DB
54void ff_bfin_idct(DCTELEM *block);
55void ff_bfin_fdct(DCTELEM *block);
3ac35bdb
MH
56
57// ALTIVEC
9686df2b
DB
58void fdct_altivec(DCTELEM *block);
59//void idct_altivec(DCTELEM *block);?? no routine
3ac35bdb 60
479044ce 61// ARM
0926c009
MR
62void ff_j_rev_dct_arm(DCTELEM *data);
63void ff_simple_idct_arm(DCTELEM *data);
64void ff_simple_idct_armv5te(DCTELEM *data);
479044ce
MR
65void ff_simple_idct_armv6(DCTELEM *data);
66void ff_simple_idct_neon(DCTELEM *data);
3ac35bdb 67
2a839eeb
MR
68void ff_simple_idct_axp(DCTELEM *data);
69
3ac35bdb 70struct algo {
36fa9ef3 71 const char *name;
36fa9ef3 72 void (*func)(DCTELEM *block);
36fa9ef3
MR
73 enum formattag { NO_PERM, MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM,
74 SSE2_PERM, PARTTRANS_PERM } format;
75 int mm_support;
dbf396d4 76 int nonspec;
3ac35bdb
MH
77};
78
79#ifndef FAAN_POSTSCALE
80#define FAAN_SCALE SCALE_PERM
81#else
82#define FAAN_SCALE NO_PERM
83#endif
84
aadd27cd
MN
85static int cpu_flags;
86
4b357756 87static const struct algo fdct_tab[] = {
74965f26
MR
88 { "REF-DBL", ff_ref_fdct, NO_PERM },
89 { "FAAN", ff_faandct, FAAN_SCALE },
90 { "IJG-AAN-INT", fdct_ifast, SCALE_PERM },
0a72533e 91 { "IJG-LLM-INT", ff_jpeg_fdct_islow_8, NO_PERM },
3ac35bdb 92
b250f9c6 93#if HAVE_MMX
74965f26
MR
94 { "MMX", ff_fdct_mmx, NO_PERM, AV_CPU_FLAG_MMX },
95 { "MMX2", ff_fdct_mmx2, NO_PERM, AV_CPU_FLAG_MMX2 },
96 { "SSE2", ff_fdct_sse2, NO_PERM, AV_CPU_FLAG_SSE2 },
94254fc0 97#endif
3ac35bdb 98
4b357756 99#if HAVE_ALTIVEC
74965f26 100 { "altivecfdct", fdct_altivec, NO_PERM, AV_CPU_FLAG_ALTIVEC },
4b357756
MR
101#endif
102
103#if ARCH_BFIN
74965f26 104 { "BFINfdct", ff_bfin_fdct, NO_PERM },
4b357756
MR
105#endif
106
107 { 0 }
108};
109
110static const struct algo idct_tab[] = {
74965f26
MR
111 { "FAANI", ff_faanidct, NO_PERM },
112 { "REF-DBL", ff_ref_idct, NO_PERM },
113 { "INT", j_rev_dct, MMX_PERM },
e7a972e1 114 { "SIMPLE-C", ff_simple_idct_8, NO_PERM },
4b357756
MR
115
116#if HAVE_MMX
b250f9c6 117#if CONFIG_GPL
74965f26
MR
118 { "LIBMPEG2-MMX", ff_mmx_idct, MMX_PERM, AV_CPU_FLAG_MMX, 1 },
119 { "LIBMPEG2-MMX2", ff_mmxext_idct, MMX_PERM, AV_CPU_FLAG_MMX2, 1 },
b9702de5 120#endif
74965f26
MR
121 { "SIMPLE-MMX", ff_simple_idct_mmx, MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX },
122 { "XVID-MMX", ff_idct_xvid_mmx, NO_PERM, AV_CPU_FLAG_MMX, 1 },
123 { "XVID-MMX2", ff_idct_xvid_mmx2, NO_PERM, AV_CPU_FLAG_MMX2, 1 },
124 { "XVID-SSE2", ff_idct_xvid_sse2, SSE2_PERM, AV_CPU_FLAG_SSE2, 1 },
3ac35bdb
MH
125#endif
126
b250f9c6 127#if ARCH_BFIN
74965f26 128 { "BFINidct", ff_bfin_idct, NO_PERM },
3ac35bdb
MH
129#endif
130
b250f9c6 131#if ARCH_ARM
74965f26
MR
132 { "SIMPLE-ARM", ff_simple_idct_arm, NO_PERM },
133 { "INT-ARM", ff_j_rev_dct_arm, MMX_PERM },
4b357756 134#endif
b250f9c6 135#if HAVE_ARMV5TE
74965f26 136 { "SIMPLE-ARMV5TE", ff_simple_idct_armv5te,NO_PERM },
479044ce 137#endif
b250f9c6 138#if HAVE_ARMV6
74965f26 139 { "SIMPLE-ARMV6", ff_simple_idct_armv6, MMX_PERM },
479044ce 140#endif
b250f9c6 141#if HAVE_NEON
74965f26 142 { "SIMPLE-NEON", ff_simple_idct_neon, PARTTRANS_PERM },
479044ce 143#endif
479044ce 144
2a839eeb 145#if ARCH_ALPHA
74965f26 146 { "SIMPLE-ALPHA", ff_simple_idct_axp, NO_PERM },
2a839eeb
MR
147#endif
148
36fa9ef3 149 { 0 }
3ac35bdb
MH
150};
151
de6d9b64 152#define AANSCALE_BITS 12
de6d9b64 153
486497e0 154uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
86748dbc 155
504ffed1 156static int64_t gettime(void)
de6d9b64
FB
157{
158 struct timeval tv;
36fa9ef3 159 gettimeofday(&tv, NULL);
0c1a9eda 160 return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
de6d9b64
FB
161}
162
163#define NB_ITS 20000
164#define NB_ITS_SPEED 50000
165
9e1586fc
FB
166static short idct_mmx_perm[64];
167
36fa9ef3
MR
168static short idct_simple_mmx_perm[64] = {
169 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D,
170 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D,
171 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D,
172 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F,
173 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F,
174 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D,
175 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F,
176 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,
86748dbc
MN
177};
178
36fa9ef3 179static const uint8_t idct_sse2_row_perm[8] = { 0, 4, 1, 5, 2, 6, 3, 7 };
ad246860 180
504ffed1 181static void idct_mmx_init(void)
9e1586fc
FB
182{
183 int i;
184
185 /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
186 for (i = 0; i < 64; i++) {
bb270c08 187 idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
9e1586fc
FB
188 }
189}
190
c6727809 191DECLARE_ALIGNED(16, static DCTELEM, block)[64];
36fa9ef3 192DECLARE_ALIGNED(8, static DCTELEM, block1)[64];
9e1586fc 193
aadd27cd
MN
194static inline void mmx_emms(void)
195{
b250f9c6 196#if HAVE_MMX
7160bb71 197 if (cpu_flags & AV_CPU_FLAG_MMX)
be449fca 198 __asm__ volatile ("emms\n\t");
aadd27cd
MN
199#endif
200}
201
dbf396d4 202static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
de6d9b64 203{
74965f26 204 void (*ref)(DCTELEM *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
de6d9b64 205 int it, i, scale;
de6d9b64 206 int err_inf, v;
dbf396d4 207 int64_t err2, ti, ti1, it1, err_sum = 0;
36fa9ef3
MR
208 int64_t sysErr[64], sysErrMax = 0;
209 int maxout = 0;
210 int blockSumErrMax = 0, blockSumErr;
64bde197 211 AVLFG prng;
dbf396d4
MR
212 double omse, ome;
213 int spec_err;
de6d9b64 214
64bde197 215 av_lfg_init(&prng, 1);
de6d9b64
FB
216
217 err_inf = 0;
218 err2 = 0;
36fa9ef3
MR
219 for (i = 0; i < 64; i++)
220 sysErr[i] = 0;
221 for (it = 0; it < NB_ITS; it++) {
222 for (i = 0; i < 64; i++)
86748dbc 223 block1[i] = 0;
36fa9ef3 224 switch (test) {
115329f1 225 case 0:
36fa9ef3
MR
226 for (i = 0; i < 64; i++)
227 block1[i] = (av_lfg_get(&prng) % 512) - 256;
cf2b4f88 228 if (is_idct) {
0de74546 229 ff_ref_fdct(block1);
36fa9ef3
MR
230 for (i = 0; i < 64; i++)
231 block1[i] >>= 3;
ad324c93 232 }
36fa9ef3
MR
233 break;
234 case 1: {
235 int num = av_lfg_get(&prng) % 10 + 1;
236 for (i = 0; i < num; i++)
237 block1[av_lfg_get(&prng) % 64] =
238 av_lfg_get(&prng) % 512 - 256;
239 }
240 break;
86748dbc 241 case 2:
64bde197 242 block1[0] = av_lfg_get(&prng) % 4096 - 2048;
36fa9ef3
MR
243 block1[63] = (block1[0] & 1) ^ 1;
244 break;
86748dbc 245 }
9e1586fc 246
4f905a65 247 if (dct->format == MMX_PERM) {
36fa9ef3 248 for (i = 0; i < 64; i++)
9e1586fc 249 block[idct_mmx_perm[i]] = block1[i];
4f905a65 250 } else if (dct->format == MMX_SIMPLE_PERM) {
36fa9ef3 251 for (i = 0; i < 64; i++)
86748dbc 252 block[idct_simple_mmx_perm[i]] = block1[i];
4f905a65 253 } else if (dct->format == SSE2_PERM) {
36fa9ef3
MR
254 for (i = 0; i < 64; i++)
255 block[(i & 0x38) | idct_sse2_row_perm[i & 7]] = block1[i];
4f905a65 256 } else if (dct->format == PARTTRANS_PERM) {
36fa9ef3
MR
257 for (i = 0; i < 64; i++)
258 block[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = block1[i];
bb270c08 259 } else {
36fa9ef3
MR
260 for (i = 0; i < 64; i++)
261 block[i] = block1[i];
9e1586fc
FB
262 }
263
4f905a65 264 dct->func(block);
aadd27cd 265 mmx_emms();
9e1586fc 266
4f905a65 267 if (dct->format == SCALE_PERM) {
36fa9ef3
MR
268 for (i = 0; i < 64; i++) {
269 scale = 8 * (1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
270 block[i] = (block[i] * scale) >> AANSCALE_BITS;
86748dbc
MN
271 }
272 }
273
74965f26 274 ref(block1);
de6d9b64 275
36fa9ef3
MR
276 blockSumErr = 0;
277 for (i = 0; i < 64; i++) {
dbf396d4
MR
278 int err = block[i] - block1[i];
279 err_sum += err;
280 v = abs(err);
de6d9b64
FB
281 if (v > err_inf)
282 err_inf = v;
283 err2 += v * v;
bb270c08
DB
284 sysErr[i] += block[i] - block1[i];
285 blockSumErr += v;
36fa9ef3
MR
286 if (abs(block[i]) > maxout)
287 maxout = abs(block[i]);
de6d9b64 288 }
36fa9ef3
MR
289 if (blockSumErrMax < blockSumErr)
290 blockSumErrMax = blockSumErr;
86748dbc 291 }
36fa9ef3
MR
292 for (i = 0; i < 64; i++)
293 sysErrMax = FFMAX(sysErrMax, FFABS(sysErr[i]));
115329f1 294
36fa9ef3
MR
295 for (i = 0; i < 64; i++) {
296 if (i % 8 == 0)
297 printf("\n");
298 printf("%7d ", (int) sysErr[i]);
de6d9b64 299 }
86748dbc 300 printf("\n");
115329f1 301
dbf396d4
MR
302 omse = (double) err2 / NB_ITS / 64;
303 ome = (double) err_sum / NB_ITS / 64;
304
305 spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015);
306
307 printf("%s %s: ppe=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
cf2b4f88 308 is_idct ? "IDCT" : "DCT", dct->name, err_inf,
dbf396d4 309 omse, ome, (double) sysErrMax / NB_ITS,
36fa9ef3 310 maxout, blockSumErrMax);
e6ff0648 311
dbf396d4
MR
312 if (spec_err && !dct->nonspec)
313 return 1;
314
7fd2c138 315 if (!speed)
dbf396d4 316 return 0;
7fd2c138 317
de6d9b64 318 /* speed test */
36fa9ef3 319 for (i = 0; i < 64; i++)
86748dbc 320 block1[i] = 0;
36fa9ef3
MR
321
322 switch (test) {
115329f1 323 case 0:
36fa9ef3
MR
324 for (i = 0; i < 64; i++)
325 block1[i] = av_lfg_get(&prng) % 512 - 256;
cf2b4f88 326 if (is_idct) {
0de74546 327 ff_ref_fdct(block1);
36fa9ef3
MR
328 for (i = 0; i < 64; i++)
329 block1[i] >>= 3;
ad324c93 330 }
36fa9ef3
MR
331 break;
332 case 1:
86748dbc 333 case 2:
36fa9ef3
MR
334 block1[0] = av_lfg_get(&prng) % 512 - 256;
335 block1[1] = av_lfg_get(&prng) % 512 - 256;
336 block1[2] = av_lfg_get(&prng) % 512 - 256;
337 block1[3] = av_lfg_get(&prng) % 512 - 256;
338 break;
86748dbc 339 }
de6d9b64 340
4f905a65 341 if (dct->format == MMX_PERM) {
36fa9ef3 342 for (i = 0; i < 64; i++)
9e1586fc 343 block[idct_mmx_perm[i]] = block1[i];
4f905a65 344 } else if (dct->format == MMX_SIMPLE_PERM) {
36fa9ef3 345 for (i = 0; i < 64; i++)
86748dbc
MN
346 block[idct_simple_mmx_perm[i]] = block1[i];
347 } else {
36fa9ef3
MR
348 for (i = 0; i < 64; i++)
349 block[i] = block1[i];
9e1586fc
FB
350 }
351
de6d9b64
FB
352 ti = gettime();
353 it1 = 0;
354 do {
36fa9ef3
MR
355 for (it = 0; it < NB_ITS_SPEED; it++) {
356 for (i = 0; i < 64; i++)
357 block[i] = block1[i];
4f905a65 358 dct->func(block);
de6d9b64
FB
359 }
360 it1 += NB_ITS_SPEED;
361 ti1 = gettime() - ti;
362 } while (ti1 < 1000000);
aadd27cd 363 mmx_emms();
de6d9b64 364
cf2b4f88 365 printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,
36fa9ef3 366 (double) it1 * 1000.0 / (double) ti1);
dbf396d4
MR
367
368 return 0;
de6d9b64
FB
369}
370
c6727809
MR
371DECLARE_ALIGNED(8, static uint8_t, img_dest)[64];
372DECLARE_ALIGNED(8, static uint8_t, img_dest1)[64];
a46a3ce4 373
504ffed1 374static void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
a46a3ce4
FB
375{
376 static int init;
377 static double c8[8][8];
378 static double c4[4][4];
379 double block1[64], block2[64], block3[64];
380 double s, sum, v;
381 int i, j, k;
382
383 if (!init) {
384 init = 1;
385
36fa9ef3 386 for (i = 0; i < 8; i++) {
a46a3ce4 387 sum = 0;
36fa9ef3
MR
388 for (j = 0; j < 8; j++) {
389 s = (i == 0) ? sqrt(1.0 / 8.0) : sqrt(1.0 / 4.0);
a46a3ce4
FB
390 c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
391 sum += c8[i][j] * c8[i][j];
392 }
393 }
115329f1 394
36fa9ef3 395 for (i = 0; i < 4; i++) {
a46a3ce4 396 sum = 0;
36fa9ef3
MR
397 for (j = 0; j < 4; j++) {
398 s = (i == 0) ? sqrt(1.0 / 4.0) : sqrt(1.0 / 2.0);
a46a3ce4
FB
399 c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
400 sum += c4[i][j] * c4[i][j];
401 }
402 }
403 }
404
405 /* butterfly */
652f0197 406 s = 0.5 * sqrt(2.0);
36fa9ef3
MR
407 for (i = 0; i < 4; i++) {
408 for (j = 0; j < 8; j++) {
409 block1[8 * (2 * i) + j] =
410 (block[8 * (2 * i) + j] + block[8 * (2 * i + 1) + j]) * s;
411 block1[8 * (2 * i + 1) + j] =
412 (block[8 * (2 * i) + j] - block[8 * (2 * i + 1) + j]) * s;
a46a3ce4
FB
413 }
414 }
415
416 /* idct8 on lines */
36fa9ef3
MR
417 for (i = 0; i < 8; i++) {
418 for (j = 0; j < 8; j++) {
a46a3ce4 419 sum = 0;
36fa9ef3
MR
420 for (k = 0; k < 8; k++)
421 sum += c8[k][j] * block1[8 * i + k];
422 block2[8 * i + j] = sum;
a46a3ce4
FB
423 }
424 }
425
426 /* idct4 */
36fa9ef3
MR
427 for (i = 0; i < 8; i++) {
428 for (j = 0; j < 4; j++) {
a46a3ce4
FB
429 /* top */
430 sum = 0;
36fa9ef3
MR
431 for (k = 0; k < 4; k++)
432 sum += c4[k][j] * block2[8 * (2 * k) + i];
433 block3[8 * (2 * j) + i] = sum;
a46a3ce4
FB
434
435 /* bottom */
436 sum = 0;
36fa9ef3
MR
437 for (k = 0; k < 4; k++)
438 sum += c4[k][j] * block2[8 * (2 * k + 1) + i];
439 block3[8 * (2 * j + 1) + i] = sum;
a46a3ce4
FB
440 }
441 }
442
443 /* clamp and store the result */
36fa9ef3
MR
444 for (i = 0; i < 8; i++) {
445 for (j = 0; j < 8; j++) {
446 v = block3[8 * i + j];
447 if (v < 0) v = 0;
448 else if (v > 255) v = 255;
449 dest[i * linesize + j] = (int) rint(v);
a46a3ce4
FB
450 }
451 }
452}
453
504ffed1 454static void idct248_error(const char *name,
36fa9ef3 455 void (*idct248_put)(uint8_t *dest, int line_size,
7fd2c138
MR
456 int16_t *block),
457 int speed)
a46a3ce4
FB
458{
459 int it, i, it1, ti, ti1, err_max, v;
64bde197 460 AVLFG prng;
294eaa26 461
64bde197 462 av_lfg_init(&prng, 1);
115329f1 463
a46a3ce4
FB
464 /* just one test to see if code is correct (precision is less
465 important here) */
466 err_max = 0;
36fa9ef3 467 for (it = 0; it < NB_ITS; it++) {
652f0197 468 /* XXX: use forward transform to generate values */
36fa9ef3 469 for (i = 0; i < 64; i++)
64bde197 470 block1[i] = av_lfg_get(&prng) % 256 - 128;
652f0197
FB
471 block1[0] += 1024;
472
36fa9ef3
MR
473 for (i = 0; i < 64; i++)
474 block[i] = block1[i];
a46a3ce4 475 idct248_ref(img_dest1, 8, block);
115329f1 476
36fa9ef3
MR
477 for (i = 0; i < 64; i++)
478 block[i] = block1[i];
652f0197 479 idct248_put(img_dest, 8, block);
115329f1 480
36fa9ef3
MR
481 for (i = 0; i < 64; i++) {
482 v = abs((int) img_dest[i] - (int) img_dest1[i]);
652f0197
FB
483 if (v == 255)
484 printf("%d %d\n", img_dest[i], img_dest1[i]);
485 if (v > err_max)
486 err_max = v;
487 }
a46a3ce4 488 }
36fa9ef3 489 printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max);
a46a3ce4 490
7fd2c138
MR
491 if (!speed)
492 return;
493
a46a3ce4
FB
494 ti = gettime();
495 it1 = 0;
496 do {
36fa9ef3
MR
497 for (it = 0; it < NB_ITS_SPEED; it++) {
498 for (i = 0; i < 64; i++)
499 block[i] = block1[i];
a46a3ce4
FB
500 idct248_put(img_dest, 8, block);
501 }
502 it1 += NB_ITS_SPEED;
503 ti1 = gettime() - ti;
504 } while (ti1 < 1000000);
aadd27cd 505 mmx_emms();
a46a3ce4 506
36fa9ef3
MR
507 printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name,
508 (double) it1 * 1000.0 / (double) ti1);
a46a3ce4
FB
509}
510
504ffed1 511static void help(void)
9e1586fc 512{
86748dbc
MN
513 printf("dct-test [-i] [<test-number>]\n"
514 "test-number 0 -> test with random matrixes\n"
515 " 1 -> test with random sparse matrixes\n"
516 " 2 -> do 3. test from mpeg4 std\n"
a46a3ce4 517 "-i test IDCT implementations\n"
7fd2c138
MR
518 "-4 test IDCT248 implementations\n"
519 "-t speed test\n");
9e1586fc
FB
520}
521
de6d9b64
FB
522int main(int argc, char **argv)
523{
a46a3ce4 524 int test_idct = 0, test_248_dct = 0;
36fa9ef3
MR
525 int c, i;
526 int test = 1;
7fd2c138 527 int speed = 0;
dbf396d4 528 int err = 0;
36fa9ef3 529
c6c98d08 530 cpu_flags = av_get_cpu_flags();
9e1586fc 531
0de74546 532 ff_ref_dct_init();
9e1586fc 533 idct_mmx_init();
f67a10cd 534
36fa9ef3
MR
535 for (i = 0; i < 256; i++)
536 cropTbl[i + MAX_NEG_CROP] = i;
537 for (i = 0; i < MAX_NEG_CROP; i++) {
486497e0
MR
538 cropTbl[i] = 0;
539 cropTbl[i + MAX_NEG_CROP + 256] = 255;
86748dbc 540 }
115329f1 541
36fa9ef3 542 for (;;) {
7fd2c138 543 c = getopt(argc, argv, "ih4t");
9e1586fc
FB
544 if (c == -1)
545 break;
36fa9ef3 546 switch (c) {
9e1586fc
FB
547 case 'i':
548 test_idct = 1;
549 break;
a46a3ce4
FB
550 case '4':
551 test_248_dct = 1;
552 break;
7fd2c138
MR
553 case 't':
554 speed = 1;
555 break;
36fa9ef3 556 default:
9e1586fc
FB
557 case 'h':
558 help();
c6bdc908 559 return 0;
9e1586fc
FB
560 }
561 }
115329f1 562
36fa9ef3
MR
563 if (optind < argc)
564 test = atoi(argv[optind]);
115329f1 565
9e1586fc
FB
566 printf("ffmpeg DCT/IDCT test\n");
567
a46a3ce4 568 if (test_248_dct) {
7fd2c138 569 idct248_error("SIMPLE-C", ff_simple_idct248_put, speed);
9e1586fc 570 } else {
4b357756 571 const struct algo *algos = test_idct ? idct_tab : fdct_tab;
36fa9ef3 572 for (i = 0; algos[i].name; i++)
4b357756 573 if (!(~cpu_flags & algos[i].mm_support)) {
dbf396d4 574 err |= dct_error(&algos[i], test, test_idct, speed);
36fa9ef3 575 }
9e1586fc 576 }
dbf396d4
MR
577
578 return err;
de6d9b64 579}