1 /* DCT test. (c) 2001 Fabrice Bellard.
2 Started from sample code by Juan J. Sierralta P.
15 /* reference fdct/idct */
16 extern void fdct(DCTELEM
*block
);
17 extern void idct(DCTELEM
*block
);
18 extern void init_fdct();
20 extern void j_rev_dct(DCTELEM
*data
);
21 extern void ff_mmx_idct(DCTELEM
*data
);
22 extern void ff_mmxext_idct(DCTELEM
*data
);
24 #define AANSCALE_BITS 12
25 static const unsigned short aanscales
[64] = {
26 /* precomputed values scaled up by 14 bits */
27 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
28 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
29 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
30 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
31 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
32 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
33 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
34 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
40 gettimeofday(&tv
,NULL
);
41 return (INT64
)tv
.tv_sec
* 1000000 + tv
.tv_usec
;
45 #define NB_ITS_SPEED 50000
47 static short idct_mmx_perm
[64];
49 void idct_mmx_init(void)
53 /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
54 for (i
= 0; i
< 64; i
++) {
55 idct_mmx_perm
[i
] = (i
& 0x38) | ((i
& 6) >> 1) | ((i
& 1) << 2);
59 static DCTELEM block
[64] __attribute__ ((aligned (8)));
60 static DCTELEM block1
[64] __attribute__ ((aligned (8)));
62 void dct_error(const char *name
, int is_idct
,
63 void (*fdct_func
)(DCTELEM
*block
),
64 void (*fdct_ref
)(DCTELEM
*block
))
68 INT64 err2
, ti
, ti1
, it1
;
74 for(it
=0;it
<NB_ITS
;it
++) {
76 block1
[i
] = random() % 256;
78 /* for idct test, generate inverse idct data */
82 if (fdct_func
== ff_mmx_idct
||
83 fdct_func
== j_rev_dct
) {
85 block
[idct_mmx_perm
[i
]] = block1
[i
];
87 memcpy(block
, block1
, sizeof(DCTELEM
) * 64);
91 emms(); /* for ff_mmx_idct */
93 if (fdct_func
== fdct_ifast
) {
95 scale
= (1 << (AANSCALE_BITS
+ 11)) / aanscales
[i
];
96 block
[i
] = (block
[i
] * scale
) >> AANSCALE_BITS
;
103 v
= abs(block
[i
] - block1
[i
]);
109 printf("%s %s: err_inf=%d err2=%0.2f\n",
110 is_idct ?
"IDCT" : "DCT",
111 name
, err_inf
, (double)err2
/ NB_ITS
/ 64.0);
115 block1
[i
] = 255 - 63 + i
;
117 /* for idct test, generate inverse idct data */
120 if (fdct_func
== ff_mmx_idct
||
121 fdct_func
== j_rev_dct
) {
123 block
[idct_mmx_perm
[i
]] = block1
[i
];
129 for(it
=0;it
<NB_ITS_SPEED
;it
++) {
130 memcpy(block
, block1
, sizeof(DCTELEM
) * 64);
134 ti1
= gettime() - ti
;
135 } while (ti1
< 1000000);
138 printf("%s %s: %0.1f kdct/s\n",
139 is_idct ?
"IDCT" : "DCT",
140 name
, (double)it1
* 1000.0 / (double)ti1
);
145 printf("dct-test [-i]\n"
146 "test DCT implementations\n");
150 int main(int argc
, char **argv
)
159 c
= getopt(argc
, argv
, "ih");
172 printf("ffmpeg DCT/IDCT test\n");
175 dct_error("REF", 0, fdct
, fdct
); /* only to verify code ! */
176 dct_error("AAN", 0, fdct_ifast
, fdct
);
177 dct_error("MMX", 0, fdct_mmx
, fdct
);
179 dct_error("REF", 1, idct
, idct
);
180 dct_error("INT", 1, j_rev_dct
, idct
);
181 dct_error("MMX", 1, ff_mmx_idct
, idct
);
182 // dct_error("MMX", 1, ff_mmxext_idct, idct);