dct-test: remove is_idct field from tables
[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
cf2b4f88 203static void dct_error(const struct algo *dct, int test, int is_idct)
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
de6d9b64 306 /* speed test */
36fa9ef3 307 for (i = 0; i < 64; i++)
86748dbc 308 block1[i] = 0;
36fa9ef3
MR
309
310 switch (test) {
115329f1 311 case 0:
36fa9ef3
MR
312 for (i = 0; i < 64; i++)
313 block1[i] = av_lfg_get(&prng) % 512 - 256;
cf2b4f88 314 if (is_idct) {
0de74546 315 ff_ref_fdct(block1);
36fa9ef3
MR
316 for (i = 0; i < 64; i++)
317 block1[i] >>= 3;
ad324c93 318 }
36fa9ef3
MR
319 break;
320 case 1:
86748dbc 321 case 2:
36fa9ef3
MR
322 block1[0] = av_lfg_get(&prng) % 512 - 256;
323 block1[1] = av_lfg_get(&prng) % 512 - 256;
324 block1[2] = av_lfg_get(&prng) % 512 - 256;
325 block1[3] = av_lfg_get(&prng) % 512 - 256;
326 break;
86748dbc 327 }
de6d9b64 328
4f905a65 329 if (dct->format == MMX_PERM) {
36fa9ef3 330 for (i = 0; i < 64; i++)
9e1586fc 331 block[idct_mmx_perm[i]] = block1[i];
4f905a65 332 } else if (dct->format == MMX_SIMPLE_PERM) {
36fa9ef3 333 for (i = 0; i < 64; i++)
86748dbc
MN
334 block[idct_simple_mmx_perm[i]] = block1[i];
335 } else {
36fa9ef3
MR
336 for (i = 0; i < 64; i++)
337 block[i] = block1[i];
9e1586fc
FB
338 }
339
de6d9b64
FB
340 ti = gettime();
341 it1 = 0;
342 do {
36fa9ef3
MR
343 for (it = 0; it < NB_ITS_SPEED; it++) {
344 for (i = 0; i < 64; i++)
345 block[i] = block1[i];
4f905a65 346 dct->func(block);
de6d9b64
FB
347 }
348 it1 += NB_ITS_SPEED;
349 ti1 = gettime() - ti;
350 } while (ti1 < 1000000);
aadd27cd 351 mmx_emms();
de6d9b64 352
cf2b4f88 353 printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,
36fa9ef3 354 (double) it1 * 1000.0 / (double) ti1);
de6d9b64
FB
355}
356
c6727809
MR
357DECLARE_ALIGNED(8, static uint8_t, img_dest)[64];
358DECLARE_ALIGNED(8, static uint8_t, img_dest1)[64];
a46a3ce4 359
504ffed1 360static void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
a46a3ce4
FB
361{
362 static int init;
363 static double c8[8][8];
364 static double c4[4][4];
365 double block1[64], block2[64], block3[64];
366 double s, sum, v;
367 int i, j, k;
368
369 if (!init) {
370 init = 1;
371
36fa9ef3 372 for (i = 0; i < 8; i++) {
a46a3ce4 373 sum = 0;
36fa9ef3
MR
374 for (j = 0; j < 8; j++) {
375 s = (i == 0) ? sqrt(1.0 / 8.0) : sqrt(1.0 / 4.0);
a46a3ce4
FB
376 c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
377 sum += c8[i][j] * c8[i][j];
378 }
379 }
115329f1 380
36fa9ef3 381 for (i = 0; i < 4; i++) {
a46a3ce4 382 sum = 0;
36fa9ef3
MR
383 for (j = 0; j < 4; j++) {
384 s = (i == 0) ? sqrt(1.0 / 4.0) : sqrt(1.0 / 2.0);
a46a3ce4
FB
385 c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
386 sum += c4[i][j] * c4[i][j];
387 }
388 }
389 }
390
391 /* butterfly */
652f0197 392 s = 0.5 * sqrt(2.0);
36fa9ef3
MR
393 for (i = 0; i < 4; i++) {
394 for (j = 0; j < 8; j++) {
395 block1[8 * (2 * i) + j] =
396 (block[8 * (2 * i) + j] + block[8 * (2 * i + 1) + j]) * s;
397 block1[8 * (2 * i + 1) + j] =
398 (block[8 * (2 * i) + j] - block[8 * (2 * i + 1) + j]) * s;
a46a3ce4
FB
399 }
400 }
401
402 /* idct8 on lines */
36fa9ef3
MR
403 for (i = 0; i < 8; i++) {
404 for (j = 0; j < 8; j++) {
a46a3ce4 405 sum = 0;
36fa9ef3
MR
406 for (k = 0; k < 8; k++)
407 sum += c8[k][j] * block1[8 * i + k];
408 block2[8 * i + j] = sum;
a46a3ce4
FB
409 }
410 }
411
412 /* idct4 */
36fa9ef3
MR
413 for (i = 0; i < 8; i++) {
414 for (j = 0; j < 4; j++) {
a46a3ce4
FB
415 /* top */
416 sum = 0;
36fa9ef3
MR
417 for (k = 0; k < 4; k++)
418 sum += c4[k][j] * block2[8 * (2 * k) + i];
419 block3[8 * (2 * j) + i] = sum;
a46a3ce4
FB
420
421 /* bottom */
422 sum = 0;
36fa9ef3
MR
423 for (k = 0; k < 4; k++)
424 sum += c4[k][j] * block2[8 * (2 * k + 1) + i];
425 block3[8 * (2 * j + 1) + i] = sum;
a46a3ce4
FB
426 }
427 }
428
429 /* clamp and store the result */
36fa9ef3
MR
430 for (i = 0; i < 8; i++) {
431 for (j = 0; j < 8; j++) {
432 v = block3[8 * i + j];
433 if (v < 0) v = 0;
434 else if (v > 255) v = 255;
435 dest[i * linesize + j] = (int) rint(v);
a46a3ce4
FB
436 }
437 }
438}
439
504ffed1 440static void idct248_error(const char *name,
36fa9ef3
MR
441 void (*idct248_put)(uint8_t *dest, int line_size,
442 int16_t *block))
a46a3ce4
FB
443{
444 int it, i, it1, ti, ti1, err_max, v;
64bde197 445 AVLFG prng;
294eaa26 446
64bde197 447 av_lfg_init(&prng, 1);
115329f1 448
a46a3ce4
FB
449 /* just one test to see if code is correct (precision is less
450 important here) */
451 err_max = 0;
36fa9ef3 452 for (it = 0; it < NB_ITS; it++) {
652f0197 453 /* XXX: use forward transform to generate values */
36fa9ef3 454 for (i = 0; i < 64; i++)
64bde197 455 block1[i] = av_lfg_get(&prng) % 256 - 128;
652f0197
FB
456 block1[0] += 1024;
457
36fa9ef3
MR
458 for (i = 0; i < 64; i++)
459 block[i] = block1[i];
a46a3ce4 460 idct248_ref(img_dest1, 8, block);
115329f1 461
36fa9ef3
MR
462 for (i = 0; i < 64; i++)
463 block[i] = block1[i];
652f0197 464 idct248_put(img_dest, 8, block);
115329f1 465
36fa9ef3
MR
466 for (i = 0; i < 64; i++) {
467 v = abs((int) img_dest[i] - (int) img_dest1[i]);
652f0197
FB
468 if (v == 255)
469 printf("%d %d\n", img_dest[i], img_dest1[i]);
470 if (v > err_max)
471 err_max = v;
472 }
a46a3ce4 473 }
36fa9ef3 474 printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max);
a46a3ce4
FB
475
476 ti = gettime();
477 it1 = 0;
478 do {
36fa9ef3
MR
479 for (it = 0; it < NB_ITS_SPEED; it++) {
480 for (i = 0; i < 64; i++)
481 block[i] = block1[i];
a46a3ce4
FB
482 idct248_put(img_dest, 8, block);
483 }
484 it1 += NB_ITS_SPEED;
485 ti1 = gettime() - ti;
486 } while (ti1 < 1000000);
aadd27cd 487 mmx_emms();
a46a3ce4 488
36fa9ef3
MR
489 printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name,
490 (double) it1 * 1000.0 / (double) ti1);
a46a3ce4
FB
491}
492
504ffed1 493static void help(void)
9e1586fc 494{
86748dbc
MN
495 printf("dct-test [-i] [<test-number>]\n"
496 "test-number 0 -> test with random matrixes\n"
497 " 1 -> test with random sparse matrixes\n"
498 " 2 -> do 3. test from mpeg4 std\n"
a46a3ce4
FB
499 "-i test IDCT implementations\n"
500 "-4 test IDCT248 implementations\n");
9e1586fc
FB
501}
502
de6d9b64
FB
503int main(int argc, char **argv)
504{
a46a3ce4 505 int test_idct = 0, test_248_dct = 0;
36fa9ef3
MR
506 int c, i;
507 int test = 1;
508
c6c98d08 509 cpu_flags = av_get_cpu_flags();
9e1586fc 510
0de74546 511 ff_ref_dct_init();
9e1586fc 512 idct_mmx_init();
f67a10cd 513
36fa9ef3
MR
514 for (i = 0; i < 256; i++)
515 cropTbl[i + MAX_NEG_CROP] = i;
516 for (i = 0; i < MAX_NEG_CROP; i++) {
486497e0
MR
517 cropTbl[i] = 0;
518 cropTbl[i + MAX_NEG_CROP + 256] = 255;
86748dbc 519 }
115329f1 520
36fa9ef3 521 for (;;) {
a46a3ce4 522 c = getopt(argc, argv, "ih4");
9e1586fc
FB
523 if (c == -1)
524 break;
36fa9ef3 525 switch (c) {
9e1586fc
FB
526 case 'i':
527 test_idct = 1;
528 break;
a46a3ce4
FB
529 case '4':
530 test_248_dct = 1;
531 break;
36fa9ef3 532 default:
9e1586fc
FB
533 case 'h':
534 help();
c6bdc908 535 return 0;
9e1586fc
FB
536 }
537 }
115329f1 538
36fa9ef3
MR
539 if (optind < argc)
540 test = atoi(argv[optind]);
115329f1 541
9e1586fc
FB
542 printf("ffmpeg DCT/IDCT test\n");
543
a46a3ce4 544 if (test_248_dct) {
59e6f60a 545 idct248_error("SIMPLE-C", ff_simple_idct248_put);
9e1586fc 546 } else {
4b357756 547 const struct algo *algos = test_idct ? idct_tab : fdct_tab;
36fa9ef3 548 for (i = 0; algos[i].name; i++)
4b357756 549 if (!(~cpu_flags & algos[i].mm_support)) {
cf2b4f88 550 dct_error(&algos[i], test, test_idct);
36fa9ef3 551 }
9e1586fc 552 }
de6d9b64
FB
553 return 0;
554}