eval: add fate test
[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
MR
72 void (*func)(DCTELEM *block);
73 void (*ref) (DCTELEM *block);
74 enum formattag { NO_PERM, MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM,
75 SSE2_PERM, PARTTRANS_PERM } format;
76 int mm_support;
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[] = {
cf2b4f88
MR
88 {"REF-DBL", ff_ref_fdct, ff_ref_fdct, NO_PERM},
89 {"FAAN", ff_faandct, ff_ref_fdct, FAAN_SCALE},
90 {"IJG-AAN-INT", fdct_ifast, ff_ref_fdct, SCALE_PERM},
91 {"IJG-LLM-INT", ff_jpeg_fdct_islow, ff_ref_fdct, NO_PERM},
3ac35bdb 92
b250f9c6 93#if HAVE_MMX
cf2b4f88
MR
94 {"MMX", ff_fdct_mmx, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX},
95 {"MMX2", ff_fdct_mmx2, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX2},
96 {"SSE2", ff_fdct_sse2, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_SSE2},
94254fc0 97#endif
3ac35bdb 98
4b357756 99#if HAVE_ALTIVEC
cf2b4f88 100 {"altivecfdct", fdct_altivec, ff_ref_fdct, NO_PERM, AV_CPU_FLAG_ALTIVEC},
4b357756
MR
101#endif
102
103#if ARCH_BFIN
cf2b4f88 104 {"BFINfdct", ff_bfin_fdct, ff_ref_fdct, NO_PERM},
4b357756
MR
105#endif
106
107 { 0 }
108};
109
110static const struct algo idct_tab[] = {
cf2b4f88
MR
111 {"FAANI", ff_faanidct, ff_ref_idct, NO_PERM},
112 {"REF-DBL", ff_ref_idct, ff_ref_idct, NO_PERM},
113 {"INT", j_rev_dct, ff_ref_idct, MMX_PERM},
114 {"SIMPLE-C", ff_simple_idct, ff_ref_idct, NO_PERM},
4b357756
MR
115
116#if HAVE_MMX
b250f9c6 117#if CONFIG_GPL
cf2b4f88
MR
118 {"LIBMPEG2-MMX", ff_mmx_idct, ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX},
119 {"LIBMPEG2-MMX2", ff_mmxext_idct, ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX2},
b9702de5 120#endif
cf2b4f88
MR
121 {"SIMPLE-MMX", ff_simple_idct_mmx, ff_ref_idct, MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX},
122 {"XVID-MMX", ff_idct_xvid_mmx, ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX},
123 {"XVID-MMX2", ff_idct_xvid_mmx2, ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX2},
124 {"XVID-SSE2", ff_idct_xvid_sse2, ff_ref_idct, SSE2_PERM, AV_CPU_FLAG_SSE2},
3ac35bdb
MH
125#endif
126
b250f9c6 127#if ARCH_BFIN
cf2b4f88 128 {"BFINidct", ff_bfin_idct, ff_ref_idct, NO_PERM},
3ac35bdb
MH
129#endif
130
b250f9c6 131#if ARCH_ARM
cf2b4f88
MR
132 {"SIMPLE-ARM", ff_simple_idct_arm, ff_ref_idct, NO_PERM },
133 {"INT-ARM", ff_j_rev_dct_arm, ff_ref_idct, MMX_PERM },
4b357756 134#endif
b250f9c6 135#if HAVE_ARMV5TE
cf2b4f88 136 {"SIMPLE-ARMV5TE", ff_simple_idct_armv5te, ff_ref_idct, NO_PERM },
479044ce 137#endif
b250f9c6 138#if HAVE_ARMV6
cf2b4f88 139 {"SIMPLE-ARMV6", ff_simple_idct_armv6, ff_ref_idct, MMX_PERM },
479044ce 140#endif
b250f9c6 141#if HAVE_NEON
cf2b4f88 142 {"SIMPLE-NEON", ff_simple_idct_neon, ff_ref_idct, PARTTRANS_PERM },
479044ce 143#endif
479044ce 144
2a839eeb 145#if ARCH_ALPHA
cf2b4f88 146 {"SIMPLE-ALPHA", ff_simple_idct_axp, ff_ref_idct, 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
MR
192DECLARE_ALIGNED(8, static DCTELEM, block1)[64];
193DECLARE_ALIGNED(8, static DCTELEM, block_org)[64];
9e1586fc 194
aadd27cd
MN
195static inline void mmx_emms(void)
196{
b250f9c6 197#if HAVE_MMX
7160bb71 198 if (cpu_flags & AV_CPU_FLAG_MMX)
be449fca 199 __asm__ volatile ("emms\n\t");
aadd27cd
MN
200#endif
201}
202
7fd2c138 203static void dct_error(const struct algo *dct, int test, int is_idct, int speed)
de6d9b64
FB
204{
205 int it, i, scale;
de6d9b64 206 int err_inf, v;
0c1a9eda 207 int64_t err2, ti, ti1, it1;
36fa9ef3
MR
208 int64_t sysErr[64], sysErrMax = 0;
209 int maxout = 0;
210 int blockSumErrMax = 0, blockSumErr;
64bde197 211 AVLFG prng;
de6d9b64 212
64bde197 213 av_lfg_init(&prng, 1);
de6d9b64
FB
214
215 err_inf = 0;
216 err2 = 0;
36fa9ef3
MR
217 for (i = 0; i < 64; i++)
218 sysErr[i] = 0;
219 for (it = 0; it < NB_ITS; it++) {
220 for (i = 0; i < 64; i++)
86748dbc 221 block1[i] = 0;
36fa9ef3 222 switch (test) {
115329f1 223 case 0:
36fa9ef3
MR
224 for (i = 0; i < 64; i++)
225 block1[i] = (av_lfg_get(&prng) % 512) - 256;
cf2b4f88 226 if (is_idct) {
0de74546 227 ff_ref_fdct(block1);
36fa9ef3
MR
228 for (i = 0; i < 64; i++)
229 block1[i] >>= 3;
ad324c93 230 }
36fa9ef3
MR
231 break;
232 case 1: {
233 int num = av_lfg_get(&prng) % 10 + 1;
234 for (i = 0; i < num; i++)
235 block1[av_lfg_get(&prng) % 64] =
236 av_lfg_get(&prng) % 512 - 256;
237 }
238 break;
86748dbc 239 case 2:
64bde197 240 block1[0] = av_lfg_get(&prng) % 4096 - 2048;
36fa9ef3
MR
241 block1[63] = (block1[0] & 1) ^ 1;
242 break;
86748dbc 243 }
9e1586fc 244
36fa9ef3
MR
245 for (i = 0; i < 64; i++)
246 block_org[i] = block1[i];
9e1586fc 247
4f905a65 248 if (dct->format == MMX_PERM) {
36fa9ef3 249 for (i = 0; i < 64; i++)
9e1586fc 250 block[idct_mmx_perm[i]] = block1[i];
4f905a65 251 } else if (dct->format == MMX_SIMPLE_PERM) {
36fa9ef3 252 for (i = 0; i < 64; i++)
86748dbc 253 block[idct_simple_mmx_perm[i]] = block1[i];
4f905a65 254 } else if (dct->format == SSE2_PERM) {
36fa9ef3
MR
255 for (i = 0; i < 64; i++)
256 block[(i & 0x38) | idct_sse2_row_perm[i & 7]] = block1[i];
4f905a65 257 } else if (dct->format == PARTTRANS_PERM) {
36fa9ef3
MR
258 for (i = 0; i < 64; i++)
259 block[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = block1[i];
bb270c08 260 } else {
36fa9ef3
MR
261 for (i = 0; i < 64; i++)
262 block[i] = block1[i];
9e1586fc
FB
263 }
264
4f905a65 265 dct->func(block);
aadd27cd 266 mmx_emms();
9e1586fc 267
4f905a65 268 if (dct->format == SCALE_PERM) {
36fa9ef3
MR
269 for (i = 0; i < 64; i++) {
270 scale = 8 * (1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
271 block[i] = (block[i] * scale) >> AANSCALE_BITS;
86748dbc
MN
272 }
273 }
274
4f905a65 275 dct->ref(block1);
de6d9b64 276
36fa9ef3
MR
277 blockSumErr = 0;
278 for (i = 0; i < 64; i++) {
de6d9b64
FB
279 v = abs(block[i] - block1[i]);
280 if (v > err_inf)
281 err_inf = v;
282 err2 += v * v;
bb270c08
DB
283 sysErr[i] += block[i] - block1[i];
284 blockSumErr += v;
36fa9ef3
MR
285 if (abs(block[i]) > maxout)
286 maxout = abs(block[i]);
de6d9b64 287 }
36fa9ef3
MR
288 if (blockSumErrMax < blockSumErr)
289 blockSumErrMax = blockSumErr;
86748dbc 290 }
36fa9ef3
MR
291 for (i = 0; i < 64; i++)
292 sysErrMax = FFMAX(sysErrMax, FFABS(sysErr[i]));
115329f1 293
36fa9ef3
MR
294 for (i = 0; i < 64; i++) {
295 if (i % 8 == 0)
296 printf("\n");
297 printf("%7d ", (int) sysErr[i]);
de6d9b64 298 }
86748dbc 299 printf("\n");
115329f1 300
86748dbc 301 printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
cf2b4f88 302 is_idct ? "IDCT" : "DCT", dct->name, err_inf,
36fa9ef3
MR
303 (double) err2 / NB_ITS / 64.0, (double) sysErrMax / NB_ITS,
304 maxout, blockSumErrMax);
e6ff0648 305
7fd2c138
MR
306 if (!speed)
307 return;
308
de6d9b64 309 /* speed test */
36fa9ef3 310 for (i = 0; i < 64; i++)
86748dbc 311 block1[i] = 0;
36fa9ef3
MR
312
313 switch (test) {
115329f1 314 case 0:
36fa9ef3
MR
315 for (i = 0; i < 64; i++)
316 block1[i] = av_lfg_get(&prng) % 512 - 256;
cf2b4f88 317 if (is_idct) {
0de74546 318 ff_ref_fdct(block1);
36fa9ef3
MR
319 for (i = 0; i < 64; i++)
320 block1[i] >>= 3;
ad324c93 321 }
36fa9ef3
MR
322 break;
323 case 1:
86748dbc 324 case 2:
36fa9ef3
MR
325 block1[0] = av_lfg_get(&prng) % 512 - 256;
326 block1[1] = av_lfg_get(&prng) % 512 - 256;
327 block1[2] = av_lfg_get(&prng) % 512 - 256;
328 block1[3] = av_lfg_get(&prng) % 512 - 256;
329 break;
86748dbc 330 }
de6d9b64 331
4f905a65 332 if (dct->format == MMX_PERM) {
36fa9ef3 333 for (i = 0; i < 64; i++)
9e1586fc 334 block[idct_mmx_perm[i]] = block1[i];
4f905a65 335 } else if (dct->format == MMX_SIMPLE_PERM) {
36fa9ef3 336 for (i = 0; i < 64; i++)
86748dbc
MN
337 block[idct_simple_mmx_perm[i]] = block1[i];
338 } else {
36fa9ef3
MR
339 for (i = 0; i < 64; i++)
340 block[i] = block1[i];
9e1586fc
FB
341 }
342
de6d9b64
FB
343 ti = gettime();
344 it1 = 0;
345 do {
36fa9ef3
MR
346 for (it = 0; it < NB_ITS_SPEED; it++) {
347 for (i = 0; i < 64; i++)
348 block[i] = block1[i];
4f905a65 349 dct->func(block);
de6d9b64
FB
350 }
351 it1 += NB_ITS_SPEED;
352 ti1 = gettime() - ti;
353 } while (ti1 < 1000000);
aadd27cd 354 mmx_emms();
de6d9b64 355
cf2b4f88 356 printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,
36fa9ef3 357 (double) it1 * 1000.0 / (double) ti1);
de6d9b64
FB
358}
359
c6727809
MR
360DECLARE_ALIGNED(8, static uint8_t, img_dest)[64];
361DECLARE_ALIGNED(8, static uint8_t, img_dest1)[64];
a46a3ce4 362
504ffed1 363static void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
a46a3ce4
FB
364{
365 static int init;
366 static double c8[8][8];
367 static double c4[4][4];
368 double block1[64], block2[64], block3[64];
369 double s, sum, v;
370 int i, j, k;
371
372 if (!init) {
373 init = 1;
374
36fa9ef3 375 for (i = 0; i < 8; i++) {
a46a3ce4 376 sum = 0;
36fa9ef3
MR
377 for (j = 0; j < 8; j++) {
378 s = (i == 0) ? sqrt(1.0 / 8.0) : sqrt(1.0 / 4.0);
a46a3ce4
FB
379 c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
380 sum += c8[i][j] * c8[i][j];
381 }
382 }
115329f1 383
36fa9ef3 384 for (i = 0; i < 4; i++) {
a46a3ce4 385 sum = 0;
36fa9ef3
MR
386 for (j = 0; j < 4; j++) {
387 s = (i == 0) ? sqrt(1.0 / 4.0) : sqrt(1.0 / 2.0);
a46a3ce4
FB
388 c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
389 sum += c4[i][j] * c4[i][j];
390 }
391 }
392 }
393
394 /* butterfly */
652f0197 395 s = 0.5 * sqrt(2.0);
36fa9ef3
MR
396 for (i = 0; i < 4; i++) {
397 for (j = 0; j < 8; j++) {
398 block1[8 * (2 * i) + j] =
399 (block[8 * (2 * i) + j] + block[8 * (2 * i + 1) + j]) * s;
400 block1[8 * (2 * i + 1) + j] =
401 (block[8 * (2 * i) + j] - block[8 * (2 * i + 1) + j]) * s;
a46a3ce4
FB
402 }
403 }
404
405 /* idct8 on lines */
36fa9ef3
MR
406 for (i = 0; i < 8; i++) {
407 for (j = 0; j < 8; j++) {
a46a3ce4 408 sum = 0;
36fa9ef3
MR
409 for (k = 0; k < 8; k++)
410 sum += c8[k][j] * block1[8 * i + k];
411 block2[8 * i + j] = sum;
a46a3ce4
FB
412 }
413 }
414
415 /* idct4 */
36fa9ef3
MR
416 for (i = 0; i < 8; i++) {
417 for (j = 0; j < 4; j++) {
a46a3ce4
FB
418 /* top */
419 sum = 0;
36fa9ef3
MR
420 for (k = 0; k < 4; k++)
421 sum += c4[k][j] * block2[8 * (2 * k) + i];
422 block3[8 * (2 * j) + i] = sum;
a46a3ce4
FB
423
424 /* bottom */
425 sum = 0;
36fa9ef3
MR
426 for (k = 0; k < 4; k++)
427 sum += c4[k][j] * block2[8 * (2 * k + 1) + i];
428 block3[8 * (2 * j + 1) + i] = sum;
a46a3ce4
FB
429 }
430 }
431
432 /* clamp and store the result */
36fa9ef3
MR
433 for (i = 0; i < 8; i++) {
434 for (j = 0; j < 8; j++) {
435 v = block3[8 * i + j];
436 if (v < 0) v = 0;
437 else if (v > 255) v = 255;
438 dest[i * linesize + j] = (int) rint(v);
a46a3ce4
FB
439 }
440 }
441}
442
504ffed1 443static void idct248_error(const char *name,
36fa9ef3 444 void (*idct248_put)(uint8_t *dest, int line_size,
7fd2c138
MR
445 int16_t *block),
446 int speed)
a46a3ce4
FB
447{
448 int it, i, it1, ti, ti1, err_max, v;
64bde197 449 AVLFG prng;
294eaa26 450
64bde197 451 av_lfg_init(&prng, 1);
115329f1 452
a46a3ce4
FB
453 /* just one test to see if code is correct (precision is less
454 important here) */
455 err_max = 0;
36fa9ef3 456 for (it = 0; it < NB_ITS; it++) {
652f0197 457 /* XXX: use forward transform to generate values */
36fa9ef3 458 for (i = 0; i < 64; i++)
64bde197 459 block1[i] = av_lfg_get(&prng) % 256 - 128;
652f0197
FB
460 block1[0] += 1024;
461
36fa9ef3
MR
462 for (i = 0; i < 64; i++)
463 block[i] = block1[i];
a46a3ce4 464 idct248_ref(img_dest1, 8, block);
115329f1 465
36fa9ef3
MR
466 for (i = 0; i < 64; i++)
467 block[i] = block1[i];
652f0197 468 idct248_put(img_dest, 8, block);
115329f1 469
36fa9ef3
MR
470 for (i = 0; i < 64; i++) {
471 v = abs((int) img_dest[i] - (int) img_dest1[i]);
652f0197
FB
472 if (v == 255)
473 printf("%d %d\n", img_dest[i], img_dest1[i]);
474 if (v > err_max)
475 err_max = v;
476 }
a46a3ce4 477 }
36fa9ef3 478 printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max);
a46a3ce4 479
7fd2c138
MR
480 if (!speed)
481 return;
482
a46a3ce4
FB
483 ti = gettime();
484 it1 = 0;
485 do {
36fa9ef3
MR
486 for (it = 0; it < NB_ITS_SPEED; it++) {
487 for (i = 0; i < 64; i++)
488 block[i] = block1[i];
a46a3ce4
FB
489 idct248_put(img_dest, 8, block);
490 }
491 it1 += NB_ITS_SPEED;
492 ti1 = gettime() - ti;
493 } while (ti1 < 1000000);
aadd27cd 494 mmx_emms();
a46a3ce4 495
36fa9ef3
MR
496 printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name,
497 (double) it1 * 1000.0 / (double) ti1);
a46a3ce4
FB
498}
499
504ffed1 500static void help(void)
9e1586fc 501{
86748dbc
MN
502 printf("dct-test [-i] [<test-number>]\n"
503 "test-number 0 -> test with random matrixes\n"
504 " 1 -> test with random sparse matrixes\n"
505 " 2 -> do 3. test from mpeg4 std\n"
a46a3ce4 506 "-i test IDCT implementations\n"
7fd2c138
MR
507 "-4 test IDCT248 implementations\n"
508 "-t speed test\n");
9e1586fc
FB
509}
510
de6d9b64
FB
511int main(int argc, char **argv)
512{
a46a3ce4 513 int test_idct = 0, test_248_dct = 0;
36fa9ef3
MR
514 int c, i;
515 int test = 1;
7fd2c138 516 int speed = 0;
36fa9ef3 517
c6c98d08 518 cpu_flags = av_get_cpu_flags();
9e1586fc 519
0de74546 520 ff_ref_dct_init();
9e1586fc 521 idct_mmx_init();
f67a10cd 522
36fa9ef3
MR
523 for (i = 0; i < 256; i++)
524 cropTbl[i + MAX_NEG_CROP] = i;
525 for (i = 0; i < MAX_NEG_CROP; i++) {
486497e0
MR
526 cropTbl[i] = 0;
527 cropTbl[i + MAX_NEG_CROP + 256] = 255;
86748dbc 528 }
115329f1 529
36fa9ef3 530 for (;;) {
7fd2c138 531 c = getopt(argc, argv, "ih4t");
9e1586fc
FB
532 if (c == -1)
533 break;
36fa9ef3 534 switch (c) {
9e1586fc
FB
535 case 'i':
536 test_idct = 1;
537 break;
a46a3ce4
FB
538 case '4':
539 test_248_dct = 1;
540 break;
7fd2c138
MR
541 case 't':
542 speed = 1;
543 break;
36fa9ef3 544 default:
9e1586fc
FB
545 case 'h':
546 help();
c6bdc908 547 return 0;
9e1586fc
FB
548 }
549 }
115329f1 550
36fa9ef3
MR
551 if (optind < argc)
552 test = atoi(argv[optind]);
115329f1 553
9e1586fc
FB
554 printf("ffmpeg DCT/IDCT test\n");
555
a46a3ce4 556 if (test_248_dct) {
7fd2c138 557 idct248_error("SIMPLE-C", ff_simple_idct248_put, speed);
9e1586fc 558 } else {
4b357756 559 const struct algo *algos = test_idct ? idct_tab : fdct_tab;
36fa9ef3 560 for (i = 0; algos[i].name; i++)
4b357756 561 if (!(~cpu_flags & algos[i].mm_support)) {
7fd2c138 562 dct_error(&algos[i], test, test_idct, speed);
36fa9ef3 563 }
9e1586fc 564 }
de6d9b64
FB
565 return 0;
566}