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

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