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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 257, Fri Jul 5 14:54:15 2002 UTC revision 1641, Fri Sep 23 12:53:35 2005 UTC
# Line 1  Line 1 
1  /**************************************************************************  /*****************************************************************************
2   *   *
3   *      XVID MPEG-4 VIDEO CODEC - Unit tests and benches   *  XVID MPEG-4 VIDEO CODEC
4     *  - Unit tests and benches -
5     *
6     *  Copyright(C) 2002 Pascal Massimino <skal@planet-d.net>
7   *   *
8   *      This program is free software; you can redistribute it and/or modify   *      This program is free software; you can redistribute it and/or modify
9   *      it under the terms of the GNU General Public License as published by   *      it under the terms of the GNU General Public License as published by
# Line 14  Line 17 
17   *   *
18   *      You should have received a copy of the GNU General Public License   *      You should have received a copy of the GNU General Public License
19   *      along with this program; if not, write to the Free Software   *      along with this program; if not, write to the Free Software
20   *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21     *
22     * $Id: xvid_bench.c,v 1.25 2005-09-23 12:53:35 suxen_drol Exp $
23   *   *
24   *************************************************************************/   ****************************************************************************/
25    
26  /************************************************************************  /*****************************************************************************
27   *   *
28   *  'Reference' output is at the end of file.   *  'Reference' output is at the end of file.
  *  Don't take the checksums and crc too seriouly, they aren't  
  *  bullet-proof...  
29   *   *
30   *   compiles with something like:   *   compiles with something like:
31   *   gcc -o xvid_bench xvid_bench.c  -I../src/ -lxvidcore -lm   *   gcc -o xvid_bench xvid_bench.c  -I../src/ -lxvidcore -lm
32   *   *
33   *      History:   ****************************************************************************/
  *  
  *      06.06.2002  initial coding      -Skal-  
  *  
  *************************************************************************/  
34    
35  #include <stdio.h>  #include <stdio.h>
36  #include <stdlib.h>  #include <stdlib.h>
37  #include <sys/time.h>  // for gettimeofday  #include <string.h>    /* for memset */
 #include <string.h>    // for memset  
38  #include <assert.h>  #include <assert.h>
39    
40    #ifndef WIN32
41    #include <sys/time.h>   /* for gettimeofday */
42    #else
43    #include <time.h>
44    #endif
45    
46    
47  #include "xvid.h"  #include "xvid.h"
48    
49  // inner guts  // inner guts
# Line 47  Line 52 
52  #include "image/colorspace.h"  #include "image/colorspace.h"
53  #include "image/interpolate8x8.h"  #include "image/interpolate8x8.h"
54  #include "utils/mem_transfer.h"  #include "utils/mem_transfer.h"
55  #include "quant/quant_h263.h"  #include "quant/quant.h"
 #include "quant/quant_mpeg4.h"  
56  #include "motion/sad.h"  #include "motion/sad.h"
57  #include "utils/emms.h"  #include "utils/emms.h"
58  #include "utils/timer.h"  #include "utils/timer.h"
59  #include "quant/quant_matrix.c"  #include "quant/quant_matrix.c"
60  #include "bitstream/cbp.h"  #include "bitstream/cbp.h"
61    
62  const int speed_ref = 100;  // on slow machines, decrease this value  #include <math.h>
63    
64    #ifndef M_PI
65    #define M_PI            3.14159265358979323846
66    #endif
67    
68    int speed_ref = 100;  /* on slow machines, decrease this value */
69    int verbose = 0;
70    unsigned int cpu_mask;
71    
72  /*********************************************************************  /*********************************************************************
73   * misc   * misc
# Line 64  Line 76 
76   /* returns time in micro-s*/   /* returns time in micro-s*/
77  double gettime_usec()  double gettime_usec()
78  {  {
79    #ifndef WIN32
80    struct timeval  tv;    struct timeval  tv;
81    gettimeofday(&tv, 0);    gettimeofday(&tv, 0);
82    return tv.tv_sec*1.0e6 + tv.tv_usec;    return tv.tv_sec*1.0e6 + tv.tv_usec;
83    #else
84            clock_t clk;
85            clk = clock();
86            return clk * 1000. / CLOCKS_PER_SEC;  /* clock() returns time in Milliseconds */
87    #endif
88  }  }
89    
90   /* returns squared deviates (mean(v*v)-mean(v)^2) of a 8x8 block */   /* returns squared deviates (mean(v*v)-mean(v)^2) of a 8x8 block */
# Line 94  Line 112 
112    unsigned int cpu;    unsigned int cpu;
113  } CPU;  } CPU;
114    
115  CPU cpu_list[] =  CPU cpu_list[] = {
116  { { "PLAINC", 0 }          { "PLAINC ", 0 },
117  , { "MMX   ", XVID_CPU_MMX }  #ifdef ARCH_IS_IA32
118  , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }          { "MMX    ", XVID_CPU_MMX },
119  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }          { "MMXEXT ", XVID_CPU_MMXEXT | XVID_CPU_MMX },
120  , { "3DNOW ", XVID_CPU_3DNOW }          { "SSE2   ", XVID_CPU_SSE2 | XVID_CPU_MMX },
121  , { "3DNOWE", XVID_CPU_3DNOWEXT }          { "3DNOW  ", XVID_CPU_3DNOW },
122            { "3DNOWE ", XVID_CPU_3DNOW | XVID_CPU_3DNOWEXT },
123  //, { "TSC   ", XVID_CPU_TSC }  #endif
124  , { 0, 0 } }  #ifdef ARCH_IS_PPC
125            { "ALTIVEC", XVID_CPU_ALTIVEC },
126  , cpu_short_list[] =  #endif
127  { { "PLAINC", 0 }  #ifdef ARCH_IS_X86_64
128  , { "MMX   ", XVID_CPU_MMX }          { "X86_64 ", XVID_CPU_ASM},
129  , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }  #endif
130  , { "IA64  ", XVID_CPU_IA64 }  #ifdef ARCH_IS_IA64
131  , { 0, 0 } }  //      { "IA64   ", XVID_CPU_IA64 },
132    #endif
133  , cpu_short_list2[] =  //      { "TSC    ", XVID_CPU_TSC },
134  { { "PLAINC", 0 }          { 0, 0 }
135  , { "MMX   ", XVID_CPU_MMX }  };
 , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }  
 , { 0, 0 } };  
136    
137    
138  int init_cpu(CPU *cpu)  int init_cpu(CPU *cpu)
139  {  {
140    int xerr, cpu_type;          xvid_gbl_info_t xinfo;
141    XVID_INIT_PARAM xinit;  
142            /* Get the available CPU flags */
143            memset(&xinfo, 0, sizeof(xinfo));
144            xinfo.version = XVID_VERSION;
145            xvid_global(NULL, XVID_GBL_INFO, &xinfo, NULL);
146    
147    cpu_type = check_cpu_features() & cpu->cpu;          /* Are we trying to test a subset of the host CPU features */
148    xinit.cpu_flags = cpu_type | XVID_CPU_FORCE;          if ((xinfo.cpu_flags & cpu->cpu) == cpu->cpu) {
149    //    xinit.cpu_flags = XVID_CPU_MMX | XVID_CPU_FORCE;                  int xerr;
150    xerr = xvid_init(NULL, 0, &xinit, NULL);                  xvid_gbl_init_t xinit;
151    if (cpu->cpu>0 && (cpu_type==0 || xerr!=XVID_ERR_OK)) {                  memset(&xinit, 0, sizeof(xinit));
152      printf( "%s - skipped...\n", cpu->name );                  xinit.cpu_flags = cpu->cpu | XVID_CPU_FORCE;
153                    xinit.version = XVID_VERSION;
154                    xerr = xvid_global(NULL, XVID_GBL_INIT, &xinit, NULL);
155                    if (xerr==XVID_ERR_FAIL) {
156                            /* libxvidcore failed to init */
157      return 0;      return 0;
158    }    }
159            } else {
160                    /* The host CPU doesn't support some required feature for this test */
161                    return(0);
162            }
163    return 1;    return 1;
164  }  }
165    
166    #define CRC32_REMAINDER 0xCBF43926
167    #define CRC32_INITIAL 0xffffffff
168    
169    #define DO1(c, crc) ((crc) = crc32tab[((unsigned int)((crc)>>24) ^ (*c++)) & 0xff] ^ ((crc) << 8))
170    #define DO2(c, crc)  DO1(c, crc); DO1(c, crc);
171    #define DO4(c, crc)  DO2(c, crc); DO2(c, crc);
172    #define DO8(c, crc)  DO4(c, crc); DO4(c, crc);
173    
174    /******************************************************************************
175    * Precomputed AAL5 CRC32 lookup table
176    ******************************************************************************/
177    
178    static unsigned long crc32tab[256] = {
179    
180            0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
181            0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
182            0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
183            0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
184            0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
185            0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
186            0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
187            0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
188            0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
189            0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
190            0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
191            0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
192            0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
193            0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
194            0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
195            0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
196            0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
197            0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
198            0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
199            0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
200            0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
201            0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
202            0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
203            0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
204            0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
205            0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
206            0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
207            0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
208            0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
209            0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
210            0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
211            0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
212            0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
213            0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
214            0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
215            0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
216            0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
217            0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
218            0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
219            0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
220            0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
221            0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
222            0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
223            0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
224            0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
225            0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
226            0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
227            0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
228            0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
229            0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
230            0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
231            0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
232            0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
233            0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
234            0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
235            0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
236            0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
237            0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
238            0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
239            0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
240            0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
241            0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
242            0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
243            0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
244    
245    };
246    
247    uint32_t
248    calc_crc(uint8_t *mem, int len, uint32_t crc)
249    {
250            while( len >= 8) {
251                    DO8(mem, crc);
252                    len -= 8;
253            }
254    
255            while( len ) {
256                    DO1(mem, crc);
257                    len--;
258            }
259    
260            return crc;
261    }
262    
263    void byte_swap(uint8_t *mem, int len, int element_size) {
264    #ifdef ARCH_IS_BIG_ENDIAN
265            int i;
266    
267            if(element_size == 1) {
268                    /* No need to swap */
269            } else if(element_size == 2) {
270                    uint8_t temp[2];
271    
272                    for(i=0; i < (len/2); i++ ) {
273                            temp[0] = mem[0];
274                            temp[1] = mem[1];
275                            mem[0] = temp[1];
276                            mem[1] = temp[0];
277    
278                            mem += 2;
279                    }
280            } else if(element_size == 4) {
281                    uint8_t temp[4];
282    
283                    for(i=0; i < (len/4); i++ ) {
284                            temp[0] = mem[0];
285                            temp[1] = mem[1];
286                            temp[2] = mem[2];
287                            temp[3] = mem[3];
288                            mem[0] = temp[3];
289                            mem[1] = temp[2];
290                            mem[2] = temp[1];
291                            mem[3] = temp[0];
292    
293                            mem += 4;
294                    }
295            } else {
296                    printf("ERROR: byte_swap unsupported element_size(%u)\n", element_size);
297            }
298    #endif
299    }
300    
301  /*********************************************************************  /*********************************************************************
302   * test DCT   * test DCT
303   *********************************************************************/   *********************************************************************/
# Line 147  Line 310 
310    int tst;    int tst;
311    CPU *cpu;    CPU *cpu;
312    int i;    int i;
313    short iDst0[8*8], iDst[8*8], fDst[8*8];          DECLARE_ALIGNED_MATRIX(iDst0, 8, 8, short, 16);
314            DECLARE_ALIGNED_MATRIX(iDst,  8, 8, short, 16);
315            DECLARE_ALIGNED_MATRIX(fDst,  8, 8, short, 16);
316    double overhead;    double overhead;
317    
318    printf( "\n ===== test fdct/idct =====\n" );    printf( "\n ===== test fdct/idct =====\n" );
# Line 163  Line 328 
328    
329    for(cpu = cpu_list; cpu->name!=0; ++cpu)    for(cpu = cpu_list; cpu->name!=0; ++cpu)
330    {    {
331      double t;                  double t, PSNR, MSE;
     int iCrc, fCrc;  
332    
333      if (!init_cpu(cpu))      if (!init_cpu(cpu))
334        continue;        continue;
# Line 180  Line 344 
344      }      }
345      emms();      emms();
346      t = (gettime_usec() - t - overhead) / nb_tests;      t = (gettime_usec() - t - overhead) / nb_tests;
347      iCrc=0; fCrc=0;                  MSE = 0.;
348      for(i=0; i<8*8; ++i) {      for(i=0; i<8*8; ++i) {
349        iCrc += ABS(iDst[i] - iDst0[i]);                          double delta = 1.0*(iDst[i] - iDst0[i]);
350        fCrc += fDst[i]^i;                          MSE += delta*delta;
351      }      }
352      printf( "%s -  %.3f usec       iCrc=%d  fCrc=%d\n",                  PSNR = (MSE==0.) ? 1.e6 : -4.3429448*log( MSE/64. );
353        cpu->name, t, iCrc, fCrc );                  printf( "%s -  %.3f usec       PSNR=%.3f  MSE=%.3f %s\n",
354        // the norm tolerates ~1 bit of diff per coeff                                  cpu->name, t, PSNR, MSE,
355      if (ABS(iCrc)>=64) printf( "*** CRC ERROR! ***\n" );                                  (ABS(MSE)>=64)? "| ERROR" :"");
356    }    }
357  }  }
358    
# Line 202  Line 366 
366    int tst;    int tst;
367    CPU *cpu;    CPU *cpu;
368    int i;    int i;
369    uint8_t Cur[16*16], Ref1[16*16], Ref2[16*16];          DECLARE_ALIGNED_MATRIX(Cur,  16, 16, uint8_t, 16);
370            DECLARE_ALIGNED_MATRIX(Ref1, 16, 16, uint8_t, 16);
371            DECLARE_ALIGNED_MATRIX(Ref2, 16, 16, uint8_t, 16);
372    
373    printf( "\n ======  test SAD ======\n" );    printf( "\n ======  test SAD ======\n" );
374    for(i=0; i<16*16;++i) {    for(i=0; i<16*16;++i) {
# Line 223  Line 389 
389      for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);      for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);
390      emms();      emms();
391      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
392      printf( "%s - sad8    %.3f usec       sad=%d\n", cpu->name, t, s );                  printf("%s - sad8    %.3f usec       sad=%d %s\n",
393      if (s!=3776) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
394                               (s!=3776)?"| ERROR": "" );
395    
396      t = gettime_usec();      t = gettime_usec();
397      emms();      emms();
398      for(tst=0; tst<nb_tests; ++tst) s = sad16(Cur, Ref1, 16, -1);      for(tst=0; tst<nb_tests; ++tst) s = sad16(Cur, Ref1, 16, -1);
399      emms();      emms();
400      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
401      printf( "%s - sad16   %.3f usec       sad=%d\n", cpu->name, t, s );                  printf("%s - sad16   %.3f usec       sad=%d %s\n",
402      if (s!=27214) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
403                               (s!=27214)?"| ERROR": "" );
404    
405      t = gettime_usec();      t = gettime_usec();
406      emms();      emms();
407      for(tst=0; tst<nb_tests; ++tst) s = sad16bi(Cur, Ref1, Ref2, 16);      for(tst=0; tst<nb_tests; ++tst) s = sad16bi(Cur, Ref1, Ref2, 16);
408      emms();      emms();
409      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
410      printf( "%s - sad16bi %.3f usec       sad=%d\n", cpu->name, t, s );                  printf( "%s - sad16bi %.3f usec       sad=%d %s\n",
411      if (s!=26274) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
412                                    (s!=26274)?"| ERROR": "" );
413    
414      t = gettime_usec();      t = gettime_usec();
415      emms();      emms();
416      for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);      for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);
417      emms();      emms();
418      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
419      printf( "%s - dev16   %.3f usec       sad=%d\n", cpu->name, t, s );                  printf( "%s - dev16   %.3f usec       sad=%d %s\n",
420      if (s!=3344) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
421                                    (s!=3344)?"| ERROR": "" );
422    
423      printf( " --- \n" );      printf( " --- \n" );
424    }    }
# Line 266  Line 436 
436  #define LEAVE \  #define LEAVE \
437      emms();                             \      emms();                             \
438      t = (gettime_usec() - t) / nb_tests;  \      t = (gettime_usec() - t) / nb_tests;  \
439      iCrc = 0;                           \          iCrc = calc_crc((uint8_t*)Dst, sizeof(Dst), CRC32_INITIAL)
     for(i=0; i<16*8; ++i) { iCrc += Dst[i]^i; }  
440    
441  #define TEST_MB(FUNC, R)                \  #define TEST_MB(FUNC, R)                \
442      ENTER                               \      ENTER                               \
# Line 285  Line 454 
454    const int nb_tests = 2000*speed_ref;    const int nb_tests = 2000*speed_ref;
455    CPU *cpu;    CPU *cpu;
456    const uint8_t Src0[16*9] = {    const uint8_t Src0[16*9] = {
457          // try to have every possible combinaison of rounding...                  /* try to have every possible combinaison of rounding... */
458        0, 0, 1, 0, 2, 0, 3, 0, 4             ,0,0,0, 0,0,0,0                  0, 0, 1, 0, 2, 0, 3, 0, 4             ,0,0,0, 0,0,0,0,
459      , 0, 1, 1, 1, 2, 1, 3, 1, 3             ,0,0,0, 0,0,0,0                  0, 1, 1, 1, 2, 1, 3, 1, 3             ,0,0,0, 0,0,0,0,
460      , 0, 2, 1, 2, 2, 2, 3, 2, 2             ,0,0,0, 0,0,0,0                  0, 2, 1, 2, 2, 2, 3, 2, 2             ,0,0,0, 0,0,0,0,
461      , 0, 3, 1, 3, 2, 3, 3, 3, 1             ,0,0,0, 0,0,0,0                  0, 3, 1, 3, 2, 3, 3, 3, 1             ,0,0,0, 0,0,0,0,
462      , 1, 3, 0, 2, 1, 0, 2, 3, 4             ,0,0,0, 0,0,0,0                  1, 3, 0, 2, 1, 0, 2, 3, 4             ,0,0,0, 0,0,0,0,
463      , 2, 2, 1, 2, 0, 1, 3, 5, 3             ,0,0,0, 0,0,0,0                  2, 2, 1, 2, 0, 1, 3, 5, 3             ,0,0,0, 0,0,0,0,
464      , 3, 1, 2, 3, 1, 2, 2, 6, 2             ,0,0,0, 0,0,0,0                  3, 1, 2, 3, 1, 2, 2, 6, 2             ,0,0,0, 0,0,0,0,
465      , 1, 0, 1, 3, 0, 3, 1, 6, 1             ,0,0,0, 0,0,0,0                  1, 0, 1, 3, 0, 3, 1, 6, 1             ,0,0,0, 0,0,0,0,
466      , 4, 3, 2, 1, 2, 3, 4, 0, 3             ,0,0,0, 0,0,0,0                  4, 3, 2, 1, 2, 3, 4, 0, 3             ,0,0,0, 0,0,0,0
467    };    };
468    uint8_t Dst[16*8] = {0};    uint8_t Dst[16*8] = {0};
469    
# Line 309  Line 478 
478        continue;        continue;
479    
480      TEST_MB(interpolate8x8_halfpel_h, 0);      TEST_MB(interpolate8x8_halfpel_h, 0);
481      printf( "%s - interp- h-round0 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s - interp- h-round0 %.3f usec       crc32=0x%08x %s\n",
482      if (iCrc!=8107) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
483                               (iCrc!=0x115381ba)?"| ERROR": "" );
484    
485      TEST_MB(interpolate8x8_halfpel_h, 1);      TEST_MB(interpolate8x8_halfpel_h, 1);
486      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
487      if (iCrc!=8100) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
488                               (iCrc!=0x2b1f528f)?"| ERROR": "" );
489    
490    
491      TEST_MB(interpolate8x8_halfpel_v, 0);      TEST_MB(interpolate8x8_halfpel_v, 0);
492      printf( "%s - interp- v-round0 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s - interp- v-round0 %.3f usec       crc32=0x%08x %s\n",
493      if (iCrc!=8108) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
494                               (iCrc!=0x423cdcc7)?"| ERROR": "" );
495    
496      TEST_MB(interpolate8x8_halfpel_v, 1);      TEST_MB(interpolate8x8_halfpel_v, 1);
497      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
498      if (iCrc!=8105) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
499                               (iCrc!=0x42202efe)?"| ERROR": "" );
500    
501    
502      TEST_MB(interpolate8x8_halfpel_hv, 0);      TEST_MB(interpolate8x8_halfpel_hv, 0);
503      printf( "%s - interp-hv-round0 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s - interp-hv-round0 %.3f usec       crc32=0x%08x %s\n",
504      if (iCrc!=8112) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
505                               (iCrc!=0xd198d387)?"| ERROR": "" );
506    
507      TEST_MB(interpolate8x8_halfpel_hv, 1);      TEST_MB(interpolate8x8_halfpel_hv, 1);
508      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
509      if (iCrc!=8103) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
510                               (iCrc!=0x9ecfd921)?"| ERROR": "" );
511    
512    
513                    /* this is a new function, as of 06.06.2002 */
514    #if 0
515                    TEST_MB2(interpolate8x8_avrg);
516                    printf("%s - interpolate8x8_c %.3f usec       crc32=0x%08x %s\n",
517                               cpu->name, t, iCrc,
518                               (iCrc!=8107)?"| ERROR": "" );
519    #endif
520    
521      printf( " --- \n" );      printf( " --- \n" );
522    }    }
# Line 367  Line 551 
551      }                                         \      }                                         \
552      emms();                                   \      emms();                                   \
553      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
554      s = 0; for(i=0; i<8*32; ++i) { s += (DST)[i]^i; }  byte_swap((uint8_t*)(DST), 8*32*sizeof((DST)[0]), sizeof((DST)[0]));  \
555    s = calc_crc((uint8_t*)(DST), 8*32*sizeof((DST)[0]), CRC32_INITIAL)
556    
557  #define TEST_TRANSFER(FUNC, DST, SRC)         \  #define TEST_TRANSFER(FUNC, DST, SRC)         \
558      TEST_TRANSFER_BEGIN(DST);                 \      TEST_TRANSFER_BEGIN(DST);                 \
# Line 393  Line 578 
578      }                                         \      }                                         \
579      emms();                                   \      emms();                                   \
580      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
581      s = 0; for(i=0; i<8*32; ++i) { s += (DST)[i]; }  byte_swap((uint8_t*)(DST), 8*32*sizeof((DST)[0]), sizeof((DST)[0]));  \
582    s = calc_crc((uint8_t*)(DST), 8*32*sizeof((DST)[0]), CRC32_INITIAL)
583    
584  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \
585      TEST_TRANSFER2_BEGIN(DST,SRC);            \      TEST_TRANSFER2_BEGIN(DST,SRC);            \
# Line 410  Line 596 
596    const int nb_tests = 4000*speed_ref;    const int nb_tests = 4000*speed_ref;
597    int i;    int i;
598    CPU *cpu;    CPU *cpu;
599    uint8_t  Src8[8*32], Dst8[8*32], Ref1[8*32], Ref2[8*32];  //      uint8_t  Src8[8*32], Dst8[8*32], Ref1[8*32], Ref2[8*32];
600    int16_t Src16[8*32], Dst16[8*32];  //      int16_t Src16[8*32], Dst16[8*32];
601      DECLARE_ALIGNED_MATRIX(Src8, 8, 32, uint8_t, CACHE_LINE);
602      DECLARE_ALIGNED_MATRIX(Dst8, 8, 32, uint8_t, CACHE_LINE);
603      DECLARE_ALIGNED_MATRIX(Ref1, 8, 32, uint8_t, CACHE_LINE);
604      DECLARE_ALIGNED_MATRIX(Ref2, 8, 32, uint8_t, CACHE_LINE);
605      DECLARE_ALIGNED_MATRIX(Src16, 8, 32, uint16_t, CACHE_LINE);
606      DECLARE_ALIGNED_MATRIX(Dst16, 8, 32, uint16_t, CACHE_LINE);
607    
608    printf( "\n ===  test transfer ===\n" );    printf( "\n ===  test transfer ===\n" );
609    
610    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
611    {    {
612      double t, overhead;      double t, overhead;
613      int tst, s;      int tst, s;
# Line 424  Line 616 
616        continue;        continue;
617    
618      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);
619      printf( "%s - 8to16     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16     %.3f usec       crc32=0x%08x %s\n",
620      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
621                               (s!=0x115814bb)?"| ERROR": "");
622    
623      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);
624      printf( "%s - 16to8     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf( "%s - 16to8     %.3f usec       crc32=0x%08x %s\n",
625      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
626                                    (s!=0xee7ccbb4)?"| ERROR": "");
627    
628      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);
629      printf( "%s - 8to8      %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to8      %.3f usec       crc32=0x%08x %s\n",
630      if (s!=20352) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
631                               (s!=0xd37b3295)?"| ERROR": "");
632    
633      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);
634      printf( "%s - 16to8add  %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 16to8add  %.3f usec       crc32=0x%08x %s\n",
635      if (s!=25536) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
636                               (s!=0xdd817bf4)?"| ERROR": "" );
637    
638      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);
639      printf( "%s - 8to16sub  %.3f usec       crc1=%d ", cpu->name, t, s );                  {
640      if (s!=28064) printf( "*** CRC ERROR! ***\n" );                          int s1, s2;
641      s = 0; for(i=0; i<8*32; ++i) { s += (Src8[i]-Ref1[i])&i; }                          s1 = calc_crc((uint8_t*)Dst16, 8*32*sizeof(Dst16[0]), CRC32_INITIAL);
642      printf( "crc2=%d\n", s);                          s2 = calc_crc((uint8_t*)Src8, 8*32*sizeof(Src8[0]), CRC32_INITIAL);
643      if (s!=16256) printf( "*** CRC ERROR! ***\n" );                          printf("%s - 8to16sub  %.3f usec       crc32(1)=0x%08x crc32(2)=0x%08x %s %s\n",
644                                       cpu->name, t, s1, s2,
645                                       (s1!=0xa1e07163)?"| ERROR1": "",
646                                       (s2!=0xd86c5d23)?"| ERROR2": "" );
647                    }
648    
649      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);
650      printf( "%s - 8to16sub2 %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16sub2 %.3f usec       crc32=0x%08x %s\n",
651      if (s!=20384) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
652                               (s!=0x99b6c4c7)?"| ERROR": "" );
653    
654      printf( " --- \n" );      printf( " --- \n" );
655    }    }
# Line 460  Line 661 
661    
662  #define TEST_QUANT(FUNC, DST, SRC)            \  #define TEST_QUANT(FUNC, DST, SRC)            \
663      t = gettime_usec();                       \      t = gettime_usec();                       \
664    for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
665      for(i=0; i<8*8; ++i) Quant[i] = qm;       \
666      set_inter_matrix( mpeg_quant_matrices, Quant );                \
667      emms();                                   \      emms();                                   \
668      for(q=1; q<=max_Q; ++q) {                 \
669      for(tst=0; tst<nb_tests; ++tst)           \      for(tst=0; tst<nb_tests; ++tst)           \
670        for(s=0, q=1; q<=max_Q; ++q) {          \            (FUNC)((DST), (SRC), q, mpeg_quant_matrices);              \
671          (FUNC)((DST), (SRC), q);              \          byte_swap((uint8_t*)(DST), 64*sizeof((DST)[0]), sizeof((DST)[0]));  \
672          for(i=0; i<64; ++i) s+=(DST)[i]^i;    \          s = calc_crc((uint8_t*)(DST), 64*sizeof((DST)[0]), s); \
673        }                                       \        }                                       \
674      emms();                                   \      emms();                                   \
675      t = (gettime_usec()-t-overhead)/nb_tests;  }                                           \
676    t = (gettime_usec()-t-overhead)/nb_tests/qm
677    
678  #define TEST_QUANT2(FUNC, DST, SRC, MULT)     \  #define TEST_QUANT2(FUNC, DST, SRC)             \
679      t = gettime_usec();                       \      t = gettime_usec();                       \
680    for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
681      for(i=0; i<8*8; ++i) Quant[i] = qm;       \
682      set_intra_matrix( mpeg_quant_matrices, Quant );                \
683      emms();                                   \      emms();                                   \
684      for(q=1; q<=max_Q; ++q) {                 \
685      for(tst=0; tst<nb_tests; ++tst)           \      for(tst=0; tst<nb_tests; ++tst)           \
686        for(s=0, q=1; q<=max_Q; ++q) {          \            (FUNC)((DST), (SRC), q, q, mpeg_quant_matrices);           \
687          (FUNC)((DST), (SRC), q, MULT);        \          byte_swap((uint8_t*)(DST), 64*sizeof((DST)[0]), sizeof((DST)[0]));  \
688          for(i=0; i<64; ++i) s+=(DST)[i]^i;    \          s = calc_crc((uint8_t*)(DST), 64*sizeof((DST)[0]), s); \
689        }                                       \        }                                       \
690      emms();                                   \      emms();                                   \
691      t = (gettime_usec()-t-overhead)/nb_tests;  }                                           \
692    t = (gettime_usec()-t-overhead)/nb_tests/qm
693    
694    #define TEST_INTRA(REFFUNC, NEWFUNC, RANGE)              \
695    { int i,q,s;\
696            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16); \
697      DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16); \
698      DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16); \
699      for(q=1;q<=max_Q;q++)          \
700        for(s=-RANGE;s<RANGE;s++) { \
701          for(i=0;i<64;i++) Src[i]=s; \
702          (REFFUNC)((Dst),(Src),q,q,mpeg_quant_matrices);   \
703          (NEWFUNC)((Dst2),(Src),q,q,mpeg_quant_matrices);  \
704          for(i=0;i<64;i++)     \
705            if(Dst[i]!=Dst2[i]) printf("ERROR : " #NEWFUNC " i%d quant:%d input:%d C_result:%d ASM_result:%d\n",i,q,s,Dst[i],Dst2[i]);  \
706        }      \
707    }
708    
709    #define TEST_INTER(REFFUNC, NEWFUNC, RANGE)              \
710    { int i,q,s;  \
711            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16); \
712      DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16); \
713      DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16); \
714      for(q=1;q<=max_Q;q++)  \
715        for(s=-RANGE;s<RANGE;s++) {   \
716          for(i=0;i<64;i++) Src[i]=s; \
717          (REFFUNC)((Dst),(Src),q,mpeg_quant_matrices);  \
718          (NEWFUNC)((Dst2),(Src),q,mpeg_quant_matrices); \
719          emms();           \
720          for(i=0;i<64;i++) \
721            if(Dst[i]!=Dst2[i]) printf("ERROR : " #NEWFUNC " i%d quant:%d input:%d C_result:%d ASM_result:%d\n",i,q,s,Dst[i],Dst2[i]); \
722        } \
723    }
724    
725  void test_quant()  void test_quant()
726  {  {
727    const int nb_tests = 150*speed_ref;          const int nb_tests = 1*speed_ref;
728    const int max_Q = 31;    const int max_Q = 31;
729    int i;          DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
730    
731            int i, qm;
732    CPU *cpu;    CPU *cpu;
733    int16_t  Src[8*8], Dst[8*8];          DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
734            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
735            DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16);
736            uint8_t Quant[8*8];
737    
738    printf( "\n =====  test quant =====\n" );    printf( "\n =====  test quant =====\n" );
739    
740    /* we deliberately enfringe the norm's specified range [-127,127], */
741    /* to test the robustness of the iquant module */
742    for(i=0; i<64; ++i) {    for(i=0; i<64; ++i) {
743      Src[i] = i-32;                  Src[i] = 1 + (i-32) * (i&6);
744      Dst[i] = 0;      Dst[i] = 0;
745    }    }
746    
747            for(cpu = cpu_list; cpu->name!=0; ++cpu)
   for(cpu = cpu_short_list; cpu->name!=0; ++cpu)  
748    {    {
749      double t, overhead;      double t, overhead;
750      int tst, s, q;                  int tst, q;
751                    uint32_t s;
752    
753      if (!init_cpu(cpu))      if (!init_cpu(cpu))
754        continue;        continue;
755    
756      set_inter_matrix( get_default_inter_matrix() );                  // exhaustive tests to compare against the (ref) C-version
757      set_intra_matrix( get_default_intra_matrix() );                  TEST_INTRA(quant_h263_intra_c,   quant_h263_intra,    2048);
758                    TEST_INTRA(dequant_h263_intra_c, dequant_h263_intra , 512 );
759                    TEST_INTER(quant_h263_inter_c,   quant_h263_inter ,   2048);
760                    TEST_INTER(dequant_h263_inter_c, dequant_h263_inter , 512 );
761    
762      overhead = -gettime_usec();      overhead = -gettime_usec();
763      for(tst=0; tst<nb_tests; ++tst)                  for(s=0,qm=1; qm<=255; ++qm) {
764        for(s=0, q=1; q<=max_Q; ++q)                          for(i=0; i<8*8; ++i) Quant[i] = qm;
765          for(i=0; i<64; ++i) s+=Dst[i]^i;                          set_inter_matrix(mpeg_quant_matrices, Quant );
766                            for(q=1; q<=max_Q; ++q)
767                                    for(i=0; i<64; ++i) s+=Dst[i]^i^qm;
768                    }
769      overhead += gettime_usec();      overhead += gettime_usec();
770    
771      TEST_QUANT2(quant4_intra, Dst, Src, 7);                  TEST_QUANT2(quant_mpeg_intra, Dst, Src);
772      printf( "%s -   quant4_intra %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s -   quant_mpeg_intra %.3f usec       crc32=0x%08x %s\n",
773      if (s!=55827) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
774                               (s!=0xfd6a21a4)? "| ERROR": "");
775      TEST_QUANT(quant4_inter, Dst, Src);  
776      printf( "%s -   quant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT(quant_mpeg_inter, Dst, Src);
777      if (s!=58201) printf( "*** CRC ERROR! ***\n" );                  printf("%s -   quant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
778                               cpu->name, t, s,
779                               (s!=0xf6de7757)?"| ERROR": "");
780      TEST_QUANT2(dequant4_intra, Dst, Src, 7);  
781      printf( "%s - dequant4_intra %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(dequant_mpeg_intra, Dst, Src);
782      if (s!=193340) printf( "*** CRC ERROR! ***\n" );                  printf("%s - dequant_mpeg_intra %.3f usec       crc32=0x%08x %s\n",
783                               cpu->name, t, s,
784      TEST_QUANT(dequant4_inter, Dst, Src);                             (s!=0x2def7bc7)?"| ERROR": "");
785      printf( "%s - dequant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );  
786      if (s!=116483) printf( "*** CRC ERROR! ***\n" );                  TEST_QUANT(dequant_mpeg_inter, Dst, Src);
787                    printf("%s - dequant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
788      TEST_QUANT2(quant_intra, Dst, Src, 7);                             cpu->name, t, s,
789      printf( "%s -    quant_intra %.3f usec       crc=%d\n", cpu->name, t, s );                             (s!=0xd878c722)?"| ERROR": "");
790      if (s!=56885) printf( "*** CRC ERROR! ***\n" );  
791                    TEST_QUANT2(quant_h263_intra, Dst, Src);
792      TEST_QUANT(quant_inter, Dst, Src);                  printf("%s -   quant_h263_intra %.3f usec       crc32=0x%08x %s\n",
793      printf( "%s -    quant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                             cpu->name, t, s,
794      if (s!=58056) printf( "*** CRC ERROR! ***\n" );                             (s!=0x2eba9d43)?"| ERROR": "");
795    
796      TEST_QUANT2(dequant_intra, Dst, Src, 7);                  TEST_QUANT(quant_h263_inter, Dst, Src);
797      printf( "%s -  dequant_intra %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s -   quant_h263_inter %.3f usec       crc32=0x%08x %s\n",
798      if (s!=-7936) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
799                               (s!=0xbd315a7e)?"| ERROR": "");
800      TEST_QUANT(dequant_inter, Dst, Src);  
801      printf( "%s -  dequant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(dequant_h263_intra, Dst, Src);
802  //    { int k,l; for(k=0; k<8; ++k) { for(l=0; l<8; ++l) printf( "[%.4d]", Dst[k*8+l]); printf("\n"); } }                  printf("%s - dequant_h263_intra %.3f usec       crc32=0x%08x %s\n",
803      if (s!=-33217) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
804                               (s!=0x9841212a)?"| ERROR": "");
805    
806                    TEST_QUANT(dequant_h263_inter, Dst, Src);
807                    printf("%s - dequant_h263_inter %.3f usec       crc32=0x%08x %s\n",
808                               cpu->name, t, s,
809                               (s!=0xe7df8fba)?"| ERROR": "");
810    
811                    printf( " --- \n" );
812            }
813    }
814    
815    /*********************************************************************
816     * test distortion operators
817     *********************************************************************/
818    
819    static void ieee_reseed(long s);
820    static long ieee_rand(int Min, int Max);
821    
822    #define TEST_SSE(FUNCTION, SRC1, SRC2, STRIDE) \
823      do { \
824        t = gettime_usec(); \
825        tst = nb_tests; \
826        while((tst--)>0) sse = (FUNCTION)((SRC1), (SRC2), (STRIDE)); \
827        emms(); \
828        t = (gettime_usec() - t)/(double)nb_tests;  \
829      } while(0)
830    
831    
832    void test_sse()
833    {
834            const int nb_tests = 100000*speed_ref;
835            int i;
836            CPU *cpu;
837            DECLARE_ALIGNED_MATRIX(Src1, 8, 8, int16_t, 16);
838            DECLARE_ALIGNED_MATRIX(Src2, 8, 8, int16_t, 16);
839            DECLARE_ALIGNED_MATRIX(Src3, 8, 8, int16_t, 16);
840            DECLARE_ALIGNED_MATRIX(Src4, 8, 8, int16_t, 16);
841    
842            printf( "\n =====  test sse =====\n" );
843    
844            ieee_reseed(1);
845            for(i=0; i<64; ++i) {
846                    Src1[i] = ieee_rand(-2048, 2047);
847                    Src2[i] = ieee_rand(-2048, 2047);
848                    Src3[i] = ieee_rand(-2048, 2047);
849                    Src4[i] = ieee_rand(-2048, 2047);
850            }
851    
852            for(cpu = cpu_list; cpu->name!=0; ++cpu)
853            {
854                    double t;
855                    int tst, sse;
856    
857                    if (!init_cpu(cpu))
858                            continue;
859    
860                    /* 16 bit element blocks */
861                    TEST_SSE(sse8_16bit, Src1, Src2, 16);
862                    printf("%s -   sse8_16bit#1 %.3f usec       sse=%d %s\n",
863                               cpu->name, t, sse, (sse!=182013834)?"| ERROR": "");
864                    TEST_SSE(sse8_16bit, Src1, Src3, 16);
865                    printf("%s -   sse8_16bit#2 %.3f usec       sse=%d %s\n",
866                               cpu->name, t, sse, (sse!=142545203)?"| ERROR": "");
867                    TEST_SSE(sse8_16bit, Src1, Src4, 16);
868                    printf("%s -   sse8_16bit#3 %.3f usec       sse=%d %s\n",
869                               cpu->name, t, sse, (sse!=146340935)?"| ERROR": "");
870                    TEST_SSE(sse8_16bit, Src2, Src3, 16);
871                    printf("%s -   sse8_16bit#4 %.3f usec       sse=%d %s\n",
872                               cpu->name, t, sse, (sse!=130136661)?"| ERROR": "");
873                    TEST_SSE(sse8_16bit, Src2, Src4, 16);
874                    printf("%s -   sse8_16bit#5 %.3f usec       sse=%d %s\n",
875                               cpu->name, t, sse, (sse!=136870353)?"| ERROR": "");
876                    TEST_SSE(sse8_16bit, Src3, Src4, 16);
877                    printf("%s -   sse8_16bit#6 %.3f usec       sse=%d %s\n",
878                               cpu->name, t, sse, (sse!=164107772)?"| ERROR": "");
879    
880                    /* 8 bit element blocks */
881                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src2, 8);
882                    printf("%s -    sse8_8bit#1 %.3f usec       sse=%d %s\n",
883                               cpu->name, t, sse, (sse!=1356423)?"| ERROR": "");
884                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src3, 8);
885                    printf("%s -    sse8_8bit#2 %.3f usec       sse=%d %s\n",
886                               cpu->name, t, sse, (sse!=1173074)?"| ERROR": "");
887                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src4, 8);
888                    printf("%s -    sse8_8bit#3 %.3f usec       sse=%d %s\n",
889                               cpu->name, t, sse, (sse!=1092357)?"| ERROR": "");
890                    TEST_SSE(sse8_8bit, (int8_t*)Src2, (int8_t*)Src3, 8);
891                    printf("%s -    sse8_8bit#4 %.3f usec       sse=%d %s\n",
892                               cpu->name, t, sse, (sse!=1360239)?"| ERROR": "");
893                    TEST_SSE(sse8_8bit, (int8_t*)Src2, (int8_t*)Src4, 8);
894                    printf("%s -    sse8_8bit#5 %.3f usec       sse=%d %s\n",
895                               cpu->name, t, sse, (sse!=1208414)?"| ERROR": "");
896                    TEST_SSE(sse8_8bit, (int8_t*)Src3, (int8_t*)Src4, 8);
897                    printf("%s -    sse8_8bit#6 %.3f usec       sse=%d %s\n",
898                               cpu->name, t, sse, (sse!=1099285)?"| ERROR": "");
899    
900      printf( " --- \n" );      printf( " --- \n" );
901    }    }
# Line 554  Line 905 
905   * test non-zero AC counting   * test non-zero AC counting
906   *********************************************************************/   *********************************************************************/
907    
908  #define TEST_CBP(FUNC, SRC)                   \  #define TEST_CBP(FUNC, SRC, NB)           \
909      t = gettime_usec();                       \      t = gettime_usec();                       \
910      emms();                                   \      emms();                                   \
911      for(tst=0; tst<nb_tests; ++tst) {         \  for(tst=0; tst<NB; ++tst) {         \
912        cbp = (FUNC)((SRC));                    \        cbp = (FUNC)((SRC));                    \
913      }                                         \      }                                         \
914      emms();                                   \      emms();                                   \
# Line 566  Line 917 
917  void test_cbp()  void test_cbp()
918  {  {
919    const int nb_tests = 10000*speed_ref;    const int nb_tests = 10000*speed_ref;
920    int i;          int i, n, m;
921    CPU *cpu;    CPU *cpu;
922    int16_t  Src1[6*64], Src2[6*64], Src3[6*64], Src4[6*64];          DECLARE_ALIGNED_MATRIX(Src1, 6, 64, int16_t, 16);
923            DECLARE_ALIGNED_MATRIX(Src2, 6, 64, int16_t, 16);
924            DECLARE_ALIGNED_MATRIX(Src3, 6, 64, int16_t, 16);
925            DECLARE_ALIGNED_MATRIX(Src4, 6, 64, int16_t, 16);
926      DECLARE_ALIGNED_MATRIX(Src5, 6, 64, int16_t, 16);
927    
928    printf( "\n =====  test cbp =====\n" );    printf( "\n =====  test cbp =====\n" );
929    
930    for(i=0; i<6*64; ++i) {    for(i=0; i<6*64; ++i) {
931      Src1[i] = (i*i*3/8192)&(i/64)&1;  // 'random'                  Src1[i] = (i*i*3/8192)&(i/64)&1;  /* 'random' */
932      Src2[i] = (i<3*64);               // half-full                  Src2[i] = (i<3*64);               /* half-full */
933      Src3[i] = ((i+32)>3*64);      Src3[i] = ((i+32)>3*64);
934      Src4[i] = (i==(3*64+2) || i==(5*64+9));      Src4[i] = (i==(3*64+2) || i==(5*64+9));
935        Src5[i] = ieee_rand(0,1) ? -1 : 1;  /* +/- test */
936    }    }
937    
938    for(cpu = cpu_short_list2; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
939    {    {
940      double t;      double t;
941      int tst, cbp;      int tst, cbp;
# Line 587  Line 943 
943      if (!init_cpu(cpu))      if (!init_cpu(cpu))
944        continue;        continue;
945    
946      TEST_CBP(calc_cbp, Src1);                  TEST_CBP(calc_cbp, Src1, nb_tests);
947      printf( "%s -   calc_cbp#1 %.3f usec       cbp=0x%x\n", cpu->name, t, cbp );                  printf("%s -   calc_cbp#1 %.3f usec       cbp=0x%02x %s\n",
948      if (cbp!=0x15) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x15)?"| ERROR": "");
949      TEST_CBP(calc_cbp, Src2);                  TEST_CBP(calc_cbp, Src2, nb_tests);
950      printf( "%s -   calc_cbp#2 %.3f usec       cbp=0x%x\n", cpu->name, t, cbp );                  printf("%s -   calc_cbp#2 %.3f usec       cbp=0x%02x %s\n",
951      if (cbp!=0x38) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x38)?"| ERROR": "");
952      TEST_CBP(calc_cbp, Src3);                  TEST_CBP(calc_cbp, Src3, nb_tests);
953      printf( "%s -   calc_cbp#3 %.3f usec       cbp=0x%x\n", cpu->name, t, cbp );                  printf("%s -   calc_cbp#3 %.3f usec       cbp=0x%02x %s\n",
954      if (cbp!=0x0f) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x0f)?"| ERROR": "" );
955      TEST_CBP(calc_cbp, Src4);                  TEST_CBP(calc_cbp, Src4, nb_tests);
956      printf( "%s -   calc_cbp#4 %.3f usec       cbp=0x%x\n", cpu->name, t, cbp );                  printf("%s -   calc_cbp#4 %.3f usec       cbp=0x%02x %s\n",
957      if (cbp!=0x05) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x05)?"| ERROR": "" );
958                    TEST_CBP(calc_cbp, Src5, nb_tests);
959                    printf("%s -   calc_cbp#4 %.3f usec       cbp=0x%02x %s\n",
960                               cpu->name, t, cbp, (cbp!=0x3f)?"| ERROR": "" );
961      printf( " --- \n" );      printf( " --- \n" );
962    }    }
963    
964            for(cpu = cpu_list; cpu->name!=0; ++cpu)  /* bench suggested by Carlo (carlo dot bramix at libero dot it) */
965            {
966                    double t;
967                    int tst, cbp, err;
968    
969                    if (!init_cpu(cpu))
970                            continue;
971    
972        err = 0;
973        for(n=0; n<6; ++n)
974        {
975          for(m=0; m<64; ++m)
976          {
977            for(i=0; i<6*64; ++i)
978              Src1[i] = (i== (m + n*64));
979    
980            TEST_CBP(calc_cbp, Src1, 1);
981            if (cbp!= (((m!=0)<<(5-n))))
982            {
983              printf( "%s -   calc_cbp#5: ERROR at pos %d / %d!\n", cpu->name, n, m);
984              err = 1;
985              break;
986            }
987          }
988        }
989        if (!err)
990          printf( " %s -    calc_cbp#5 : OK\n", cpu->name );
991    
992            }
993    }
994    
995    /*********************************************************************
996     * fdct/idct IEEE1180 compliance
997     *********************************************************************/
998    
999    typedef struct {
1000            long Errors[64];
1001            long Sqr_Errors[64];
1002            long Max_Errors[64];
1003            long Nb;
1004    } STATS_8x8;
1005    
1006    void init_stats(STATS_8x8 *S)
1007    {
1008            int i;
1009            for(i=0; i<64; ++i) {
1010                    S->Errors[i]     = 0;
1011                    S->Sqr_Errors[i] = 0;
1012                    S->Max_Errors[i] = 0;
1013            }
1014            S->Nb = 0;
1015    }
1016    
1017    void store_stats(STATS_8x8 *S, short Blk[64], short Ref[64])
1018    {
1019            int i;
1020            for(i=0; i<64; ++i)
1021            {
1022                    short Err = Blk[i] - Ref[i];
1023                    S->Errors[i] += Err;
1024                    S->Sqr_Errors[i] += Err * Err;
1025                    if (Err<0) Err = -Err;
1026                    if (S->Max_Errors[i]<Err)
1027                            S->Max_Errors[i] = Err;
1028            }
1029            S->Nb++;
1030    }
1031    
1032    void print_stats(STATS_8x8 *S)
1033    {
1034            int i;
1035            double Norm;
1036    
1037            assert(S->Nb>0);
1038            Norm = 1. / (double)S->Nb;
1039            printf("\n== Max absolute values of errors ==\n");
1040            for(i=0; i<64; i++) {
1041                    printf("  %4ld", S->Max_Errors[i]);
1042                    if ((i&7)==7) printf("\n");
1043            }
1044    
1045            printf("\n== Mean square errors ==\n");
1046            for(i=0; i<64; i++)
1047            {
1048                    double Err = Norm * (double)S->Sqr_Errors[i];
1049                    printf(" %.3f", Err);
1050                    if ((i&7)==7) printf("\n");
1051            }
1052    
1053            printf("\n== Mean errors ==\n");
1054            for(i=0; i<64; i++)
1055            {
1056                    double Err = Norm * (double)S->Errors[i];
1057                    printf(" %.3f", Err);
1058                    if ((i&7)==7) printf("\n");
1059            }
1060            printf("\n");
1061    }
1062    
1063    static const char *CHECK(double v, double l) {
1064            if (fabs(v)<=l) return "ok";
1065            else return "FAIL!";
1066    }
1067    
1068    void report_stats(STATS_8x8 *S, const double *Limits)
1069    {
1070            int i;
1071            double Norm, PE, PMSE, OMSE, PME, OME;
1072    
1073            assert(S->Nb>0);
1074            Norm = 1. / (double)S->Nb;
1075            PE = 0.;
1076            for(i=0; i<64; i++) {
1077                    if (PE<S->Max_Errors[i])
1078                            PE = S->Max_Errors[i];
1079            }
1080    
1081            PMSE = 0.;
1082            OMSE = 0.;
1083            for(i=0; i<64; i++)
1084            {
1085                    double Err = Norm * (double)S->Sqr_Errors[i];
1086                    OMSE += Err;
1087                    if (PMSE < Err) PMSE = Err;
1088            }
1089            OMSE /= 64.;
1090    
1091            PME = 0.;
1092            OME = 0.;
1093            for(i=0; i<64; i++)
1094            {
1095                    double Err = Norm * (double)S->Errors[i];
1096                    OME += Err;
1097                    Err = fabs(Err);
1098                    if (PME < Err) PME = Err;
1099            }
1100            OME /= 64.;
1101    
1102            printf( "Peak error:   %4.4f\n", PE );
1103            printf( "Peak MSE:     %4.4f\n", PMSE );
1104            printf( "Overall MSE:  %4.4f\n", OMSE );
1105            printf( "Peak ME:      %4.4f\n", PME );
1106            printf( "Overall ME:   %4.4f\n", OME );
1107    
1108            if (Limits!=0)
1109            {
1110                    printf( "[PE<=%.4f %s]  ", Limits[0], CHECK(PE,   Limits[0]) );
1111                    printf( "\n" );
1112                    printf( "[PMSE<=%.4f %s]", Limits[1], CHECK(PMSE, Limits[1]) );
1113                    printf( "[OMSE<=%.4f %s]", Limits[2], CHECK(OMSE, Limits[2]) );
1114                    printf( "\n" );
1115                    printf( "[PME<=%.4f %s] ", Limits[3], CHECK(PME , Limits[3]) );
1116                    printf( "[OME<=%.4f %s] ", Limits[4], CHECK(OME , Limits[4]) );
1117                    printf( "\n" );
1118            }
1119    }
1120    
1121    ///* ////////////////////////////////////////////////////// */
1122    /* Pseudo-random generator specified by IEEE 1180 */
1123    
1124    static long ieee_seed = 1;
1125    static void ieee_reseed(long s) {
1126            ieee_seed = s;
1127    }
1128    static long ieee_rand(int Min, int Max)
1129    {
1130            static double z = (double) 0x7fffffff;
1131    
1132            long i,j;
1133            double x;
1134    
1135            ieee_seed = (ieee_seed * 1103515245) + 12345;
1136            i = ieee_seed & 0x7ffffffe;
1137            x = ((double) i) / z;
1138            x *= (Max-Min+1);
1139            j = (long)x;
1140            j = j + Min;
1141            assert(j>=Min && j<=Max);
1142            return (short)j;
1143    }
1144    
1145    #define CLAMP(x, M)   (x) = ((x)<-(M)) ? (-(M)) : ((x)>=(M) ? ((M)-1) : (x))
1146    
1147    static double Cos[8][8];
1148    static void init_ref_dct()
1149    {
1150            int i, j;
1151            for(i=0; i<8; i++)
1152            {
1153                    double scale = (i == 0) ? sqrt(0.125) : 0.5;
1154                    for (j=0; j<8; j++)
1155                            Cos[i][j] = scale*cos( (M_PI/8.0)*i*(j + 0.5) );
1156            }
1157    }
1158    
1159    void ref_idct(short *M)
1160    {
1161            int i, j, k;
1162            double Tmp[8][8];
1163    
1164            for(i=0; i<8; i++) {
1165                    for(j=0; j<8; j++)
1166                    {
1167                            double Sum = 0.0;
1168                            for (k=0; k<8; k++) Sum += Cos[k][j]*M[8*i+k];
1169                            Tmp[i][j] = Sum;
1170                    }
1171            }
1172            for(i=0; i<8; i++) {
1173                    for(j=0; j<8; j++) {
1174                            double Sum = 0.0;
1175                            for (k=0; k<8; k++) Sum += Cos[k][i]*Tmp[k][j];
1176                            M[8*i+j] = (short)floor(Sum + .5);
1177                    }
1178            }
1179    }
1180    
1181    void ref_fdct(short *M)
1182    {
1183            int i, j, k;
1184            double Tmp[8][8];
1185    
1186            for(i=0; i<8; i++) {
1187                    for(j=0; j<8; j++)
1188                    {
1189                            double Sum = 0.0;
1190                            for (k=0; k<8; k++) Sum += Cos[j][k]*M[8*i+k];
1191                            Tmp[i][j] = Sum;
1192                    }
1193            }
1194            for(i=0; i<8; i++) {
1195                    for(j=0; j<8; j++) {
1196                            double Sum = 0.0;
1197                            for (k=0; k<8; k++) Sum += Cos[i][k]*Tmp[k][j];
1198                            M[8*i+j] = (short)floor(Sum + 0.5);
1199                    }
1200            }
1201    }
1202    
1203    void test_IEEE1180_compliance(int Min, int Max, int Sign)
1204    {
1205            static const double ILimits[5] = { 1., 0.06, 0.02, 0.015, 0.0015 };
1206            int Loops = 10000;
1207            int i, m, n;
1208            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, short, 16); /* reference */
1209            DECLARE_ALIGNED_MATRIX(Blk,  8, 8, short, 16);
1210            DECLARE_ALIGNED_MATRIX(iBlk, 8, 8, short, 16);
1211            DECLARE_ALIGNED_MATRIX(Ref_FDCT, 8, 8, short, 16);
1212            DECLARE_ALIGNED_MATRIX(Ref_IDCT, 8, 8, short, 16);
1213    
1214            STATS_8x8 FStats; /* forward dct stats */
1215            STATS_8x8 IStats; /* inverse dct stats */
1216    
1217            CPU *cpu;
1218    
1219            init_ref_dct();
1220    
1221            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1222            {
1223                    if (!init_cpu(cpu))
1224                            continue;
1225    
1226                    printf( "\n===== IEEE test for %s ==== (Min=%d Max=%d Sign=%d Loops=%d)\n",
1227                                    cpu->name, Min, Max, Sign, Loops);
1228    
1229                    init_stats(&IStats);
1230                    init_stats(&FStats);
1231    
1232                    ieee_reseed(1);
1233                    for(n=0; n<Loops; ++n)
1234                    {
1235                            for(i=0; i<64; ++i)
1236                                    Blk0[i] = (short)ieee_rand(Min,Max) * Sign;
1237    
1238                            /* hmm, I'm not quite sure this is exactly */
1239                            /* the tests described in the norm. check... */
1240    
1241                            memcpy(Ref_FDCT, Blk0, 64*sizeof(short));
1242                            ref_fdct(Ref_FDCT);
1243                            for(i=0; i<64; i++) CLAMP( Ref_FDCT[i], 2048 );
1244    
1245                            memcpy(Blk, Blk0, 64*sizeof(short));
1246                            emms(); fdct(Blk); emms();
1247                            for(i=0; i<64; i++) CLAMP( Blk[i], 2048 );
1248    
1249                            store_stats(&FStats, Blk, Ref_FDCT);
1250    
1251    
1252                            memcpy(Ref_IDCT, Ref_FDCT, 64*sizeof(short));
1253                            ref_idct(Ref_IDCT);
1254                            for (i=0; i<64; i++) CLAMP( Ref_IDCT[i], 256 );
1255    
1256                            memcpy(iBlk, Ref_FDCT, 64*sizeof(short));
1257                            emms(); idct(iBlk); emms();
1258                            for(i=0; i<64; i++) CLAMP( iBlk[i], 256 );
1259    
1260                            store_stats(&IStats, iBlk, Ref_IDCT);
1261                    }
1262    
1263    
1264                    printf( "\n  -- FDCT report --\n" );
1265    //    print_stats(&FStats);
1266                    report_stats(&FStats, 0); /* so far I know, IEEE1180 says nothing for fdct */
1267    
1268                    for(i=0; i<64; i++) Blk[i] = 0;
1269                    emms(); fdct(Blk); emms();
1270                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1271                    printf( "FDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1272    
1273                    printf( "\n  -- IDCT report --\n" );
1274    //    print_stats(&IStats);
1275                    report_stats(&IStats, ILimits);
1276    
1277    
1278                    for(i=0; i<64; i++) Blk[i] = 0;
1279                    emms(); idct(Blk); emms();
1280                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1281                    printf( "IDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1282            }
1283    }
1284    
1285    
1286    void test_dct_saturation(int Min, int Max)
1287    {
1288    /* test behaviour on input range fringe */
1289    
1290            int i, n, p;
1291            CPU *cpu;
1292    //  const short IDCT_MAX =  2047;  /* 12bits input */
1293    //  const short IDCT_MIN = -2048;
1294    //  const short IDCT_OUT =   256;  /* 9bits ouput */
1295            const int Partitions = 4;
1296            const int Loops = 10000 / Partitions;
1297    
1298            init_ref_dct();
1299    
1300            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1301            {
1302                    short Blk0[64], Blk[64];
1303                    STATS_8x8 Stats;
1304    
1305                    if (!init_cpu(cpu))
1306                            continue;
1307    
1308                    printf( "\n===== IEEE test for %s Min=%d Max=%d =====\n",
1309                                    cpu->name, Min, Max );
1310    
1311                    /* FDCT tests // */
1312    
1313                    init_stats(&Stats);
1314    
1315                    /* test each computation channels separately */
1316                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Max : 0;
1317                    ref_fdct(Blk0);
1318                    emms(); fdct(Blk); emms();
1319                    store_stats(&Stats, Blk, Blk0);
1320    
1321                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Min : 0;
1322                    ref_fdct(Blk0);
1323                    emms(); fdct(Blk); emms();
1324                    store_stats(&Stats, Blk, Blk0);
1325    
1326                    /* randomly saturated inputs */
1327                    for(p=0; p<Partitions; ++p)
1328                    {
1329                            for(n=0; n<Loops; ++n)
1330                            {
1331                                    for(i=0; i<64; ++i)
1332                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? Max : Min;
1333                                    ref_fdct(Blk0);
1334                                    emms(); fdct(Blk); emms();
1335                                    store_stats(&Stats, Blk, Blk0);
1336                            }
1337                    }
1338                    printf( "\n  -- FDCT saturation report --\n" );
1339                    report_stats(&Stats, 0);
1340    
1341    
1342                    /* IDCT tests // */
1343    #if 0
1344                    /* no finished yet */
1345    
1346                    init_stats(&Stats);
1347    
1348    /* test each computation channel separately */
1349                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MAX : 0;
1350                    ref_idct(Blk0);
1351                    emms(); idct(Blk); emms();
1352                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1353                    store_stats(&Stats, Blk, Blk0);
1354    
1355                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MIN : 0;
1356                    ref_idct(Blk0);
1357                    emms(); idct(Blk); emms();
1358                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1359                    store_stats(&Stats, Blk, Blk0);
1360    
1361                    /* randomly saturated inputs */
1362                    for(p=0; p<Partitions; ++p)
1363                    {
1364                            for(n=0; n<Loops; ++n)
1365                            {
1366                                    for(i=0; i<64; ++i)
1367                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? IDCT_MAX : IDCT_MIN;
1368                                    ref_idct(Blk0);
1369                                    emms(); idct(Blk); emms();
1370                                    for(i=0; i<64; i++) { CLAMP(Blk0[i],IDCT_OUT); CLAMP(Blk[i],IDCT_OUT); }
1371                                    store_stats(&Stats, Blk, Blk0);
1372                            }
1373                    }
1374    
1375                    printf( "\n  -- IDCT saturation report --\n" );
1376                    print_stats(&Stats);
1377                    report_stats(&Stats, 0);
1378    #endif
1379            }
1380  }  }
1381    
1382  /*********************************************************************  /*********************************************************************
1383   * measure raw decoding speed   * measure raw decoding speed
1384   *********************************************************************/   *********************************************************************/
1385    
1386  void test_dec(const char *name, int width, int height, int with_chksum)  void test_dec(const char *name, int width, int height, int ref_chksum)
1387  {  {
1388    FILE *f = 0;    FILE *f = 0;
1389    void *dechandle = 0;    void *dechandle = 0;
1390    int xerr;    int xerr;
1391          XVID_INIT_PARAM xinit;          xvid_gbl_init_t xinit;
1392          XVID_DEC_PARAM xparam;          xvid_dec_create_t xparam;
1393          XVID_DEC_FRAME xframe;          xvid_dec_frame_t xframe;
1394          double t = 0.;          double t = 0.;
1395          int nb = 0;          int nb = 0;
1396    uint8_t *buf = 0;    uint8_t *buf = 0;
1397    uint8_t *rgb_out = 0;          uint8_t *yuv_out = 0;
1398    int buf_size, pos;    int buf_size, pos;
1399    uint32_t chksum = 0;    uint32_t chksum = 0;
1400            int bps = (width+31) & ~31;
1401    
1402          xinit.cpu_flags = 0;          memset(&xinit, 0, sizeof(xinit));
1403          xvid_init(NULL, 0, &xinit, NULL);          xinit.cpu_flags = cpu_mask;
1404          printf( "API version: %d, core build:%d\n", xinit.api_version, xinit.core_build);          xinit.version = XVID_VERSION;
1405            xvid_global(NULL, 0, &xinit, NULL);
1406    
1407            memset(&xparam, 0, sizeof(xparam));
1408          xparam.width = width;          xparam.width = width;
1409          xparam.height = height;          xparam.height = height;
1410            xparam.version = XVID_VERSION;
1411          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
1412          if (xerr!=XVID_ERR_OK) {          if (xerr==XVID_ERR_FAIL) {
1413            printf("can't init decoder (err=%d)\n", xerr);                  printf("ERROR: can't init decoder (err=%d)\n", xerr);
1414            return;            return;
1415          }          }
1416          dechandle = xparam.handle;          dechandle = xparam.handle;
# Line 639  Line 1418 
1418    
1419          f = fopen(name, "rb");          f = fopen(name, "rb");
1420    if (f==0) {    if (f==0) {
1421      printf( "can't open file '%s'\n", name);                  printf( "ERROR: can't open file '%s'\n", name);
1422      return;      return;
1423    }    }
1424    fseek(f, 0, SEEK_END);    fseek(f, 0, SEEK_END);
1425    buf_size = ftell(f);    buf_size = ftell(f);
1426    fseek(f, 0, SEEK_SET);    fseek(f, 0, SEEK_SET);
1427    if (buf_size<=0) {    if (buf_size<=0) {
1428      printf("error while stating file\n");                  printf("ERROR: error while stating file\n");
1429      goto End;      goto End;
1430    }    }
   else printf( "Input size: %d\n", buf_size);  
1431    
1432    buf = malloc(buf_size); // should be enuf'          buf = malloc(buf_size);
1433    rgb_out = calloc(4, width*height);  // <-room for _RGB24          yuv_out = calloc(1, bps*height*3/2 + 15);
1434    if (buf==0 || rgb_out==0) {          if (buf==0 || yuv_out==0) {
1435      printf( "malloc failed!\n" );                  printf( "ERROR: malloc failed!\n" );
1436      goto End;      goto End;
1437    }    }
1438    
1439    if (fread(buf, buf_size, 1, f)!=1) {    if (fread(buf, buf_size, 1, f)!=1) {
1440      printf( "file-read failed\n" );                  printf( "ERROR: file-read failed\n" );
1441      goto End;      goto End;
1442    }    }
1443    
# Line 667  Line 1445 
1445    pos = 0;    pos = 0;
1446    t = -gettime_usec();    t = -gettime_usec();
1447    while(1) {    while(1) {
1448              int y;
1449    
1450                    memset(&xframe, 0, sizeof(xframe));
1451                    xframe.version = XVID_VERSION;
1452      xframe.bitstream = buf + pos;      xframe.bitstream = buf + pos;
1453      xframe.length = buf_size - pos;      xframe.length = buf_size - pos;
1454      xframe.image = rgb_out;                  xframe.output.plane[0] = (uint8_t*)(((size_t)yuv_out + 15) & ~15);
1455      xframe.stride = width;                  xframe.output.plane[1] = (uint8_t*)xframe.output.plane[0] + bps*height;
1456      xframe.colorspace = XVID_CSP_RGB24;                  xframe.output.plane[2] = (uint8_t*)xframe.output.plane[1] + bps/2;
1457                    xframe.output.stride[0] = bps;
1458                    xframe.output.stride[1] = bps;
1459                    xframe.output.stride[2] = bps;
1460                    xframe.output.csp = XVID_CSP_I420;
1461      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);
1462                    if (xerr<0) {
1463                            printf("ERROR: decoding failed for frame #%d (err=%d)!\n", nb, xerr);
1464                            break;
1465                    }
1466                    else if (xerr==0)
1467                      break;
1468        else if (verbose>0) printf("#%d %d\n", nb, xerr );
1469    
1470                    pos += xerr;
1471      nb++;      nb++;
1472      pos += xframe.length;  
1473      if (with_chksum) {      for(y=0; y<height/2; ++y) {
1474        int k = width*height;                    chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+0)*bps, width, chksum);
1475        uint32_t *ptr = (uint32_t *)rgb_out;                          chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+1)*bps, width, chksum);
1476        while(k-->0) chksum += *ptr++;                          chksum = calc_crc((uint8_t*)xframe.output.plane[1] + y*bps, width/2, chksum);
1477                            chksum = calc_crc((uint8_t*)xframe.output.plane[2] + y*bps, width/2, chksum);
1478      }      }
1479      if (pos==buf_size)      if (pos==buf_size)
1480        break;        break;
     if (xerr!=XVID_ERR_OK) {  
           printf("decoding failed for frame #%d (err=%d)!\n", nb, xerr);  
           break;  
         }  
1481    }    }
1482    t += gettime_usec();    t += gettime_usec();
1483            if (ref_chksum==0) {
1484    if (t>0.)    if (t>0.)
1485      printf( "%d frames decoded in %.3f s -> %.1f FPS\n", nb, t*1.e-6f, (float)(nb*1.e6f/t) );                    printf( "%d frames decoded in %.3f s -> %.1f FPS   Checksum:0x%.8x\n", nb, t*1.e-6f, (float)(nb*1.e6f/t), chksum );
1486    if (with_chksum)    }
1487      printf("checksum: 0x%.8x\n", chksum);    else {
1488                    printf("FPS:%.1f Checksum: 0x%.8x Expected:0x%.8x | %s\n",
1489                      t>0. ? (float)(nb*1.e6f/t) : 0.f, chksum, ref_chksum, (chksum==ref_chksum) ? "OK" : "ERROR");
1490      }
1491    
1492  End:  End:
1493    if (rgb_out!=0) free(rgb_out);          if (yuv_out!=0) free(yuv_out);
1494    if (buf!=0) free(buf);    if (buf!=0) free(buf);
1495    if (dechandle!=0) {    if (dechandle!=0) {
1496      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);
1497      if (xerr!=XVID_ERR_OK)                  if (xerr==XVID_ERR_FAIL)
1498              printf("destroy-decoder failed (err=%d)!\n", xerr);                          printf("ERROR: destroy-decoder failed (err=%d)!\n", xerr);
1499    }    }
1500    if (f!=0) fclose(f);    if (f!=0) fclose(f);
1501  }  }
# Line 711  Line 1507 
1507  void test_bugs1()  void test_bugs1()
1508  {  {
1509    CPU *cpu;    CPU *cpu;
1510            uint16_t mpeg_quant_matrices[64*8];
1511    
1512    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );
1513    
1514    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1515    {    {
1516      int i;      int i;
1517      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 723  Line 1520 
1520        continue;        continue;
1521    
1522      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1523      set_intra_matrix( get_default_intra_matrix() );                  set_intra_matrix( mpeg_quant_matrices, get_default_intra_matrix() );
1524      dequant4_intra(Dst, Src, 32, 5);                  dequant_mpeg_intra(Dst, Src, 31, 5, mpeg_quant_matrices);
1525      printf( "dequant4_intra with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_intra with CPU=%s:  ", cpu->name);
1526      printf( "  Out[]= " );      printf( "  Out[]= " );
1527      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1528      printf( "\n" );      printf( "\n" );
# Line 733  Line 1530 
1530    
1531    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );
1532    
1533    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1534    {    {
1535      int i;      int i;
1536      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 742  Line 1539 
1539        continue;        continue;
1540    
1541      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1542      set_inter_matrix( get_default_inter_matrix() );                  set_inter_matrix( mpeg_quant_matrices, get_default_inter_matrix() );
1543      dequant4_inter(Dst, Src, 32);                  dequant_mpeg_inter(Dst, Src, 31, mpeg_quant_matrices);
1544      printf( "dequant4_inter with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_inter with CPU=%s:  ", cpu->name);
1545      printf( "  Out[]= " );      printf( "  Out[]= " );
1546      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1547      printf( "\n" );      printf( "\n" );
# Line 754  Line 1551 
1551  void test_dct_precision_diffs()  void test_dct_precision_diffs()
1552  {  {
1553    CPU *cpu;    CPU *cpu;
1554    short Blk[8*8], Blk0[8*8];          DECLARE_ALIGNED_MATRIX(Blk, 8, 8, int16_t, 16);
1555            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, int16_t, 16);
1556    
1557    printf( "\n =====  fdct/idct saturation diffs =====\n" );          printf( "\n =====  fdct/idct precision diffs =====\n" );
1558    
1559    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1560    {    {
1561      int i;      int i;
1562    
# Line 782  Line 1580 
1580    }    }
1581  }  }
1582    
1583    void test_quant_bug()
1584    {
1585            const int max_Q = 31;
1586            int i, n, qm, q;
1587            CPU *cpu;
1588            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
1589            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
1590            uint8_t Quant[8*8];
1591            CPU cpu_bug_list[] = { { "PLAINC", 0 }, { "MMX   ", XVID_CPU_MMX }, {0,0} };
1592            uint16_t Crcs_Inter[2][32];
1593            uint16_t Crcs_Intra[2][32];
1594            DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
1595    
1596            printf( "\n =====  test MPEG4-quantize bug =====\n" );
1597    
1598            for(i=0; i<64; ++i) Src[i] = 2048*(i-32)/32;
1599    
1600    #if 1
1601            for(qm=1; qm<=255; ++qm)
1602            {
1603                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1604                    set_inter_matrix( mpeg_quant_matrices, Quant );
1605    
1606                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1607                    {
1608                            uint16_t s;
1609    
1610                            if (!init_cpu(cpu))
1611                                    continue;
1612    
1613                            for(q=1; q<=max_Q; ++q) {
1614                                    emms();
1615                                    quant_mpeg_inter( Dst, Src, q, mpeg_quant_matrices );
1616                                    emms();
1617                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1618                                    Crcs_Inter[n][q] = s;
1619                            }
1620                    }
1621    
1622                    for(q=1; q<=max_Q; ++q)
1623                            for(i=0; i<n-1; ++i)
1624                                    if (Crcs_Inter[i][q]!=Crcs_Inter[i+1][q])
1625                                            printf( "Discrepancy Inter: qm=%d, q=%d  -> %d/%d !\n",
1626                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1627            }
1628    #endif
1629    
1630    #if 1
1631            for(qm=1; qm<=255; ++qm)
1632            {
1633                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1634                    set_intra_matrix( mpeg_quant_matrices, Quant );
1635    
1636                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1637                    {
1638                            uint16_t s;
1639    
1640                            if (!init_cpu(cpu))
1641                                    continue;
1642    
1643                            for(q=1; q<=max_Q; ++q) {
1644                                    emms();
1645                                    quant_mpeg_intra( Dst, Src, q, q, mpeg_quant_matrices);
1646                                    emms();
1647                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1648                                    Crcs_Intra[n][q] = s;
1649                            }
1650                    }
1651    
1652                    for(q=1; q<=max_Q; ++q)
1653                            for(i=0; i<n-1; ++i)
1654                                    if (Crcs_Intra[i][q]!=Crcs_Intra[i+1][q])
1655                                            printf( "Discrepancy Intra: qm=%d, q=%d  -> %d/%d!\n",
1656                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1657            }
1658    #endif
1659    }
1660    /*********************************************************************/
1661    
1662    static uint32_t __inline log2bin_v1(uint32_t value)
1663    {
1664      int n = 0;
1665      while (value) {
1666        value >>= 1;
1667        n++;
1668      }
1669      return n;
1670    }
1671    
1672    static const uint8_t log2_tab_16[16] =  { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
1673    
1674    static uint32_t __inline log2bin_v2(uint32_t value)
1675    {
1676      int n = 0;
1677      if (value & 0xffff0000) {
1678        value >>= 16;
1679        n += 16;
1680      }
1681      if (value & 0xff00) {
1682        value >>= 8;
1683        n += 8;
1684      }
1685      if (value & 0xf0) {
1686        value >>= 4;
1687        n += 4;
1688      }
1689     return n + log2_tab_16[value];
1690    }
1691    
1692    void test_log2bin()
1693    {
1694            const int nb_tests = 3000*speed_ref;
1695      int n, crc1=0, crc2=0;
1696      uint32_t s, s0;
1697      double t1, t2;
1698    
1699      t1 = gettime_usec();
1700      s0 = (int)(t1*31.241);
1701      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1702        crc1 += log2bin_v1(s);
1703      t1 = (gettime_usec()-t1) / nb_tests;
1704    
1705      t2 = gettime_usec();
1706      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1707        crc2 += log2bin_v2(s);
1708      t2 = (gettime_usec() - t2) / nb_tests;
1709    
1710      printf( "log2bin_v1: %.3f sec  crc=%d\n", t1, crc1 );
1711      printf( "log2bin_v2: %.3f sec  crc=%d\n", t2, crc2 );
1712      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1713    }
1714    
1715    /*********************************************************************/
1716    
1717    static void __inline old_gcd(int *num, int *den)
1718    {
1719     int i = *num;
1720      while (i > 1) {
1721        if (*num % i == 0 && *den % i == 0) {
1722          *num /= i;
1723          *den /= i;
1724          i = *num;
1725          continue;
1726        }
1727        i--;
1728      }
1729    }
1730    
1731    static uint32_t gcd(int num, int den)
1732    {
1733      int tmp;
1734      while( (tmp=num%den) ) { num = den; den = tmp; }
1735      return den;
1736    }
1737    static void __inline new_gcd(int *num, int *den)
1738    {
1739      const int div = gcd(*num, *den);
1740      if (num) {
1741        *num /= div;
1742        *den /= div;
1743      }
1744    }
1745    
1746    void test_gcd()
1747    {
1748            const int nb_tests = 10*speed_ref;
1749      int i;
1750      uint32_t crc1=0, crc2=0;
1751      uint32_t n0, n, d0, d;
1752      double t1, t2;
1753    
1754      t1 = gettime_usec();
1755      n0 = 0xfffff & (int)(t1*31.241);
1756      d0 = 0xfffff & (int)( ((n0*4123)%17) | 1 );
1757      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1758        old_gcd(&n, &d);
1759        crc1 = (((crc1>>4)^d) + ((crc1<<2)^n) ) & 0xffffff;
1760        n = d;
1761        d = (d*12363+31) & 0xffff;
1762        d |= !d;
1763      }
1764      t1 = (gettime_usec()-t1) / nb_tests;
1765    
1766      t2 = gettime_usec();
1767      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1768        new_gcd(&n, &d);
1769        crc2 = (((crc2>>4)^d) + ((crc2<<2)^n) ) & 0xffffff;
1770        n = d;
1771        d = (d*12363+31) & 0xffff;
1772        d |= !d;
1773      }
1774      t2 = (gettime_usec() - t2) / nb_tests;
1775    
1776      printf( "old_gcd: %.3f sec  crc=%d\n", t1, crc1 );
1777      printf( "new_gcd: %.3f sec  crc=%d\n", t2, crc2 );
1778      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1779    }
1780    
1781  /*********************************************************************  /*********************************************************************
1782   * main   * main
1783   *********************************************************************/   *********************************************************************/
1784    
1785  int main(int argc, char *argv[])  static void arg_missing(const char *opt)
1786    {
1787      printf( "missing argument after option '%s'\n", opt);
1788      exit(-1);
1789    }
1790    
1791    int main(int argc, const char *argv[])
1792    {
1793            int c, what = 0;
1794            int width, height;
1795            uint32_t chksum = 0;
1796      const char * test_bitstream = 0;
1797    
1798            cpu_mask = 0;  // default => will use autodectect
1799            for(c=1; c<argc; ++c)
1800  {  {
1801    int what = 0;            if (!strcmp(argv[c], "-v")) verbose++;
1802    if (argc>1) what = atoi(argv[1]);            else if (!strcmp(argv[c], "-c"))      cpu_mask = 0 /* PLAIN_C */ | XVID_CPU_FORCE;
1803              else if (!strcmp(argv[c], "-mmx"))    cpu_mask = XVID_CPU_MMX    | XVID_CPU_FORCE;
1804              else if (!strcmp(argv[c], "-mmxext")) cpu_mask = XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
1805              else if (!strcmp(argv[c], "-sse2"))   cpu_mask = XVID_CPU_SSE2   | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
1806              else if (!strcmp(argv[c], "-3dnow"))  cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_FORCE;
1807              else if (!strcmp(argv[c], "-3dnowe")) cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_3DNOWEXT | XVID_CPU_FORCE;
1808              else if (!strcmp(argv[c], "-altivec")) cpu_mask = XVID_CPU_ALTIVEC | XVID_CPU_FORCE;
1809              else if (!strcmp(argv[c], "-spd")) {
1810          if (++c==argc) arg_missing( argv[argc-1] );
1811          speed_ref = atoi(argv[c]);
1812        }
1813              else if (argv[c][0]!='-') {
1814                what = atoi(argv[c]);
1815                if (what==9) {
1816                  if (c+4>argc) {
1817                    printf("usage: %s %d bitstream width height (checksum)\n", argv[0], what);
1818                    exit(-1);
1819            }
1820            test_bitstream = argv[++c];
1821                  width  = atoi(argv[++c]);
1822                  height = atoi(argv[++c]);
1823                  if (c+1<argc && argv[c+1][0]!='-') {
1824                    if (sscanf(argv[c+1], "0x%x", &chksum)!=1) {
1825                      printf( "can't read checksum value.\n" );
1826                      exit(-1);
1827              }
1828              else c++;
1829            }
1830    //        printf( "[%s] %dx%d (0x%.8x)\n", test_bitstream, width, height, chksum);
1831          }
1832        }
1833        else {
1834          printf( "unrecognized option '%s'\n", argv[c]);
1835          exit(-1);
1836        }
1837      }
1838    
1839    
1840    if (what==0 || what==1) test_dct();    if (what==0 || what==1) test_dct();
1841    if (what==0 || what==2) test_mb();    if (what==0 || what==2) test_mb();
1842    if (what==0 || what==3) test_sad();    if (what==0 || what==3) test_sad();
1843    if (what==0 || what==4) test_transfer();    if (what==0 || what==4) test_transfer();
1844    if (what==0 || what==5) test_quant();    if (what==0 || what==5) test_quant();
1845    if (what==0 || what==6) test_cbp();    if (what==0 || what==6) test_cbp();
1846            if (what==0 || what==10) test_sse();
1847    if (what==8) {          if (what==0 || what==11) test_log2bin();
1848      int width, height;          if (what==0 || what==12) test_gcd();
1849      if (argc<5) {  
1850        printf("usage: %s %d [bitstream] [width] [height]\n", argv[0], what);  
1851        return 1;          if (what==7) {
1852      }                  test_IEEE1180_compliance(-256, 255, 1);
1853      width = atoi(argv[3]);                  test_IEEE1180_compliance(-256, 255,-1);
1854      height = atoi(argv[4]);                  test_IEEE1180_compliance(  -5,   5, 1);
1855      test_dec(argv[2], width, height, (argc>5));                  test_IEEE1180_compliance(  -5,   5,-1);
1856                    test_IEEE1180_compliance(-300, 300, 1);
1857                    test_IEEE1180_compliance(-300, 300,-1);
1858    }    }
1859            if (what==8) test_dct_saturation(-256, 255);
1860    
1861            if (test_bitstream)
1862              test_dec(test_bitstream, width, height, chksum);
1863    if (what==-1) {    if (what==-1) {
     test_bugs1();  
1864      test_dct_precision_diffs();      test_dct_precision_diffs();
1865                    test_bugs1();
1866    }    }
1867    return 0;          if (what==-2)
1868                    test_quant_bug();
1869    
1870            if ((what >= 0 && what <= 6) || what == 10) {
1871                    printf("\n\n"
1872                               "NB: If a function isn't optimised for a specific set of intructions,\n"
1873                               "    a C function is used instead. So don't panic if some functions\n"
1874                               "    may appear to be slow.\n");
1875            }
1876    
1877    #ifdef ARCH_IS_IA32
1878            if (what == 0 || what == 5) {
1879                    printf("\n"
1880                               "NB: MMX mpeg4 quantization is known to have very small errors (+/-1 magnitude)\n"
1881                               "    for 1 or 2 coefficients a block. This is mainly caused by the fact the unit\n"
1882                               "    test goes far behind the usual limits of real encoding. Please do not report\n"
1883                               "    this error to the developers.\n");
1884  }  }
1885    #endif
1886    
1887  /*********************************************************************          return 0;
1888   * 'Reference' output (except for timing) on a PIII 1.13Ghz/linux  }
  *********************************************************************/  
 /*  
1889    
1890   ===== test fdct/idct =====  /*********************************************************************/
 PLAINC -  2.631 usec       iCrc=3  fCrc=-85  
 MMX    -  0.596 usec       iCrc=3  fCrc=-67  
 MMXEXT -  0.608 usec       iCrc=3  fCrc=-67  
 SSE2   -  0.605 usec       iCrc=3  fCrc=-67  
 3DNOW  - skipped...  
 3DNOWE - skipped...  
   
  ===  test block motion ===  
 PLAINC - interp- h-round0 1.031 usec       iCrc=8107  
 PLAINC -           round1 1.022 usec       iCrc=8100  
 PLAINC - interp- v-round0 1.002 usec       iCrc=8108  
 PLAINC -           round1 1.011 usec       iCrc=8105  
 PLAINC - interp-hv-round0 1.623 usec       iCrc=8112  
 PLAINC -           round1 1.621 usec       iCrc=8103  
 PLAINC - interpolate8x8_c 0.229 usec       iCrc=8107  
  ---  
 MMX    - interp- h-round0 0.105 usec       iCrc=8107  
 MMX    -           round1 0.105 usec       iCrc=8100  
 MMX    - interp- v-round0 0.106 usec       iCrc=8108  
 MMX    -           round1 0.107 usec       iCrc=8105  
 MMX    - interp-hv-round0 0.145 usec       iCrc=8112  
 MMX    -           round1 0.145 usec       iCrc=8103  
 MMX    - interpolate8x8_c 0.229 usec       iCrc=8107  
  ---  
 MMXEXT - interp- h-round0 0.027 usec       iCrc=8107  
 MMXEXT -           round1 0.041 usec       iCrc=8100  
 MMXEXT - interp- v-round0 0.027 usec       iCrc=8108  
 MMXEXT -           round1 0.040 usec       iCrc=8105  
 MMXEXT - interp-hv-round0 0.070 usec       iCrc=8112  
 MMXEXT -           round1 0.066 usec       iCrc=8103  
 MMXEXT - interpolate8x8_c 0.027 usec       iCrc=8107  
  ---  
 SSE2   - interp- h-round0 0.106 usec       iCrc=8107  
 SSE2   -           round1 0.105 usec       iCrc=8100  
 SSE2   - interp- v-round0 0.106 usec       iCrc=8108  
 SSE2   -           round1 0.106 usec       iCrc=8105  
 SSE2   - interp-hv-round0 0.145 usec       iCrc=8112  
 SSE2   -           round1 0.145 usec       iCrc=8103  
 SSE2   - interpolate8x8_c 0.237 usec       iCrc=8107  
  ---  
 3DNOW  - skipped...  
 3DNOWE - skipped...  
   
  ======  test SAD ======  
 PLAINC - sad8    0.296 usec       sad=3776  
 PLAINC - sad16   1.599 usec       sad=27214  
 PLAINC - sad16bi 2.350 usec       sad=26274  
 PLAINC - dev16   1.610 usec       sad=3344  
  ---  
 MMX    - sad8    0.057 usec       sad=3776  
 MMX    - sad16   0.178 usec       sad=27214  
 MMX    - sad16bi 2.381 usec       sad=26274  
 MMX    - dev16   0.312 usec       sad=3344  
  ---  
 MMXEXT - sad8    0.036 usec       sad=3776  
 MMXEXT - sad16   0.106 usec       sad=27214  
 MMXEXT - sad16bi 0.182 usec       sad=26274  
 MMXEXT - dev16   0.193 usec       sad=3344  
  ---  
 SSE2   - sad8    0.057 usec       sad=3776  
 SSE2   - sad16   0.178 usec       sad=27214  
 SSE2   - sad16bi 2.427 usec       sad=26274  
 SSE2   - dev16   0.313 usec       sad=3344  
  ---  
 3DNOW  - skipped...  
 3DNOWE - skipped...  
   
  ===  test transfer ===  
 PLAINC - 8to16     0.124 usec       crc=28288  
 PLAINC - 16to8     0.753 usec       crc=28288  
 PLAINC - 8to8      0.041 usec       crc=20352  
 PLAINC - 16to8add  0.916 usec       crc=25536  
 PLAINC - 8to16sub  0.812 usec       crc1=28064 crc2=16256  
 PLAINC - 8to16sub2 0.954 usec       crc=20384  
  ---  
 MMX    - 8to16     0.037 usec       crc=28288  
 MMX    - 16to8     0.016 usec       crc=28288  
 MMX    - 8to8      0.018 usec       crc=20352  
 MMX    - 16to8add  0.044 usec       crc=25536  
 MMX    - 8to16sub  0.065 usec       crc1=28064 crc2=16256  
 MMX    - 8to16sub2 0.110 usec       crc=20384  
  ---  
 MMXEXT - 8to16     0.032 usec       crc=28288  
 MMXEXT - 16to8     0.023 usec       crc=28288  
 MMXEXT - 8to8      0.018 usec       crc=20352  
 MMXEXT - 16to8add  0.041 usec       crc=25536  
 MMXEXT - 8to16sub  0.065 usec       crc1=28064 crc2=16256  
 MMXEXT - 8to16sub2 0.069 usec       crc=20384  
  ---  
   
  =====  test quant =====  
 PLAINC -   quant4_intra 78.889 usec       crc=55827  
 PLAINC -   quant4_inter 71.957 usec       crc=58201  
 PLAINC - dequant4_intra 34.968 usec       crc=193340  
 PLAINC - dequant4_inter 40.792 usec       crc=116483  
 PLAINC -    quant_intra 30.845 usec       crc=56885  
 PLAINC -    quant_inter 34.842 usec       crc=58056  
 PLAINC -  dequant_intra 33.211 usec       crc=-7936  
 PLAINC -  dequant_inter 45.486 usec       crc=-33217  
  ---  
 MMX    -   quant4_intra 9.030 usec       crc=55827  
 MMX    -   quant4_inter 8.234 usec       crc=58201  
 MMX    - dequant4_intra 18.330 usec       crc=193340  
 MMX    - dequant4_inter 19.181 usec       crc=116483  
 MMX    -    quant_intra 7.124 usec       crc=56885  
 MMX    -    quant_inter 6.861 usec       crc=58056  
 MMX    -  dequant_intra 9.048 usec       crc=-7936  
 MMX    -  dequant_inter 8.203 usec       crc=-33217  
  ---  
 MMXEXT -   quant4_intra 9.045 usec       crc=55827  
 MMXEXT -   quant4_inter 8.232 usec       crc=58201  
 MMXEXT - dequant4_intra 18.250 usec       crc=193340  
 MMXEXT - dequant4_inter 19.256 usec       crc=116483  
 MMXEXT -    quant_intra 7.121 usec       crc=56885  
 MMXEXT -    quant_inter 6.855 usec       crc=58056  
 MMXEXT -  dequant_intra 9.034 usec       crc=-7936  
 MMXEXT -  dequant_inter 8.202 usec       crc=-33217  
  ---  
   
  =====  test cbp =====  
 PLAINC -   calc_cbp#1 0.545 usec       cbp=0x15  
 PLAINC -   calc_cbp#2 0.540 usec       cbp=0x38  
 PLAINC -   calc_cbp#3 0.477 usec       cbp=0xf  
 PLAINC -   calc_cbp#4 0.739 usec       cbp=0x5  
  ---  
 MMX    -   calc_cbp#1 0.136 usec       cbp=0x15  
 MMX    -   calc_cbp#2 0.131 usec       cbp=0x38  
 MMX    -   calc_cbp#3 0.132 usec       cbp=0xf  
 MMX    -   calc_cbp#4 0.135 usec       cbp=0x5  
  ---  
 SSE2   -   calc_cbp#1 0.135 usec       cbp=0x15  
 SSE2   -   calc_cbp#2 0.131 usec       cbp=0x38  
 SSE2   -   calc_cbp#3 0.134 usec       cbp=0xf  
 SSE2   -   calc_cbp#4 0.136 usec       cbp=0x5  
  ---  
 */  

Legend:
Removed from v.257  
changed lines
  Added in v.1641

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