[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 225, Wed Jun 19 14:27:08 2002 UTC revision 1629, Fri Aug 5 20:49:23 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.23 2005-08-05 20:49:23 Skal 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.0e6f + 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  //, { "TSC   ", XVID_CPU_TSC }          { "3DNOWE ", XVID_CPU_3DNOW | XVID_CPU_3DNOWEXT },
123  , { 0, 0 } }  #endif
124    #ifdef ARCH_IS_PPC
125  , cpu_short_list[] =          { "ALTIVEC", XVID_CPU_ALTIVEC },
126  { { "PLAINC", 0 }  #endif
127  , { "MMX   ", XVID_CPU_MMX }  #ifdef ARCH_IS_X86_64
128  , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }          { "X86_64 ", XVID_CPU_ASM},
129  , { 0, 0 } }  #endif
130    #ifdef ARCH_IS_IA64
131  , cpu_short_list2[] =  //      { "IA64   ", XVID_CPU_IA64 },
132  { { "PLAINC", 0 }  #endif
133  , { "MMX   ", XVID_CPU_MMX }  //      { "TSC    ", XVID_CPU_TSC },
134  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }          { 0, 0 }
135  , { 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 145  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 161  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 178  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 200  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 221  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 264  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 283  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 307  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 365  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 391  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 408  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 422  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 458  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 552  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 564  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    
927    printf( "\n =====  test cbp =====\n" );    printf( "\n =====  test cbp =====\n" );
928    
929    for(i=0; i<6*64; ++i) {    for(i=0; i<6*64; ++i) {
930      Src1[i] = (i*i*3/8192)&(i/64)&1;  // 'random'                  Src1[i] = (i*i*3/8192)&(i/64)&1;  /* 'random' */
931      Src2[i] = (i<3*64);               // half-full                  Src2[i] = (i<3*64);               /* half-full */
932      Src3[i] = ((i+32)>3*64);      Src3[i] = ((i+32)>3*64);
933      Src4[i] = (i==(3*64+2) || i==(5*64+9));      Src4[i] = (i==(3*64+2) || i==(5*64+9));
934    }    }
935    
936    for(cpu = cpu_short_list2; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
937    {    {
938      double t;      double t;
939      int tst, cbp;      int tst, cbp;
# Line 585  Line 941 
941      if (!init_cpu(cpu))      if (!init_cpu(cpu))
942        continue;        continue;
943    
944      TEST_CBP(calc_cbp, Src1);                  TEST_CBP(calc_cbp, Src1, nb_tests);
945      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",
946      if (cbp!=0x15) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x15)?"| ERROR": "");
947      TEST_CBP(calc_cbp, Src2);                  TEST_CBP(calc_cbp, Src2, nb_tests);
948      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",
949      if (cbp!=0x38) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x38)?"| ERROR": "");
950      TEST_CBP(calc_cbp, Src3);                  TEST_CBP(calc_cbp, Src3, nb_tests);
951      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",
952      if (cbp!=0x0f) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x0f)?"| ERROR": "" );
953      TEST_CBP(calc_cbp, Src4);                  TEST_CBP(calc_cbp, Src4, nb_tests);
954      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",
955      if (cbp!=0x05) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x05)?"| ERROR": "" );
956      printf( " --- \n" );      printf( " --- \n" );
957    }    }
958    
959            for(cpu = cpu_list; cpu->name!=0; ++cpu)  /* bench suggested by Carlo (carlo dot bramix at libero dot it) */
960            {
961                    double t;
962                    int tst, cbp, err;
963    
964                    if (!init_cpu(cpu))
965                            continue;
966    
967        err = 0;
968        for(n=0; n<6; ++n)
969        {
970          for(m=0; m<64; ++m)
971          {
972            for(i=0; i<6*64; ++i)
973              Src1[i] = (i== (m + n*64));
974    
975            TEST_CBP(calc_cbp, Src1, 1);
976            if (cbp!= (((m!=0)<<(5-n))))
977            {
978              printf( "%s -   calc_cbp#5: ERROR at pos %d / %d!\n", cpu->name, n, m);
979              err = 1;
980              break;
981            }
982          }
983        }
984        if (!err)
985          printf( " %s -    calc_cbp#5 : OK\n", cpu->name );
986    
987            }
988    }
989    
990    /*********************************************************************
991     * fdct/idct IEEE1180 compliance
992     *********************************************************************/
993    
994    typedef struct {
995            long Errors[64];
996            long Sqr_Errors[64];
997            long Max_Errors[64];
998            long Nb;
999    } STATS_8x8;
1000    
1001    void init_stats(STATS_8x8 *S)
1002    {
1003            int i;
1004            for(i=0; i<64; ++i) {
1005                    S->Errors[i]     = 0;
1006                    S->Sqr_Errors[i] = 0;
1007                    S->Max_Errors[i] = 0;
1008            }
1009            S->Nb = 0;
1010    }
1011    
1012    void store_stats(STATS_8x8 *S, short Blk[64], short Ref[64])
1013    {
1014            int i;
1015            for(i=0; i<64; ++i)
1016            {
1017                    short Err = Blk[i] - Ref[i];
1018                    S->Errors[i] += Err;
1019                    S->Sqr_Errors[i] += Err * Err;
1020                    if (Err<0) Err = -Err;
1021                    if (S->Max_Errors[i]<Err)
1022                            S->Max_Errors[i] = Err;
1023            }
1024            S->Nb++;
1025    }
1026    
1027    void print_stats(STATS_8x8 *S)
1028    {
1029            int i;
1030            double Norm;
1031    
1032            assert(S->Nb>0);
1033            Norm = 1. / (double)S->Nb;
1034            printf("\n== Max absolute values of errors ==\n");
1035            for(i=0; i<64; i++) {
1036                    printf("  %4ld", S->Max_Errors[i]);
1037                    if ((i&7)==7) printf("\n");
1038            }
1039    
1040            printf("\n== Mean square errors ==\n");
1041            for(i=0; i<64; i++)
1042            {
1043                    double Err = Norm * (double)S->Sqr_Errors[i];
1044                    printf(" %.3f", Err);
1045                    if ((i&7)==7) printf("\n");
1046            }
1047    
1048            printf("\n== Mean errors ==\n");
1049            for(i=0; i<64; i++)
1050            {
1051                    double Err = Norm * (double)S->Errors[i];
1052                    printf(" %.3f", Err);
1053                    if ((i&7)==7) printf("\n");
1054            }
1055            printf("\n");
1056    }
1057    
1058    static const char *CHECK(double v, double l) {
1059            if (fabs(v)<=l) return "ok";
1060            else return "FAIL!";
1061    }
1062    
1063    void report_stats(STATS_8x8 *S, const double *Limits)
1064    {
1065            int i;
1066            double Norm, PE, PMSE, OMSE, PME, OME;
1067    
1068            assert(S->Nb>0);
1069            Norm = 1. / (double)S->Nb;
1070            PE = 0.;
1071            for(i=0; i<64; i++) {
1072                    if (PE<S->Max_Errors[i])
1073                            PE = S->Max_Errors[i];
1074            }
1075    
1076            PMSE = 0.;
1077            OMSE = 0.;
1078            for(i=0; i<64; i++)
1079            {
1080                    double Err = Norm * (double)S->Sqr_Errors[i];
1081                    OMSE += Err;
1082                    if (PMSE < Err) PMSE = Err;
1083            }
1084            OMSE /= 64.;
1085    
1086            PME = 0.;
1087            OME = 0.;
1088            for(i=0; i<64; i++)
1089            {
1090                    double Err = Norm * (double)S->Errors[i];
1091                    OME += Err;
1092                    Err = fabs(Err);
1093                    if (PME < Err) PME = Err;
1094            }
1095            OME /= 64.;
1096    
1097            printf( "Peak error:   %4.4f\n", PE );
1098            printf( "Peak MSE:     %4.4f\n", PMSE );
1099            printf( "Overall MSE:  %4.4f\n", OMSE );
1100            printf( "Peak ME:      %4.4f\n", PME );
1101            printf( "Overall ME:   %4.4f\n", OME );
1102    
1103            if (Limits!=0)
1104            {
1105                    printf( "[PE<=%.4f %s]  ", Limits[0], CHECK(PE,   Limits[0]) );
1106                    printf( "\n" );
1107                    printf( "[PMSE<=%.4f %s]", Limits[1], CHECK(PMSE, Limits[1]) );
1108                    printf( "[OMSE<=%.4f %s]", Limits[2], CHECK(OMSE, Limits[2]) );
1109                    printf( "\n" );
1110                    printf( "[PME<=%.4f %s] ", Limits[3], CHECK(PME , Limits[3]) );
1111                    printf( "[OME<=%.4f %s] ", Limits[4], CHECK(OME , Limits[4]) );
1112                    printf( "\n" );
1113            }
1114    }
1115    
1116    ///* ////////////////////////////////////////////////////// */
1117    /* Pseudo-random generator specified by IEEE 1180 */
1118    
1119    static long ieee_seed = 1;
1120    static void ieee_reseed(long s) {
1121            ieee_seed = s;
1122    }
1123    static long ieee_rand(int Min, int Max)
1124    {
1125            static double z = (double) 0x7fffffff;
1126    
1127            long i,j;
1128            double x;
1129    
1130            ieee_seed = (ieee_seed * 1103515245) + 12345;
1131            i = ieee_seed & 0x7ffffffe;
1132            x = ((double) i) / z;
1133            x *= (Max-Min+1);
1134            j = (long)x;
1135            j = j + Min;
1136            assert(j>=Min && j<=Max);
1137            return (short)j;
1138    }
1139    
1140    #define CLAMP(x, M)   (x) = ((x)<-(M)) ? (-(M)) : ((x)>=(M) ? ((M)-1) : (x))
1141    
1142    static double Cos[8][8];
1143    static void init_ref_dct()
1144    {
1145            int i, j;
1146            for(i=0; i<8; i++)
1147            {
1148                    double scale = (i == 0) ? sqrt(0.125) : 0.5;
1149                    for (j=0; j<8; j++)
1150                            Cos[i][j] = scale*cos( (M_PI/8.0)*i*(j + 0.5) );
1151            }
1152    }
1153    
1154    void ref_idct(short *M)
1155    {
1156            int i, j, k;
1157            double Tmp[8][8];
1158    
1159            for(i=0; i<8; i++) {
1160                    for(j=0; j<8; j++)
1161                    {
1162                            double Sum = 0.0;
1163                            for (k=0; k<8; k++) Sum += Cos[k][j]*M[8*i+k];
1164                            Tmp[i][j] = Sum;
1165                    }
1166            }
1167            for(i=0; i<8; i++) {
1168                    for(j=0; j<8; j++) {
1169                            double Sum = 0.0;
1170                            for (k=0; k<8; k++) Sum += Cos[k][i]*Tmp[k][j];
1171                            M[8*i+j] = (short)floor(Sum + .5);
1172                    }
1173            }
1174    }
1175    
1176    void ref_fdct(short *M)
1177    {
1178            int i, j, k;
1179            double Tmp[8][8];
1180    
1181            for(i=0; i<8; i++) {
1182                    for(j=0; j<8; j++)
1183                    {
1184                            double Sum = 0.0;
1185                            for (k=0; k<8; k++) Sum += Cos[j][k]*M[8*i+k];
1186                            Tmp[i][j] = Sum;
1187                    }
1188            }
1189            for(i=0; i<8; i++) {
1190                    for(j=0; j<8; j++) {
1191                            double Sum = 0.0;
1192                            for (k=0; k<8; k++) Sum += Cos[i][k]*Tmp[k][j];
1193                            M[8*i+j] = (short)floor(Sum + 0.5);
1194                    }
1195            }
1196    }
1197    
1198    void test_IEEE1180_compliance(int Min, int Max, int Sign)
1199    {
1200            static const double ILimits[5] = { 1., 0.06, 0.02, 0.015, 0.0015 };
1201            int Loops = 10000;
1202            int i, m, n;
1203            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, short, 16); /* reference */
1204            DECLARE_ALIGNED_MATRIX(Blk,  8, 8, short, 16);
1205            DECLARE_ALIGNED_MATRIX(iBlk, 8, 8, short, 16);
1206            DECLARE_ALIGNED_MATRIX(Ref_FDCT, 8, 8, short, 16);
1207            DECLARE_ALIGNED_MATRIX(Ref_IDCT, 8, 8, short, 16);
1208    
1209            STATS_8x8 FStats; /* forward dct stats */
1210            STATS_8x8 IStats; /* inverse dct stats */
1211    
1212            CPU *cpu;
1213    
1214            init_ref_dct();
1215    
1216            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1217            {
1218                    if (!init_cpu(cpu))
1219                            continue;
1220    
1221                    printf( "\n===== IEEE test for %s ==== (Min=%d Max=%d Sign=%d Loops=%d)\n",
1222                                    cpu->name, Min, Max, Sign, Loops);
1223    
1224                    init_stats(&IStats);
1225                    init_stats(&FStats);
1226    
1227                    ieee_reseed(1);
1228                    for(n=0; n<Loops; ++n)
1229                    {
1230                            for(i=0; i<64; ++i)
1231                                    Blk0[i] = (short)ieee_rand(Min,Max) * Sign;
1232    
1233                            /* hmm, I'm not quite sure this is exactly */
1234                            /* the tests described in the norm. check... */
1235    
1236                            memcpy(Ref_FDCT, Blk0, 64*sizeof(short));
1237                            ref_fdct(Ref_FDCT);
1238                            for(i=0; i<64; i++) CLAMP( Ref_FDCT[i], 2048 );
1239    
1240                            memcpy(Blk, Blk0, 64*sizeof(short));
1241                            emms(); fdct(Blk); emms();
1242                            for(i=0; i<64; i++) CLAMP( Blk[i], 2048 );
1243    
1244                            store_stats(&FStats, Blk, Ref_FDCT);
1245    
1246    
1247                            memcpy(Ref_IDCT, Ref_FDCT, 64*sizeof(short));
1248                            ref_idct(Ref_IDCT);
1249                            for (i=0; i<64; i++) CLAMP( Ref_IDCT[i], 256 );
1250    
1251                            memcpy(iBlk, Ref_FDCT, 64*sizeof(short));
1252                            emms(); idct(iBlk); emms();
1253                            for(i=0; i<64; i++) CLAMP( iBlk[i], 256 );
1254    
1255                            store_stats(&IStats, iBlk, Ref_IDCT);
1256                    }
1257    
1258    
1259                    printf( "\n  -- FDCT report --\n" );
1260    //    print_stats(&FStats);
1261                    report_stats(&FStats, 0); /* so far I know, IEEE1180 says nothing for fdct */
1262    
1263                    for(i=0; i<64; i++) Blk[i] = 0;
1264                    emms(); fdct(Blk); emms();
1265                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1266                    printf( "FDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1267    
1268                    printf( "\n  -- IDCT report --\n" );
1269    //    print_stats(&IStats);
1270                    report_stats(&IStats, ILimits);
1271    
1272    
1273                    for(i=0; i<64; i++) Blk[i] = 0;
1274                    emms(); idct(Blk); emms();
1275                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1276                    printf( "IDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1277            }
1278    }
1279    
1280    
1281    void test_dct_saturation(int Min, int Max)
1282    {
1283    /* test behaviour on input range fringe */
1284    
1285            int i, n, p;
1286            CPU *cpu;
1287    //  const short IDCT_MAX =  2047;  /* 12bits input */
1288    //  const short IDCT_MIN = -2048;
1289    //  const short IDCT_OUT =   256;  /* 9bits ouput */
1290            const int Partitions = 4;
1291            const int Loops = 10000 / Partitions;
1292    
1293            init_ref_dct();
1294    
1295            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1296            {
1297                    short Blk0[64], Blk[64];
1298                    STATS_8x8 Stats;
1299    
1300                    if (!init_cpu(cpu))
1301                            continue;
1302    
1303                    printf( "\n===== IEEE test for %s Min=%d Max=%d =====\n",
1304                                    cpu->name, Min, Max );
1305    
1306                    /* FDCT tests // */
1307    
1308                    init_stats(&Stats);
1309    
1310                    /* test each computation channels separately */
1311                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Max : 0;
1312                    ref_fdct(Blk0);
1313                    emms(); fdct(Blk); emms();
1314                    store_stats(&Stats, Blk, Blk0);
1315    
1316                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Min : 0;
1317                    ref_fdct(Blk0);
1318                    emms(); fdct(Blk); emms();
1319                    store_stats(&Stats, Blk, Blk0);
1320    
1321                    /* randomly saturated inputs */
1322                    for(p=0; p<Partitions; ++p)
1323                    {
1324                            for(n=0; n<Loops; ++n)
1325                            {
1326                                    for(i=0; i<64; ++i)
1327                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? Max : Min;
1328                                    ref_fdct(Blk0);
1329                                    emms(); fdct(Blk); emms();
1330                                    store_stats(&Stats, Blk, Blk0);
1331                            }
1332                    }
1333                    printf( "\n  -- FDCT saturation report --\n" );
1334                    report_stats(&Stats, 0);
1335    
1336    
1337                    /* IDCT tests // */
1338    #if 0
1339                    /* no finished yet */
1340    
1341                    init_stats(&Stats);
1342    
1343    /* test each computation channel separately */
1344                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MAX : 0;
1345                    ref_idct(Blk0);
1346                    emms(); idct(Blk); emms();
1347                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1348                    store_stats(&Stats, Blk, Blk0);
1349    
1350                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MIN : 0;
1351                    ref_idct(Blk0);
1352                    emms(); idct(Blk); emms();
1353                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1354                    store_stats(&Stats, Blk, Blk0);
1355    
1356                    /* randomly saturated inputs */
1357                    for(p=0; p<Partitions; ++p)
1358                    {
1359                            for(n=0; n<Loops; ++n)
1360                            {
1361                                    for(i=0; i<64; ++i)
1362                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? IDCT_MAX : IDCT_MIN;
1363                                    ref_idct(Blk0);
1364                                    emms(); idct(Blk); emms();
1365                                    for(i=0; i<64; i++) { CLAMP(Blk0[i],IDCT_OUT); CLAMP(Blk[i],IDCT_OUT); }
1366                                    store_stats(&Stats, Blk, Blk0);
1367                            }
1368                    }
1369    
1370                    printf( "\n  -- IDCT saturation report --\n" );
1371                    print_stats(&Stats);
1372                    report_stats(&Stats, 0);
1373    #endif
1374            }
1375  }  }
1376    
1377  /*********************************************************************  /*********************************************************************
1378   * measure raw decoding speed   * measure raw decoding speed
1379   *********************************************************************/   *********************************************************************/
1380    
1381  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)
1382  {  {
1383    FILE *f = 0;    FILE *f = 0;
1384    void *dechandle = 0;    void *dechandle = 0;
1385    int xerr;    int xerr;
1386          XVID_INIT_PARAM xinit;          xvid_gbl_init_t xinit;
1387          XVID_DEC_PARAM xparam;          xvid_dec_create_t xparam;
1388          XVID_DEC_FRAME xframe;          xvid_dec_frame_t xframe;
1389          double t = 0.;          double t = 0.;
1390          int nb = 0;          int nb = 0;
1391    uint8_t *buf = 0;    uint8_t *buf = 0;
1392    uint8_t *rgb_out = 0;          uint8_t *yuv_out = 0;
1393    int buf_size, pos;    int buf_size, pos;
1394    uint32_t chksum = 0;    uint32_t chksum = 0;
1395            int bps = (width+31) & ~31;
1396    
1397          xinit.cpu_flags = 0;          memset(&xinit, 0, sizeof(xinit));
1398          xvid_init(NULL, 0, &xinit, NULL);          xinit.cpu_flags = cpu_mask;
1399          printf( "API version: %d, core build:%d\n", xinit.api_version, xinit.core_build);          xinit.version = XVID_VERSION;
1400            xvid_global(NULL, 0, &xinit, NULL);
1401    
1402            memset(&xparam, 0, sizeof(xparam));
1403          xparam.width = width;          xparam.width = width;
1404          xparam.height = height;          xparam.height = height;
1405            xparam.version = XVID_VERSION;
1406          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
1407          if (xerr!=XVID_ERR_OK) {          if (xerr==XVID_ERR_FAIL) {
1408            printf("can't init decoder (err=%d)\n", xerr);                  printf("ERROR: can't init decoder (err=%d)\n", xerr);
1409            return;            return;
1410          }          }
1411          dechandle = xparam.handle;          dechandle = xparam.handle;
# Line 637  Line 1413 
1413    
1414          f = fopen(name, "rb");          f = fopen(name, "rb");
1415    if (f==0) {    if (f==0) {
1416      printf( "can't open file '%s'\n", name);                  printf( "ERROR: can't open file '%s'\n", name);
1417      return;      return;
1418    }    }
1419    fseek(f, 0, SEEK_END);    fseek(f, 0, SEEK_END);
1420    buf_size = ftell(f);    buf_size = ftell(f);
1421    fseek(f, 0, SEEK_SET);    fseek(f, 0, SEEK_SET);
1422    if (buf_size<=0) {    if (buf_size<=0) {
1423      printf("error while stating file\n");                  printf("ERROR: error while stating file\n");
1424      goto End;      goto End;
1425    }    }
   else printf( "Input size: %d\n", buf_size);  
1426    
1427    buf = malloc(buf_size); // should be enuf'          buf = malloc(buf_size);
1428    rgb_out = calloc(4, width*height);  // <-room for _RGB24          yuv_out = calloc(1, bps*height*3/2 + 15);
1429    if (buf==0 || rgb_out==0) {          if (buf==0 || yuv_out==0) {
1430      printf( "malloc failed!\n" );                  printf( "ERROR: malloc failed!\n" );
1431      goto End;      goto End;
1432    }    }
1433    
1434    if (fread(buf, buf_size, 1, f)!=1) {    if (fread(buf, buf_size, 1, f)!=1) {
1435      printf( "file-read failed\n" );                  printf( "ERROR: file-read failed\n" );
1436      goto End;      goto End;
1437    }    }
1438    
# Line 665  Line 1440 
1440    pos = 0;    pos = 0;
1441    t = -gettime_usec();    t = -gettime_usec();
1442    while(1) {    while(1) {
1443              int y;
1444    
1445                    memset(&xframe, 0, sizeof(xframe));
1446                    xframe.version = XVID_VERSION;
1447      xframe.bitstream = buf + pos;      xframe.bitstream = buf + pos;
1448      xframe.length = buf_size - pos;      xframe.length = buf_size - pos;
1449      xframe.image = rgb_out;                  xframe.output.plane[0] = (uint8_t*)(((size_t)yuv_out + 15) & ~15);
1450      xframe.stride = width;                  xframe.output.plane[1] = xframe.output.plane[0] + bps*height;
1451      xframe.colorspace = XVID_CSP_RGB24;                  xframe.output.plane[2] = xframe.output.plane[1] + bps/2;
1452                    xframe.output.stride[0] = bps;
1453                    xframe.output.stride[1] = bps;
1454                    xframe.output.stride[2] = bps;
1455                    xframe.output.csp = XVID_CSP_I420;
1456      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);
1457                    if (xerr<0) {
1458                            printf("ERROR: decoding failed for frame #%d (err=%d)!\n", nb, xerr);
1459                            break;
1460                    }
1461                    else if (xerr==0)
1462                      break;
1463        else if (verbose>0) printf("#%d %d\n", nb, xerr );
1464    
1465                    pos += xerr;
1466      nb++;      nb++;
1467      pos += xframe.length;  
1468      if (with_chksum) {      for(y=0; y<height/2; ++y) {
1469        int k = width*height;                    chksum = calc_crc(xframe.output.plane[0] + (2*y+0)*bps, width, chksum);
1470        uint32_t *ptr = (uint32_t *)rgb_out;                          chksum = calc_crc(xframe.output.plane[0] + (2*y+1)*bps, width, chksum);
1471        while(k-->0) chksum += *ptr++;                          chksum = calc_crc(xframe.output.plane[1] + y*bps, width/2, chksum);
1472                            chksum = calc_crc(xframe.output.plane[2] + y*bps, width/2, chksum);
1473      }      }
1474      if (pos==buf_size)      if (pos==buf_size)
1475        break;        break;
     if (xerr!=XVID_ERR_OK) {  
           printf("decoding failed for frame #%d (err=%d)!\n", nb, xerr);  
           break;  
         }  
1476    }    }
1477    t += gettime_usec();    t += gettime_usec();
1478            if (ref_chksum==0) {
1479    if (t>0.)    if (t>0.)
1480      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 );
1481    if (with_chksum)    }
1482      printf("checksum: 0x%.8x\n", chksum);    else {
1483                    printf("FPS:%.1f Checksum: 0x%.8x Expected:0x%.8x | %s\n",
1484                      t>0. ? (float)(nb*1.e6f/t) : 0.f, chksum, ref_chksum, (chksum==ref_chksum) ? "OK" : "ERROR");
1485      }
1486    
1487  End:  End:
1488    if (rgb_out!=0) free(rgb_out);          if (yuv_out!=0) free(yuv_out);
1489    if (buf!=0) free(buf);    if (buf!=0) free(buf);
1490    if (dechandle!=0) {    if (dechandle!=0) {
1491      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);
1492      if (xerr!=XVID_ERR_OK)                  if (xerr==XVID_ERR_FAIL)
1493              printf("destroy-decoder failed (err=%d)!\n", xerr);                          printf("ERROR: destroy-decoder failed (err=%d)!\n", xerr);
1494    }    }
1495    if (f!=0) fclose(f);    if (f!=0) fclose(f);
1496  }  }
# Line 709  Line 1502 
1502  void test_bugs1()  void test_bugs1()
1503  {  {
1504    CPU *cpu;    CPU *cpu;
1505            uint16_t mpeg_quant_matrices[64*8];
1506    
1507    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );
1508    
1509    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1510    {    {
1511      int i;      int i;
1512      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 721  Line 1515 
1515        continue;        continue;
1516    
1517      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1518      set_intra_matrix( get_default_intra_matrix() );                  set_intra_matrix( mpeg_quant_matrices, get_default_intra_matrix() );
1519      dequant4_intra(Dst, Src, 32, 5);                  dequant_mpeg_intra(Dst, Src, 31, 5, mpeg_quant_matrices);
1520      printf( "dequant4_intra with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_intra with CPU=%s:  ", cpu->name);
1521      printf( "  Out[]= " );      printf( "  Out[]= " );
1522      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1523      printf( "\n" );      printf( "\n" );
# Line 731  Line 1525 
1525    
1526    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );
1527    
1528    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1529    {    {
1530      int i;      int i;
1531      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 740  Line 1534 
1534        continue;        continue;
1535    
1536      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1537      set_inter_matrix( get_default_inter_matrix() );                  set_inter_matrix( mpeg_quant_matrices, get_default_inter_matrix() );
1538      dequant4_inter(Dst, Src, 32);                  dequant_mpeg_inter(Dst, Src, 31, mpeg_quant_matrices);
1539      printf( "dequant4_inter with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_inter with CPU=%s:  ", cpu->name);
1540      printf( "  Out[]= " );      printf( "  Out[]= " );
1541      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1542      printf( "\n" );      printf( "\n" );
# Line 752  Line 1546 
1546  void test_dct_precision_diffs()  void test_dct_precision_diffs()
1547  {  {
1548    CPU *cpu;    CPU *cpu;
1549    short Blk[8*8], Blk0[8*8];          DECLARE_ALIGNED_MATRIX(Blk, 8, 8, int16_t, 16);
1550            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, int16_t, 16);
1551    
1552    printf( "\n =====  fdct/idct saturation diffs =====\n" );          printf( "\n =====  fdct/idct precision diffs =====\n" );
1553    
1554    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1555    {    {
1556      int i;      int i;
1557    
# Line 780  Line 1575 
1575    }    }
1576  }  }
1577    
1578    void test_quant_bug()
1579    {
1580            const int max_Q = 31;
1581            int i, n, qm, q;
1582            CPU *cpu;
1583            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
1584            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
1585            uint8_t Quant[8*8];
1586            CPU cpu_bug_list[] = { { "PLAINC", 0 }, { "MMX   ", XVID_CPU_MMX }, {0,0} };
1587            uint16_t Crcs_Inter[2][32];
1588            uint16_t Crcs_Intra[2][32];
1589            DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
1590    
1591            printf( "\n =====  test MPEG4-quantize bug =====\n" );
1592    
1593            for(i=0; i<64; ++i) Src[i] = 2048*(i-32)/32;
1594    
1595    #if 1
1596            for(qm=1; qm<=255; ++qm)
1597            {
1598                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1599                    set_inter_matrix( mpeg_quant_matrices, Quant );
1600    
1601                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1602                    {
1603                            uint16_t s;
1604    
1605                            if (!init_cpu(cpu))
1606                                    continue;
1607    
1608                            for(q=1; q<=max_Q; ++q) {
1609                                    emms();
1610                                    quant_mpeg_inter( Dst, Src, q, mpeg_quant_matrices );
1611                                    emms();
1612                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1613                                    Crcs_Inter[n][q] = s;
1614                            }
1615                    }
1616    
1617                    for(q=1; q<=max_Q; ++q)
1618                            for(i=0; i<n-1; ++i)
1619                                    if (Crcs_Inter[i][q]!=Crcs_Inter[i+1][q])
1620                                            printf( "Discrepancy Inter: qm=%d, q=%d  -> %d/%d !\n",
1621                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1622            }
1623    #endif
1624    
1625    #if 1
1626            for(qm=1; qm<=255; ++qm)
1627            {
1628                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1629                    set_intra_matrix( mpeg_quant_matrices, Quant );
1630    
1631                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1632                    {
1633                            uint16_t s;
1634    
1635                            if (!init_cpu(cpu))
1636                                    continue;
1637    
1638                            for(q=1; q<=max_Q; ++q) {
1639                                    emms();
1640                                    quant_mpeg_intra( Dst, Src, q, q, mpeg_quant_matrices);
1641                                    emms();
1642                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1643                                    Crcs_Intra[n][q] = s;
1644                            }
1645                    }
1646    
1647                    for(q=1; q<=max_Q; ++q)
1648                            for(i=0; i<n-1; ++i)
1649                                    if (Crcs_Intra[i][q]!=Crcs_Intra[i+1][q])
1650                                            printf( "Discrepancy Intra: qm=%d, q=%d  -> %d/%d!\n",
1651                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1652            }
1653    #endif
1654    }
1655    /*********************************************************************/
1656    
1657    static uint32_t __inline log2bin_v1(uint32_t value)
1658    {
1659      int n = 0;
1660      while (value) {
1661        value >>= 1;
1662        n++;
1663      }
1664      return n;
1665    }
1666    
1667    static const uint8_t log2_tab_16[16] =  { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
1668    
1669    static uint32_t __inline log2bin_v2(uint32_t value)
1670    {
1671      int n = 0;
1672      if (value & 0xffff0000) {
1673        value >>= 16;
1674        n += 16;
1675      }
1676      if (value & 0xff00) {
1677        value >>= 8;
1678        n += 8;
1679      }
1680      if (value & 0xf0) {
1681        value >>= 4;
1682        n += 4;
1683      }
1684     return n + log2_tab_16[value];
1685    }
1686    
1687    void test_log2bin()
1688    {
1689            const int nb_tests = 3000*speed_ref;
1690      int n, crc1=0, crc2=0;
1691      uint32_t s, s0;
1692      double t1, t2;
1693    
1694      t1 = gettime_usec();
1695      s0 = (int)(t1*31.241);
1696      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1697        crc1 += log2bin_v1(s);
1698      t1 = (gettime_usec()-t1) / nb_tests;
1699    
1700      t2 = gettime_usec();
1701      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1702        crc2 += log2bin_v2(s);
1703      t2 = (gettime_usec() - t2) / nb_tests;
1704    
1705      printf( "log2bin_v1: %.3f sec  crc=%d\n", t1, crc1 );
1706      printf( "log2bin_v2: %.3f sec  crc=%d\n", t2, crc2 );
1707      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1708    }
1709    
1710    /*********************************************************************/
1711    
1712    static void __inline old_gcd(int *num, int *den)
1713    {
1714     int i = *num;
1715      while (i > 1) {
1716        if (*num % i == 0 && *den % i == 0) {
1717          *num /= i;
1718          *den /= i;
1719          i = *num;
1720          continue;
1721        }
1722        i--;
1723      }
1724    }
1725    
1726    static uint32_t gcd(int num, int den)
1727    {
1728      int tmp;
1729      while( (tmp=num%den) ) { num = den; den = tmp; }
1730      return den;
1731    }
1732    static void __inline new_gcd(int *num, int *den)
1733    {
1734      const int div = gcd(*num, *den);
1735      if (num) {
1736        *num /= div;
1737        *den /= div;
1738      }
1739    }
1740    
1741    void test_gcd()
1742    {
1743            const int nb_tests = 10*speed_ref;
1744      int i;
1745      uint32_t crc1=0, crc2=0;
1746      uint32_t n0, n, d0, d;
1747      double t1, t2;
1748    
1749      t1 = gettime_usec();
1750      n0 = 0xfffff & (int)(t1*31.241);
1751      d0 = 0xfffff & (int)( ((n0*4123)%17) | 1 );
1752      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1753        old_gcd(&n, &d);
1754        crc1 = (((crc1>>4)^d) + ((crc1<<2)^n) ) & 0xffffff;
1755        n = d;
1756        d = (d*12363+31) & 0xffff;
1757        d |= !d;
1758      }
1759      t1 = (gettime_usec()-t1) / nb_tests;
1760    
1761      t2 = gettime_usec();
1762      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1763        new_gcd(&n, &d);
1764        crc2 = (((crc2>>4)^d) + ((crc2<<2)^n) ) & 0xffffff;
1765        n = d;
1766        d = (d*12363+31) & 0xffff;
1767        d |= !d;
1768      }
1769      t2 = (gettime_usec() - t2) / nb_tests;
1770    
1771      printf( "old_gcd: %.3f sec  crc=%d\n", t1, crc1 );
1772      printf( "new_gcd: %.3f sec  crc=%d\n", t2, crc2 );
1773      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1774    }
1775    
1776  /*********************************************************************  /*********************************************************************
1777   * main   * main
1778   *********************************************************************/   *********************************************************************/
1779    
1780  int main(int argc, char *argv[])  static void arg_missing(const char *opt)
1781    {
1782      printf( "missing argument after option '%s'\n", opt);
1783      exit(-1);
1784    }
1785    
1786    int main(int argc, const char *argv[])
1787    {
1788            int c, what = 0;
1789            int width, height;
1790            uint32_t chksum = 0;
1791      const char * test_bitstream = 0;
1792    
1793            cpu_mask = 0;  // default => will use autodectect
1794            for(c=1; c<argc; ++c)
1795  {  {
1796    int what = 0;            if (!strcmp(argv[c], "-v")) verbose++;
1797    if (argc>1) what = atoi(argv[1]);            else if (!strcmp(argv[c], "-c"))      cpu_mask = 0 /* PLAIN_C */ | XVID_CPU_FORCE;
1798              else if (!strcmp(argv[c], "-mmx"))    cpu_mask = XVID_CPU_MMX    | XVID_CPU_FORCE;
1799              else if (!strcmp(argv[c], "-mmxext")) cpu_mask = XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
1800              else if (!strcmp(argv[c], "-sse2"))   cpu_mask = XVID_CPU_SSE2   | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
1801              else if (!strcmp(argv[c], "-3dnow"))  cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_FORCE;
1802              else if (!strcmp(argv[c], "-3dnowe")) cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_3DNOWEXT | XVID_CPU_FORCE;
1803              else if (!strcmp(argv[c], "-altivec")) cpu_mask = XVID_CPU_ALTIVEC | XVID_CPU_FORCE;
1804              else if (!strcmp(argv[c], "-spd")) {
1805          if (++c==argc) arg_missing( argv[argc-1] );
1806          speed_ref = atoi(argv[c]);
1807        }
1808              else if (argv[c][0]!='-') {
1809                what = atoi(argv[c]);
1810                if (what==9) {
1811                  if (c+4>argc) {
1812                    printf("usage: %s %d bitstream width height (checksum)\n", argv[0], what);
1813                    exit(-1);
1814            }
1815            test_bitstream = argv[++c];
1816                  width  = atoi(argv[++c]);
1817                  height = atoi(argv[++c]);
1818                  if (c+1<argc && argv[c+1][0]!='-') {
1819                    if (sscanf(argv[c+1], "0x%x", &chksum)!=1) {
1820                      printf( "can't read checksum value.\n" );
1821                      exit(-1);
1822              }
1823              else c++;
1824            }
1825    //        printf( "[%s] %dx%d (0x%.8x)\n", test_bitstream, width, height, chksum);
1826          }
1827        }
1828        else {
1829          printf( "unrecognized option '%s'\n", argv[c]);
1830          exit(-1);
1831        }
1832      }
1833    
1834    
1835    if (what==0 || what==1) test_dct();    if (what==0 || what==1) test_dct();
1836    if (what==0 || what==2) test_mb();    if (what==0 || what==2) test_mb();
1837    if (what==0 || what==3) test_sad();    if (what==0 || what==3) test_sad();
1838    if (what==0 || what==4) test_transfer();    if (what==0 || what==4) test_transfer();
1839    if (what==0 || what==5) test_quant();    if (what==0 || what==5) test_quant();
1840    if (what==0 || what==6) test_cbp();    if (what==0 || what==6) test_cbp();
1841            if (what==0 || what==10) test_sse();
1842    if (what==8) {          if (what==0 || what==11) test_log2bin();
1843      int width, height;          if (what==0 || what==12) test_gcd();
1844      if (argc<5) {  
1845        printf("usage: %s %d [bitstream] [width] [height]\n", argv[0], what);  
1846        return 1;          if (what==7) {
1847      }                  test_IEEE1180_compliance(-256, 255, 1);
1848      width = atoi(argv[3]);                  test_IEEE1180_compliance(-256, 255,-1);
1849      height = atoi(argv[4]);                  test_IEEE1180_compliance(  -5,   5, 1);
1850      test_dec(argv[2], width, height, (argc>5));                  test_IEEE1180_compliance(  -5,   5,-1);
1851                    test_IEEE1180_compliance(-300, 300, 1);
1852                    test_IEEE1180_compliance(-300, 300,-1);
1853    }    }
1854            if (what==8) test_dct_saturation(-256, 255);
1855    
1856            if (test_bitstream)
1857              test_dec(test_bitstream, width, height, chksum);
1858    if (what==-1) {    if (what==-1) {
     test_bugs1();  
1859      test_dct_precision_diffs();      test_dct_precision_diffs();
1860                    test_bugs1();
1861    }    }
1862    return 0;          if (what==-2)
1863                    test_quant_bug();
1864    
1865            if ((what >= 0 && what <= 6) || what == 10) {
1866                    printf("\n\n"
1867                               "NB: If a function isn't optimised for a specific set of intructions,\n"
1868                               "    a C function is used instead. So don't panic if some functions\n"
1869                               "    may appear to be slow.\n");
1870            }
1871    
1872    #ifdef ARCH_IS_IA32
1873            if (what == 0 || what == 5) {
1874                    printf("\n"
1875                               "NB: MMX mpeg4 quantization is known to have very small errors (+/-1 magnitude)\n"
1876                               "    for 1 or 2 coefficients a block. This is mainly caused by the fact the unit\n"
1877                               "    test goes far behind the usual limits of real encoding. Please do not report\n"
1878                               "    this error to the developers.\n");
1879  }  }
1880    #endif
1881    
1882  /*********************************************************************          return 0;
1883   * 'Reference' output (except for timing) on a PIII 1.13Ghz/linux  }
  *********************************************************************/  
 /*  
1884    
1885   ===== 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.225  
changed lines
  Added in v.1629

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