[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 1652, Thu Nov 3 05:44:07 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.27 2005-11-03 05:44:07 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        /* New functions for field prediction by CK 1.10.2005 */
522    #pragma NEW8X4
523                    TEST_MB(interpolate8x4_halfpel_h, 0);
524                    printf("%s - interpfield-h -round0 %.3f usec       crc32=0x%08x %s\n",
525                               cpu->name, t, iCrc,
526                               (iCrc!=0x9538d6df)?"| ERROR": "" );
527    
528                    TEST_MB(interpolate8x4_halfpel_h, 1);
529                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
530                               cpu->name, t, iCrc,
531                               (iCrc!=0xde5f1db4)?"| ERROR": "" );
532    
533    
534                    TEST_MB(interpolate8x4_halfpel_v, 0);
535                    printf("%s - interpfield- v-round0 %.3f usec       crc32=0x%08x %s\n",
536                               cpu->name, t, iCrc,
537                               (iCrc!=0xea5a69ef)?"| ERROR": "" );
538    
539                    TEST_MB(interpolate8x4_halfpel_v, 1);
540                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
541                               cpu->name, t, iCrc,
542                               (iCrc!=0x4f10ec0f)?"| ERROR": "" );
543    
544    
545                    TEST_MB(interpolate8x4_halfpel_hv, 0);
546                    printf("%s - interpfield-hv-round0 %.3f usec       crc32=0x%08x %s\n",
547                               cpu->name, t, iCrc,
548                               (iCrc!=0xf97ee367)?"| ERROR": "" );
549    
550                    TEST_MB(interpolate8x4_halfpel_hv, 1);
551                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
552                               cpu->name, t, iCrc,
553                               (iCrc!=0xb6a9f581)?"| ERROR": "" );
554    /* End of 8x4 functions */
555    
556      printf( " --- \n" );      printf( " --- \n" );
557    }    }
# Line 365  Line 586 
586      }                                         \      }                                         \
587      emms();                                   \      emms();                                   \
588      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
589      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]));  \
590    s = calc_crc((uint8_t*)(DST), 8*32*sizeof((DST)[0]), CRC32_INITIAL)
591    
592  #define TEST_TRANSFER(FUNC, DST, SRC)         \  #define TEST_TRANSFER(FUNC, DST, SRC)         \
593      TEST_TRANSFER_BEGIN(DST);                 \      TEST_TRANSFER_BEGIN(DST);                 \
# Line 391  Line 613 
613      }                                         \      }                                         \
614      emms();                                   \      emms();                                   \
615      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
616      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]));  \
617    s = calc_crc((uint8_t*)(DST), 8*32*sizeof((DST)[0]), CRC32_INITIAL)
618    
619  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \
620      TEST_TRANSFER2_BEGIN(DST,SRC);            \      TEST_TRANSFER2_BEGIN(DST,SRC);            \
# Line 408  Line 631 
631    const int nb_tests = 4000*speed_ref;    const int nb_tests = 4000*speed_ref;
632    int i;    int i;
633    CPU *cpu;    CPU *cpu;
634    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];
635    int16_t Src16[8*32], Dst16[8*32];  //      int16_t Src16[8*32], Dst16[8*32];
636      DECLARE_ALIGNED_MATRIX(Src8, 8, 32, uint8_t, CACHE_LINE);
637      DECLARE_ALIGNED_MATRIX(Dst8, 8, 32, uint8_t, CACHE_LINE);
638      DECLARE_ALIGNED_MATRIX(Ref1, 8, 32, uint8_t, CACHE_LINE);
639      DECLARE_ALIGNED_MATRIX(Ref2, 8, 32, uint8_t, CACHE_LINE);
640      DECLARE_ALIGNED_MATRIX(Src16, 8, 32, uint16_t, CACHE_LINE);
641      DECLARE_ALIGNED_MATRIX(Dst16, 8, 32, uint16_t, CACHE_LINE);
642    
643    printf( "\n ===  test transfer ===\n" );    printf( "\n ===  test transfer ===\n" );
644    
645    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
646    {    {
647      double t, overhead;      double t, overhead;
648      int tst, s;      int tst, s;
# Line 422  Line 651 
651        continue;        continue;
652    
653      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);
654      printf( "%s - 8to16     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16     %.3f usec       crc32=0x%08x %s\n",
655      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
656                               (s!=0x115814bb)?"| ERROR": "");
657    
658      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);
659      printf( "%s - 16to8     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf( "%s - 16to8     %.3f usec       crc32=0x%08x %s\n",
660      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
661                                    (s!=0xee7ccbb4)?"| ERROR": "");
662    
663        /* New functions for field prediction by CK 1.10.2005 */
664    #pragma NEW8X4
665                    TEST_TRANSFER(transfer8x4_copy, Dst8, Src8);
666                    printf("%s - 8to4      %.3f usec       crc32=0x%08x %s\n",
667                               cpu->name, t, s,
668                               (s!=0xbb9c3db5)?"| ERROR": "");
669    /* End of new functions */
670    
671      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);
672      printf( "%s - 8to8      %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to8      %.3f usec       crc32=0x%08x %s\n",
673      if (s!=20352) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
674                               (s!=0xd37b3295)?"| ERROR": "");
675    
676      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);
677      printf( "%s - 16to8add  %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 16to8add  %.3f usec       crc32=0x%08x %s\n",
678      if (s!=25536) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
679                               (s!=0xdd817bf4)?"| ERROR": "" );
680    
681      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);
682      printf( "%s - 8to16sub  %.3f usec       crc1=%d ", cpu->name, t, s );                  {
683      if (s!=28064) printf( "*** CRC ERROR! ***\n" );                          int s1, s2;
684      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);
685      printf( "crc2=%d\n", s);                          s2 = calc_crc((uint8_t*)Src8, 8*32*sizeof(Src8[0]), CRC32_INITIAL);
686      if (s!=16256) printf( "*** CRC ERROR! ***\n" );                          printf("%s - 8to16sub  %.3f usec       crc32(1)=0x%08x crc32(2)=0x%08x %s %s\n",
687                                       cpu->name, t, s1, s2,
688                                       (s1!=0xa1e07163)?"| ERROR1": "",
689                                       (s2!=0xd86c5d23)?"| ERROR2": "" );
690                    }
691    
692      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);
693      printf( "%s - 8to16sub2 %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16sub2 %.3f usec       crc32=0x%08x %s\n",
694      if (s!=20384) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
695                               (s!=0x99b6c4c7)?"| ERROR": "" );
696    
697      printf( " --- \n" );      printf( " --- \n" );
698    }    }
# Line 458  Line 704 
704    
705  #define TEST_QUANT(FUNC, DST, SRC)            \  #define TEST_QUANT(FUNC, DST, SRC)            \
706      t = gettime_usec();                       \      t = gettime_usec();                       \
707    for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
708      for(i=0; i<8*8; ++i) Quant[i] = qm;       \
709      set_inter_matrix( mpeg_quant_matrices, Quant );                \
710      emms();                                   \      emms();                                   \
711      for(q=1; q<=max_Q; ++q) {                 \
712      for(tst=0; tst<nb_tests; ++tst)           \      for(tst=0; tst<nb_tests; ++tst)           \
713        for(s=0, q=1; q<=max_Q; ++q) {          \            (FUNC)((DST), (SRC), q, mpeg_quant_matrices);              \
714          (FUNC)((DST), (SRC), q);              \          byte_swap((uint8_t*)(DST), 64*sizeof((DST)[0]), sizeof((DST)[0]));  \
715          for(i=0; i<64; ++i) s+=(DST)[i]^i;    \          s = calc_crc((uint8_t*)(DST), 64*sizeof((DST)[0]), s); \
716        }                                       \        }                                       \
717      emms();                                   \      emms();                                   \
718      t = (gettime_usec()-t-overhead)/nb_tests;  }                                           \
719    t = (gettime_usec()-t-overhead)/nb_tests/qm
720    
721  #define TEST_QUANT2(FUNC, DST, SRC, MULT)     \  #define TEST_QUANT2(FUNC, DST, SRC)             \
722      t = gettime_usec();                       \      t = gettime_usec();                       \
723    for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
724      for(i=0; i<8*8; ++i) Quant[i] = qm;       \
725      set_intra_matrix( mpeg_quant_matrices, Quant );                \
726      emms();                                   \      emms();                                   \
727      for(q=1; q<=max_Q; ++q) {                 \
728      for(tst=0; tst<nb_tests; ++tst)           \      for(tst=0; tst<nb_tests; ++tst)           \
729        for(s=0, q=1; q<=max_Q; ++q) {          \            (FUNC)((DST), (SRC), q, q, mpeg_quant_matrices);           \
730          (FUNC)((DST), (SRC), q, MULT);        \          byte_swap((uint8_t*)(DST), 64*sizeof((DST)[0]), sizeof((DST)[0]));  \
731          for(i=0; i<64; ++i) s+=(DST)[i]^i;    \          s = calc_crc((uint8_t*)(DST), 64*sizeof((DST)[0]), s); \
732        }                                       \        }                                       \
733      emms();                                   \      emms();                                   \
734      t = (gettime_usec()-t-overhead)/nb_tests;  }                                           \
735    t = (gettime_usec()-t-overhead)/nb_tests/qm
736    
737    #define TEST_INTRA(REFFUNC, NEWFUNC, RANGE)              \
738    { int i,q,s;\
739            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16); \
740      DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16); \
741      DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16); \
742      for(q=1;q<=max_Q;q++)          \
743        for(s=-RANGE;s<RANGE;s++) { \
744          for(i=0;i<64;i++) Src[i]=s; \
745          (REFFUNC)((Dst),(Src),q,q,mpeg_quant_matrices);   \
746          (NEWFUNC)((Dst2),(Src),q,q,mpeg_quant_matrices);  \
747          for(i=0;i<64;i++)     \
748            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]);  \
749        }      \
750    }
751    
752    #define TEST_INTER(REFFUNC, NEWFUNC, RANGE)              \
753    { int i,q,s;  \
754            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16); \
755      DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16); \
756      DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16); \
757      for(q=1;q<=max_Q;q++)  \
758        for(s=-RANGE;s<RANGE;s++) {   \
759          for(i=0;i<64;i++) Src[i]=s; \
760          (REFFUNC)((Dst),(Src),q,mpeg_quant_matrices);  \
761          (NEWFUNC)((Dst2),(Src),q,mpeg_quant_matrices); \
762          emms();           \
763          for(i=0;i<64;i++) \
764            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]); \
765        } \
766    }
767    
768  void test_quant()  void test_quant()
769  {  {
770    const int nb_tests = 150*speed_ref;          const int nb_tests = 1*speed_ref;
771    const int max_Q = 31;    const int max_Q = 31;
772    int i;          DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
773    
774            int i, qm;
775    CPU *cpu;    CPU *cpu;
776    int16_t  Src[8*8], Dst[8*8];          DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
777            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
778            DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16);
779            uint8_t Quant[8*8];
780    
781    printf( "\n =====  test quant =====\n" );    printf( "\n =====  test quant =====\n" );
782    
783    /* we deliberately enfringe the norm's specified range [-127,127], */
784    /* to test the robustness of the iquant module */
785    for(i=0; i<64; ++i) {    for(i=0; i<64; ++i) {
786      Src[i] = i-32;                  Src[i] = 1 + (i-32) * (i&6);
787      Dst[i] = 0;      Dst[i] = 0;
788    }    }
789    
790            for(cpu = cpu_list; cpu->name!=0; ++cpu)
   for(cpu = cpu_short_list; cpu->name!=0; ++cpu)  
791    {    {
792      double t, overhead;      double t, overhead;
793      int tst, s, q;                  int tst, q;
794                    uint32_t s;
795    
796      if (!init_cpu(cpu))      if (!init_cpu(cpu))
797        continue;        continue;
798    
799      set_inter_matrix( get_default_inter_matrix() );                  // exhaustive tests to compare against the (ref) C-version
800      set_intra_matrix( get_default_intra_matrix() );                  TEST_INTRA(quant_h263_intra_c,   quant_h263_intra,    2048);
801                    TEST_INTRA(dequant_h263_intra_c, dequant_h263_intra , 512 );
802                    TEST_INTER(quant_h263_inter_c,   quant_h263_inter ,   2048);
803                    TEST_INTER(dequant_h263_inter_c, dequant_h263_inter , 512 );
804    
805      overhead = -gettime_usec();      overhead = -gettime_usec();
806      for(tst=0; tst<nb_tests; ++tst)                  for(s=0,qm=1; qm<=255; ++qm) {
807        for(s=0, q=1; q<=max_Q; ++q)                          for(i=0; i<8*8; ++i) Quant[i] = qm;
808          for(i=0; i<64; ++i) s+=Dst[i]^i;                          set_inter_matrix(mpeg_quant_matrices, Quant );
809                            for(q=1; q<=max_Q; ++q)
810                                    for(i=0; i<64; ++i) s+=Dst[i]^i^qm;
811                    }
812      overhead += gettime_usec();      overhead += gettime_usec();
813    
814      TEST_QUANT2(quant4_intra, Dst, Src, 7);                  TEST_QUANT2(quant_mpeg_intra, Dst, Src);
815      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",
816      if (s!=55827) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
817                               (s!=0xfd6a21a4)? "| ERROR": "");
818      TEST_QUANT(quant4_inter, Dst, Src);  
819      printf( "%s -   quant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT(quant_mpeg_inter, Dst, Src);
820      if (s!=58201) printf( "*** CRC ERROR! ***\n" );                  printf("%s -   quant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
821                               cpu->name, t, s,
822                               (s!=0xf6de7757)?"| ERROR": "");
823      TEST_QUANT2(dequant4_intra, Dst, Src, 7);  
824      printf( "%s - dequant4_intra %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(dequant_mpeg_intra, Dst, Src);
825      if (s!=193340) printf( "*** CRC ERROR! ***\n" );                  printf("%s - dequant_mpeg_intra %.3f usec       crc32=0x%08x %s\n",
826                               cpu->name, t, s,
827      TEST_QUANT(dequant4_inter, Dst, Src);                             (s!=0x2def7bc7)?"| ERROR": "");
828      printf( "%s - dequant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );  
829      if (s!=116483) printf( "*** CRC ERROR! ***\n" );                  TEST_QUANT(dequant_mpeg_inter, Dst, Src);
830                    printf("%s - dequant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
831      TEST_QUANT2(quant_intra, Dst, Src, 7);                             cpu->name, t, s,
832      printf( "%s -    quant_intra %.3f usec       crc=%d\n", cpu->name, t, s );                             (s!=0xd878c722)?"| ERROR": "");
833      if (s!=56885) printf( "*** CRC ERROR! ***\n" );  
834                    TEST_QUANT2(quant_h263_intra, Dst, Src);
835      TEST_QUANT(quant_inter, Dst, Src);                  printf("%s -   quant_h263_intra %.3f usec       crc32=0x%08x %s\n",
836      printf( "%s -    quant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                             cpu->name, t, s,
837      if (s!=58056) printf( "*** CRC ERROR! ***\n" );                             (s!=0x2eba9d43)?"| ERROR": "");
838    
839      TEST_QUANT2(dequant_intra, Dst, Src, 7);                  TEST_QUANT(quant_h263_inter, Dst, Src);
840      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",
841      if (s!=-7936) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
842                               (s!=0xbd315a7e)?"| ERROR": "");
843      TEST_QUANT(dequant_inter, Dst, Src);  
844      printf( "%s -  dequant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(dequant_h263_intra, Dst, Src);
845  //    { 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",
846      if (s!=-33217) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
847                               (s!=0x9841212a)?"| ERROR": "");
848    
849                    TEST_QUANT(dequant_h263_inter, Dst, Src);
850                    printf("%s - dequant_h263_inter %.3f usec       crc32=0x%08x %s\n",
851                               cpu->name, t, s,
852                               (s!=0xe7df8fba)?"| ERROR": "");
853    
854                    printf( " --- \n" );
855            }
856    }
857    
858    /*********************************************************************
859     * test distortion operators
860     *********************************************************************/
861    
862    static void ieee_reseed(long s);
863    static long ieee_rand(int Min, int Max);
864    
865    #define TEST_SSE(FUNCTION, SRC1, SRC2, STRIDE) \
866      do { \
867        t = gettime_usec(); \
868        tst = nb_tests; \
869        while((tst--)>0) sse = (FUNCTION)((SRC1), (SRC2), (STRIDE)); \
870        emms(); \
871        t = (gettime_usec() - t)/(double)nb_tests;  \
872      } while(0)
873    
874    
875    void test_sse()
876    {
877            const int nb_tests = 100000*speed_ref;
878            int i;
879            CPU *cpu;
880            DECLARE_ALIGNED_MATRIX(Src1, 8, 8, int16_t, 16);
881            DECLARE_ALIGNED_MATRIX(Src2, 8, 8, int16_t, 16);
882            DECLARE_ALIGNED_MATRIX(Src3, 8, 8, int16_t, 16);
883            DECLARE_ALIGNED_MATRIX(Src4, 8, 8, int16_t, 16);
884    
885            printf( "\n =====  test sse =====\n" );
886    
887            ieee_reseed(1);
888            for(i=0; i<64; ++i) {
889                    Src1[i] = ieee_rand(-2048, 2047);
890                    Src2[i] = ieee_rand(-2048, 2047);
891                    Src3[i] = ieee_rand(-2048, 2047);
892                    Src4[i] = ieee_rand(-2048, 2047);
893            }
894    
895            for(cpu = cpu_list; cpu->name!=0; ++cpu)
896            {
897                    double t;
898                    int tst, sse;
899    
900                    if (!init_cpu(cpu))
901                            continue;
902    
903                    /* 16 bit element blocks */
904                    TEST_SSE(sse8_16bit, Src1, Src2, 16);
905                    printf("%s -   sse8_16bit#1 %.3f usec       sse=%d %s\n",
906                               cpu->name, t, sse, (sse!=182013834)?"| ERROR": "");
907                    TEST_SSE(sse8_16bit, Src1, Src3, 16);
908                    printf("%s -   sse8_16bit#2 %.3f usec       sse=%d %s\n",
909                               cpu->name, t, sse, (sse!=142545203)?"| ERROR": "");
910                    TEST_SSE(sse8_16bit, Src1, Src4, 16);
911                    printf("%s -   sse8_16bit#3 %.3f usec       sse=%d %s\n",
912                               cpu->name, t, sse, (sse!=146340935)?"| ERROR": "");
913                    TEST_SSE(sse8_16bit, Src2, Src3, 16);
914                    printf("%s -   sse8_16bit#4 %.3f usec       sse=%d %s\n",
915                               cpu->name, t, sse, (sse!=130136661)?"| ERROR": "");
916                    TEST_SSE(sse8_16bit, Src2, Src4, 16);
917                    printf("%s -   sse8_16bit#5 %.3f usec       sse=%d %s\n",
918                               cpu->name, t, sse, (sse!=136870353)?"| ERROR": "");
919                    TEST_SSE(sse8_16bit, Src3, Src4, 16);
920                    printf("%s -   sse8_16bit#6 %.3f usec       sse=%d %s\n",
921                               cpu->name, t, sse, (sse!=164107772)?"| ERROR": "");
922    
923                    /* 8 bit element blocks */
924                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src2, 8);
925                    printf("%s -    sse8_8bit#1 %.3f usec       sse=%d %s\n",
926                               cpu->name, t, sse, (sse!=1356423)?"| ERROR": "");
927                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src3, 8);
928                    printf("%s -    sse8_8bit#2 %.3f usec       sse=%d %s\n",
929                               cpu->name, t, sse, (sse!=1173074)?"| ERROR": "");
930                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src4, 8);
931                    printf("%s -    sse8_8bit#3 %.3f usec       sse=%d %s\n",
932                               cpu->name, t, sse, (sse!=1092357)?"| ERROR": "");
933                    TEST_SSE(sse8_8bit, (int8_t*)Src2, (int8_t*)Src3, 8);
934                    printf("%s -    sse8_8bit#4 %.3f usec       sse=%d %s\n",
935                               cpu->name, t, sse, (sse!=1360239)?"| ERROR": "");
936                    TEST_SSE(sse8_8bit, (int8_t*)Src2, (int8_t*)Src4, 8);
937                    printf("%s -    sse8_8bit#5 %.3f usec       sse=%d %s\n",
938                               cpu->name, t, sse, (sse!=1208414)?"| ERROR": "");
939                    TEST_SSE(sse8_8bit, (int8_t*)Src3, (int8_t*)Src4, 8);
940                    printf("%s -    sse8_8bit#6 %.3f usec       sse=%d %s\n",
941                               cpu->name, t, sse, (sse!=1099285)?"| ERROR": "");
942    
943      printf( " --- \n" );      printf( " --- \n" );
944    }    }
# Line 552  Line 948 
948   * test non-zero AC counting   * test non-zero AC counting
949   *********************************************************************/   *********************************************************************/
950    
951  #define TEST_CBP(FUNC, SRC)                   \  #define TEST_CBP(FUNC, SRC, NB)           \
952      t = gettime_usec();                       \      t = gettime_usec();                       \
953      emms();                                   \      emms();                                   \
954      for(tst=0; tst<nb_tests; ++tst) {         \  for(tst=0; tst<NB; ++tst) {         \
955        cbp = (FUNC)((SRC));                    \        cbp = (FUNC)((SRC));                    \
956      }                                         \      }                                         \
957      emms();                                   \      emms();                                   \
# Line 564  Line 960 
960  void test_cbp()  void test_cbp()
961  {  {
962    const int nb_tests = 10000*speed_ref;    const int nb_tests = 10000*speed_ref;
963    int i;          int i, n, m;
964    CPU *cpu;    CPU *cpu;
965    int16_t  Src1[6*64], Src2[6*64], Src3[6*64], Src4[6*64];          DECLARE_ALIGNED_MATRIX(Src1, 6, 64, int16_t, 16);
966            DECLARE_ALIGNED_MATRIX(Src2, 6, 64, int16_t, 16);
967            DECLARE_ALIGNED_MATRIX(Src3, 6, 64, int16_t, 16);
968            DECLARE_ALIGNED_MATRIX(Src4, 6, 64, int16_t, 16);
969      DECLARE_ALIGNED_MATRIX(Src5, 6, 64, int16_t, 16);
970    
971    printf( "\n =====  test cbp =====\n" );    printf( "\n =====  test cbp =====\n" );
972    
973    for(i=0; i<6*64; ++i) {    for(i=0; i<6*64; ++i) {
974      Src1[i] = (i*i*3/8192)&(i/64)&1;  // 'random'                  Src1[i] = (i*i*3/8192)&(i/64)&1;  /* 'random' */
975      Src2[i] = (i<3*64);               // half-full                  Src2[i] = (i<3*64);               /* half-full */
976      Src3[i] = ((i+32)>3*64);      Src3[i] = ((i+32)>3*64);
977      Src4[i] = (i==(3*64+2) || i==(5*64+9));      Src4[i] = (i==(3*64+2) || i==(5*64+9));
978        Src5[i] = ieee_rand(0,1) ? -1 : 1;  /* +/- test */
979    }    }
980    
981    for(cpu = cpu_short_list2; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
982    {    {
983      double t;      double t;
984      int tst, cbp;      int tst, cbp;
# Line 585  Line 986 
986      if (!init_cpu(cpu))      if (!init_cpu(cpu))
987        continue;        continue;
988    
989      TEST_CBP(calc_cbp, Src1);                  TEST_CBP(calc_cbp, Src1, nb_tests);
990      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",
991      if (cbp!=0x15) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x15)?"| ERROR": "");
992      TEST_CBP(calc_cbp, Src2);                  TEST_CBP(calc_cbp, Src2, nb_tests);
993      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",
994      if (cbp!=0x38) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x38)?"| ERROR": "");
995      TEST_CBP(calc_cbp, Src3);                  TEST_CBP(calc_cbp, Src3, nb_tests);
996      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",
997      if (cbp!=0x0f) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x0f)?"| ERROR": "" );
998      TEST_CBP(calc_cbp, Src4);                  TEST_CBP(calc_cbp, Src4, nb_tests);
999      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",
1000      if (cbp!=0x05) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x05)?"| ERROR": "" );
1001                    TEST_CBP(calc_cbp, Src5, nb_tests);
1002                    printf("%s -   calc_cbp#4 %.3f usec       cbp=0x%02x %s\n",
1003                               cpu->name, t, cbp, (cbp!=0x3f)?"| ERROR": "" );
1004      printf( " --- \n" );      printf( " --- \n" );
1005    }    }
1006    
1007            for(cpu = cpu_list; cpu->name!=0; ++cpu)  /* bench suggested by Carlo (carlo dot bramix at libero dot it) */
1008            {
1009                    double t;
1010                    int tst, cbp, err;
1011    
1012                    if (!init_cpu(cpu))
1013                            continue;
1014    
1015        err = 0;
1016        for(n=0; n<6; ++n)
1017        {
1018          for(m=0; m<64; ++m)
1019          {
1020            for(i=0; i<6*64; ++i)
1021              Src1[i] = (i== (m + n*64));
1022    
1023            TEST_CBP(calc_cbp, Src1, 1);
1024            if (cbp!= (((m!=0)<<(5-n))))
1025            {
1026              printf( "%s -   calc_cbp#5: ERROR at pos %d / %d!\n", cpu->name, n, m);
1027              err = 1;
1028              break;
1029            }
1030          }
1031        }
1032        if (!err)
1033          printf( " %s -    calc_cbp#5 : OK\n", cpu->name );
1034    
1035            }
1036    }
1037    
1038    /*********************************************************************
1039     * fdct/idct IEEE1180 compliance
1040     *********************************************************************/
1041    
1042    typedef struct {
1043            long Errors[64];
1044            long Sqr_Errors[64];
1045            long Max_Errors[64];
1046            long Nb;
1047    } STATS_8x8;
1048    
1049    void init_stats(STATS_8x8 *S)
1050    {
1051            int i;
1052            for(i=0; i<64; ++i) {
1053                    S->Errors[i]     = 0;
1054                    S->Sqr_Errors[i] = 0;
1055                    S->Max_Errors[i] = 0;
1056            }
1057            S->Nb = 0;
1058    }
1059    
1060    void store_stats(STATS_8x8 *S, short Blk[64], short Ref[64])
1061    {
1062            int i;
1063            for(i=0; i<64; ++i)
1064            {
1065                    short Err = Blk[i] - Ref[i];
1066                    S->Errors[i] += Err;
1067                    S->Sqr_Errors[i] += Err * Err;
1068                    if (Err<0) Err = -Err;
1069                    if (S->Max_Errors[i]<Err)
1070                            S->Max_Errors[i] = Err;
1071            }
1072            S->Nb++;
1073    }
1074    
1075    void print_stats(STATS_8x8 *S)
1076    {
1077            int i;
1078            double Norm;
1079    
1080            assert(S->Nb>0);
1081            Norm = 1. / (double)S->Nb;
1082            printf("\n== Max absolute values of errors ==\n");
1083            for(i=0; i<64; i++) {
1084                    printf("  %4ld", S->Max_Errors[i]);
1085                    if ((i&7)==7) printf("\n");
1086            }
1087    
1088            printf("\n== Mean square errors ==\n");
1089            for(i=0; i<64; i++)
1090            {
1091                    double Err = Norm * (double)S->Sqr_Errors[i];
1092                    printf(" %.3f", Err);
1093                    if ((i&7)==7) printf("\n");
1094            }
1095    
1096            printf("\n== Mean errors ==\n");
1097            for(i=0; i<64; i++)
1098            {
1099                    double Err = Norm * (double)S->Errors[i];
1100                    printf(" %.3f", Err);
1101                    if ((i&7)==7) printf("\n");
1102            }
1103            printf("\n");
1104    }
1105    
1106    static const char *CHECK(double v, double l) {
1107            if (fabs(v)<=l) return "ok";
1108            else return "FAIL!";
1109    }
1110    
1111    void report_stats(STATS_8x8 *S, const double *Limits)
1112    {
1113            int i;
1114            double Norm, PE, PMSE, OMSE, PME, OME;
1115    
1116            assert(S->Nb>0);
1117            Norm = 1. / (double)S->Nb;
1118            PE = 0.;
1119            for(i=0; i<64; i++) {
1120                    if (PE<S->Max_Errors[i])
1121                            PE = S->Max_Errors[i];
1122            }
1123    
1124            PMSE = 0.;
1125            OMSE = 0.;
1126            for(i=0; i<64; i++)
1127            {
1128                    double Err = Norm * (double)S->Sqr_Errors[i];
1129                    OMSE += Err;
1130                    if (PMSE < Err) PMSE = Err;
1131            }
1132            OMSE /= 64.;
1133    
1134            PME = 0.;
1135            OME = 0.;
1136            for(i=0; i<64; i++)
1137            {
1138                    double Err = Norm * (double)S->Errors[i];
1139                    OME += Err;
1140                    Err = fabs(Err);
1141                    if (PME < Err) PME = Err;
1142            }
1143            OME /= 64.;
1144    
1145            printf( "Peak error:   %4.4f\n", PE );
1146            printf( "Peak MSE:     %4.4f\n", PMSE );
1147            printf( "Overall MSE:  %4.4f\n", OMSE );
1148            printf( "Peak ME:      %4.4f\n", PME );
1149            printf( "Overall ME:   %4.4f\n", OME );
1150    
1151            if (Limits!=0)
1152            {
1153                    printf( "[PE<=%.4f %s]  ", Limits[0], CHECK(PE,   Limits[0]) );
1154                    printf( "\n" );
1155                    printf( "[PMSE<=%.4f %s]", Limits[1], CHECK(PMSE, Limits[1]) );
1156                    printf( "[OMSE<=%.4f %s]", Limits[2], CHECK(OMSE, Limits[2]) );
1157                    printf( "\n" );
1158                    printf( "[PME<=%.4f %s] ", Limits[3], CHECK(PME , Limits[3]) );
1159                    printf( "[OME<=%.4f %s] ", Limits[4], CHECK(OME , Limits[4]) );
1160                    printf( "\n" );
1161            }
1162    }
1163    
1164    ///* ////////////////////////////////////////////////////// */
1165    /* Pseudo-random generator specified by IEEE 1180 */
1166    
1167    static long ieee_seed = 1;
1168    static void ieee_reseed(long s) {
1169            ieee_seed = s;
1170    }
1171    static long ieee_rand(int Min, int Max)
1172    {
1173            static double z = (double) 0x7fffffff;
1174    
1175            long i,j;
1176            double x;
1177    
1178            ieee_seed = (ieee_seed * 1103515245) + 12345;
1179            i = ieee_seed & 0x7ffffffe;
1180            x = ((double) i) / z;
1181            x *= (Max-Min+1);
1182            j = (long)x;
1183            j = j + Min;
1184            assert(j>=Min && j<=Max);
1185            return (short)j;
1186    }
1187    
1188    #define CLAMP(x, M)   (x) = ((x)<-(M)) ? (-(M)) : ((x)>=(M) ? ((M)-1) : (x))
1189    
1190    static double Cos[8][8];
1191    static void init_ref_dct()
1192    {
1193            int i, j;
1194            for(i=0; i<8; i++)
1195            {
1196                    double scale = (i == 0) ? sqrt(0.125) : 0.5;
1197                    for (j=0; j<8; j++)
1198                            Cos[i][j] = scale*cos( (M_PI/8.0)*i*(j + 0.5) );
1199            }
1200    }
1201    
1202    void ref_idct(short *M)
1203    {
1204            int i, j, k;
1205            double Tmp[8][8];
1206    
1207            for(i=0; i<8; i++) {
1208                    for(j=0; j<8; j++)
1209                    {
1210                            double Sum = 0.0;
1211                            for (k=0; k<8; k++) Sum += Cos[k][j]*M[8*i+k];
1212                            Tmp[i][j] = Sum;
1213                    }
1214            }
1215            for(i=0; i<8; i++) {
1216                    for(j=0; j<8; j++) {
1217                            double Sum = 0.0;
1218                            for (k=0; k<8; k++) Sum += Cos[k][i]*Tmp[k][j];
1219                            M[8*i+j] = (short)floor(Sum + .5);
1220                    }
1221            }
1222    }
1223    
1224    void ref_fdct(short *M)
1225    {
1226            int i, j, k;
1227            double Tmp[8][8];
1228    
1229            for(i=0; i<8; i++) {
1230                    for(j=0; j<8; j++)
1231                    {
1232                            double Sum = 0.0;
1233                            for (k=0; k<8; k++) Sum += Cos[j][k]*M[8*i+k];
1234                            Tmp[i][j] = Sum;
1235                    }
1236            }
1237            for(i=0; i<8; i++) {
1238                    for(j=0; j<8; j++) {
1239                            double Sum = 0.0;
1240                            for (k=0; k<8; k++) Sum += Cos[i][k]*Tmp[k][j];
1241                            M[8*i+j] = (short)floor(Sum + 0.5);
1242                    }
1243            }
1244    }
1245    
1246    void test_IEEE1180_compliance(int Min, int Max, int Sign)
1247    {
1248            static const double ILimits[5] = { 1., 0.06, 0.02, 0.015, 0.0015 };
1249            int Loops = 10000;
1250            int i, m, n;
1251            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, short, 16); /* reference */
1252            DECLARE_ALIGNED_MATRIX(Blk,  8, 8, short, 16);
1253            DECLARE_ALIGNED_MATRIX(iBlk, 8, 8, short, 16);
1254            DECLARE_ALIGNED_MATRIX(Ref_FDCT, 8, 8, short, 16);
1255            DECLARE_ALIGNED_MATRIX(Ref_IDCT, 8, 8, short, 16);
1256    
1257            STATS_8x8 FStats; /* forward dct stats */
1258            STATS_8x8 IStats; /* inverse dct stats */
1259    
1260            CPU *cpu;
1261    
1262            init_ref_dct();
1263    
1264            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1265            {
1266                    if (!init_cpu(cpu))
1267                            continue;
1268    
1269                    printf( "\n===== IEEE test for %s ==== (Min=%d Max=%d Sign=%d Loops=%d)\n",
1270                                    cpu->name, Min, Max, Sign, Loops);
1271    
1272                    init_stats(&IStats);
1273                    init_stats(&FStats);
1274    
1275                    ieee_reseed(1);
1276                    for(n=0; n<Loops; ++n)
1277                    {
1278                            for(i=0; i<64; ++i)
1279                                    Blk0[i] = (short)ieee_rand(Min,Max) * Sign;
1280    
1281                            /* hmm, I'm not quite sure this is exactly */
1282                            /* the tests described in the norm. check... */
1283    
1284                            memcpy(Ref_FDCT, Blk0, 64*sizeof(short));
1285                            ref_fdct(Ref_FDCT);
1286                            for(i=0; i<64; i++) CLAMP( Ref_FDCT[i], 2048 );
1287    
1288                            memcpy(Blk, Blk0, 64*sizeof(short));
1289                            emms(); fdct(Blk); emms();
1290                            for(i=0; i<64; i++) CLAMP( Blk[i], 2048 );
1291    
1292                            store_stats(&FStats, Blk, Ref_FDCT);
1293    
1294    
1295                            memcpy(Ref_IDCT, Ref_FDCT, 64*sizeof(short));
1296                            ref_idct(Ref_IDCT);
1297                            for (i=0; i<64; i++) CLAMP( Ref_IDCT[i], 256 );
1298    
1299                            memcpy(iBlk, Ref_FDCT, 64*sizeof(short));
1300                            emms(); idct(iBlk); emms();
1301                            for(i=0; i<64; i++) CLAMP( iBlk[i], 256 );
1302    
1303                            store_stats(&IStats, iBlk, Ref_IDCT);
1304                    }
1305    
1306    
1307                    printf( "\n  -- FDCT report --\n" );
1308    //    print_stats(&FStats);
1309                    report_stats(&FStats, 0); /* so far I know, IEEE1180 says nothing for fdct */
1310    
1311                    for(i=0; i<64; i++) Blk[i] = 0;
1312                    emms(); fdct(Blk); emms();
1313                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1314                    printf( "FDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1315    
1316                    printf( "\n  -- IDCT report --\n" );
1317    //    print_stats(&IStats);
1318                    report_stats(&IStats, ILimits);
1319    
1320    
1321                    for(i=0; i<64; i++) Blk[i] = 0;
1322                    emms(); idct(Blk); emms();
1323                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1324                    printf( "IDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1325            }
1326    }
1327    
1328    
1329    void test_dct_saturation(int Min, int Max)
1330    {
1331    /* test behaviour on input range fringe */
1332    
1333            int i, n, p;
1334            CPU *cpu;
1335    //  const short IDCT_MAX =  2047;  /* 12bits input */
1336    //  const short IDCT_MIN = -2048;
1337    //  const short IDCT_OUT =   256;  /* 9bits ouput */
1338            const int Partitions = 4;
1339            const int Loops = 10000 / Partitions;
1340    
1341            init_ref_dct();
1342    
1343            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1344            {
1345                    short Blk0[64], Blk[64];
1346                    STATS_8x8 Stats;
1347    
1348                    if (!init_cpu(cpu))
1349                            continue;
1350    
1351                    printf( "\n===== IEEE test for %s Min=%d Max=%d =====\n",
1352                                    cpu->name, Min, Max );
1353    
1354                    /* FDCT tests // */
1355    
1356                    init_stats(&Stats);
1357    
1358                    /* test each computation channels separately */
1359                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Max : 0;
1360                    ref_fdct(Blk0);
1361                    emms(); fdct(Blk); emms();
1362                    store_stats(&Stats, Blk, Blk0);
1363    
1364                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Min : 0;
1365                    ref_fdct(Blk0);
1366                    emms(); fdct(Blk); emms();
1367                    store_stats(&Stats, Blk, Blk0);
1368    
1369                    /* randomly saturated inputs */
1370                    for(p=0; p<Partitions; ++p)
1371                    {
1372                            for(n=0; n<Loops; ++n)
1373                            {
1374                                    for(i=0; i<64; ++i)
1375                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? Max : Min;
1376                                    ref_fdct(Blk0);
1377                                    emms(); fdct(Blk); emms();
1378                                    store_stats(&Stats, Blk, Blk0);
1379                            }
1380                    }
1381                    printf( "\n  -- FDCT saturation report --\n" );
1382                    report_stats(&Stats, 0);
1383    
1384    
1385                    /* IDCT tests // */
1386    #if 0
1387                    /* no finished yet */
1388    
1389                    init_stats(&Stats);
1390    
1391    /* test each computation channel separately */
1392                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MAX : 0;
1393                    ref_idct(Blk0);
1394                    emms(); idct(Blk); emms();
1395                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1396                    store_stats(&Stats, Blk, Blk0);
1397    
1398                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MIN : 0;
1399                    ref_idct(Blk0);
1400                    emms(); idct(Blk); emms();
1401                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1402                    store_stats(&Stats, Blk, Blk0);
1403    
1404                    /* randomly saturated inputs */
1405                    for(p=0; p<Partitions; ++p)
1406                    {
1407                            for(n=0; n<Loops; ++n)
1408                            {
1409                                    for(i=0; i<64; ++i)
1410                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? IDCT_MAX : IDCT_MIN;
1411                                    ref_idct(Blk0);
1412                                    emms(); idct(Blk); emms();
1413                                    for(i=0; i<64; i++) { CLAMP(Blk0[i],IDCT_OUT); CLAMP(Blk[i],IDCT_OUT); }
1414                                    store_stats(&Stats, Blk, Blk0);
1415                            }
1416                    }
1417    
1418                    printf( "\n  -- IDCT saturation report --\n" );
1419                    print_stats(&Stats);
1420                    report_stats(&Stats, 0);
1421    #endif
1422            }
1423  }  }
1424    
1425  /*********************************************************************  /*********************************************************************
1426   * measure raw decoding speed   * measure raw decoding speed
1427   *********************************************************************/   *********************************************************************/
1428    
1429  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)
1430  {  {
1431    FILE *f = 0;    FILE *f = 0;
1432    void *dechandle = 0;    void *dechandle = 0;
1433    int xerr;    int xerr;
1434          XVID_INIT_PARAM xinit;          xvid_gbl_init_t xinit;
1435          XVID_DEC_PARAM xparam;          xvid_dec_create_t xparam;
1436          XVID_DEC_FRAME xframe;          xvid_dec_frame_t xframe;
1437          double t = 0.;          double t = 0.;
1438          int nb = 0;          int nb = 0;
1439    uint8_t *buf = 0;    uint8_t *buf = 0;
1440    uint8_t *rgb_out = 0;          uint8_t *yuv_out = 0;
1441    int buf_size, pos;    int buf_size, pos;
1442    uint32_t chksum = 0;    uint32_t chksum = 0;
1443            int bps = (width+31) & ~31;
1444    
1445          xinit.cpu_flags = 0;          memset(&xinit, 0, sizeof(xinit));
1446          xvid_init(NULL, 0, &xinit, NULL);          xinit.cpu_flags = cpu_mask;
1447          printf( "API version: %d, core build:%d\n", xinit.api_version, xinit.core_build);          xinit.version = XVID_VERSION;
1448            xvid_global(NULL, 0, &xinit, NULL);
1449    
1450            memset(&xparam, 0, sizeof(xparam));
1451          xparam.width = width;          xparam.width = width;
1452          xparam.height = height;          xparam.height = height;
1453            xparam.version = XVID_VERSION;
1454          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
1455          if (xerr!=XVID_ERR_OK) {          if (xerr==XVID_ERR_FAIL) {
1456            printf("can't init decoder (err=%d)\n", xerr);                  printf("ERROR: can't init decoder (err=%d)\n", xerr);
1457            return;            return;
1458          }          }
1459          dechandle = xparam.handle;          dechandle = xparam.handle;
# Line 637  Line 1461 
1461    
1462          f = fopen(name, "rb");          f = fopen(name, "rb");
1463    if (f==0) {    if (f==0) {
1464      printf( "can't open file '%s'\n", name);                  printf( "ERROR: can't open file '%s'\n", name);
1465      return;      return;
1466    }    }
1467    fseek(f, 0, SEEK_END);    fseek(f, 0, SEEK_END);
1468    buf_size = ftell(f);    buf_size = ftell(f);
1469    fseek(f, 0, SEEK_SET);    fseek(f, 0, SEEK_SET);
1470    if (buf_size<=0) {    if (buf_size<=0) {
1471      printf("error while stating file\n");                  printf("ERROR: error while stating file\n");
1472      goto End;      goto End;
1473    }    }
   else printf( "Input size: %d\n", buf_size);  
1474    
1475    buf = malloc(buf_size); // should be enuf'          buf = malloc(buf_size);
1476    rgb_out = calloc(4, width*height);  // <-room for _RGB24          yuv_out = calloc(1, bps*height*3/2 + 15);
1477    if (buf==0 || rgb_out==0) {          if (buf==0 || yuv_out==0) {
1478      printf( "malloc failed!\n" );                  printf( "ERROR: malloc failed!\n" );
1479      goto End;      goto End;
1480    }    }
1481    
1482    if (fread(buf, buf_size, 1, f)!=1) {    if (fread(buf, buf_size, 1, f)!=1) {
1483      printf( "file-read failed\n" );                  printf( "ERROR: file-read failed\n" );
1484      goto End;      goto End;
1485    }    }
1486    
# Line 665  Line 1488 
1488    pos = 0;    pos = 0;
1489    t = -gettime_usec();    t = -gettime_usec();
1490    while(1) {    while(1) {
1491              int y;
1492    
1493                    memset(&xframe, 0, sizeof(xframe));
1494                    xframe.version = XVID_VERSION;
1495      xframe.bitstream = buf + pos;      xframe.bitstream = buf + pos;
1496      xframe.length = buf_size - pos;      xframe.length = buf_size - pos;
1497      xframe.image = rgb_out;                  xframe.output.plane[0] = (uint8_t*)(((size_t)yuv_out + 15) & ~15);
1498      xframe.stride = width;                  xframe.output.plane[1] = (uint8_t*)xframe.output.plane[0] + bps*height;
1499      xframe.colorspace = XVID_CSP_RGB24;                  xframe.output.plane[2] = (uint8_t*)xframe.output.plane[1] + bps/2;
1500                    xframe.output.stride[0] = bps;
1501                    xframe.output.stride[1] = bps;
1502                    xframe.output.stride[2] = bps;
1503                    xframe.output.csp = XVID_CSP_I420;
1504      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);
1505                    if (xerr<0) {
1506                            printf("ERROR: decoding failed for frame #%d (err=%d)!\n", nb, xerr);
1507                            break;
1508                    }
1509                    else if (xerr==0)
1510                      break;
1511        else if (verbose>0) printf("#%d %d\n", nb, xerr );
1512    
1513                    pos += xerr;
1514      nb++;      nb++;
1515      pos += xframe.length;  
1516      if (with_chksum) {      for(y=0; y<height/2; ++y) {
1517        int k = width*height;                    chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+0)*bps, width, chksum);
1518        uint32_t *ptr = (uint32_t *)rgb_out;                          chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+1)*bps, width, chksum);
1519        while(k-->0) chksum += *ptr++;                          chksum = calc_crc((uint8_t*)xframe.output.plane[1] + y*bps, width/2, chksum);
1520                            chksum = calc_crc((uint8_t*)xframe.output.plane[2] + y*bps, width/2, chksum);
1521      }      }
1522      if (pos==buf_size)      if (pos==buf_size)
1523        break;        break;
     if (xerr!=XVID_ERR_OK) {  
           printf("decoding failed for frame #%d (err=%d)!\n", nb, xerr);  
           break;  
         }  
1524    }    }
1525    t += gettime_usec();    t += gettime_usec();
1526            if (ref_chksum==0) {
1527    if (t>0.)    if (t>0.)
1528      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 );
1529    if (with_chksum)    }
1530      printf("checksum: 0x%.8x\n", chksum);    else {
1531                    printf("FPS:%.1f Checksum: 0x%.8x Expected:0x%.8x | %s\n",
1532                      t>0. ? (float)(nb*1.e6f/t) : 0.f, chksum, ref_chksum, (chksum==ref_chksum) ? "OK" : "ERROR");
1533      }
1534    
1535  End:  End:
1536    if (rgb_out!=0) free(rgb_out);          if (yuv_out!=0) free(yuv_out);
1537    if (buf!=0) free(buf);    if (buf!=0) free(buf);
1538    if (dechandle!=0) {    if (dechandle!=0) {
1539      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);
1540      if (xerr!=XVID_ERR_OK)                  if (xerr==XVID_ERR_FAIL)
1541              printf("destroy-decoder failed (err=%d)!\n", xerr);                          printf("ERROR: destroy-decoder failed (err=%d)!\n", xerr);
1542    }    }
1543    if (f!=0) fclose(f);    if (f!=0) fclose(f);
1544  }  }
# Line 709  Line 1550 
1550  void test_bugs1()  void test_bugs1()
1551  {  {
1552    CPU *cpu;    CPU *cpu;
1553            uint16_t mpeg_quant_matrices[64*8];
1554    
1555    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );
1556    
1557    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1558    {    {
1559      int i;      int i;
1560      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 721  Line 1563 
1563        continue;        continue;
1564    
1565      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1566      set_intra_matrix( get_default_intra_matrix() );                  set_intra_matrix( mpeg_quant_matrices, get_default_intra_matrix() );
1567      dequant4_intra(Dst, Src, 32, 5);                  dequant_mpeg_intra(Dst, Src, 31, 5, mpeg_quant_matrices);
1568      printf( "dequant4_intra with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_intra with CPU=%s:  ", cpu->name);
1569      printf( "  Out[]= " );      printf( "  Out[]= " );
1570      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1571      printf( "\n" );      printf( "\n" );
# Line 731  Line 1573 
1573    
1574    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );
1575    
1576    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1577    {    {
1578      int i;      int i;
1579      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 740  Line 1582 
1582        continue;        continue;
1583    
1584      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1585      set_inter_matrix( get_default_inter_matrix() );                  set_inter_matrix( mpeg_quant_matrices, get_default_inter_matrix() );
1586      dequant4_inter(Dst, Src, 32);                  dequant_mpeg_inter(Dst, Src, 31, mpeg_quant_matrices);
1587      printf( "dequant4_inter with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_inter with CPU=%s:  ", cpu->name);
1588      printf( "  Out[]= " );      printf( "  Out[]= " );
1589      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1590      printf( "\n" );      printf( "\n" );
# Line 752  Line 1594 
1594  void test_dct_precision_diffs()  void test_dct_precision_diffs()
1595  {  {
1596    CPU *cpu;    CPU *cpu;
1597    short Blk[8*8], Blk0[8*8];          DECLARE_ALIGNED_MATRIX(Blk, 8, 8, int16_t, 16);
1598            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, int16_t, 16);
1599    
1600    printf( "\n =====  fdct/idct saturation diffs =====\n" );          printf( "\n =====  fdct/idct precision diffs =====\n" );
1601    
1602    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1603    {    {
1604      int i;      int i;
1605    
# Line 780  Line 1623 
1623    }    }
1624  }  }
1625    
1626    void test_quant_bug()
1627    {
1628            const int max_Q = 31;
1629            int i, n, qm, q;
1630            CPU *cpu;
1631            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
1632            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
1633            uint8_t Quant[8*8];
1634            CPU cpu_bug_list[] = { { "PLAINC", 0 }, { "MMX   ", XVID_CPU_MMX }, {0,0} };
1635            uint16_t Crcs_Inter[2][32];
1636            uint16_t Crcs_Intra[2][32];
1637            DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
1638    
1639            printf( "\n =====  test MPEG4-quantize bug =====\n" );
1640    
1641            for(i=0; i<64; ++i) Src[i] = 2048*(i-32)/32;
1642    
1643    #if 1
1644            for(qm=1; qm<=255; ++qm)
1645            {
1646                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1647                    set_inter_matrix( mpeg_quant_matrices, Quant );
1648    
1649                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1650                    {
1651                            uint16_t s;
1652    
1653                            if (!init_cpu(cpu))
1654                                    continue;
1655    
1656                            for(q=1; q<=max_Q; ++q) {
1657                                    emms();
1658                                    quant_mpeg_inter( Dst, Src, q, mpeg_quant_matrices );
1659                                    emms();
1660                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1661                                    Crcs_Inter[n][q] = s;
1662                            }
1663                    }
1664    
1665                    for(q=1; q<=max_Q; ++q)
1666                            for(i=0; i<n-1; ++i)
1667                                    if (Crcs_Inter[i][q]!=Crcs_Inter[i+1][q])
1668                                            printf( "Discrepancy Inter: qm=%d, q=%d  -> %d/%d !\n",
1669                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1670            }
1671    #endif
1672    
1673    #if 1
1674            for(qm=1; qm<=255; ++qm)
1675            {
1676                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1677                    set_intra_matrix( mpeg_quant_matrices, Quant );
1678    
1679                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1680                    {
1681                            uint16_t s;
1682    
1683                            if (!init_cpu(cpu))
1684                                    continue;
1685    
1686                            for(q=1; q<=max_Q; ++q) {
1687                                    emms();
1688                                    quant_mpeg_intra( Dst, Src, q, q, mpeg_quant_matrices);
1689                                    emms();
1690                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1691                                    Crcs_Intra[n][q] = s;
1692                            }
1693                    }
1694    
1695                    for(q=1; q<=max_Q; ++q)
1696                            for(i=0; i<n-1; ++i)
1697                                    if (Crcs_Intra[i][q]!=Crcs_Intra[i+1][q])
1698                                            printf( "Discrepancy Intra: qm=%d, q=%d  -> %d/%d!\n",
1699                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1700            }
1701    #endif
1702    }
1703    /*********************************************************************/
1704    
1705    static uint32_t __inline log2bin_v1(uint32_t value)
1706    {
1707      int n = 0;
1708      while (value) {
1709        value >>= 1;
1710        n++;
1711      }
1712      return n;
1713    }
1714    
1715    static const uint8_t log2_tab_16[16] =  { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
1716    
1717    static uint32_t __inline log2bin_v2(uint32_t value)
1718    {
1719      int n = 0;
1720      if (value & 0xffff0000) {
1721        value >>= 16;
1722        n += 16;
1723      }
1724      if (value & 0xff00) {
1725        value >>= 8;
1726        n += 8;
1727      }
1728      if (value & 0xf0) {
1729        value >>= 4;
1730        n += 4;
1731      }
1732     return n + log2_tab_16[value];
1733    }
1734    
1735    void test_log2bin()
1736    {
1737            const int nb_tests = 3000*speed_ref;
1738      int n, crc1=0, crc2=0;
1739      uint32_t s, s0;
1740      double t1, t2;
1741    
1742      t1 = gettime_usec();
1743      s0 = (int)(t1*31.241);
1744      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1745        crc1 += log2bin_v1(s);
1746      t1 = (gettime_usec()-t1) / nb_tests;
1747    
1748      t2 = gettime_usec();
1749      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1750        crc2 += log2bin_v2(s);
1751      t2 = (gettime_usec() - t2) / nb_tests;
1752    
1753      printf( "log2bin_v1: %.3f sec  crc=%d\n", t1, crc1 );
1754      printf( "log2bin_v2: %.3f sec  crc=%d\n", t2, crc2 );
1755      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1756    }
1757    
1758    /*********************************************************************/
1759    
1760    static void __inline old_gcd(int *num, int *den)
1761    {
1762     int i = *num;
1763      while (i > 1) {
1764        if (*num % i == 0 && *den % i == 0) {
1765          *num /= i;
1766          *den /= i;
1767          i = *num;
1768          continue;
1769        }
1770        i--;
1771      }
1772    }
1773    
1774    static uint32_t gcd(int num, int den)
1775    {
1776      int tmp;
1777      while( (tmp=num%den) ) { num = den; den = tmp; }
1778      return den;
1779    }
1780    static void __inline new_gcd(int *num, int *den)
1781    {
1782      const int div = gcd(*num, *den);
1783      if (num) {
1784        *num /= div;
1785        *den /= div;
1786      }
1787    }
1788    
1789    void test_gcd()
1790    {
1791            const int nb_tests = 10*speed_ref;
1792      int i;
1793      uint32_t crc1=0, crc2=0;
1794      uint32_t n0, n, d0, d;
1795      double t1, t2;
1796    
1797      t1 = gettime_usec();
1798      n0 = 0xfffff & (int)(t1*31.241);
1799      d0 = 0xfffff & (int)( ((n0*4123)%17) | 1 );
1800      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1801        old_gcd(&n, &d);
1802        crc1 = (((crc1>>4)^d) + ((crc1<<2)^n) ) & 0xffffff;
1803        n = d;
1804        d = (d*12363+31) & 0xffff;
1805        d |= !d;
1806      }
1807      t1 = (gettime_usec()-t1) / nb_tests;
1808    
1809      t2 = gettime_usec();
1810      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1811        new_gcd(&n, &d);
1812        crc2 = (((crc2>>4)^d) + ((crc2<<2)^n) ) & 0xffffff;
1813        n = d;
1814        d = (d*12363+31) & 0xffff;
1815        d |= !d;
1816      }
1817      t2 = (gettime_usec() - t2) / nb_tests;
1818    
1819      printf( "old_gcd: %.3f sec  crc=%d\n", t1, crc1 );
1820      printf( "new_gcd: %.3f sec  crc=%d\n", t2, crc2 );
1821      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1822    }
1823    
1824    /*********************************************************************
1825     * test compiler
1826     *********************************************************************/
1827    
1828    void test_compiler() {
1829      int nb_err = 0;
1830      int32_t v;
1831      if (sizeof(uint16_t)<2) {
1832        printf( "ERROR: sizeof(uint16_t)<2 !!\n" );
1833        nb_err++;
1834      }
1835      if (sizeof(int16_t)<2) {
1836        printf( "ERROR: sizeof(int16_t)<2 !!\n" );
1837        nb_err++;
1838      }
1839      if (sizeof(uint8_t)!=1) {
1840        printf( "ERROR: sizeof(uint8_t)!=1 !!\n" );
1841        nb_err++;
1842      }
1843      if (sizeof(int8_t)!=1) {
1844        printf( "ERROR: sizeof(int8_t)!=1 !!\n" );
1845        nb_err++;
1846      }
1847      if (sizeof(uint32_t)<4) {
1848        printf( "ERROR: sizeof(uint32_t)<4 !!\n" );
1849        nb_err++;
1850      }
1851      if (sizeof(int32_t)<4) {
1852        printf( "ERROR: sizeof(int32_t)<4 !!\n" );
1853        nb_err++;
1854      }
1855             /* yes, i know, this test is silly. But better be safe than sorry. :) */
1856      for(v=1000; v>=0; v--) {
1857        if ( (v>>2) != v/4)
1858          nb_err++;
1859      }
1860      for(v=-1000; v!=-1; v++) {
1861        if ( (v>>2) != (v/4)-!!(v%4))
1862          nb_err++;
1863      }
1864      if (nb_err!=0) {
1865        printf( "ERROR! please post your platform/compiler specs to xvid-devel@xvid.org !\n" );
1866      }
1867    }
1868    
1869  /*********************************************************************  /*********************************************************************
1870   * main   * main
1871   *********************************************************************/   *********************************************************************/
1872    
1873  int main(int argc, char *argv[])  static void arg_missing(const char *opt)
1874  {  {
1875    int what = 0;    printf( "missing argument after option '%s'\n", opt);
1876    if (argc>1) what = atoi(argv[1]);    exit(-1);
1877    }
1878    
1879    int main(int argc, const char *argv[])
1880    {
1881            int c, what = 0;
1882            int width, height;
1883            uint32_t chksum = 0;
1884      const char * test_bitstream = 0;
1885    
1886            cpu_mask = 0;  // default => will use autodectect
1887            for(c=1; c<argc; ++c)
1888            {
1889              if (!strcmp(argv[c], "-v")) verbose++;
1890              else if (!strcmp(argv[c], "-c"))      cpu_mask = 0 /* PLAIN_C */ | XVID_CPU_FORCE;
1891              else if (!strcmp(argv[c], "-mmx"))    cpu_mask = XVID_CPU_MMX    | XVID_CPU_FORCE;
1892              else if (!strcmp(argv[c], "-mmxext")) cpu_mask = XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
1893              else if (!strcmp(argv[c], "-sse2"))   cpu_mask = XVID_CPU_SSE2   | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
1894              else if (!strcmp(argv[c], "-3dnow"))  cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_FORCE;
1895              else if (!strcmp(argv[c], "-3dnowe")) cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_3DNOWEXT | XVID_CPU_FORCE;
1896              else if (!strcmp(argv[c], "-altivec")) cpu_mask = XVID_CPU_ALTIVEC | XVID_CPU_FORCE;
1897              else if (!strcmp(argv[c], "-spd")) {
1898          if (++c==argc) arg_missing( argv[argc-1] );
1899          speed_ref = atoi(argv[c]);
1900        }
1901              else if (argv[c][0]!='-') {
1902                what = atoi(argv[c]);
1903                if (what==9) {
1904                  if (c+4>argc) {
1905                    printf("usage: %s %d bitstream width height (checksum)\n", argv[0], what);
1906                    exit(-1);
1907            }
1908            test_bitstream = argv[++c];
1909                  width  = atoi(argv[++c]);
1910                  height = atoi(argv[++c]);
1911                  if (c+1<argc && argv[c+1][0]!='-') {
1912                    if (sscanf(argv[c+1], "0x%x", &chksum)!=1) {
1913                      printf( "can't read checksum value.\n" );
1914                      exit(-1);
1915              }
1916              else c++;
1917            }
1918    //        printf( "[%s] %dx%d (0x%.8x)\n", test_bitstream, width, height, chksum);
1919          }
1920        }
1921        else {
1922          printf( "unrecognized option '%s'\n", argv[c]);
1923          exit(-1);
1924        }
1925      }
1926    
1927    
1928    if (what==0 || what==1) test_dct();    if (what==0 || what==1) test_dct();
1929    if (what==0 || what==2) test_mb();    if (what==0 || what==2) test_mb();
1930    if (what==0 || what==3) test_sad();    if (what==0 || what==3) test_sad();
1931    if (what==0 || what==4) test_transfer();    if (what==0 || what==4) test_transfer();
1932    if (what==0 || what==5) test_quant();    if (what==0 || what==5) test_quant();
1933    if (what==0 || what==6) test_cbp();    if (what==0 || what==6) test_cbp();
1934            if (what==0 || what==10) test_sse();
1935    if (what==8) {          if (what==0 || what==11) test_log2bin();
1936      int width, height;          if (what==0 || what==12) test_gcd();
1937      if (argc<5) {          if (what==0 || what==13) test_compiler();
1938        printf("usage: %s %d [bitstream] [width] [height]\n", argv[0], what);  
1939        return 1;  
1940      }          if (what==7) {
1941      width = atoi(argv[3]);                  test_IEEE1180_compliance(-256, 255, 1);
1942      height = atoi(argv[4]);                  test_IEEE1180_compliance(-256, 255,-1);
1943      test_dec(argv[2], width, height, (argc>5));                  test_IEEE1180_compliance(  -5,   5, 1);
1944                    test_IEEE1180_compliance(  -5,   5,-1);
1945                    test_IEEE1180_compliance(-300, 300, 1);
1946                    test_IEEE1180_compliance(-300, 300,-1);
1947    }    }
1948            if (what==8) test_dct_saturation(-256, 255);
1949    
1950            if (test_bitstream)
1951              test_dec(test_bitstream, width, height, chksum);
1952    if (what==-1) {    if (what==-1) {
     test_bugs1();  
1953      test_dct_precision_diffs();      test_dct_precision_diffs();
1954                    test_bugs1();
1955    }    }
1956    return 0;          if (what==-2)
1957                    test_quant_bug();
1958    
1959            if ((what >= 0 && what <= 6) || what == 10) {
1960                    printf("\n\n"
1961                               "NB: If a function isn't optimised for a specific set of intructions,\n"
1962                               "    a C function is used instead. So don't panic if some functions\n"
1963                               "    may appear to be slow.\n");
1964            }
1965    
1966    #ifdef ARCH_IS_IA32
1967            if (what == 0 || what == 5) {
1968                    printf("\n"
1969                               "NB: MMX mpeg4 quantization is known to have very small errors (+/-1 magnitude)\n"
1970                               "    for 1 or 2 coefficients a block. This is mainly caused by the fact the unit\n"
1971                               "    test goes far behind the usual limits of real encoding. Please do not report\n"
1972                               "    this error to the developers.\n");
1973  }  }
1974    #endif
1975    
1976  /*********************************************************************          return 0;
1977   * 'Reference' output (except for timing) on a PIII 1.13Ghz/linux  }
  *********************************************************************/  
 /*  
1978    
1979   ===== 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.1652

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