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