[svn] / trunk / xvidcore / examples / xvid_bench.c Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/examples/xvid_bench.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 225 - (view) (download)

1 : Isibaar 225 /**************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC - Unit tests and benches
4 :     *
5 :     * This program is free software; you can redistribute it and/or modify
6 :     * it under the terms of the GNU General Public License as published by
7 :     * the Free Software Foundation; either version 2 of the License, or
8 :     * (at your option) any later version.
9 :     *
10 :     * This program is distributed in the hope that it will be useful,
11 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 :     * GNU General Public License for more details.
14 :     *
15 :     * You should have received a copy of the GNU General Public License
16 :     * along with this program; if not, write to the Free Software
17 :     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 :     *
19 :     *************************************************************************/
20 :    
21 :     /************************************************************************
22 :     *
23 :     * 'Reference' output is at the end of file.
24 :     * Don't take the checksums and crc too seriouly, they aren't
25 :     * bullet-proof...
26 :     *
27 :     * compiles with something like:
28 :     * gcc -o xvid_bench xvid_bench.c -I../src/ -lxvidcore -lm
29 :     *
30 :     * History:
31 :     *
32 :     * 06.06.2002 initial coding -Skal-
33 :     *
34 :     *************************************************************************/
35 :    
36 :     #include <stdio.h>
37 :     #include <stdlib.h>
38 :     #include <sys/time.h> // for gettimeofday
39 :     #include <string.h> // for memset
40 :     #include <assert.h>
41 :    
42 :     #include "xvid.h"
43 :    
44 :     // inner guts
45 :     #include "dct/idct.h"
46 :     #include "dct/fdct.h"
47 :     #include "image/colorspace.h"
48 :     #include "image/interpolate8x8.h"
49 :     #include "utils/mem_transfer.h"
50 :     #include "quant/quant_h263.h"
51 :     #include "quant/quant_mpeg4.h"
52 :     #include "motion/sad.h"
53 :     #include "utils/emms.h"
54 :     #include "utils/timer.h"
55 :     #include "quant/quant_matrix.c"
56 :     #include "bitstream/cbp.h"
57 :    
58 :     const int speed_ref = 100; // on slow machines, decrease this value
59 :    
60 :     /*********************************************************************
61 :     * misc
62 :     *********************************************************************/
63 :    
64 :     /* returns time in micro-s*/
65 :     double gettime_usec()
66 :     {
67 :     struct timeval tv;
68 :     gettimeofday(&tv, 0);
69 :     return tv.tv_sec*1.0e6f + tv.tv_usec;
70 :     }
71 :    
72 :     /* returns squared deviates (mean(v*v)-mean(v)^2) of a 8x8 block */
73 :     double sqr_dev(uint8_t v[8*8])
74 :     {
75 :     double sum=0.;
76 :     double sum2=0.;
77 :     int n;
78 :     for (n=0;n<8*8;n++)
79 :     {
80 :     sum += v[n];
81 :     sum2 += v[n]*v[n];
82 :     }
83 :     sum2 /= n;
84 :     sum /= n;
85 :     return sum2-sum*sum;
86 :     }
87 :    
88 :     /*********************************************************************
89 :     * cpu init
90 :     *********************************************************************/
91 :    
92 :     typedef struct {
93 :     const char *name;
94 :     unsigned int cpu;
95 :     } CPU;
96 :    
97 :     CPU cpu_list[] =
98 :     { { "PLAINC", 0 }
99 :     , { "MMX ", XVID_CPU_MMX }
100 :     , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }
101 :     , { "SSE2 ", XVID_CPU_SSE2 | XVID_CPU_MMX }
102 :     , { "3DNOW ", XVID_CPU_3DNOW }
103 :     , { "3DNOWE", XVID_CPU_3DNOWEXT }
104 :     //, { "TSC ", XVID_CPU_TSC }
105 :     , { 0, 0 } }
106 :    
107 :     , cpu_short_list[] =
108 :     { { "PLAINC", 0 }
109 :     , { "MMX ", XVID_CPU_MMX }
110 :     , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }
111 :     , { 0, 0 } }
112 :    
113 :     , cpu_short_list2[] =
114 :     { { "PLAINC", 0 }
115 :     , { "MMX ", XVID_CPU_MMX }
116 :     , { "SSE2 ", XVID_CPU_SSE2 | XVID_CPU_MMX }
117 :     , { 0, 0 } };
118 :    
119 :    
120 :     int init_cpu(CPU *cpu)
121 :     {
122 :     int xerr, cpu_type;
123 :     XVID_INIT_PARAM xinit;
124 :    
125 :     cpu_type = check_cpu_features() & cpu->cpu;
126 :     xinit.cpu_flags = cpu_type | XVID_CPU_FORCE;
127 :     // xinit.cpu_flags = XVID_CPU_MMX | XVID_CPU_FORCE;
128 :     xerr = xvid_init(NULL, 0, &xinit, NULL);
129 :     if (cpu->cpu>0 && (cpu_type==0 || xerr!=XVID_ERR_OK)) {
130 :     printf( "%s - skipped...\n", cpu->name );
131 :     return 0;
132 :     }
133 :     return 1;
134 :     }
135 :    
136 :     /*********************************************************************
137 :     * test DCT
138 :     *********************************************************************/
139 :    
140 :     #define ABS(X) ((X)<0 ? -(X) : (X))
141 :    
142 :     void test_dct()
143 :     {
144 :     const int nb_tests = 300*speed_ref;
145 :     int tst;
146 :     CPU *cpu;
147 :     int i;
148 :     short iDst0[8*8], iDst[8*8], fDst[8*8];
149 :     double overhead;
150 :    
151 :     printf( "\n ===== test fdct/idct =====\n" );
152 :    
153 :     for(i=0; i<8*8; ++i) iDst0[i] = (i*7-i*i) & 0x7f;
154 :     overhead = gettime_usec();
155 :     for(tst=0; tst<nb_tests; ++tst)
156 :     {
157 :     for(i=0; i<8*8; ++i) fDst[i] = iDst0[i];
158 :     for(i=0; i<8*8; ++i) iDst[i] = fDst[i];
159 :     }
160 :     overhead = gettime_usec() - overhead;
161 :    
162 :     for(cpu = cpu_list; cpu->name!=0; ++cpu)
163 :     {
164 :     double t;
165 :     int iCrc, fCrc;
166 :    
167 :     if (!init_cpu(cpu))
168 :     continue;
169 :    
170 :     t = gettime_usec();
171 :     emms();
172 :     for(tst=0; tst<nb_tests; ++tst)
173 :     {
174 :     for(i=0; i<8*8; ++i) fDst[i] = iDst0[i];
175 :     fdct(fDst);
176 :     for(i=0; i<8*8; ++i) iDst[i] = fDst[i];
177 :     idct(iDst);
178 :     }
179 :     emms();
180 :     t = (gettime_usec() - t - overhead) / nb_tests;
181 :     iCrc=0; fCrc=0;
182 :     for(i=0; i<8*8; ++i) {
183 :     iCrc += ABS(iDst[i] - iDst0[i]);
184 :     fCrc += fDst[i]^i;
185 :     }
186 :     printf( "%s - %.3f usec iCrc=%d fCrc=%d\n",
187 :     cpu->name, t, iCrc, fCrc );
188 :     // the norm tolerates ~1 bit of diff per coeff
189 :     if (ABS(iCrc)>=64) printf( "*** CRC ERROR! ***\n" );
190 :     }
191 :     }
192 :    
193 :     /*********************************************************************
194 :     * test SAD
195 :     *********************************************************************/
196 :    
197 :     void test_sad()
198 :     {
199 :     const int nb_tests = 2000*speed_ref;
200 :     int tst;
201 :     CPU *cpu;
202 :     int i;
203 :     uint8_t Cur[16*16], Ref1[16*16], Ref2[16*16];
204 :    
205 :     printf( "\n ====== test SAD ======\n" );
206 :     for(i=0; i<16*16;++i) {
207 :     Cur[i] = (i/5) ^ 0x05;
208 :     Ref1[i] = (i + 0x0b) & 0xff;
209 :     Ref2[i] = i ^ 0x76;
210 :     }
211 :    
212 :     for(cpu = cpu_list; cpu->name!=0; ++cpu)
213 :     {
214 :     double t;
215 :     uint32_t s;
216 :     if (!init_cpu(cpu))
217 :     continue;
218 :    
219 :     t = gettime_usec();
220 :     emms();
221 :     for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);
222 :     emms();
223 :     t = (gettime_usec() - t) / nb_tests;
224 :     printf( "%s - sad8 %.3f usec sad=%d\n", cpu->name, t, s );
225 :     if (s!=3776) printf( "*** CRC ERROR! ***\n" );
226 :    
227 :     t = gettime_usec();
228 :     emms();
229 :     for(tst=0; tst<nb_tests; ++tst) s = sad16(Cur, Ref1, 16, -1);
230 :     emms();
231 :     t = (gettime_usec() - t) / nb_tests;
232 :     printf( "%s - sad16 %.3f usec sad=%d\n", cpu->name, t, s );
233 :     if (s!=27214) printf( "*** CRC ERROR! ***\n" );
234 :    
235 :     t = gettime_usec();
236 :     emms();
237 :     for(tst=0; tst<nb_tests; ++tst) s = sad16bi(Cur, Ref1, Ref2, 16);
238 :     emms();
239 :     t = (gettime_usec() - t) / nb_tests;
240 :     printf( "%s - sad16bi %.3f usec sad=%d\n", cpu->name, t, s );
241 :     if (s!=26274) printf( "*** CRC ERROR! ***\n" );
242 :    
243 :     t = gettime_usec();
244 :     emms();
245 :     for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);
246 :     emms();
247 :     t = (gettime_usec() - t) / nb_tests;
248 :     printf( "%s - dev16 %.3f usec sad=%d\n", cpu->name, t, s );
249 :     if (s!=3344) printf( "*** CRC ERROR! ***\n" );
250 :    
251 :     printf( " --- \n" );
252 :     }
253 :     }
254 :    
255 :     /*********************************************************************
256 :     * test interpolation
257 :     *********************************************************************/
258 :    
259 :     #define ENTER \
260 :     for(i=0; i<16*8; ++i) Dst[i] = 0; \
261 :     t = gettime_usec(); \
262 :     emms();
263 :    
264 :     #define LEAVE \
265 :     emms(); \
266 :     t = (gettime_usec() - t) / nb_tests; \
267 :     iCrc = 0; \
268 :     for(i=0; i<16*8; ++i) { iCrc += Dst[i]^i; }
269 :    
270 :     #define TEST_MB(FUNC, R) \
271 :     ENTER \
272 :     for(tst=0; tst<nb_tests; ++tst) (FUNC)(Dst, Src0, 16, (R)); \
273 :     LEAVE
274 :    
275 :     #define TEST_MB2(FUNC) \
276 :     ENTER \
277 :     for(tst=0; tst<nb_tests; ++tst) (FUNC)(Dst, Src0, 16); \
278 :     LEAVE
279 :    
280 :    
281 :     void test_mb()
282 :     {
283 :     const int nb_tests = 2000*speed_ref;
284 :     CPU *cpu;
285 :     const uint8_t Src0[16*9] = {
286 :     // try to have every possible combinaison of rounding...
287 :     0, 0, 1, 0, 2, 0, 3, 0, 4 ,0,0,0, 0,0,0,0
288 :     , 0, 1, 1, 1, 2, 1, 3, 1, 3 ,0,0,0, 0,0,0,0
289 :     , 0, 2, 1, 2, 2, 2, 3, 2, 2 ,0,0,0, 0,0,0,0
290 :     , 0, 3, 1, 3, 2, 3, 3, 3, 1 ,0,0,0, 0,0,0,0
291 :     , 1, 3, 0, 2, 1, 0, 2, 3, 4 ,0,0,0, 0,0,0,0
292 :     , 2, 2, 1, 2, 0, 1, 3, 5, 3 ,0,0,0, 0,0,0,0
293 :     , 3, 1, 2, 3, 1, 2, 2, 6, 2 ,0,0,0, 0,0,0,0
294 :     , 1, 0, 1, 3, 0, 3, 1, 6, 1 ,0,0,0, 0,0,0,0
295 :     , 4, 3, 2, 1, 2, 3, 4, 0, 3 ,0,0,0, 0,0,0,0
296 :     };
297 :     uint8_t Dst[16*8] = {0};
298 :    
299 :     printf( "\n === test block motion ===\n" );
300 :    
301 :     for(cpu = cpu_list; cpu->name!=0; ++cpu)
302 :     {
303 :     double t;
304 :     int tst, i, iCrc;
305 :    
306 :     if (!init_cpu(cpu))
307 :     continue;
308 :    
309 :     TEST_MB(interpolate8x8_halfpel_h, 0);
310 :     printf( "%s - interp- h-round0 %.3f usec iCrc=%d\n", cpu->name, t, iCrc );
311 :     if (iCrc!=8107) printf( "*** CRC ERROR! ***\n" );
312 :    
313 :     TEST_MB(interpolate8x8_halfpel_h, 1);
314 :     printf( "%s - round1 %.3f usec iCrc=%d\n", cpu->name, t, iCrc );
315 :     if (iCrc!=8100) printf( "*** CRC ERROR! ***\n" );
316 :    
317 :    
318 :     TEST_MB(interpolate8x8_halfpel_v, 0);
319 :     printf( "%s - interp- v-round0 %.3f usec iCrc=%d\n", cpu->name, t, iCrc );
320 :     if (iCrc!=8108) printf( "*** CRC ERROR! ***\n" );
321 :    
322 :     TEST_MB(interpolate8x8_halfpel_v, 1);
323 :     printf( "%s - round1 %.3f usec iCrc=%d\n", cpu->name, t, iCrc );
324 :     if (iCrc!=8105) printf( "*** CRC ERROR! ***\n" );
325 :    
326 :    
327 :     TEST_MB(interpolate8x8_halfpel_hv, 0);
328 :     printf( "%s - interp-hv-round0 %.3f usec iCrc=%d\n", cpu->name, t, iCrc );
329 :     if (iCrc!=8112) printf( "*** CRC ERROR! ***\n" );
330 :    
331 :     TEST_MB(interpolate8x8_halfpel_hv, 1);
332 :     printf( "%s - round1 %.3f usec iCrc=%d\n", cpu->name, t, iCrc );
333 :     if (iCrc!=8103) printf( "*** CRC ERROR! ***\n" );
334 :    
335 :     printf( " --- \n" );
336 :     }
337 :     }
338 :    
339 :     /*********************************************************************
340 :     * test transfer
341 :     *********************************************************************/
342 :    
343 :     #define INIT_TRANSFER \
344 :     for(i=0; i<8*32; ++i) { \
345 :     Src8[i] = i; Src16[i] = i; \
346 :     Dst8[i] = 0; Dst16[i] = 0; \
347 :     Ref1[i] = i^0x27; \
348 :     Ref2[i] = i^0x51; \
349 :     }
350 :    
351 :     #define TEST_TRANSFER_BEGIN(DST) \
352 :     INIT_TRANSFER \
353 :     overhead = -gettime_usec(); \
354 :     for(tst=0; tst<nb_tests; ++tst) { \
355 :     for(i=0; i<8*32; ++i) (DST)[i] = i^0x6a;\
356 :     } \
357 :     overhead += gettime_usec(); \
358 :     t = gettime_usec(); \
359 :     emms(); \
360 :     for(tst=0; tst<nb_tests; ++tst) { \
361 :     for(i=0; i<8*32; ++i) (DST)[i] = i^0x6a;
362 :    
363 :    
364 :     #define TEST_TRANSFER_END(DST) \
365 :     } \
366 :     emms(); \
367 :     t = (gettime_usec()-t -overhead) / nb_tests;\
368 :     s = 0; for(i=0; i<8*32; ++i) { s += (DST)[i]^i; }
369 :    
370 :     #define TEST_TRANSFER(FUNC, DST, SRC) \
371 :     TEST_TRANSFER_BEGIN(DST); \
372 :     (FUNC)((DST), (SRC), 32); \
373 :     TEST_TRANSFER_END(DST)
374 :    
375 :    
376 :     #define TEST_TRANSFER2_BEGIN(DST, SRC) \
377 :     INIT_TRANSFER \
378 :     overhead = -gettime_usec(); \
379 :     for(tst=0; tst<nb_tests; ++tst) { \
380 :     for(i=0; i<8*32; ++i) (DST)[i] = i^0x6a;\
381 :     for(i=0; i<8*32; ++i) (SRC)[i] = i^0x3e;\
382 :     } \
383 :     overhead += gettime_usec(); \
384 :     t = gettime_usec(); \
385 :     emms(); \
386 :     for(tst=0; tst<nb_tests; ++tst) { \
387 :     for(i=0; i<8*32; ++i) (DST)[i] = i^0x6a;\
388 :     for(i=0; i<8*32; ++i) (SRC)[i] = i^0x3e;
389 :    
390 :     #define TEST_TRANSFER2_END(DST) \
391 :     } \
392 :     emms(); \
393 :     t = (gettime_usec()-t -overhead) / nb_tests;\
394 :     s = 0; for(i=0; i<8*32; ++i) { s += (DST)[i]; }
395 :    
396 :     #define TEST_TRANSFER2(FUNC, DST, SRC, R1) \
397 :     TEST_TRANSFER2_BEGIN(DST,SRC); \
398 :     (FUNC)((DST), (SRC), (R1), 32); \
399 :     TEST_TRANSFER2_END(DST)
400 :    
401 :     #define TEST_TRANSFER3(FUNC, DST, SRC, R1, R2)\
402 :     TEST_TRANSFER_BEGIN(DST); \
403 :     (FUNC)((DST), (SRC), (R1), (R2), 32); \
404 :     TEST_TRANSFER_END(DST)
405 :    
406 :     void test_transfer()
407 :     {
408 :     const int nb_tests = 4000*speed_ref;
409 :     int i;
410 :     CPU *cpu;
411 :     uint8_t Src8[8*32], Dst8[8*32], Ref1[8*32], Ref2[8*32];
412 :     int16_t Src16[8*32], Dst16[8*32];
413 :    
414 :     printf( "\n === test transfer ===\n" );
415 :    
416 :     for(cpu = cpu_short_list; cpu->name!=0; ++cpu)
417 :     {
418 :     double t, overhead;
419 :     int tst, s;
420 :    
421 :     if (!init_cpu(cpu))
422 :     continue;
423 :    
424 :     TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);
425 :     printf( "%s - 8to16 %.3f usec crc=%d\n", cpu->name, t, s );
426 :     if (s!=28288) printf( "*** CRC ERROR! ***\n" );
427 :    
428 :     TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);
429 :     printf( "%s - 16to8 %.3f usec crc=%d\n", cpu->name, t, s );
430 :     if (s!=28288) printf( "*** CRC ERROR! ***\n" );
431 :    
432 :     TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);
433 :     printf( "%s - 8to8 %.3f usec crc=%d\n", cpu->name, t, s );
434 :     if (s!=20352) printf( "*** CRC ERROR! ***\n" );
435 :    
436 :     TEST_TRANSFER(transfer_16to8add, Dst8, Src16);
437 :     printf( "%s - 16to8add %.3f usec crc=%d\n", cpu->name, t, s );
438 :     if (s!=25536) printf( "*** CRC ERROR! ***\n" );
439 :    
440 :     TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);
441 :     printf( "%s - 8to16sub %.3f usec crc1=%d ", cpu->name, t, s );
442 :     if (s!=28064) printf( "*** CRC ERROR! ***\n" );
443 :     s = 0; for(i=0; i<8*32; ++i) { s += (Src8[i]-Ref1[i])&i; }
444 :     printf( "crc2=%d\n", s);
445 :     if (s!=16256) printf( "*** CRC ERROR! ***\n" );
446 :    
447 :     TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);
448 :     printf( "%s - 8to16sub2 %.3f usec crc=%d\n", cpu->name, t, s );
449 :     if (s!=20384) printf( "*** CRC ERROR! ***\n" );
450 :    
451 :     printf( " --- \n" );
452 :     }
453 :     }
454 :    
455 :     /*********************************************************************
456 :     * test quantization
457 :     *********************************************************************/
458 :    
459 :     #define TEST_QUANT(FUNC, DST, SRC) \
460 :     t = gettime_usec(); \
461 :     emms(); \
462 :     for(tst=0; tst<nb_tests; ++tst) \
463 :     for(s=0, q=1; q<=max_Q; ++q) { \
464 :     (FUNC)((DST), (SRC), q); \
465 :     for(i=0; i<64; ++i) s+=(DST)[i]^i; \
466 :     } \
467 :     emms(); \
468 :     t = (gettime_usec()-t-overhead)/nb_tests;
469 :    
470 :     #define TEST_QUANT2(FUNC, DST, SRC, MULT) \
471 :     t = gettime_usec(); \
472 :     emms(); \
473 :     for(tst=0; tst<nb_tests; ++tst) \
474 :     for(s=0, q=1; q<=max_Q; ++q) { \
475 :     (FUNC)((DST), (SRC), q, MULT); \
476 :     for(i=0; i<64; ++i) s+=(DST)[i]^i; \
477 :     } \
478 :     emms(); \
479 :     t = (gettime_usec()-t-overhead)/nb_tests;
480 :    
481 :     void test_quant()
482 :     {
483 :     const int nb_tests = 150*speed_ref;
484 :     const int max_Q = 31;
485 :     int i;
486 :     CPU *cpu;
487 :     int16_t Src[8*8], Dst[8*8];
488 :    
489 :     printf( "\n ===== test quant =====\n" );
490 :    
491 :     for(i=0; i<64; ++i) {
492 :     Src[i] = i-32;
493 :     Dst[i] = 0;
494 :     }
495 :    
496 :    
497 :     for(cpu = cpu_short_list; cpu->name!=0; ++cpu)
498 :     {
499 :     double t, overhead;
500 :     int tst, s, q;
501 :    
502 :     if (!init_cpu(cpu))
503 :     continue;
504 :    
505 :     set_inter_matrix( get_default_inter_matrix() );
506 :     set_intra_matrix( get_default_intra_matrix() );
507 :     overhead = -gettime_usec();
508 :     for(tst=0; tst<nb_tests; ++tst)
509 :     for(s=0, q=1; q<=max_Q; ++q)
510 :     for(i=0; i<64; ++i) s+=Dst[i]^i;
511 :     overhead += gettime_usec();
512 :    
513 :     TEST_QUANT2(quant4_intra, Dst, Src, 7);
514 :     printf( "%s - quant4_intra %.3f usec crc=%d\n", cpu->name, t, s );
515 :     if (s!=55827) printf( "*** CRC ERROR! ***\n" );
516 :    
517 :     TEST_QUANT(quant4_inter, Dst, Src);
518 :     printf( "%s - quant4_inter %.3f usec crc=%d\n", cpu->name, t, s );
519 :     if (s!=58201) printf( "*** CRC ERROR! ***\n" );
520 :    
521 :    
522 :     TEST_QUANT2(dequant4_intra, Dst, Src, 7);
523 :     printf( "%s - dequant4_intra %.3f usec crc=%d\n", cpu->name, t, s );
524 :     if (s!=193340) printf( "*** CRC ERROR! ***\n" );
525 :    
526 :     TEST_QUANT(dequant4_inter, Dst, Src);
527 :     printf( "%s - dequant4_inter %.3f usec crc=%d\n", cpu->name, t, s );
528 :     if (s!=116483) printf( "*** CRC ERROR! ***\n" );
529 :    
530 :     TEST_QUANT2(quant_intra, Dst, Src, 7);
531 :     printf( "%s - quant_intra %.3f usec crc=%d\n", cpu->name, t, s );
532 :     if (s!=56885) printf( "*** CRC ERROR! ***\n" );
533 :    
534 :     TEST_QUANT(quant_inter, Dst, Src);
535 :     printf( "%s - quant_inter %.3f usec crc=%d\n", cpu->name, t, s );
536 :     if (s!=58056) printf( "*** CRC ERROR! ***\n" );
537 :    
538 :     TEST_QUANT2(dequant_intra, Dst, Src, 7);
539 :     printf( "%s - dequant_intra %.3f usec crc=%d\n", cpu->name, t, s );
540 :     if (s!=-7936) printf( "*** CRC ERROR! ***\n" );
541 :    
542 :     TEST_QUANT(dequant_inter, Dst, Src);
543 :     printf( "%s - dequant_inter %.3f usec crc=%d\n", cpu->name, t, s );
544 :     // { int k,l; for(k=0; k<8; ++k) { for(l=0; l<8; ++l) printf( "[%.4d]", Dst[k*8+l]); printf("\n"); } }
545 :     if (s!=-33217) printf( "*** CRC ERROR! ***\n" );
546 :    
547 :     printf( " --- \n" );
548 :     }
549 :     }
550 :    
551 :     /*********************************************************************
552 :     * test non-zero AC counting
553 :     *********************************************************************/
554 :    
555 :     #define TEST_CBP(FUNC, SRC) \
556 :     t = gettime_usec(); \
557 :     emms(); \
558 :     for(tst=0; tst<nb_tests; ++tst) { \
559 :     cbp = (FUNC)((SRC)); \
560 :     } \
561 :     emms(); \
562 :     t = (gettime_usec()-t ) / nb_tests;
563 :    
564 :     void test_cbp()
565 :     {
566 :     const int nb_tests = 10000*speed_ref;
567 :     int i;
568 :     CPU *cpu;
569 :     int16_t Src1[6*64], Src2[6*64], Src3[6*64], Src4[6*64];
570 :    
571 :     printf( "\n ===== test cbp =====\n" );
572 :    
573 :     for(i=0; i<6*64; ++i) {
574 :     Src1[i] = (i*i*3/8192)&(i/64)&1; // 'random'
575 :     Src2[i] = (i<3*64); // half-full
576 :     Src3[i] = ((i+32)>3*64);
577 :     Src4[i] = (i==(3*64+2) || i==(5*64+9));
578 :     }
579 :    
580 :     for(cpu = cpu_short_list2; cpu->name!=0; ++cpu)
581 :     {
582 :     double t;
583 :     int tst, cbp;
584 :    
585 :     if (!init_cpu(cpu))
586 :     continue;
587 :    
588 :     TEST_CBP(calc_cbp, Src1);
589 :     printf( "%s - calc_cbp#1 %.3f usec cbp=0x%x\n", cpu->name, t, cbp );
590 :     if (cbp!=0x15) printf( "*** CRC ERROR! ***\n" );
591 :     TEST_CBP(calc_cbp, Src2);
592 :     printf( "%s - calc_cbp#2 %.3f usec cbp=0x%x\n", cpu->name, t, cbp );
593 :     if (cbp!=0x38) printf( "*** CRC ERROR! ***\n" );
594 :     TEST_CBP(calc_cbp, Src3);
595 :     printf( "%s - calc_cbp#3 %.3f usec cbp=0x%x\n", cpu->name, t, cbp );
596 :     if (cbp!=0x0f) printf( "*** CRC ERROR! ***\n" );
597 :     TEST_CBP(calc_cbp, Src4);
598 :     printf( "%s - calc_cbp#4 %.3f usec cbp=0x%x\n", cpu->name, t, cbp );
599 :     if (cbp!=0x05) printf( "*** CRC ERROR! ***\n" );
600 :     printf( " --- \n" );
601 :     }
602 :     }
603 :    
604 :     /*********************************************************************
605 :     * measure raw decoding speed
606 :     *********************************************************************/
607 :    
608 :     void test_dec(const char *name, int width, int height, int with_chksum)
609 :     {
610 :     FILE *f = 0;
611 :     void *dechandle = 0;
612 :     int xerr;
613 :     XVID_INIT_PARAM xinit;
614 :     XVID_DEC_PARAM xparam;
615 :     XVID_DEC_FRAME xframe;
616 :     double t = 0.;
617 :     int nb = 0;
618 :     uint8_t *buf = 0;
619 :     uint8_t *rgb_out = 0;
620 :     int buf_size, pos;
621 :     uint32_t chksum = 0;
622 :    
623 :     xinit.cpu_flags = 0;
624 :     xvid_init(NULL, 0, &xinit, NULL);
625 :     printf( "API version: %d, core build:%d\n", xinit.api_version, xinit.core_build);
626 :    
627 :    
628 :     xparam.width = width;
629 :     xparam.height = height;
630 :     xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
631 :     if (xerr!=XVID_ERR_OK) {
632 :     printf("can't init decoder (err=%d)\n", xerr);
633 :     return;
634 :     }
635 :     dechandle = xparam.handle;
636 :    
637 :    
638 :     f = fopen(name, "rb");
639 :     if (f==0) {
640 :     printf( "can't open file '%s'\n", name);
641 :     return;
642 :     }
643 :     fseek(f, 0, SEEK_END);
644 :     buf_size = ftell(f);
645 :     fseek(f, 0, SEEK_SET);
646 :     if (buf_size<=0) {
647 :     printf("error while stating file\n");
648 :     goto End;
649 :     }
650 :     else printf( "Input size: %d\n", buf_size);
651 :    
652 :     buf = malloc(buf_size); // should be enuf'
653 :     rgb_out = calloc(4, width*height); // <-room for _RGB24
654 :     if (buf==0 || rgb_out==0) {
655 :     printf( "malloc failed!\n" );
656 :     goto End;
657 :     }
658 :    
659 :     if (fread(buf, buf_size, 1, f)!=1) {
660 :     printf( "file-read failed\n" );
661 :     goto End;
662 :     }
663 :    
664 :     nb = 0;
665 :     pos = 0;
666 :     t = -gettime_usec();
667 :     while(1) {
668 :     xframe.bitstream = buf + pos;
669 :     xframe.length = buf_size - pos;
670 :     xframe.image = rgb_out;
671 :     xframe.stride = width;
672 :     xframe.colorspace = XVID_CSP_RGB24;
673 :     xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);
674 :     nb++;
675 :     pos += xframe.length;
676 :     if (with_chksum) {
677 :     int k = width*height;
678 :     uint32_t *ptr = (uint32_t *)rgb_out;
679 :     while(k-->0) chksum += *ptr++;
680 :     }
681 :     if (pos==buf_size)
682 :     break;
683 :     if (xerr!=XVID_ERR_OK) {
684 :     printf("decoding failed for frame #%d (err=%d)!\n", nb, xerr);
685 :     break;
686 :     }
687 :     }
688 :     t += gettime_usec();
689 :     if (t>0.)
690 :     printf( "%d frames decoded in %.3f s -> %.1f FPS\n", nb, t*1.e-6f, (float)(nb*1.e6f/t) );
691 :     if (with_chksum)
692 :     printf("checksum: 0x%.8x\n", chksum);
693 :    
694 :     End:
695 :     if (rgb_out!=0) free(rgb_out);
696 :     if (buf!=0) free(buf);
697 :     if (dechandle!=0) {
698 :     xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);
699 :     if (xerr!=XVID_ERR_OK)
700 :     printf("destroy-decoder failed (err=%d)!\n", xerr);
701 :     }
702 :     if (f!=0) fclose(f);
703 :     }
704 :    
705 :     /*********************************************************************
706 :     * non-regression tests
707 :     *********************************************************************/
708 :    
709 :     void test_bugs1()
710 :     {
711 :     CPU *cpu;
712 :    
713 :     printf( "\n ===== (de)quant4_intra saturation bug? =====\n" );
714 :    
715 :     for(cpu = cpu_short_list; cpu->name!=0; ++cpu)
716 :     {
717 :     int i;
718 :     int16_t Src[8*8], Dst[8*8];
719 :    
720 :     if (!init_cpu(cpu))
721 :     continue;
722 :    
723 :     for(i=0; i<64; ++i) Src[i] = i-32;
724 :     set_intra_matrix( get_default_intra_matrix() );
725 :     dequant4_intra(Dst, Src, 32, 5);
726 :     printf( "dequant4_intra with CPU=%s: ", cpu->name);
727 :     printf( " Out[]= " );
728 :     for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
729 :     printf( "\n" );
730 :     }
731 :    
732 :     printf( "\n ===== (de)quant4_inter saturation bug? =====\n" );
733 :    
734 :     for(cpu = cpu_short_list; cpu->name!=0; ++cpu)
735 :     {
736 :     int i;
737 :     int16_t Src[8*8], Dst[8*8];
738 :    
739 :     if (!init_cpu(cpu))
740 :     continue;
741 :    
742 :     for(i=0; i<64; ++i) Src[i] = i-32;
743 :     set_inter_matrix( get_default_inter_matrix() );
744 :     dequant4_inter(Dst, Src, 32);
745 :     printf( "dequant4_inter with CPU=%s: ", cpu->name);
746 :     printf( " Out[]= " );
747 :     for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
748 :     printf( "\n" );
749 :     }
750 :     }
751 :    
752 :     void test_dct_precision_diffs()
753 :     {
754 :     CPU *cpu;
755 :     short Blk[8*8], Blk0[8*8];
756 :    
757 :     printf( "\n ===== fdct/idct saturation diffs =====\n" );
758 :    
759 :     for(cpu = cpu_short_list; cpu->name!=0; ++cpu)
760 :     {
761 :     int i;
762 :    
763 :     if (!init_cpu(cpu))
764 :     continue;
765 :    
766 :     for(i=0; i<8*8; ++i) {
767 :     Blk0[i] = (i*7-i*i) & 0x7f;
768 :     Blk[i] = Blk0[i];
769 :     }
770 :    
771 :     fdct(Blk);
772 :     idct(Blk);
773 :     printf( " fdct+idct diffs with CPU=%s: \n", cpu->name );
774 :     for(i=0; i<8; ++i) {
775 :     int j;
776 :     for(j=0; j<8; ++j) printf( " %d ", Blk[i*8+j]-Blk0[i*8+j]);
777 :     printf("\n");
778 :     }
779 :     printf("\n");
780 :     }
781 :     }
782 :    
783 :    
784 :     /*********************************************************************
785 :     * main
786 :     *********************************************************************/
787 :    
788 :     int main(int argc, char *argv[])
789 :     {
790 :     int what = 0;
791 :     if (argc>1) what = atoi(argv[1]);
792 :     if (what==0 || what==1) test_dct();
793 :     if (what==0 || what==2) test_mb();
794 :     if (what==0 || what==3) test_sad();
795 :     if (what==0 || what==4) test_transfer();
796 :     if (what==0 || what==5) test_quant();
797 :     if (what==0 || what==6) test_cbp();
798 :    
799 :     if (what==8) {
800 :     int width, height;
801 :     if (argc<5) {
802 :     printf("usage: %s %d [bitstream] [width] [height]\n", argv[0], what);
803 :     return 1;
804 :     }
805 :     width = atoi(argv[3]);
806 :     height = atoi(argv[4]);
807 :     test_dec(argv[2], width, height, (argc>5));
808 :     }
809 :    
810 :     if (what==-1) {
811 :     test_bugs1();
812 :     test_dct_precision_diffs();
813 :     }
814 :     return 0;
815 :     }
816 :    
817 :     /*********************************************************************
818 :     * 'Reference' output (except for timing) on a PIII 1.13Ghz/linux
819 :     *********************************************************************/
820 :     /*
821 :    
822 :     ===== test fdct/idct =====
823 :     PLAINC - 2.631 usec iCrc=3 fCrc=-85
824 :     MMX - 0.596 usec iCrc=3 fCrc=-67
825 :     MMXEXT - 0.608 usec iCrc=3 fCrc=-67
826 :     SSE2 - 0.605 usec iCrc=3 fCrc=-67
827 :     3DNOW - skipped...
828 :     3DNOWE - skipped...
829 :    
830 :     === test block motion ===
831 :     PLAINC - interp- h-round0 1.031 usec iCrc=8107
832 :     PLAINC - round1 1.022 usec iCrc=8100
833 :     PLAINC - interp- v-round0 1.002 usec iCrc=8108
834 :     PLAINC - round1 1.011 usec iCrc=8105
835 :     PLAINC - interp-hv-round0 1.623 usec iCrc=8112
836 :     PLAINC - round1 1.621 usec iCrc=8103
837 :     PLAINC - interpolate8x8_c 0.229 usec iCrc=8107
838 :     ---
839 :     MMX - interp- h-round0 0.105 usec iCrc=8107
840 :     MMX - round1 0.105 usec iCrc=8100
841 :     MMX - interp- v-round0 0.106 usec iCrc=8108
842 :     MMX - round1 0.107 usec iCrc=8105
843 :     MMX - interp-hv-round0 0.145 usec iCrc=8112
844 :     MMX - round1 0.145 usec iCrc=8103
845 :     MMX - interpolate8x8_c 0.229 usec iCrc=8107
846 :     ---
847 :     MMXEXT - interp- h-round0 0.027 usec iCrc=8107
848 :     MMXEXT - round1 0.041 usec iCrc=8100
849 :     MMXEXT - interp- v-round0 0.027 usec iCrc=8108
850 :     MMXEXT - round1 0.040 usec iCrc=8105
851 :     MMXEXT - interp-hv-round0 0.070 usec iCrc=8112
852 :     MMXEXT - round1 0.066 usec iCrc=8103
853 :     MMXEXT - interpolate8x8_c 0.027 usec iCrc=8107
854 :     ---
855 :     SSE2 - interp- h-round0 0.106 usec iCrc=8107
856 :     SSE2 - round1 0.105 usec iCrc=8100
857 :     SSE2 - interp- v-round0 0.106 usec iCrc=8108
858 :     SSE2 - round1 0.106 usec iCrc=8105
859 :     SSE2 - interp-hv-round0 0.145 usec iCrc=8112
860 :     SSE2 - round1 0.145 usec iCrc=8103
861 :     SSE2 - interpolate8x8_c 0.237 usec iCrc=8107
862 :     ---
863 :     3DNOW - skipped...
864 :     3DNOWE - skipped...
865 :    
866 :     ====== test SAD ======
867 :     PLAINC - sad8 0.296 usec sad=3776
868 :     PLAINC - sad16 1.599 usec sad=27214
869 :     PLAINC - sad16bi 2.350 usec sad=26274
870 :     PLAINC - dev16 1.610 usec sad=3344
871 :     ---
872 :     MMX - sad8 0.057 usec sad=3776
873 :     MMX - sad16 0.178 usec sad=27214
874 :     MMX - sad16bi 2.381 usec sad=26274
875 :     MMX - dev16 0.312 usec sad=3344
876 :     ---
877 :     MMXEXT - sad8 0.036 usec sad=3776
878 :     MMXEXT - sad16 0.106 usec sad=27214
879 :     MMXEXT - sad16bi 0.182 usec sad=26274
880 :     MMXEXT - dev16 0.193 usec sad=3344
881 :     ---
882 :     SSE2 - sad8 0.057 usec sad=3776
883 :     SSE2 - sad16 0.178 usec sad=27214
884 :     SSE2 - sad16bi 2.427 usec sad=26274
885 :     SSE2 - dev16 0.313 usec sad=3344
886 :     ---
887 :     3DNOW - skipped...
888 :     3DNOWE - skipped...
889 :    
890 :     === test transfer ===
891 :     PLAINC - 8to16 0.124 usec crc=28288
892 :     PLAINC - 16to8 0.753 usec crc=28288
893 :     PLAINC - 8to8 0.041 usec crc=20352
894 :     PLAINC - 16to8add 0.916 usec crc=25536
895 :     PLAINC - 8to16sub 0.812 usec crc1=28064 crc2=16256
896 :     PLAINC - 8to16sub2 0.954 usec crc=20384
897 :     ---
898 :     MMX - 8to16 0.037 usec crc=28288
899 :     MMX - 16to8 0.016 usec crc=28288
900 :     MMX - 8to8 0.018 usec crc=20352
901 :     MMX - 16to8add 0.044 usec crc=25536
902 :     MMX - 8to16sub 0.065 usec crc1=28064 crc2=16256
903 :     MMX - 8to16sub2 0.110 usec crc=20384
904 :     ---
905 :     MMXEXT - 8to16 0.032 usec crc=28288
906 :     MMXEXT - 16to8 0.023 usec crc=28288
907 :     MMXEXT - 8to8 0.018 usec crc=20352
908 :     MMXEXT - 16to8add 0.041 usec crc=25536
909 :     MMXEXT - 8to16sub 0.065 usec crc1=28064 crc2=16256
910 :     MMXEXT - 8to16sub2 0.069 usec crc=20384
911 :     ---
912 :    
913 :     ===== test quant =====
914 :     PLAINC - quant4_intra 78.889 usec crc=55827
915 :     PLAINC - quant4_inter 71.957 usec crc=58201
916 :     PLAINC - dequant4_intra 34.968 usec crc=193340
917 :     PLAINC - dequant4_inter 40.792 usec crc=116483
918 :     PLAINC - quant_intra 30.845 usec crc=56885
919 :     PLAINC - quant_inter 34.842 usec crc=58056
920 :     PLAINC - dequant_intra 33.211 usec crc=-7936
921 :     PLAINC - dequant_inter 45.486 usec crc=-33217
922 :     ---
923 :     MMX - quant4_intra 9.030 usec crc=55827
924 :     MMX - quant4_inter 8.234 usec crc=58201
925 :     MMX - dequant4_intra 18.330 usec crc=193340
926 :     MMX - dequant4_inter 19.181 usec crc=116483
927 :     MMX - quant_intra 7.124 usec crc=56885
928 :     MMX - quant_inter 6.861 usec crc=58056
929 :     MMX - dequant_intra 9.048 usec crc=-7936
930 :     MMX - dequant_inter 8.203 usec crc=-33217
931 :     ---
932 :     MMXEXT - quant4_intra 9.045 usec crc=55827
933 :     MMXEXT - quant4_inter 8.232 usec crc=58201
934 :     MMXEXT - dequant4_intra 18.250 usec crc=193340
935 :     MMXEXT - dequant4_inter 19.256 usec crc=116483
936 :     MMXEXT - quant_intra 7.121 usec crc=56885
937 :     MMXEXT - quant_inter 6.855 usec crc=58056
938 :     MMXEXT - dequant_intra 9.034 usec crc=-7936
939 :     MMXEXT - dequant_inter 8.202 usec crc=-33217
940 :     ---
941 :    
942 :     ===== test cbp =====
943 :     PLAINC - calc_cbp#1 0.545 usec cbp=0x15
944 :     PLAINC - calc_cbp#2 0.540 usec cbp=0x38
945 :     PLAINC - calc_cbp#3 0.477 usec cbp=0xf
946 :     PLAINC - calc_cbp#4 0.739 usec cbp=0x5
947 :     ---
948 :     MMX - calc_cbp#1 0.136 usec cbp=0x15
949 :     MMX - calc_cbp#2 0.131 usec cbp=0x38
950 :     MMX - calc_cbp#3 0.132 usec cbp=0xf
951 :     MMX - calc_cbp#4 0.135 usec cbp=0x5
952 :     ---
953 :     SSE2 - calc_cbp#1 0.135 usec cbp=0x15
954 :     SSE2 - calc_cbp#2 0.131 usec cbp=0x38
955 :     SSE2 - calc_cbp#3 0.134 usec cbp=0xf
956 :     SSE2 - calc_cbp#4 0.136 usec cbp=0x5
957 :     ---
958 :     */

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4