[svn] / branches / dev-api-4 / xvidcore / examples / xvid_bench.c Repository:
ViewVC logotype

Diff of /branches/dev-api-4/xvidcore/examples/xvid_bench.c

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

trunk/xvidcore/examples/xvid_bench.c revision 257, Fri Jul 5 14:54:15 2002 UTC branches/dev-api-4/xvidcore/examples/xvid_bench.c revision 1230, Sun Nov 30 16:13:16 2003 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.9.2.9 2003-11-30 16:13:15 edgomez Exp $
23   *   *
24   *************************************************************************/   ****************************************************************************/
25    
26  /************************************************************************  /*****************************************************************************
27   *   *
28   *  'Reference' output is at the end of file.   *  'Reference' output is at the end of file.
29   *  Don't take the checksums and crc too seriouly, they aren't   *  Don't take the checksums and crc too seriouly, they aren't
30   *  bullet-proof...   *  bullet-proof (should plug some .md5 here)...
31   *   *
32   *   compiles with something like:   *   compiles with something like:
33   *   gcc -o xvid_bench xvid_bench.c  -I../src/ -lxvidcore -lm   *   gcc -o xvid_bench xvid_bench.c  -I../src/ -lxvidcore -lm
34   *   *
35   *      History:   ****************************************************************************/
  *  
  *      06.06.2002  initial coding      -Skal-  
  *  
  *************************************************************************/  
36    
37  #include <stdio.h>  #include <stdio.h>
38  #include <stdlib.h>  #include <stdlib.h>
39  #include <sys/time.h>  // for gettimeofday  #include <string.h>    /* for memset */
 #include <string.h>    // for memset  
40  #include <assert.h>  #include <assert.h>
41    
42    #ifndef WIN32
43    #include <sys/time.h>   /* for gettimeofday */
44    #else
45    #include <time.h>
46    #endif
47    
48    
49  #include "xvid.h"  #include "xvid.h"
50    
51  // inner guts  // inner guts
# Line 47  Line 54 
54  #include "image/colorspace.h"  #include "image/colorspace.h"
55  #include "image/interpolate8x8.h"  #include "image/interpolate8x8.h"
56  #include "utils/mem_transfer.h"  #include "utils/mem_transfer.h"
57  #include "quant/quant_h263.h"  #include "quant/quant.h"
 #include "quant/quant_mpeg4.h"  
58  #include "motion/sad.h"  #include "motion/sad.h"
59  #include "utils/emms.h"  #include "utils/emms.h"
60  #include "utils/timer.h"  #include "utils/timer.h"
61  #include "quant/quant_matrix.c"  #include "quant/quant_matrix.c"
62  #include "bitstream/cbp.h"  #include "bitstream/cbp.h"
63    
64  const int speed_ref = 100;  // on slow machines, decrease this value  #include <math.h>
65    
66    #ifndef M_PI
67    #define M_PI            3.14159265358979323846
68    #endif
69    
70    const int speed_ref = 100;  /* on slow machines, decrease this value */
71    
72  /*********************************************************************  /*********************************************************************
73   * misc   * misc
# Line 64  Line 76 
76   /* returns time in micro-s*/   /* returns time in micro-s*/
77  double gettime_usec()  double gettime_usec()
78  {  {
79    #ifndef WIN32
80    struct timeval  tv;    struct timeval  tv;
81    gettimeofday(&tv, 0);    gettimeofday(&tv, 0);
82    return tv.tv_sec*1.0e6 + tv.tv_usec;    return tv.tv_sec*1.0e6 + tv.tv_usec;
83    #else
84            clock_t clk;
85            clk = clock();
86            return clk * 1000000 / CLOCKS_PER_SEC;
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 96  Line 114 
114    
115  CPU cpu_list[] =  CPU cpu_list[] =
116  { { "PLAINC", 0 }  { { "PLAINC", 0 }
117    #ifdef ARCH_IS_IA32
118  , { "MMX   ", XVID_CPU_MMX }  , { "MMX   ", XVID_CPU_MMX }
119  , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }  , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }
120  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }
121  , { "3DNOW ", XVID_CPU_3DNOW }  , { "3DNOW ", XVID_CPU_3DNOW }
122  , { "3DNOWE", XVID_CPU_3DNOWEXT }    , { "3DNOWE", XVID_CPU_3DNOW | XVID_CPU_3DNOWEXT }
123    #endif
124    //, { "IA64  ", XVID_CPU_IA64 }
125  //, { "TSC   ", XVID_CPU_TSC }  //, { "TSC   ", XVID_CPU_TSC }
126  , { 0, 0 } }    , { 0, 0 } };
127    
128  , cpu_short_list[] =  CPU  cpu_short_list[] =
129  { { "PLAINC", 0 }  { { "PLAINC", 0 }
130    #ifdef ARCH_IS_IA32
131  , { "MMX   ", XVID_CPU_MMX }  , { "MMX   ", XVID_CPU_MMX }
132  , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }  //, { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }
133  , { "IA64  ", XVID_CPU_IA64 }  #endif
134  , { 0, 0 } }  //, { "IA64  ", XVID_CPU_IA64 }
135      , { 0, 0 } };
136    
137  , cpu_short_list2[] =  CPU cpu_short_list2[] =
138  { { "PLAINC", 0 }  { { "PLAINC", 0 }
139    #ifdef ARCH_IS_IA32
140  , { "MMX   ", XVID_CPU_MMX }  , { "MMX   ", XVID_CPU_MMX }
141  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }
142    #endif
143  , { 0, 0 } };  , { 0, 0 } };
144    
145    
146  int init_cpu(CPU *cpu)  int init_cpu(CPU *cpu)
147  {  {
148    int xerr, cpu_type;          xvid_gbl_info_t xinfo;
149    XVID_INIT_PARAM xinit;  
150            /* Get the available CPU flags */
151            memset(&xinfo, 0, sizeof(xinfo));
152            xinfo.version = XVID_VERSION;
153            xvid_global(NULL, XVID_GBL_INFO, &xinfo, NULL);
154    
155    cpu_type = check_cpu_features() & cpu->cpu;          /* Are we trying to test a subset of the host CPU features */
156    xinit.cpu_flags = cpu_type | XVID_CPU_FORCE;          if ((xinfo.cpu_flags & cpu->cpu) == cpu->cpu) {
157    //    xinit.cpu_flags = XVID_CPU_MMX | XVID_CPU_FORCE;                  int xerr;
158    xerr = xvid_init(NULL, 0, &xinit, NULL);                  xvid_gbl_init_t xinit;
159    if (cpu->cpu>0 && (cpu_type==0 || xerr!=XVID_ERR_OK)) {                  memset(&xinit, 0, sizeof(xinit));
160      printf( "%s - skipped...\n", cpu->name );                  xinit.cpu_flags = cpu->cpu | XVID_CPU_FORCE;
161                    xinit.version = XVID_VERSION;
162                    xerr = xvid_global(NULL, XVID_GBL_INIT, &xinit, NULL);
163                    if (xerr==XVID_ERR_FAIL) {
164                            /* libxvidcore failed to init */
165      return 0;      return 0;
166    }    }
167            } else {
168                    /* The host CPU doesn't support some required feature for this test */
169                    return(0);
170            }
171    return 1;    return 1;
172  }  }
173    
174    #define CRC32_REMAINDER 0xCBF43926
175    #define CRC32_INITIAL 0xffffffff
176    
177    #define DO1(c, crc) ((crc) = crc32tab[((unsigned int)((crc)>>24) ^ (*c++)) & 0xff] ^ ((crc) << 8))
178    #define DO2(c, crc)  DO1(c, crc); DO1(c, crc);
179    #define DO4(c, crc)  DO2(c, crc); DO2(c, crc);
180    #define DO8(c, crc)  DO4(c, crc); DO4(c, crc);
181    
182    /******************************************************************************
183    * Precomputed AAL5 CRC32 lookup table
184    ******************************************************************************/
185    
186    static unsigned long crc32tab[256] = {
187    
188            0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
189            0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
190            0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
191            0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
192            0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
193            0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
194            0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
195            0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
196            0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
197            0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
198            0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
199            0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
200            0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
201            0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
202            0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
203            0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
204            0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
205            0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
206            0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
207            0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
208            0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
209            0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
210            0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
211            0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
212            0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
213            0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
214            0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
215            0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
216            0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
217            0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
218            0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
219            0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
220            0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
221            0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
222            0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
223            0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
224            0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
225            0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
226            0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
227            0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
228            0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
229            0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
230            0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
231            0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
232            0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
233            0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
234            0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
235            0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
236            0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
237            0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
238            0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
239            0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
240            0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
241            0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
242            0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
243            0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
244            0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
245            0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
246            0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
247            0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
248            0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
249            0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
250            0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
251            0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
252    
253    };
254    
255    uint32_t
256    calc_crc(uint8_t *mem, int len, uint32_t initial)
257    {
258    
259            register unsigned int crc;
260    
261            crc = initial;
262    
263            while( len >= 8) {
264                    DO8(mem, crc);
265                    len -= 8;
266            }
267    
268            while( len ) {
269                    DO1(mem, crc);
270                    len--;
271            }
272    
273            return(crc);
274    
275    }
276    
277  /*********************************************************************  /*********************************************************************
278   * test DCT   * test DCT
279   *********************************************************************/   *********************************************************************/
# Line 147  Line 286 
286    int tst;    int tst;
287    CPU *cpu;    CPU *cpu;
288    int i;    int i;
289    short iDst0[8*8], iDst[8*8], fDst[8*8];          DECLARE_ALIGNED_MATRIX(iDst0, 8, 8, short, 16);
290            DECLARE_ALIGNED_MATRIX(iDst,  8, 8, short, 16);
291            DECLARE_ALIGNED_MATRIX(fDst,  8, 8, short, 16);
292    double overhead;    double overhead;
293    
294    printf( "\n ===== test fdct/idct =====\n" );    printf( "\n ===== test fdct/idct =====\n" );
# Line 163  Line 304 
304    
305    for(cpu = cpu_list; cpu->name!=0; ++cpu)    for(cpu = cpu_list; cpu->name!=0; ++cpu)
306    {    {
307      double t;                  double t, PSNR, MSE;
     int iCrc, fCrc;  
308    
309      if (!init_cpu(cpu))      if (!init_cpu(cpu))
310        continue;        continue;
# Line 180  Line 320 
320      }      }
321      emms();      emms();
322      t = (gettime_usec() - t - overhead) / nb_tests;      t = (gettime_usec() - t - overhead) / nb_tests;
323      iCrc=0; fCrc=0;                  MSE = 0.;
324      for(i=0; i<8*8; ++i) {      for(i=0; i<8*8; ++i) {
325        iCrc += ABS(iDst[i] - iDst0[i]);                          double delta = 1.0*(iDst[i] - iDst0[i]);
326        fCrc += fDst[i]^i;                          MSE += delta*delta;
327      }      }
328      printf( "%s -  %.3f usec       iCrc=%d  fCrc=%d\n",                  PSNR = (MSE==0.) ? 1.e6 : -4.3429448*log( MSE/64. );
329        cpu->name, t, iCrc, fCrc );                  printf( "%s -  %.3f usec       PSNR=%.3f  MSE=%.3f %s\n",
330        // the norm tolerates ~1 bit of diff per coeff                                  cpu->name, t, PSNR, MSE,
331      if (ABS(iCrc)>=64) printf( "*** CRC ERROR! ***\n" );                                  (ABS(MSE)>=64)? "| ERROR" :"");
332    }    }
333  }  }
334    
# Line 223  Line 363 
363      for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);      for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);
364      emms();      emms();
365      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
366      printf( "%s - sad8    %.3f usec       sad=%d\n", cpu->name, t, s );                  printf("%s - sad8    %.3f usec       sad=%d %s\n",
367      if (s!=3776) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
368                               (s!=3776)?"| ERROR": "" );
369    
370      t = gettime_usec();      t = gettime_usec();
371      emms();      emms();
372      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);
373      emms();      emms();
374      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
375      printf( "%s - sad16   %.3f usec       sad=%d\n", cpu->name, t, s );                  printf("%s - sad16   %.3f usec       sad=%d %s\n",
376      if (s!=27214) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
377                               (s!=27214)?"| ERROR": "" );
378    
379      t = gettime_usec();      t = gettime_usec();
380      emms();      emms();
381      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);
382      emms();      emms();
383      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
384      printf( "%s - sad16bi %.3f usec       sad=%d\n", cpu->name, t, s );                  printf( "%s - sad16bi %.3f usec       sad=%d %s\n",
385      if (s!=26274) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
386                                    (s!=26274)?"| ERROR": "" );
387    
388      t = gettime_usec();      t = gettime_usec();
389      emms();      emms();
390      for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);      for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);
391      emms();      emms();
392      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
393      printf( "%s - dev16   %.3f usec       sad=%d\n", cpu->name, t, s );                  printf( "%s - dev16   %.3f usec       sad=%d %s\n",
394      if (s!=3344) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
395                                    (s!=3344)?"| ERROR": "" );
396    
397      printf( " --- \n" );      printf( " --- \n" );
398    }    }
# Line 266  Line 410 
410  #define LEAVE \  #define LEAVE \
411      emms();                             \      emms();                             \
412      t = (gettime_usec() - t) / nb_tests;  \      t = (gettime_usec() - t) / nb_tests;  \
413      iCrc = 0;                           \          iCrc = calc_crc((uint8_t*)Dst, sizeof(Dst), CRC32_INITIAL)
     for(i=0; i<16*8; ++i) { iCrc += Dst[i]^i; }  
414    
415  #define TEST_MB(FUNC, R)                \  #define TEST_MB(FUNC, R)                \
416      ENTER                               \      ENTER                               \
# Line 285  Line 428 
428    const int nb_tests = 2000*speed_ref;    const int nb_tests = 2000*speed_ref;
429    CPU *cpu;    CPU *cpu;
430    const uint8_t Src0[16*9] = {    const uint8_t Src0[16*9] = {
431          // try to have every possible combinaison of rounding...                  /* try to have every possible combinaison of rounding... */
432        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,
433      , 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,
434      , 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,
435      , 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,
436      , 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,
437      , 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,
438      , 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,
439      , 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,
440      , 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
441    };    };
442    uint8_t Dst[16*8] = {0};    uint8_t Dst[16*8] = {0};
443    
# Line 309  Line 452 
452        continue;        continue;
453    
454      TEST_MB(interpolate8x8_halfpel_h, 0);      TEST_MB(interpolate8x8_halfpel_h, 0);
455      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",
456      if (iCrc!=8107) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
457                               (iCrc!=0x115381ba)?"| ERROR": "" );
458    
459      TEST_MB(interpolate8x8_halfpel_h, 1);      TEST_MB(interpolate8x8_halfpel_h, 1);
460      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
461      if (iCrc!=8100) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
462                               (iCrc!=0x2b1f528f)?"| ERROR": "" );
463    
464    
465      TEST_MB(interpolate8x8_halfpel_v, 0);      TEST_MB(interpolate8x8_halfpel_v, 0);
466      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",
467      if (iCrc!=8108) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
468                               (iCrc!=0x423cdcc7)?"| ERROR": "" );
469    
470      TEST_MB(interpolate8x8_halfpel_v, 1);      TEST_MB(interpolate8x8_halfpel_v, 1);
471      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
472      if (iCrc!=8105) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
473                               (iCrc!=0x42202efe)?"| ERROR": "" );
474    
475    
476      TEST_MB(interpolate8x8_halfpel_hv, 0);      TEST_MB(interpolate8x8_halfpel_hv, 0);
477      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",
478      if (iCrc!=8112) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
479                               (iCrc!=0xd198d387)?"| ERROR": "" );
480    
481      TEST_MB(interpolate8x8_halfpel_hv, 1);      TEST_MB(interpolate8x8_halfpel_hv, 1);
482      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
483      if (iCrc!=8103) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
484                               (iCrc!=0x9ecfd921)?"| ERROR": "" );
485    
486    
487                    /* this is a new function, as of 06.06.2002 */
488    #if 0
489                    TEST_MB2(interpolate8x8_avrg);
490                    printf("%s - interpolate8x8_c %.3f usec       crc32=0x%08x %s\n",
491                               cpu->name, t, iCrc,
492                               (iCrc!=8107)?"| ERROR": "" );
493    #endif
494    
495      printf( " --- \n" );      printf( " --- \n" );
496    }    }
# Line 367  Line 525 
525      }                                         \      }                                         \
526      emms();                                   \      emms();                                   \
527      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
528      s = 0; for(i=0; i<8*32; ++i) { s += (DST)[i]^i; }  s = calc_crc((uint8_t*)(DST), sizeof((DST)), CRC32_INITIAL)
529    
530  #define TEST_TRANSFER(FUNC, DST, SRC)         \  #define TEST_TRANSFER(FUNC, DST, SRC)         \
531      TEST_TRANSFER_BEGIN(DST);                 \      TEST_TRANSFER_BEGIN(DST);                 \
# Line 393  Line 551 
551      }                                         \      }                                         \
552      emms();                                   \      emms();                                   \
553      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
554      s = 0; for(i=0; i<8*32; ++i) { s += (DST)[i]; }  s = calc_crc((uint8_t*)(DST), sizeof((DST)), CRC32_INITIAL)
555    
556  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \
557      TEST_TRANSFER2_BEGIN(DST,SRC);            \      TEST_TRANSFER2_BEGIN(DST,SRC);            \
# Line 415  Line 573 
573    
574    printf( "\n ===  test transfer ===\n" );    printf( "\n ===  test transfer ===\n" );
575    
576    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
577    {    {
578      double t, overhead;      double t, overhead;
579      int tst, s;      int tst, s;
# Line 424  Line 582 
582        continue;        continue;
583    
584      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);
585      printf( "%s - 8to16     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16     %.3f usec       crc32=0x%08x %s\n",
586      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
587                               (s!=0x115814bb)?"| ERROR": "");
588    
589      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);
590      printf( "%s - 16to8     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf( "%s - 16to8     %.3f usec       crc32=0x%08x %s\n",
591      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
592                                    (s!=0xee7ccbb4)?"| ERROR": "");
593    
594      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);
595      printf( "%s - 8to8      %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to8      %.3f usec       crc32=0x%08x %s\n",
596      if (s!=20352) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
597                               (s!=0xd37b3295)?"| ERROR": "");
598    
599      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);
600      printf( "%s - 16to8add  %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 16to8add  %.3f usec       crc32=0x%08x %s\n",
601      if (s!=25536) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
602                               (s!=0xdd817bf4)?"| ERROR": "" );
603    
604      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);
605      printf( "%s - 8to16sub  %.3f usec       crc1=%d ", cpu->name, t, s );                  {
606      if (s!=28064) printf( "*** CRC ERROR! ***\n" );                          int s1, s2;
607      s = 0; for(i=0; i<8*32; ++i) { s += (Src8[i]-Ref1[i])&i; }                          s1 = calc_crc((uint8_t*)Dst16, sizeof(Dst16), CRC32_INITIAL);
608      printf( "crc2=%d\n", s);                          s2 = calc_crc((uint8_t*)Src8, sizeof(Src8), CRC32_INITIAL);
609      if (s!=16256) printf( "*** CRC ERROR! ***\n" );                          printf("%s - 8to16sub  %.3f usec       crc32(1)=0x%08x crc32(2)=0x%08x %s %s\n",
610                                       cpu->name, t, s1, s2,
611                                       (s1!=0xa1e07163)?"| ERROR1": "",
612                                       (s2!=0xd86c5d23)?"| ERROR2": "" );
613                    }
614    
615      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);
616      printf( "%s - 8to16sub2 %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16sub2 %.3f usec       crc32=0x%08x %s\n",
617      if (s!=20384) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
618                               (s!=0x99b6c4c7)?"| ERROR": "" );
619    
620      printf( " --- \n" );      printf( " --- \n" );
621    }    }
# Line 460  Line 627 
627    
628  #define TEST_QUANT(FUNC, DST, SRC)            \  #define TEST_QUANT(FUNC, DST, SRC)            \
629      t = gettime_usec();                       \      t = gettime_usec();                       \
630    for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
631      for(i=0; i<8*8; ++i) Quant[i] = qm;       \
632      set_inter_matrix( mpeg_quant_matrices, Quant );                \
633      emms();                                   \      emms();                                   \
634      for(q=1; q<=max_Q; ++q) {                 \
635      for(tst=0; tst<nb_tests; ++tst)           \      for(tst=0; tst<nb_tests; ++tst)           \
636        for(s=0, q=1; q<=max_Q; ++q) {          \            (FUNC)((DST), (SRC), q, mpeg_quant_matrices);              \
637          (FUNC)((DST), (SRC), q);              \          s = calc_crc((uint8_t*)(DST), sizeof((DST)), s); \
         for(i=0; i<64; ++i) s+=(DST)[i]^i;    \  
638        }                                       \        }                                       \
639      emms();                                   \      emms();                                   \
640      t = (gettime_usec()-t-overhead)/nb_tests;  }                                           \
641    t = (gettime_usec()-t-overhead)/nb_tests/qm
642    
643  #define TEST_QUANT2(FUNC, DST, SRC, MULT)     \  #define TEST_QUANT2(FUNC, DST, SRC)             \
644      t = gettime_usec();                       \      t = gettime_usec();                       \
645    for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
646      for(i=0; i<8*8; ++i) Quant[i] = qm;       \
647      set_intra_matrix( mpeg_quant_matrices, Quant );                \
648      emms();                                   \      emms();                                   \
649      for(q=1; q<=max_Q; ++q) {                 \
650      for(tst=0; tst<nb_tests; ++tst)           \      for(tst=0; tst<nb_tests; ++tst)           \
651        for(s=0, q=1; q<=max_Q; ++q) {          \            (FUNC)((DST), (SRC), q, q, mpeg_quant_matrices);           \
652          (FUNC)((DST), (SRC), q, MULT);        \          s = calc_crc((uint8_t*)(DST), sizeof((DST)), s); \
         for(i=0; i<64; ++i) s+=(DST)[i]^i;    \  
653        }                                       \        }                                       \
654      emms();                                   \      emms();                                   \
655      t = (gettime_usec()-t-overhead)/nb_tests;  }                                           \
656    t = (gettime_usec()-t-overhead)/nb_tests/qm
657    
658  void test_quant()  void test_quant()
659  {  {
660    const int nb_tests = 150*speed_ref;          const int nb_tests = 1*speed_ref;
661    const int max_Q = 31;    const int max_Q = 31;
662    int i;          uint16_t mpeg_quant_matrices[64*8];
663    
664            int i, qm;
665    CPU *cpu;    CPU *cpu;
666    int16_t  Src[8*8], Dst[8*8];    int16_t  Src[8*8], Dst[8*8];
667            uint8_t Quant[8*8];
668    
669    printf( "\n =====  test quant =====\n" );    printf( "\n =====  test quant =====\n" );
670    
671    /* we deliberately enfringe the norm's specified range [-127,127], */
672    /* to test the robustness of the iquant module */
673    for(i=0; i<64; ++i) {    for(i=0; i<64; ++i) {
674      Src[i] = i-32;                  Src[i] = 1 + (i-32) * (i&6);
675      Dst[i] = 0;      Dst[i] = 0;
676    }    }
677    
678            for(cpu = cpu_list; cpu->name!=0; ++cpu)
   for(cpu = cpu_short_list; cpu->name!=0; ++cpu)  
679    {    {
680      double t, overhead;      double t, overhead;
681      int tst, s, q;                  int tst, q;
682                    uint32_t s;
683    
684      if (!init_cpu(cpu))      if (!init_cpu(cpu))
685        continue;        continue;
686    
     set_inter_matrix( get_default_inter_matrix() );  
     set_intra_matrix( get_default_intra_matrix() );  
687      overhead = -gettime_usec();      overhead = -gettime_usec();
688      for(tst=0; tst<nb_tests; ++tst)                  for(s=0,qm=1; qm<=255; ++qm) {
689        for(s=0, q=1; q<=max_Q; ++q)                          for(i=0; i<8*8; ++i) Quant[i] = qm;
690          for(i=0; i<64; ++i) s+=Dst[i]^i;                          set_inter_matrix(mpeg_quant_matrices, Quant );
691                            for(q=1; q<=max_Q; ++q)
692                                    for(i=0; i<64; ++i) s+=Dst[i]^i^qm;
693                    }
694      overhead += gettime_usec();      overhead += gettime_usec();
695    
696      TEST_QUANT2(quant4_intra, Dst, Src, 7);                  TEST_QUANT2(quant_mpeg_intra, Dst, Src);
697      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",
698      if (s!=55827) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
699                               (s!=0xfd6a21a4)? "| ERROR": "");
700      TEST_QUANT(quant4_inter, Dst, Src);  
701      printf( "%s -   quant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT(quant_mpeg_inter, Dst, Src);
702      if (s!=58201) printf( "*** CRC ERROR! ***\n" );                  printf("%s -   quant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
703                               cpu->name, t, s,
704                               (s!=0xf6de7757)?"| ERROR": "");
705      TEST_QUANT2(dequant4_intra, Dst, Src, 7);  
706      printf( "%s - dequant4_intra %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(dequant_mpeg_intra, Dst, Src);
707      if (s!=193340) printf( "*** CRC ERROR! ***\n" );                  printf("%s - dequant_mpeg_intra %.3f usec       crc32=0x%08x %s\n",
708                               cpu->name, t, s,
709      TEST_QUANT(dequant4_inter, Dst, Src);                             (s!=0x2def7bc7)?"| ERROR": "");
710      printf( "%s - dequant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );  
711      if (s!=116483) printf( "*** CRC ERROR! ***\n" );                  TEST_QUANT(dequant_mpeg_inter, Dst, Src);
712                    printf("%s - dequant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
713      TEST_QUANT2(quant_intra, Dst, Src, 7);                             cpu->name, t, s,
714      printf( "%s -    quant_intra %.3f usec       crc=%d\n", cpu->name, t, s );                             (s!=0xd878c722)?"| ERROR": "");
715      if (s!=56885) printf( "*** CRC ERROR! ***\n" );  
716                    TEST_QUANT2(quant_h263_intra, Dst, Src);
717      TEST_QUANT(quant_inter, Dst, Src);                  printf("%s -   quant_h263_intra %.3f usec       crc32=0x%08x %s\n",
718      printf( "%s -    quant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                             cpu->name, t, s,
719      if (s!=58056) printf( "*** CRC ERROR! ***\n" );                             (s!=0x2eba9d43)?"| ERROR": "");
720    
721      TEST_QUANT2(dequant_intra, Dst, Src, 7);                  TEST_QUANT(quant_h263_inter, Dst, Src);
722      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",
723      if (s!=-7936) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
724                               (s!=0xbd315a7e)?"| ERROR": "");
725      TEST_QUANT(dequant_inter, Dst, Src);  
726      printf( "%s -  dequant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(dequant_h263_intra, Dst, Src);
727  //    { 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",
728      if (s!=-33217) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
729                               (s!=0x9841212a)?"| ERROR": "");
730    
731                    TEST_QUANT(dequant_h263_inter, Dst, Src);
732                    printf("%s - dequant_h263_inter %.3f usec       crc32=0x%08x %s\n",
733                               cpu->name, t, s,
734                               (s!=0xe7df8fba)?"| ERROR": "");
735    
736      printf( " --- \n" );      printf( " --- \n" );
737    }    }
# Line 573  Line 760 
760    printf( "\n =====  test cbp =====\n" );    printf( "\n =====  test cbp =====\n" );
761    
762    for(i=0; i<6*64; ++i) {    for(i=0; i<6*64; ++i) {
763      Src1[i] = (i*i*3/8192)&(i/64)&1;  // 'random'                  Src1[i] = (i*i*3/8192)&(i/64)&1;  /* 'random' */
764      Src2[i] = (i<3*64);               // half-full                  Src2[i] = (i<3*64);               /* half-full */
765      Src3[i] = ((i+32)>3*64);      Src3[i] = ((i+32)>3*64);
766      Src4[i] = (i==(3*64+2) || i==(5*64+9));      Src4[i] = (i==(3*64+2) || i==(5*64+9));
767    }    }
768    
769    for(cpu = cpu_short_list2; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
770    {    {
771      double t;      double t;
772      int tst, cbp;      int tst, cbp;
# Line 588  Line 775 
775        continue;        continue;
776    
777      TEST_CBP(calc_cbp, Src1);      TEST_CBP(calc_cbp, Src1);
778      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\n",
779      if (cbp!=0x15) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x15)?"| ERROR": "");
780      TEST_CBP(calc_cbp, Src2);      TEST_CBP(calc_cbp, Src2);
781      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\n",
782      if (cbp!=0x38) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x38)?"| ERROR": "");
783      TEST_CBP(calc_cbp, Src3);      TEST_CBP(calc_cbp, Src3);
784      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\n",
785      if (cbp!=0x0f) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x0f)?"| ERROR": "" );
786      TEST_CBP(calc_cbp, Src4);      TEST_CBP(calc_cbp, Src4);
787      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\n",
788      if (cbp!=0x05) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x05)?"| ERROR": "" );
789      printf( " --- \n" );      printf( " --- \n" );
790    }    }
791  }  }
792    
793  /*********************************************************************  /*********************************************************************
794     * fdct/idct IEEE1180 compliance
795     *********************************************************************/
796    
797    typedef struct {
798            long Errors[64];
799            long Sqr_Errors[64];
800            long Max_Errors[64];
801            long Nb;
802    } STATS_8x8;
803    
804    void init_stats(STATS_8x8 *S)
805    {
806            int i;
807            for(i=0; i<64; ++i) {
808                    S->Errors[i]     = 0;
809                    S->Sqr_Errors[i] = 0;
810                    S->Max_Errors[i] = 0;
811            }
812            S->Nb = 0;
813    }
814    
815    void store_stats(STATS_8x8 *S, short Blk[64], short Ref[64])
816    {
817            int i;
818            for(i=0; i<64; ++i)
819            {
820                    short Err = Blk[i] - Ref[i];
821                    S->Errors[i] += Err;
822                    S->Sqr_Errors[i] += Err * Err;
823                    if (Err<0) Err = -Err;
824                    if (S->Max_Errors[i]<Err)
825                            S->Max_Errors[i] = Err;
826            }
827            S->Nb++;
828    }
829    
830    void print_stats(STATS_8x8 *S)
831    {
832            int i;
833            double Norm;
834    
835            assert(S->Nb>0);
836            Norm = 1. / (double)S->Nb;
837            printf("\n== Max absolute values of errors ==\n");
838            for(i=0; i<64; i++) {
839                    printf("  %4ld", S->Max_Errors[i]);
840                    if ((i&7)==7) printf("\n");
841            }
842    
843            printf("\n== Mean square errors ==\n");
844            for(i=0; i<64; i++)
845            {
846                    double Err = Norm * (double)S->Sqr_Errors[i];
847                    printf(" %.3f", Err);
848                    if ((i&7)==7) printf("\n");
849            }
850    
851            printf("\n== Mean errors ==\n");
852            for(i=0; i<64; i++)
853            {
854                    double Err = Norm * (double)S->Errors[i];
855                    printf(" %.3f", Err);
856                    if ((i&7)==7) printf("\n");
857            }
858            printf("\n");
859    }
860    
861    static const char *CHECK(double v, double l) {
862            if (fabs(v)<=l) return "ok";
863            else return "FAIL!";
864    }
865    
866    void report_stats(STATS_8x8 *S, const double *Limits)
867    {
868            int i;
869            double Norm, PE, PMSE, OMSE, PME, OME;
870    
871            assert(S->Nb>0);
872            Norm = 1. / (double)S->Nb;
873            PE = 0.;
874            for(i=0; i<64; i++) {
875                    if (PE<S->Max_Errors[i])
876                            PE = S->Max_Errors[i];
877            }
878    
879            PMSE = 0.;
880            OMSE = 0.;
881            for(i=0; i<64; i++)
882            {
883                    double Err = Norm * (double)S->Sqr_Errors[i];
884                    OMSE += Err;
885                    if (PMSE < Err) PMSE = Err;
886            }
887            OMSE /= 64.;
888    
889            PME = 0.;
890            OME = 0.;
891            for(i=0; i<64; i++)
892            {
893                    double Err = Norm * (double)S->Errors[i];
894                    OME += Err;
895                    Err = fabs(Err);
896                    if (PME < Err) PME = Err;
897            }
898            OME /= 64.;
899    
900            printf( "Peak error:   %4.4f\n", PE );
901            printf( "Peak MSE:     %4.4f\n", PMSE );
902            printf( "Overall MSE:  %4.4f\n", OMSE );
903            printf( "Peak ME:      %4.4f\n", PME );
904            printf( "Overall ME:   %4.4f\n", OME );
905    
906            if (Limits!=0)
907            {
908                    printf( "[PE<=%.4f %s]  ", Limits[0], CHECK(PE,   Limits[0]) );
909                    printf( "\n" );
910                    printf( "[PMSE<=%.4f %s]", Limits[1], CHECK(PMSE, Limits[1]) );
911                    printf( "[OMSE<=%.4f %s]", Limits[2], CHECK(OMSE, Limits[2]) );
912                    printf( "\n" );
913                    printf( "[PME<=%.4f %s] ", Limits[3], CHECK(PME , Limits[3]) );
914                    printf( "[OME<=%.4f %s] ", Limits[4], CHECK(OME , Limits[4]) );
915                    printf( "\n" );
916            }
917    }
918    
919    ///* ////////////////////////////////////////////////////// */
920    /* Pseudo-random generator specified by IEEE 1180 */
921    
922    static long ieee_seed = 1;
923    static void ieee_reseed(long s) {
924            ieee_seed = s;
925    }
926    static long ieee_rand(int Min, int Max)
927    {
928            static double z = (double) 0x7fffffff;
929    
930            long i,j;
931            double x;
932    
933            ieee_seed = (ieee_seed * 1103515245) + 12345;
934            i = ieee_seed & 0x7ffffffe;
935            x = ((double) i) / z;
936            x *= (Max-Min+1);
937            j = (long)x;
938            j = j + Min;
939            assert(j>=Min && j<=Max);
940            return (short)j;
941    }
942    
943    #define CLAMP(x, M)   (x) = ((x)<-(M)) ? (-(M)) : ((x)>=(M) ? ((M)-1) : (x))
944    
945    static double Cos[8][8];
946    static void init_ref_dct()
947    {
948            int i, j;
949            for(i=0; i<8; i++)
950            {
951                    double scale = (i == 0) ? sqrt(0.125) : 0.5;
952                    for (j=0; j<8; j++)
953                            Cos[i][j] = scale*cos( (M_PI/8.0)*i*(j + 0.5) );
954            }
955    }
956    
957    void ref_idct(short *M)
958    {
959            int i, j, k;
960            double Tmp[8][8];
961    
962            for(i=0; i<8; i++) {
963                    for(j=0; j<8; j++)
964                    {
965                            double Sum = 0.0;
966                            for (k=0; k<8; k++) Sum += Cos[k][j]*M[8*i+k];
967                            Tmp[i][j] = Sum;
968                    }
969            }
970            for(i=0; i<8; i++) {
971                    for(j=0; j<8; j++) {
972                            double Sum = 0.0;
973                            for (k=0; k<8; k++) Sum += Cos[k][i]*Tmp[k][j];
974                            M[8*i+j] = (short)floor(Sum + .5);
975                    }
976            }
977    }
978    
979    void ref_fdct(short *M)
980    {
981            int i, j, k;
982            double Tmp[8][8];
983    
984            for(i=0; i<8; i++) {
985                    for(j=0; j<8; j++)
986                    {
987                            double Sum = 0.0;
988                            for (k=0; k<8; k++) Sum += Cos[j][k]*M[8*i+k];
989                            Tmp[i][j] = Sum;
990                    }
991            }
992            for(i=0; i<8; i++) {
993                    for(j=0; j<8; j++) {
994                            double Sum = 0.0;
995                            for (k=0; k<8; k++) Sum += Cos[i][k]*Tmp[k][j];
996                            M[8*i+j] = (short)floor(Sum + 0.5);
997                    }
998            }
999    }
1000    
1001    void test_IEEE1180_compliance(int Min, int Max, int Sign)
1002    {
1003            static const double ILimits[5] = { 1., 0.06, 0.02, 0.015, 0.0015 };
1004            int Loops = 10000;
1005            int i, m, n;
1006            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, short, 16); /* reference */
1007            DECLARE_ALIGNED_MATRIX(Blk,  8, 8, short, 16);
1008            DECLARE_ALIGNED_MATRIX(iBlk, 8, 8, short, 16);
1009            DECLARE_ALIGNED_MATRIX(Ref_FDCT, 8, 8, short, 16);
1010            DECLARE_ALIGNED_MATRIX(Ref_IDCT, 8, 8, short, 16);
1011    
1012            STATS_8x8 FStats; /* forward dct stats */
1013            STATS_8x8 IStats; /* inverse dct stats */
1014    
1015            CPU *cpu;
1016    
1017            init_ref_dct();
1018    
1019            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1020            {
1021                    if (!init_cpu(cpu))
1022                            continue;
1023    
1024                    printf( "\n===== IEEE test for %s ==== (Min=%d Max=%d Sign=%d Loops=%d)\n",
1025                                    cpu->name, Min, Max, Sign, Loops);
1026    
1027                    init_stats(&IStats);
1028                    init_stats(&FStats);
1029    
1030                    ieee_reseed(1);
1031                    for(n=0; n<Loops; ++n)
1032                    {
1033                            for(i=0; i<64; ++i)
1034                                    Blk0[i] = (short)ieee_rand(Min,Max) * Sign;
1035    
1036                            /* hmm, I'm not quite sure this is exactly */
1037                            /* the tests described in the norm. check... */
1038    
1039                            memcpy(Ref_FDCT, Blk0, 64*sizeof(short));
1040                            ref_fdct(Ref_FDCT);
1041                            for(i=0; i<64; i++) CLAMP( Ref_FDCT[i], 2048 );
1042    
1043                            memcpy(Blk, Blk0, 64*sizeof(short));
1044                            emms(); fdct(Blk); emms();
1045                            for(i=0; i<64; i++) CLAMP( Blk[i], 2048 );
1046    
1047                            store_stats(&FStats, Blk, Ref_FDCT);
1048    
1049    
1050                            memcpy(Ref_IDCT, Ref_FDCT, 64*sizeof(short));
1051                            ref_idct(Ref_IDCT);
1052                            for (i=0; i<64; i++) CLAMP( Ref_IDCT[i], 256 );
1053    
1054                            memcpy(iBlk, Ref_FDCT, 64*sizeof(short));
1055                            emms(); idct(iBlk); emms();
1056                            for(i=0; i<64; i++) CLAMP( iBlk[i], 256 );
1057    
1058                            store_stats(&IStats, iBlk, Ref_IDCT);
1059                    }
1060    
1061    
1062                    printf( "\n  -- FDCT report --\n" );
1063    //    print_stats(&FStats);
1064                    report_stats(&FStats, 0); /* so far I know, IEEE1180 says nothing for fdct */
1065    
1066                    for(i=0; i<64; i++) Blk[i] = 0;
1067                    emms(); fdct(Blk); emms();
1068                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1069                    printf( "FDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1070    
1071                    printf( "\n  -- IDCT report --\n" );
1072    //    print_stats(&IStats);
1073                    report_stats(&IStats, ILimits);
1074    
1075    
1076                    for(i=0; i<64; i++) Blk[i] = 0;
1077                    emms(); idct(Blk); emms();
1078                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1079                    printf( "IDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1080            }
1081    }
1082    
1083    
1084    void test_dct_saturation(int Min, int Max)
1085    {
1086    /* test behaviour on input range fringe */
1087    
1088            int i, n, p;
1089            CPU *cpu;
1090    //  const short IDCT_MAX =  2047;  /* 12bits input */
1091    //  const short IDCT_MIN = -2048;
1092    //  const short IDCT_OUT =   256;  /* 9bits ouput */
1093            const int Partitions = 4;
1094            const int Loops = 10000 / Partitions;
1095    
1096            init_ref_dct();
1097    
1098            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1099            {
1100                    short Blk0[64], Blk[64];
1101                    STATS_8x8 Stats;
1102    
1103                    if (!init_cpu(cpu))
1104                            continue;
1105    
1106                    printf( "\n===== IEEE test for %s Min=%d Max=%d =====\n",
1107                                    cpu->name, Min, Max );
1108    
1109                    /* FDCT tests // */
1110    
1111                    init_stats(&Stats);
1112    
1113                    /* test each computation channels separately */
1114                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Max : 0;
1115                    ref_fdct(Blk0);
1116                    emms(); fdct(Blk); emms();
1117                    store_stats(&Stats, Blk, Blk0);
1118    
1119                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Min : 0;
1120                    ref_fdct(Blk0);
1121                    emms(); fdct(Blk); emms();
1122                    store_stats(&Stats, Blk, Blk0);
1123    
1124                    /* randomly saturated inputs */
1125                    for(p=0; p<Partitions; ++p)
1126                    {
1127                            for(n=0; n<Loops; ++n)
1128                            {
1129                                    for(i=0; i<64; ++i)
1130                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? Max : Min;
1131                                    ref_fdct(Blk0);
1132                                    emms(); fdct(Blk); emms();
1133                                    store_stats(&Stats, Blk, Blk0);
1134                            }
1135                    }
1136                    printf( "\n  -- FDCT saturation report --\n" );
1137                    report_stats(&Stats, 0);
1138    
1139    
1140                    /* IDCT tests // */
1141    #if 0
1142                    /* no finished yet */
1143    
1144                    init_stats(&Stats);
1145    
1146    /* test each computation channel separately */
1147                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MAX : 0;
1148                    ref_idct(Blk0);
1149                    emms(); idct(Blk); emms();
1150                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1151                    store_stats(&Stats, Blk, Blk0);
1152    
1153                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MIN : 0;
1154                    ref_idct(Blk0);
1155                    emms(); idct(Blk); emms();
1156                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1157                    store_stats(&Stats, Blk, Blk0);
1158    
1159                    /* randomly saturated inputs */
1160                    for(p=0; p<Partitions; ++p)
1161                    {
1162                            for(n=0; n<Loops; ++n)
1163                            {
1164                                    for(i=0; i<64; ++i)
1165                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? IDCT_MAX : IDCT_MIN;
1166                                    ref_idct(Blk0);
1167                                    emms(); idct(Blk); emms();
1168                                    for(i=0; i<64; i++) { CLAMP(Blk0[i],IDCT_OUT); CLAMP(Blk[i],IDCT_OUT); }
1169                                    store_stats(&Stats, Blk, Blk0);
1170                            }
1171                    }
1172    
1173                    printf( "\n  -- IDCT saturation report --\n" );
1174                    print_stats(&Stats);
1175                    report_stats(&Stats, 0);
1176    #endif
1177            }
1178    }
1179    
1180    /*********************************************************************
1181   * measure raw decoding speed   * measure raw decoding speed
1182   *********************************************************************/   *********************************************************************/
1183    
# Line 612  Line 1186 
1186    FILE *f = 0;    FILE *f = 0;
1187    void *dechandle = 0;    void *dechandle = 0;
1188    int xerr;    int xerr;
1189          XVID_INIT_PARAM xinit;          xvid_gbl_init_t xinit;
1190          XVID_DEC_PARAM xparam;          xvid_dec_create_t xparam;
1191          XVID_DEC_FRAME xframe;          xvid_dec_frame_t xframe;
1192          double t = 0.;          double t = 0.;
1193          int nb = 0;          int nb = 0;
1194    uint8_t *buf = 0;    uint8_t *buf = 0;
# Line 622  Line 1196 
1196    int buf_size, pos;    int buf_size, pos;
1197    uint32_t chksum = 0;    uint32_t chksum = 0;
1198    
1199          xinit.cpu_flags = 0;          memset(&xinit, 0, sizeof(xinit));
1200          xvid_init(NULL, 0, &xinit, NULL);          xinit.cpu_flags = XVID_CPU_MMX | XVID_CPU_FORCE;
1201          printf( "API version: %d, core build:%d\n", xinit.api_version, xinit.core_build);          xinit.version = XVID_VERSION;
1202            xvid_global(NULL, 0, &xinit, NULL);
1203    
1204            memset(&xparam, 0, sizeof(xparam));
1205          xparam.width = width;          xparam.width = width;
1206          xparam.height = height;          xparam.height = height;
1207            xparam.version = XVID_VERSION;
1208          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
1209          if (xerr!=XVID_ERR_OK) {          if (xerr==XVID_ERR_FAIL) {
1210            printf("can't init decoder (err=%d)\n", xerr);            printf("can't init decoder (err=%d)\n", xerr);
1211            return;            return;
1212          }          }
# Line 651  Line 1227 
1227    }    }
1228    else printf( "Input size: %d\n", buf_size);    else printf( "Input size: %d\n", buf_size);
1229    
1230    buf = malloc(buf_size); // should be enuf'          buf = malloc(buf_size); /* should be enuf' */
1231    rgb_out = calloc(4, width*height);  // <-room for _RGB24          rgb_out = calloc(4, width*height);  /* <-room for _RGB24 */
1232    if (buf==0 || rgb_out==0) {    if (buf==0 || rgb_out==0) {
1233      printf( "malloc failed!\n" );      printf( "malloc failed!\n" );
1234      goto End;      goto End;
# Line 667  Line 1243 
1243    pos = 0;    pos = 0;
1244    t = -gettime_usec();    t = -gettime_usec();
1245    while(1) {    while(1) {
1246                    memset(&xframe, 0, sizeof(xframe));
1247                    xframe.version = XVID_VERSION;
1248      xframe.bitstream = buf + pos;      xframe.bitstream = buf + pos;
1249      xframe.length = buf_size - pos;      xframe.length = buf_size - pos;
1250      xframe.image = rgb_out;                  xframe.output.plane[0] = rgb_out;
1251      xframe.stride = width;                  xframe.output.stride[0] = width;
1252      xframe.colorspace = XVID_CSP_RGB24;                  xframe.output.csp = XVID_CSP_BGR;
1253      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);
1254      nb++;      nb++;
1255      pos += xframe.length;      pos += xframe.length;
# Line 682  Line 1260 
1260      }      }
1261      if (pos==buf_size)      if (pos==buf_size)
1262        break;        break;
1263      if (xerr!=XVID_ERR_OK) {                  if (xerr==XVID_ERR_FAIL) {
1264            printf("decoding failed for frame #%d (err=%d)!\n", nb, xerr);            printf("decoding failed for frame #%d (err=%d)!\n", nb, xerr);
1265            break;            break;
1266          }          }
# Line 698  Line 1276 
1276    if (buf!=0) free(buf);    if (buf!=0) free(buf);
1277    if (dechandle!=0) {    if (dechandle!=0) {
1278      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);
1279      if (xerr!=XVID_ERR_OK)                  if (xerr==XVID_ERR_FAIL)
1280              printf("destroy-decoder failed (err=%d)!\n", xerr);              printf("destroy-decoder failed (err=%d)!\n", xerr);
1281    }    }
1282    if (f!=0) fclose(f);    if (f!=0) fclose(f);
# Line 711  Line 1289 
1289  void test_bugs1()  void test_bugs1()
1290  {  {
1291    CPU *cpu;    CPU *cpu;
1292            uint16_t mpeg_quant_matrices[64*8];
1293    
1294    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );
1295    
1296    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1297    {    {
1298      int i;      int i;
1299      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 723  Line 1302 
1302        continue;        continue;
1303    
1304      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1305      set_intra_matrix( get_default_intra_matrix() );                  set_intra_matrix( mpeg_quant_matrices, get_default_intra_matrix() );
1306      dequant4_intra(Dst, Src, 32, 5);                  dequant_mpeg_intra(Dst, Src, 31, 5, mpeg_quant_matrices);
1307      printf( "dequant4_intra with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_intra with CPU=%s:  ", cpu->name);
1308      printf( "  Out[]= " );      printf( "  Out[]= " );
1309      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1310      printf( "\n" );      printf( "\n" );
# Line 733  Line 1312 
1312    
1313    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );
1314    
1315    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1316    {    {
1317      int i;      int i;
1318      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 742  Line 1321 
1321        continue;        continue;
1322    
1323      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1324      set_inter_matrix( get_default_inter_matrix() );                  set_inter_matrix( mpeg_quant_matrices, get_default_inter_matrix() );
1325      dequant4_inter(Dst, Src, 32);                  dequant_mpeg_inter(Dst, Src, 31, mpeg_quant_matrices);
1326      printf( "dequant4_inter with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_inter with CPU=%s:  ", cpu->name);
1327      printf( "  Out[]= " );      printf( "  Out[]= " );
1328      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1329      printf( "\n" );      printf( "\n" );
# Line 756  Line 1335 
1335    CPU *cpu;    CPU *cpu;
1336    short Blk[8*8], Blk0[8*8];    short Blk[8*8], Blk0[8*8];
1337    
1338    printf( "\n =====  fdct/idct saturation diffs =====\n" );          printf( "\n =====  fdct/idct precision diffs =====\n" );
1339    
1340    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1341    {    {
1342      int i;      int i;
1343    
# Line 782  Line 1361 
1361    }    }
1362  }  }
1363    
1364    void test_quant_bug()
1365    {
1366            const int max_Q = 31;
1367            int i, n, qm, q;
1368            CPU *cpu;
1369            int16_t  Src[8*8], Dst[8*8];
1370            uint8_t Quant[8*8];
1371            CPU cpu_bug_list[] = { { "PLAINC", 0 }, { "MMX   ", XVID_CPU_MMX }, {0,0} };
1372            uint16_t Crcs_Inter[2][32];
1373            uint16_t Crcs_Intra[2][32];
1374            uint16_t mpeg_quant_matrices[64*8];
1375    
1376            printf( "\n =====  test MPEG4-quantize bug =====\n" );
1377    
1378            for(i=0; i<64; ++i) Src[i] = 2048*(i-32)/32;
1379    
1380    #if 1
1381            for(qm=1; qm<=255; ++qm)
1382            {
1383                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1384                    set_inter_matrix( mpeg_quant_matrices, Quant );
1385    
1386                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1387                    {
1388                            uint16_t s;
1389    
1390                            if (!init_cpu(cpu))
1391                                    continue;
1392    
1393                            for(q=1; q<=max_Q; ++q) {
1394                                    emms();
1395                                    quant_mpeg_inter( Dst, Src, q, mpeg_quant_matrices );
1396                                    emms();
1397                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1398                                    Crcs_Inter[n][q] = s;
1399                            }
1400                    }
1401    
1402                    for(q=1; q<=max_Q; ++q)
1403                            for(i=0; i<n-1; ++i)
1404                                    if (Crcs_Inter[i][q]!=Crcs_Inter[i+1][q])
1405                                            printf( "Discrepancy Inter: qm=%d, q=%d  -> %d/%d !\n",
1406                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1407            }
1408    #endif
1409    
1410    #if 1
1411            for(qm=1; qm<=255; ++qm)
1412            {
1413                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1414                    set_intra_matrix( mpeg_quant_matrices, Quant );
1415    
1416                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1417                    {
1418                            uint16_t s;
1419    
1420                            if (!init_cpu(cpu))
1421                                    continue;
1422    
1423                            for(q=1; q<=max_Q; ++q) {
1424                                    emms();
1425                                    quant_mpeg_intra( Dst, Src, q, q, mpeg_quant_matrices);
1426                                    emms();
1427                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1428                                    Crcs_Intra[n][q] = s;
1429                            }
1430                    }
1431    
1432                    for(q=1; q<=max_Q; ++q)
1433                            for(i=0; i<n-1; ++i)
1434                                    if (Crcs_Intra[i][q]!=Crcs_Intra[i+1][q])
1435                                            printf( "Discrepancy Intra: qm=%d, q=%d  -> %d/%d!\n",
1436                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1437            }
1438    #endif
1439    }
1440    
1441  /*********************************************************************  /*********************************************************************
1442   * main   * main
# Line 798  Line 1453 
1453    if (what==0 || what==5) test_quant();    if (what==0 || what==5) test_quant();
1454    if (what==0 || what==6) test_cbp();    if (what==0 || what==6) test_cbp();
1455    
1456    if (what==8) {          if (what==7) {
1457                    test_IEEE1180_compliance(-256, 255, 1);
1458                    test_IEEE1180_compliance(-256, 255,-1);
1459                    test_IEEE1180_compliance(  -5,   5, 1);
1460                    test_IEEE1180_compliance(  -5,   5,-1);
1461                    test_IEEE1180_compliance(-300, 300, 1);
1462                    test_IEEE1180_compliance(-300, 300,-1);
1463            }
1464            if (what==8) test_dct_saturation(-256, 255);
1465    
1466            if (what==9) {
1467      int width, height;      int width, height;
1468      if (argc<5) {      if (argc<5) {
1469        printf("usage: %s %d [bitstream] [width] [height]\n", argv[0], what);        printf("usage: %s %d [bitstream] [width] [height]\n", argv[0], what);
# Line 810  Line 1475 
1475    }    }
1476    
1477    if (what==-1) {    if (what==-1) {
     test_bugs1();  
1478      test_dct_precision_diffs();      test_dct_precision_diffs();
1479                    test_bugs1();
1480    }    }
1481            if (what==-2)
1482                    test_quant_bug();
1483    
1484            if (what >= 0 && what <= 6) {
1485                    printf("\n\n"
1486                               "NB: If a function isn't optimised for a specific set of intructions,\n"
1487                               "    a C function is used instead. So don't panic if some functions\n"
1488                               "    may appear to be slow.\n");
1489            }
1490    
1491    #ifdef ARCH_IS_IA32
1492            if (what == 0 || what == 5) {
1493                    printf("\n"
1494                               "NB: MMX mpeg4 quantization is known to have very small errors (+/-1 magnitude)\n"
1495                               "    for 1 or 2 coefficients a block. This is mainly caused by the fact the unit\n"
1496                               "    test goes far behind the usual limits of real encoding. Please do not report\n"
1497                               "    this error to the developers.\n");
1498            }
1499    #endif
1500    
1501    return 0;    return 0;
1502  }  }
1503    
1504  /*********************************************************************  /*********************************************************************
1505   * 'Reference' output (except for timing) on a PIII 1.13Ghz/linux   * 'Reference' output (except for timing) on an Athlon XP 2200+
1506   *********************************************************************/   *********************************************************************/
1507  /*  
1508    /* as of 2002-01-07, there's a problem with MMX mpeg4-quantization */
1509    /* as of 2003-11-30, the problem is still here */
1510    
1511    /*********************************************************************
1512    
1513    
1514   ===== test fdct/idct =====   ===== test fdct/idct =====
1515  PLAINC -  2.631 usec       iCrc=3  fCrc=-85  PLAINC -  2.867 usec       PSNR=13.291  MSE=3.000
1516  MMX    -  0.596 usec       iCrc=3  fCrc=-67  MMX    -  -0.211 usec       PSNR=9.611  MSE=7.000
1517  MMXEXT -  0.608 usec       iCrc=3  fCrc=-67  MMXEXT -  -0.256 usec       PSNR=9.611  MSE=7.000
1518  SSE2   -  0.605 usec       iCrc=3  fCrc=-67  3DNOW  -  2.855 usec       PSNR=13.291  MSE=3.000
1519  3DNOW  - skipped...  3DNOWE -  1.429 usec       PSNR=13.291  MSE=3.000
 3DNOWE - skipped...  
1520    
1521   ===  test block motion ===   ===  test block motion ===
1522  PLAINC - interp- h-round0 1.031 usec       iCrc=8107  PLAINC - interp- h-round0 0.538 usec       crc32=0x115381ba
1523  PLAINC -           round1 1.022 usec       iCrc=8100  PLAINC -           round1 0.527 usec       crc32=0x2b1f528f
1524  PLAINC - interp- v-round0 1.002 usec       iCrc=8108  PLAINC - interp- v-round0 0.554 usec       crc32=0x423cdcc7
1525  PLAINC -           round1 1.011 usec       iCrc=8105  PLAINC -           round1 0.551 usec       crc32=0x42202efe
1526  PLAINC - interp-hv-round0 1.623 usec       iCrc=8112  PLAINC - interp-hv-round0 1.041 usec       crc32=0xd198d387
1527  PLAINC -           round1 1.621 usec       iCrc=8103  PLAINC -           round1 1.038 usec       crc32=0x9ecfd921
1528  PLAINC - interpolate8x8_c 0.229 usec       iCrc=8107   ---
1529   ---  MMX    - interp- h-round0 0.051 usec       crc32=0x115381ba
1530  MMX    - interp- h-round0 0.105 usec       iCrc=8107  MMX    -           round1 0.053 usec       crc32=0x2b1f528f
1531  MMX    -           round1 0.105 usec       iCrc=8100  MMX    - interp- v-round0 0.048 usec       crc32=0x423cdcc7
1532  MMX    - interp- v-round0 0.106 usec       iCrc=8108  MMX    -           round1 0.048 usec       crc32=0x42202efe
1533  MMX    -           round1 0.107 usec       iCrc=8105  MMX    - interp-hv-round0 0.074 usec       crc32=0xd198d387
1534  MMX    - interp-hv-round0 0.145 usec       iCrc=8112  MMX    -           round1 0.073 usec       crc32=0x9ecfd921
1535  MMX    -           round1 0.145 usec       iCrc=8103   ---
1536  MMX    - interpolate8x8_c 0.229 usec       iCrc=8107  MMXEXT - interp- h-round0 0.020 usec       crc32=0x115381ba
1537   ---  MMXEXT -           round1 0.025 usec       crc32=0x2b1f528f
1538  MMXEXT - interp- h-round0 0.027 usec       iCrc=8107  MMXEXT - interp- v-round0 0.016 usec       crc32=0x423cdcc7
1539  MMXEXT -           round1 0.041 usec       iCrc=8100  MMXEXT -           round1 0.024 usec       crc32=0x42202efe
1540  MMXEXT - interp- v-round0 0.027 usec       iCrc=8108  MMXEXT - interp-hv-round0 0.037 usec       crc32=0xd198d387
1541  MMXEXT -           round1 0.040 usec       iCrc=8105  MMXEXT -           round1 0.037 usec       crc32=0x9ecfd921
1542  MMXEXT - interp-hv-round0 0.070 usec       iCrc=8112   ---
1543  MMXEXT -           round1 0.066 usec       iCrc=8103  3DNOW  - interp- h-round0 0.020 usec       crc32=0x115381ba
1544  MMXEXT - interpolate8x8_c 0.027 usec       iCrc=8107  3DNOW  -           round1 0.029 usec       crc32=0x2b1f528f
1545   ---  3DNOW  - interp- v-round0 0.016 usec       crc32=0x423cdcc7
1546  SSE2   - interp- h-round0 0.106 usec       iCrc=8107  3DNOW  -           round1 0.024 usec       crc32=0x42202efe
1547  SSE2   -           round1 0.105 usec       iCrc=8100  3DNOW  - interp-hv-round0 0.038 usec       crc32=0xd198d387
1548  SSE2   - interp- v-round0 0.106 usec       iCrc=8108  3DNOW  -           round1 0.039 usec       crc32=0x9ecfd921
1549  SSE2   -           round1 0.106 usec       iCrc=8105   ---
1550  SSE2   - interp-hv-round0 0.145 usec       iCrc=8112  3DNOWE - interp- h-round0 0.020 usec       crc32=0x115381ba
1551  SSE2   -           round1 0.145 usec       iCrc=8103  3DNOWE -           round1 0.024 usec       crc32=0x2b1f528f
1552  SSE2   - interpolate8x8_c 0.237 usec       iCrc=8107  3DNOWE - interp- v-round0 0.016 usec       crc32=0x423cdcc7
1553    3DNOWE -           round1 0.021 usec       crc32=0x42202efe
1554    3DNOWE - interp-hv-round0 0.037 usec       crc32=0xd198d387
1555    3DNOWE -           round1 0.036 usec       crc32=0x9ecfd921
1556   ---   ---
 3DNOW  - skipped...  
 3DNOWE - skipped...  
1557    
1558   ======  test SAD ======   ======  test SAD ======
1559  PLAINC - sad8    0.296 usec       sad=3776  PLAINC - sad8    0.505 usec       sad=3776
1560  PLAINC - sad16   1.599 usec       sad=27214  PLAINC - sad16   1.941 usec       sad=27214
1561  PLAINC - sad16bi 2.350 usec       sad=26274  PLAINC - sad16bi 4.925 usec       sad=26274
1562  PLAINC - dev16   1.610 usec       sad=3344  PLAINC - dev16   4.254 usec       sad=3344
1563   ---   ---
1564  MMX    - sad8    0.057 usec       sad=3776  MMX    - sad8    0.036 usec       sad=3776
1565  MMX    - sad16   0.178 usec       sad=27214  MMX    - sad16   0.107 usec       sad=27214
1566  MMX    - sad16bi 2.381 usec       sad=26274  MMX    - sad16bi 0.259 usec       sad=26274
1567  MMX    - dev16   0.312 usec       sad=3344  MMX    - dev16   0.187 usec       sad=3344
1568   ---   ---
1569  MMXEXT - sad8    0.036 usec       sad=3776  MMXEXT - sad8    0.016 usec       sad=3776
1570  MMXEXT - sad16   0.106 usec       sad=27214  MMXEXT - sad16   0.050 usec       sad=27214
1571  MMXEXT - sad16bi 0.182 usec       sad=26274  MMXEXT - sad16bi 0.060 usec       sad=26274
1572  MMXEXT - dev16   0.193 usec       sad=3344  MMXEXT - dev16   0.086 usec       sad=3344
1573   ---   ---
1574  SSE2   - sad8    0.057 usec       sad=3776  3DNOW  - sad8    0.506 usec       sad=3776
1575  SSE2   - sad16   0.178 usec       sad=27214  3DNOW  - sad16   1.954 usec       sad=27214
1576  SSE2   - sad16bi 2.427 usec       sad=26274  3DNOW  - sad16bi 0.119 usec       sad=26274
1577  SSE2   - dev16   0.313 usec       sad=3344  3DNOW  - dev16   4.252 usec       sad=3344
1578     ---
1579    3DNOWE - sad8    0.017 usec       sad=3776
1580    3DNOWE - sad16   0.038 usec       sad=27214
1581    3DNOWE - sad16bi 0.052 usec       sad=26274
1582    3DNOWE - dev16   0.067 usec       sad=3344
1583   ---   ---
 3DNOW  - skipped...  
 3DNOWE - skipped...  
1584    
1585   ===  test transfer ===   ===  test transfer ===
1586  PLAINC - 8to16     0.124 usec       crc=28288  PLAINC - 8to16     0.603 usec       crc32=0x115814bb
1587  PLAINC - 16to8     0.753 usec       crc=28288  PLAINC - 16to8     1.077 usec       crc32=0xee7ccbb4
1588  PLAINC - 8to8      0.041 usec       crc=20352  PLAINC - 8to8      0.679 usec       crc32=0xd37b3295
1589  PLAINC - 16to8add  0.916 usec       crc=25536  PLAINC - 16to8add  1.341 usec       crc32=0xdd817bf4
1590  PLAINC - 8to16sub  0.812 usec       crc1=28064 crc2=16256  PLAINC - 8to16sub  1.566 usec       crc32(1)=0xa1e07163 crc32(2)=0xd86c5d23
1591  PLAINC - 8to16sub2 0.954 usec       crc=20384  PLAINC - 8to16sub2 2.206 usec       crc32=0x99b6c4c7
1592   ---   ---
1593  MMX    - 8to16     0.037 usec       crc=28288  MMX    - 8to16     -0.025 usec       crc32=0x115814bb
1594  MMX    - 16to8     0.016 usec       crc=28288  MMX    - 16to8     -0.049 usec       crc32=0xee7ccbb4
1595  MMX    - 8to8      0.018 usec       crc=20352  MMX    - 8to8      0.014 usec       crc32=0xd37b3295
1596  MMX    - 16to8add  0.044 usec       crc=25536  MMX    - 16to8add  0.011 usec       crc32=0xdd817bf4
1597  MMX    - 8to16sub  0.065 usec       crc1=28064 crc2=16256  MMX    - 8to16sub  0.108 usec       crc32(1)=0xa1e07163 crc32(2)=0xd86c5d23
1598  MMX    - 8to16sub2 0.110 usec       crc=20384  MMX    - 8to16sub2 0.164 usec       crc32=0x99b6c4c7
1599   ---   ---
1600  MMXEXT - 8to16     0.032 usec       crc=28288  MMXEXT - 8to16     -0.054 usec       crc32=0x115814bb
1601  MMXEXT - 16to8     0.023 usec       crc=28288  MMXEXT - 16to8     0.010 usec       crc32=0xee7ccbb4
1602  MMXEXT - 8to8      0.018 usec       crc=20352  MMXEXT - 8to8      0.015 usec       crc32=0xd37b3295
1603  MMXEXT - 16to8add  0.041 usec       crc=25536  MMXEXT - 16to8add  0.008 usec       crc32=0xdd817bf4
1604  MMXEXT - 8to16sub  0.065 usec       crc1=28064 crc2=16256  MMXEXT - 8to16sub  0.263 usec       crc32(1)=0xa1e07163 crc32(2)=0xd86c5d23
1605  MMXEXT - 8to16sub2 0.069 usec       crc=20384  MMXEXT - 8to16sub2 0.178 usec       crc32=0x99b6c4c7
1606     ---
1607    3DNOW  - 8to16     0.666 usec       crc32=0x115814bb
1608    3DNOW  - 16to8     1.078 usec       crc32=0xee7ccbb4
1609    3DNOW  - 8to8      0.665 usec       crc32=0xd37b3295
1610    3DNOW  - 16to8add  1.365 usec       crc32=0xdd817bf4
1611    3DNOW  - 8to16sub  1.356 usec       crc32(1)=0xa1e07163 crc32(2)=0xd86c5d23
1612    3DNOW  - 8to16sub2 2.098 usec       crc32=0x99b6c4c7
1613     ---
1614    3DNOWE - 8to16     -0.024 usec       crc32=0x115814bb
1615    3DNOWE - 16to8     0.010 usec       crc32=0xee7ccbb4
1616    3DNOWE - 8to8      0.014 usec       crc32=0xd37b3295
1617    3DNOWE - 16to8add  0.016 usec       crc32=0xdd817bf4
1618    3DNOWE - 8to16sub  -0.000 usec       crc32(1)=0xa1e07163 crc32(2)=0xd86c5d23
1619    3DNOWE - 8to16sub2 -0.031 usec       crc32=0x99b6c4c7
1620   ---   ---
1621    
1622   =====  test quant =====   =====  test quant =====
1623  PLAINC -   quant4_intra 78.889 usec       crc=55827  PLAINC -   quant_mpeg_intra 98.631 usec       crc32=0xfd6a21a4
1624  PLAINC -   quant4_inter 71.957 usec       crc=58201  PLAINC -   quant_mpeg_inter 104.876 usec       crc32=0xf6de7757
1625  PLAINC - dequant4_intra 34.968 usec       crc=193340  PLAINC - dequant_mpeg_intra 50.285 usec       crc32=0x2def7bc7
1626  PLAINC - dequant4_inter 40.792 usec       crc=116483  PLAINC - dequant_mpeg_inter 58.316 usec       crc32=0xd878c722
1627  PLAINC -    quant_intra 30.845 usec       crc=56885  PLAINC -   quant_h263_intra 33.803 usec       crc32=0x2eba9d43
1628  PLAINC -    quant_inter 34.842 usec       crc=58056  PLAINC -   quant_h263_inter 45.411 usec       crc32=0xbd315a7e
1629  PLAINC -  dequant_intra 33.211 usec       crc=-7936  PLAINC - dequant_h263_intra 39.302 usec       crc32=0x9841212a
1630  PLAINC -  dequant_inter 45.486 usec       crc=-33217  PLAINC - dequant_h263_inter 44.124 usec       crc32=0xe7df8fba
1631   ---   ---
1632  MMX    -   quant4_intra 9.030 usec       crc=55827  MMX    -   quant_mpeg_intra 4.273 usec       crc32=0xdacabdb6 | ERROR
1633  MMX    -   quant4_inter 8.234 usec       crc=58201  MMX    -   quant_mpeg_inter 3.576 usec       crc32=0x72883ab6 | ERROR
1634  MMX    - dequant4_intra 18.330 usec       crc=193340  MMX    - dequant_mpeg_intra 3.793 usec       crc32=0x2def7bc7
1635  MMX    - dequant4_inter 19.181 usec       crc=116483  MMX    - dequant_mpeg_inter 4.808 usec       crc32=0xd878c722
1636  MMX    -    quant_intra 7.124 usec       crc=56885  MMX    -   quant_h263_intra 2.881 usec       crc32=0x2eba9d43
1637  MMX    -    quant_inter 6.861 usec       crc=58056  MMX    -   quant_h263_inter 2.550 usec       crc32=0xbd315a7e
1638  MMX    -  dequant_intra 9.048 usec       crc=-7936  MMX    - dequant_h263_intra 2.974 usec       crc32=0x9841212a
1639  MMX    -  dequant_inter 8.203 usec       crc=-33217  MMX    - dequant_h263_inter 2.906 usec       crc32=0xe7df8fba
1640   ---   ---
1641  MMXEXT -   quant4_intra 9.045 usec       crc=55827  MMXEXT -   quant_mpeg_intra 4.221 usec       crc32=0xfd6a21a4
1642  MMXEXT -   quant4_inter 8.232 usec       crc=58201  MMXEXT -   quant_mpeg_inter 4.339 usec       crc32=0xf6de7757
1643  MMXEXT - dequant4_intra 18.250 usec       crc=193340  MMXEXT - dequant_mpeg_intra 3.802 usec       crc32=0x2def7bc7
1644  MMXEXT - dequant4_inter 19.256 usec       crc=116483  MMXEXT - dequant_mpeg_inter 4.821 usec       crc32=0xd878c722
1645  MMXEXT -    quant_intra 7.121 usec       crc=56885  MMXEXT -   quant_h263_intra 2.884 usec       crc32=0x2eba9d43
1646  MMXEXT -    quant_inter 6.855 usec       crc=58056  MMXEXT -   quant_h263_inter 2.554 usec       crc32=0xbd315a7e
1647  MMXEXT -  dequant_intra 9.034 usec       crc=-7936  MMXEXT - dequant_h263_intra 2.728 usec       crc32=0x9841212a
1648  MMXEXT -  dequant_inter 8.202 usec       crc=-33217  MMXEXT - dequant_h263_inter 2.611 usec       crc32=0xe7df8fba
1649     ---
1650    3DNOW  -   quant_mpeg_intra 98.512 usec       crc32=0xfd6a21a4
1651    3DNOW  -   quant_mpeg_inter 104.873 usec       crc32=0xf6de7757
1652    3DNOW  - dequant_mpeg_intra 50.219 usec       crc32=0x2def7bc7
1653    3DNOW  - dequant_mpeg_inter 58.254 usec       crc32=0xd878c722
1654    3DNOW  -   quant_h263_intra 33.778 usec       crc32=0x2eba9d43
1655    3DNOW  -   quant_h263_inter 41.998 usec       crc32=0xbd315a7e
1656    3DNOW  - dequant_h263_intra 39.344 usec       crc32=0x9841212a
1657    3DNOW  - dequant_h263_inter 43.607 usec       crc32=0xe7df8fba
1658     ---
1659    3DNOWE -   quant_mpeg_intra 98.490 usec       crc32=0xfd6a21a4
1660    3DNOWE -   quant_mpeg_inter 104.889 usec       crc32=0xf6de7757
1661    3DNOWE - dequant_mpeg_intra 3.277 usec       crc32=0x2def7bc7
1662    3DNOWE - dequant_mpeg_inter 4.485 usec       crc32=0xd878c722
1663    3DNOWE -   quant_h263_intra 1.882 usec       crc32=0x2eba9d43
1664    3DNOWE -   quant_h263_inter 2.246 usec       crc32=0xbd315a7e
1665    3DNOWE - dequant_h263_intra 3.457 usec       crc32=0x9841212a
1666    3DNOWE - dequant_h263_inter 3.275 usec       crc32=0xe7df8fba
1667   ---   ---
1668    
1669   =====  test cbp =====   =====  test cbp =====
1670  PLAINC -   calc_cbp#1 0.545 usec       cbp=0x15  PLAINC -   calc_cbp#1 0.168 usec       cbp=0x15
1671  PLAINC -   calc_cbp#2 0.540 usec       cbp=0x38  PLAINC -   calc_cbp#2 0.168 usec       cbp=0x38
1672  PLAINC -   calc_cbp#3 0.477 usec       cbp=0xf  PLAINC -   calc_cbp#3 0.157 usec       cbp=0x0f
1673  PLAINC -   calc_cbp#4 0.739 usec       cbp=0x5  PLAINC -   calc_cbp#4 0.235 usec       cbp=0x05
  ---  
 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  
1674   ---   ---
1675  */  MMX    -   calc_cbp#1 0.070 usec       cbp=0x15
1676    MMX    -   calc_cbp#2 0.062 usec       cbp=0x38
1677    MMX    -   calc_cbp#3 0.062 usec       cbp=0x0f
1678    MMX    -   calc_cbp#4 0.061 usec       cbp=0x05
1679     ---
1680    MMXEXT -   calc_cbp#1 0.062 usec       cbp=0x15
1681    MMXEXT -   calc_cbp#2 0.061 usec       cbp=0x38
1682    MMXEXT -   calc_cbp#3 0.061 usec       cbp=0x0f
1683    MMXEXT -   calc_cbp#4 0.061 usec       cbp=0x05
1684     ---
1685    3DNOW  -   calc_cbp#1 0.168 usec       cbp=0x15
1686    3DNOW  -   calc_cbp#2 0.168 usec       cbp=0x38
1687    3DNOW  -   calc_cbp#3 0.157 usec       cbp=0x0f
1688    3DNOW  -   calc_cbp#4 0.238 usec       cbp=0x05
1689     ---
1690    3DNOWE -   calc_cbp#1 0.049 usec       cbp=0x15
1691    3DNOWE -   calc_cbp#2 0.049 usec       cbp=0x38
1692    3DNOWE -   calc_cbp#3 0.049 usec       cbp=0x0f
1693    3DNOWE -   calc_cbp#4 0.049 usec       cbp=0x05
1694     ---
1695    
1696    
1697    NB: If a function isn't optimised for a specific set of intructions,
1698        a C function is used instead. So don't panic if some functions
1699        may appear to be slow.
1700    
1701    NB: MMX mpeg4 quantization is known to have very small errors (+/-1 magnitude)
1702        for 1 or 2 coefficients a block. This is mainly caused by the fact the unit
1703        test goes far behind the usual limits of real encoding. Please do not report
1704        this error to the developers
1705    
1706    *********************************************************************/

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

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