vsrc_testsrc: fix mailing list reference URL
[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
ae2e8971
MR
202static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng)
203{
204 int i, j;
205
206 memset(block, 0, 64 * sizeof(*block));
207
208 switch (test) {
209 case 0:
210 for (i = 0; i < 64; i++)
211 block[i] = (av_lfg_get(prng) % 512) - 256;
212 if (is_idct) {
213 ff_ref_fdct(block);
214 for (i = 0; i < 64; i++)
215 block[i] >>= 3;
216 }
217 break;
218 case 1:
219 j = av_lfg_get(prng) % 10 + 1;
220 for (i = 0; i < j; i++)
221 block[av_lfg_get(prng) % 64] = av_lfg_get(prng) % 512 - 256;
222 break;
223 case 2:
224 block[ 0] = av_lfg_get(prng) % 4096 - 2048;
225 block[63] = (block[0] & 1) ^ 1;
226 break;
227 }
228}
229
230static void permute(DCTELEM dst[64], const DCTELEM src[64], int perm)
231{
232 int i;
233
234 if (perm == MMX_PERM) {
235 for (i = 0; i < 64; i++)
236 dst[idct_mmx_perm[i]] = src[i];
237 } else if (perm == MMX_SIMPLE_PERM) {
238 for (i = 0; i < 64; i++)
239 dst[idct_simple_mmx_perm[i]] = src[i];
240 } else if (perm == SSE2_PERM) {
241 for (i = 0; i < 64; i++)
242 dst[(i & 0x38) | idct_sse2_row_perm[i & 7]] = src[i];
243 } else if (perm == PARTTRANS_PERM) {
244 for (i = 0; i < 64; i++)
245 dst[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = src[i];
246 } else {
247 for (i = 0; i < 64; i++)
248 dst[i] = src[i];
249 }
250}
251
dbf396d4 252static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
de6d9b64 253{
74965f26 254 void (*ref)(DCTELEM *block) = is_idct ? ff_ref_idct : ff_ref_fdct;
de6d9b64 255 int it, i, scale;
de6d9b64 256 int err_inf, v;
dbf396d4 257 int64_t err2, ti, ti1, it1, err_sum = 0;
36fa9ef3
MR
258 int64_t sysErr[64], sysErrMax = 0;
259 int maxout = 0;
260 int blockSumErrMax = 0, blockSumErr;
64bde197 261 AVLFG prng;
dbf396d4
MR
262 double omse, ome;
263 int spec_err;
de6d9b64 264
64bde197 265 av_lfg_init(&prng, 1);
de6d9b64
FB
266
267 err_inf = 0;
268 err2 = 0;
36fa9ef3
MR
269 for (i = 0; i < 64; i++)
270 sysErr[i] = 0;
271 for (it = 0; it < NB_ITS; it++) {
ae2e8971
MR
272 init_block(block1, test, is_idct, &prng);
273 permute(block, block1, dct->format);
9e1586fc 274
4f905a65 275 dct->func(block);
aadd27cd 276 mmx_emms();
9e1586fc 277
4f905a65 278 if (dct->format == SCALE_PERM) {
36fa9ef3
MR
279 for (i = 0; i < 64; i++) {
280 scale = 8 * (1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
281 block[i] = (block[i] * scale) >> AANSCALE_BITS;
86748dbc
MN
282 }
283 }
284
74965f26 285 ref(block1);
de6d9b64 286
36fa9ef3
MR
287 blockSumErr = 0;
288 for (i = 0; i < 64; i++) {
dbf396d4
MR
289 int err = block[i] - block1[i];
290 err_sum += err;
291 v = abs(err);
de6d9b64
FB
292 if (v > err_inf)
293 err_inf = v;
294 err2 += v * v;
bb270c08
DB
295 sysErr[i] += block[i] - block1[i];
296 blockSumErr += v;
36fa9ef3
MR
297 if (abs(block[i]) > maxout)
298 maxout = abs(block[i]);
de6d9b64 299 }
36fa9ef3
MR
300 if (blockSumErrMax < blockSumErr)
301 blockSumErrMax = blockSumErr;
86748dbc 302 }
36fa9ef3
MR
303 for (i = 0; i < 64; i++)
304 sysErrMax = FFMAX(sysErrMax, FFABS(sysErr[i]));
115329f1 305
36fa9ef3
MR
306 for (i = 0; i < 64; i++) {
307 if (i % 8 == 0)
308 printf("\n");
309 printf("%7d ", (int) sysErr[i]);
de6d9b64 310 }
86748dbc 311 printf("\n");
115329f1 312
dbf396d4
MR
313 omse = (double) err2 / NB_ITS / 64;
314 ome = (double) err_sum / NB_ITS / 64;
315
316 spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015);
317
318 printf("%s %s: ppe=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
cf2b4f88 319 is_idct ? "IDCT" : "DCT", dct->name, err_inf,
dbf396d4 320 omse, ome, (double) sysErrMax / NB_ITS,
36fa9ef3 321 maxout, blockSumErrMax);
e6ff0648 322
dbf396d4
MR
323 if (spec_err && !dct->nonspec)
324 return 1;
325
7fd2c138 326 if (!speed)
dbf396d4 327 return 0;
7fd2c138 328
de6d9b64 329 /* speed test */
ae2e8971
MR
330 init_block(block, test, is_idct, &prng);
331 permute(block1, block, dct->format);
9e1586fc 332
de6d9b64
FB
333 ti = gettime();
334 it1 = 0;
335 do {
36fa9ef3 336 for (it = 0; it < NB_ITS_SPEED; it++) {
ae2e8971 337 memcpy(block, block1, sizeof(block));
4f905a65 338 dct->func(block);
de6d9b64
FB
339 }
340 it1 += NB_ITS_SPEED;
341 ti1 = gettime() - ti;
342 } while (ti1 < 1000000);
aadd27cd 343 mmx_emms();
de6d9b64 344
cf2b4f88 345 printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,
36fa9ef3 346 (double) it1 * 1000.0 / (double) ti1);
dbf396d4
MR
347
348 return 0;
de6d9b64
FB
349}
350
c6727809
MR
351DECLARE_ALIGNED(8, static uint8_t, img_dest)[64];
352DECLARE_ALIGNED(8, static uint8_t, img_dest1)[64];
a46a3ce4 353
504ffed1 354static void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
a46a3ce4
FB
355{
356 static int init;
357 static double c8[8][8];
358 static double c4[4][4];
359 double block1[64], block2[64], block3[64];
360 double s, sum, v;
361 int i, j, k;
362
363 if (!init) {
364 init = 1;
365
36fa9ef3 366 for (i = 0; i < 8; i++) {
a46a3ce4 367 sum = 0;
36fa9ef3
MR
368 for (j = 0; j < 8; j++) {
369 s = (i == 0) ? sqrt(1.0 / 8.0) : sqrt(1.0 / 4.0);
a46a3ce4
FB
370 c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
371 sum += c8[i][j] * c8[i][j];
372 }
373 }
115329f1 374
36fa9ef3 375 for (i = 0; i < 4; i++) {
a46a3ce4 376 sum = 0;
36fa9ef3
MR
377 for (j = 0; j < 4; j++) {
378 s = (i == 0) ? sqrt(1.0 / 4.0) : sqrt(1.0 / 2.0);
a46a3ce4
FB
379 c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
380 sum += c4[i][j] * c4[i][j];
381 }
382 }
383 }
384
385 /* butterfly */
652f0197 386 s = 0.5 * sqrt(2.0);
36fa9ef3
MR
387 for (i = 0; i < 4; i++) {
388 for (j = 0; j < 8; j++) {
389 block1[8 * (2 * i) + j] =
390 (block[8 * (2 * i) + j] + block[8 * (2 * i + 1) + j]) * s;
391 block1[8 * (2 * i + 1) + j] =
392 (block[8 * (2 * i) + j] - block[8 * (2 * i + 1) + j]) * s;
a46a3ce4
FB
393 }
394 }
395
396 /* idct8 on lines */
36fa9ef3
MR
397 for (i = 0; i < 8; i++) {
398 for (j = 0; j < 8; j++) {
a46a3ce4 399 sum = 0;
36fa9ef3
MR
400 for (k = 0; k < 8; k++)
401 sum += c8[k][j] * block1[8 * i + k];
402 block2[8 * i + j] = sum;
a46a3ce4
FB
403 }
404 }
405
406 /* idct4 */
36fa9ef3
MR
407 for (i = 0; i < 8; i++) {
408 for (j = 0; j < 4; j++) {
a46a3ce4
FB
409 /* top */
410 sum = 0;
36fa9ef3
MR
411 for (k = 0; k < 4; k++)
412 sum += c4[k][j] * block2[8 * (2 * k) + i];
413 block3[8 * (2 * j) + i] = sum;
a46a3ce4
FB
414
415 /* bottom */
416 sum = 0;
36fa9ef3
MR
417 for (k = 0; k < 4; k++)
418 sum += c4[k][j] * block2[8 * (2 * k + 1) + i];
419 block3[8 * (2 * j + 1) + i] = sum;
a46a3ce4
FB
420 }
421 }
422
423 /* clamp and store the result */
36fa9ef3
MR
424 for (i = 0; i < 8; i++) {
425 for (j = 0; j < 8; j++) {
426 v = block3[8 * i + j];
427 if (v < 0) v = 0;
428 else if (v > 255) v = 255;
429 dest[i * linesize + j] = (int) rint(v);
a46a3ce4
FB
430 }
431 }
432}
433
504ffed1 434static void idct248_error(const char *name,
36fa9ef3 435 void (*idct248_put)(uint8_t *dest, int line_size,
7fd2c138
MR
436 int16_t *block),
437 int speed)
a46a3ce4
FB
438{
439 int it, i, it1, ti, ti1, err_max, v;
64bde197 440 AVLFG prng;
294eaa26 441
64bde197 442 av_lfg_init(&prng, 1);
115329f1 443
a46a3ce4
FB
444 /* just one test to see if code is correct (precision is less
445 important here) */
446 err_max = 0;
36fa9ef3 447 for (it = 0; it < NB_ITS; it++) {
652f0197 448 /* XXX: use forward transform to generate values */
36fa9ef3 449 for (i = 0; i < 64; i++)
64bde197 450 block1[i] = av_lfg_get(&prng) % 256 - 128;
652f0197
FB
451 block1[0] += 1024;
452
36fa9ef3
MR
453 for (i = 0; i < 64; i++)
454 block[i] = block1[i];
a46a3ce4 455 idct248_ref(img_dest1, 8, block);
115329f1 456
36fa9ef3
MR
457 for (i = 0; i < 64; i++)
458 block[i] = block1[i];
652f0197 459 idct248_put(img_dest, 8, block);
115329f1 460
36fa9ef3
MR
461 for (i = 0; i < 64; i++) {
462 v = abs((int) img_dest[i] - (int) img_dest1[i]);
652f0197
FB
463 if (v == 255)
464 printf("%d %d\n", img_dest[i], img_dest1[i]);
465 if (v > err_max)
466 err_max = v;
467 }
a46a3ce4 468 }
36fa9ef3 469 printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max);
a46a3ce4 470
7fd2c138
MR
471 if (!speed)
472 return;
473
a46a3ce4
FB
474 ti = gettime();
475 it1 = 0;
476 do {
36fa9ef3
MR
477 for (it = 0; it < NB_ITS_SPEED; it++) {
478 for (i = 0; i < 64; i++)
479 block[i] = block1[i];
a46a3ce4
FB
480 idct248_put(img_dest, 8, block);
481 }
482 it1 += NB_ITS_SPEED;
483 ti1 = gettime() - ti;
484 } while (ti1 < 1000000);
aadd27cd 485 mmx_emms();
a46a3ce4 486
36fa9ef3
MR
487 printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name,
488 (double) it1 * 1000.0 / (double) ti1);
a46a3ce4
FB
489}
490
504ffed1 491static void help(void)
9e1586fc 492{
86748dbc
MN
493 printf("dct-test [-i] [<test-number>]\n"
494 "test-number 0 -> test with random matrixes\n"
495 " 1 -> test with random sparse matrixes\n"
496 " 2 -> do 3. test from mpeg4 std\n"
a46a3ce4 497 "-i test IDCT implementations\n"
7fd2c138
MR
498 "-4 test IDCT248 implementations\n"
499 "-t speed test\n");
9e1586fc
FB
500}
501
de6d9b64
FB
502int main(int argc, char **argv)
503{
a46a3ce4 504 int test_idct = 0, test_248_dct = 0;
36fa9ef3
MR
505 int c, i;
506 int test = 1;
7fd2c138 507 int speed = 0;
dbf396d4 508 int err = 0;
36fa9ef3 509
c6c98d08 510 cpu_flags = av_get_cpu_flags();
9e1586fc 511
0de74546 512 ff_ref_dct_init();
9e1586fc 513 idct_mmx_init();
f67a10cd 514
36fa9ef3
MR
515 for (i = 0; i < 256; i++)
516 cropTbl[i + MAX_NEG_CROP] = i;
517 for (i = 0; i < MAX_NEG_CROP; i++) {
486497e0
MR
518 cropTbl[i] = 0;
519 cropTbl[i + MAX_NEG_CROP + 256] = 255;
86748dbc 520 }
115329f1 521
36fa9ef3 522 for (;;) {
7fd2c138 523 c = getopt(argc, argv, "ih4t");
9e1586fc
FB
524 if (c == -1)
525 break;
36fa9ef3 526 switch (c) {
9e1586fc
FB
527 case 'i':
528 test_idct = 1;
529 break;
a46a3ce4
FB
530 case '4':
531 test_248_dct = 1;
532 break;
7fd2c138
MR
533 case 't':
534 speed = 1;
535 break;
36fa9ef3 536 default:
9e1586fc
FB
537 case 'h':
538 help();
c6bdc908 539 return 0;
9e1586fc
FB
540 }
541 }
115329f1 542
36fa9ef3
MR
543 if (optind < argc)
544 test = atoi(argv[optind]);
115329f1 545
9e1586fc
FB
546 printf("ffmpeg DCT/IDCT test\n");
547
a46a3ce4 548 if (test_248_dct) {
7fd2c138 549 idct248_error("SIMPLE-C", ff_simple_idct248_put, speed);
9e1586fc 550 } else {
4b357756 551 const struct algo *algos = test_idct ? idct_tab : fdct_tab;
36fa9ef3 552 for (i = 0; algos[i].name; i++)
4b357756 553 if (!(~cpu_flags & algos[i].mm_support)) {
dbf396d4 554 err |= dct_error(&algos[i], test, test_idct, speed);
36fa9ef3 555 }
9e1586fc 556 }
dbf396d4
MR
557
558 return err;
de6d9b64 559}