[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 2021, Wed Jul 6 10:25:14 2011 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$
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
50    #include "portab.h"
51  #include "dct/idct.h"  #include "dct/idct.h"
52  #include "dct/fdct.h"  #include "dct/fdct.h"
53  #include "image/colorspace.h"  #include "image/colorspace.h"
54  #include "image/interpolate8x8.h"  #include "image/interpolate8x8.h"
55  #include "utils/mem_transfer.h"  #include "utils/mem_transfer.h"
56  #include "quant/quant_h263.h"  #include "quant/quant.h"
 #include "quant/quant_mpeg4.h"  
57  #include "motion/sad.h"  #include "motion/sad.h"
58  #include "utils/emms.h"  #include "utils/emms.h"
59  #include "utils/timer.h"  #include "utils/timer.h"
60  #include "quant/quant_matrix.c"  #include "quant/quant_matrix.c"
61  #include "bitstream/cbp.h"  #include "bitstream/cbp.h"
62    #include "bitstream/bitstream.h"
63    
64    #include <math.h>
65    
66    #ifndef M_PI
67    #define M_PI            3.14159265358979323846
68    #endif
69    
70  const int speed_ref = 100;  // on slow machines, decrease this value  int speed_ref = 100;  /* on slow machines, decrease this value */
71    int verbose = 0;
72    unsigned int cpu_mask;
73    
74  /*********************************************************************  /*********************************************************************
75   * misc   * misc
# Line 64  Line 78 
78   /* returns time in micro-s*/   /* returns time in micro-s*/
79  double gettime_usec()  double gettime_usec()
80  {  {
81    #ifndef WIN32
82    struct timeval  tv;    struct timeval  tv;
83    gettimeofday(&tv, 0);    gettimeofday(&tv, 0);
84    return tv.tv_sec*1.0e6f + tv.tv_usec;          return tv.tv_sec*1.0e6 + tv.tv_usec;
85    #else
86            clock_t clk;
87            clk = clock();
88            return clk * 1000. / CLOCKS_PER_SEC;  /* clock() returns time in Milliseconds */
89    #endif
90  }  }
91    
92   /* 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 114 
114    unsigned int cpu;    unsigned int cpu;
115  } CPU;  } CPU;
116    
117  CPU cpu_list[] =  CPU cpu_list[] = {
118  { { "PLAINC", 0 }          { "PLAINC ", 0 },
119  , { "MMX   ", XVID_CPU_MMX }  #if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
120  , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }          { "MMX    ", XVID_CPU_MMX },
121  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }          { "MMXEXT ", XVID_CPU_MMXEXT | XVID_CPU_MMX },
122  , { "3DNOW ", XVID_CPU_3DNOW }          { "SSE2   ", XVID_CPU_SSE2 | XVID_CPU_MMX },
123  , { "3DNOWE", XVID_CPU_3DNOWEXT }          { "SSE3   ", XVID_CPU_SSE3 | XVID_CPU_SSE2 | XVID_CPU_MMX },
124  //, { "TSC   ", XVID_CPU_TSC }          { "SSE41  ", XVID_CPU_SSE41| XVID_CPU_SSE3 | XVID_CPU_SSE2 | XVID_CPU_MMX },
125  , { 0, 0 } }          { "3DNOW  ", XVID_CPU_3DNOW },
126            { "3DNOWE ", XVID_CPU_3DNOW | XVID_CPU_3DNOWEXT },
127  , cpu_short_list[] =  #endif
128  { { "PLAINC", 0 }  #ifdef ARCH_IS_PPC
129  , { "MMX   ", XVID_CPU_MMX }          { "ALTIVEC", XVID_CPU_ALTIVEC },
130  , { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }  #endif
131  , { 0, 0 } }  #ifdef ARCH_IS_IA64
132    //      { "IA64   ", XVID_CPU_IA64 },
133  , cpu_short_list2[] =  #endif
134  { { "PLAINC", 0 }  //      { "TSC    ", XVID_CPU_TSC },
135  , { "MMX   ", XVID_CPU_MMX }          { 0, 0 }
136  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }  };
 , { 0, 0 } };  
137    
138    
139  int init_cpu(CPU *cpu)  int init_cpu(CPU *cpu)
140  {  {
141    int xerr, cpu_type;          xvid_gbl_info_t xinfo;
142    XVID_INIT_PARAM xinit;  
143            /* Get the available CPU flags */
144            memset(&xinfo, 0, sizeof(xinfo));
145            xinfo.version = XVID_VERSION;
146            xvid_global(NULL, XVID_GBL_INFO, &xinfo, NULL);
147    
148    cpu_type = check_cpu_features() & cpu->cpu;          /* Are we trying to test a subset of the host CPU features */
149    xinit.cpu_flags = cpu_type | XVID_CPU_FORCE;          if ((xinfo.cpu_flags & cpu->cpu) == cpu->cpu) {
150    //    xinit.cpu_flags = XVID_CPU_MMX | XVID_CPU_FORCE;                  int xerr;
151    xerr = xvid_init(NULL, 0, &xinit, NULL);                  xvid_gbl_init_t xinit;
152    if (cpu->cpu>0 && (cpu_type==0 || xerr!=XVID_ERR_OK)) {                  memset(&xinit, 0, sizeof(xinit));
153      printf( "%s - skipped...\n", cpu->name );                  xinit.cpu_flags = cpu->cpu | XVID_CPU_FORCE;
154                    xinit.version = XVID_VERSION;
155                    xerr = xvid_global(NULL, XVID_GBL_INIT, &xinit, NULL);
156                    if (xerr==XVID_ERR_FAIL) {
157                            /* libxvidcore failed to init */
158      return 0;      return 0;
159    }    }
160            } else {
161                    /* The host CPU doesn't support some required feature for this test */
162                    return(0);
163            }
164    return 1;    return 1;
165  }  }
166    
167    #define CRC32_REMAINDER 0xCBF43926
168    #define CRC32_INITIAL 0xffffffff
169    
170    #define DO1(c, crc) ((crc) = crc32tab[((unsigned int)((crc)>>24) ^ (*c++)) & 0xff] ^ ((crc) << 8))
171    #define DO2(c, crc)  DO1(c, crc); DO1(c, crc);
172    #define DO4(c, crc)  DO2(c, crc); DO2(c, crc);
173    #define DO8(c, crc)  DO4(c, crc); DO4(c, crc);
174    
175    /******************************************************************************
176    * Precomputed AAL5 CRC32 lookup table
177    ******************************************************************************/
178    
179    static unsigned long crc32tab[256] = {
180    
181            0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
182            0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
183            0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
184            0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
185            0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
186            0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
187            0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
188            0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
189            0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
190            0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
191            0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
192            0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
193            0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
194            0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
195            0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
196            0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
197            0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
198            0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
199            0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
200            0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
201            0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
202            0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
203            0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
204            0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
205            0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
206            0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
207            0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
208            0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
209            0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
210            0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
211            0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
212            0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
213            0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
214            0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
215            0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
216            0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
217            0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
218            0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
219            0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
220            0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
221            0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
222            0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
223            0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
224            0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
225            0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
226            0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
227            0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
228            0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
229            0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
230            0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
231            0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
232            0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
233            0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
234            0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
235            0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
236            0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
237            0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
238            0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
239            0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
240            0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
241            0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
242            0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
243            0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
244            0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
245    
246    };
247    
248    uint32_t
249    calc_crc(uint8_t *mem, int len, uint32_t crc)
250    {
251            while( len >= 8) {
252                    DO8(mem, crc);
253                    len -= 8;
254            }
255    
256            while( len ) {
257                    DO1(mem, crc);
258                    len--;
259            }
260    
261            return crc;
262    }
263    
264    void byte_swap(uint8_t *mem, int len, int element_size) {
265    #ifdef ARCH_IS_BIG_ENDIAN
266            int i;
267    
268            if(element_size == 1) {
269                    /* No need to swap */
270            } else if(element_size == 2) {
271                    uint8_t temp[2];
272    
273                    for(i=0; i < (len/2); i++ ) {
274                            temp[0] = mem[0];
275                            temp[1] = mem[1];
276                            mem[0] = temp[1];
277                            mem[1] = temp[0];
278    
279                            mem += 2;
280                    }
281            } else if(element_size == 4) {
282                    uint8_t temp[4];
283    
284                    for(i=0; i < (len/4); i++ ) {
285                            temp[0] = mem[0];
286                            temp[1] = mem[1];
287                            temp[2] = mem[2];
288                            temp[3] = mem[3];
289                            mem[0] = temp[3];
290                            mem[1] = temp[2];
291                            mem[2] = temp[1];
292                            mem[3] = temp[0];
293    
294                            mem += 4;
295                    }
296            } else {
297                    printf("ERROR: byte_swap unsupported element_size(%u)\n", element_size);
298            }
299    #endif
300    }
301    
302  /*********************************************************************  /*********************************************************************
303   * test DCT   * test DCT
304   *********************************************************************/   *********************************************************************/
# Line 145  Line 311 
311    int tst;    int tst;
312    CPU *cpu;    CPU *cpu;
313    int i;    int i;
314    short iDst0[8*8], iDst[8*8], fDst[8*8];          DECLARE_ALIGNED_MATRIX(iDst0, 8, 8, short, 16);
315            DECLARE_ALIGNED_MATRIX(iDst,  8, 8, short, 16);
316            DECLARE_ALIGNED_MATRIX(fDst,  8, 8, short, 16);
317    double overhead;    double overhead;
318    
319    printf( "\n ===== test fdct/idct =====\n" );    printf( "\n ===== test fdct/idct =====\n" );
# Line 161  Line 329 
329    
330    for(cpu = cpu_list; cpu->name!=0; ++cpu)    for(cpu = cpu_list; cpu->name!=0; ++cpu)
331    {    {
332      double t;                  double t, PSNR, MSE;
     int iCrc, fCrc;  
333    
334      if (!init_cpu(cpu))      if (!init_cpu(cpu))
335        continue;        continue;
# Line 178  Line 345 
345      }      }
346      emms();      emms();
347      t = (gettime_usec() - t - overhead) / nb_tests;      t = (gettime_usec() - t - overhead) / nb_tests;
348      iCrc=0; fCrc=0;                  MSE = 0.;
349      for(i=0; i<8*8; ++i) {      for(i=0; i<8*8; ++i) {
350        iCrc += ABS(iDst[i] - iDst0[i]);                          double delta = 1.0*(iDst[i] - iDst0[i]);
351        fCrc += fDst[i]^i;                          MSE += delta*delta;
352      }      }
353      printf( "%s -  %.3f usec       iCrc=%d  fCrc=%d\n",                  PSNR = (MSE==0.) ? 1.e6 : -4.3429448*log( MSE/64. );
354        cpu->name, t, iCrc, fCrc );                  printf( "%s -  %.3f usec       PSNR=%.3f  MSE=%.3f %s\n",
355        // the norm tolerates ~1 bit of diff per coeff                                  cpu->name, t, PSNR, MSE,
356      if (ABS(iCrc)>=64) printf( "*** CRC ERROR! ***\n" );                                  (ABS(MSE)>=64)? "| ERROR" :"");
357    }    }
358  }  }
359    
# Line 200  Line 367 
367    int tst;    int tst;
368    CPU *cpu;    CPU *cpu;
369    int i;    int i;
370    uint8_t Cur[16*16], Ref1[16*16], Ref2[16*16];          DECLARE_ALIGNED_MATRIX(Cur,  16, 16, uint8_t, 16);
371            DECLARE_ALIGNED_MATRIX(Ref1, 16, 16, uint8_t, 16);
372            DECLARE_ALIGNED_MATRIX(Ref2, 16, 16, uint8_t, 16);
373    
374    printf( "\n ======  test SAD ======\n" );    printf( "\n ======  test SAD ======\n" );
375    for(i=0; i<16*16;++i) {    for(i=0; i<16*16;++i) {
# Line 221  Line 390 
390      for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);      for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);
391      emms();      emms();
392      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
393      printf( "%s - sad8    %.3f usec       sad=%d\n", cpu->name, t, s );                  printf("%s - sad8    %.3f usec       sad=%d %s\n",
394      if (s!=3776) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
395                               (s!=3776)?"| ERROR": "" );
396    
397      t = gettime_usec();      t = gettime_usec();
398      emms();      emms();
399      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);
400      emms();      emms();
401      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
402      printf( "%s - sad16   %.3f usec       sad=%d\n", cpu->name, t, s );                  printf("%s - sad16   %.3f usec       sad=%d %s\n",
403      if (s!=27214) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
404                               (s!=27214)?"| ERROR": "" );
405    
406      t = gettime_usec();      t = gettime_usec();
407      emms();      emms();
408      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);
409      emms();      emms();
410      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
411      printf( "%s - sad16bi %.3f usec       sad=%d\n", cpu->name, t, s );                  printf( "%s - sad16bi %.3f usec       sad=%d %s\n",
412      if (s!=26274) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
413                                    (s!=26274)?"| ERROR": "" );
414    
415                    t = gettime_usec();
416                    emms();
417                    for(tst=0; tst<nb_tests; ++tst) s = sad8bi(Cur, Ref1, Ref2, 8);
418                    emms();
419                    t = (gettime_usec() - t) / nb_tests;
420                    printf( "%s - sad8bi %.3f usec       sad=%d %s\n",
421                                    cpu->name, t, s,
422                                    (s!=4002)?"| ERROR": "" );
423    
424      t = gettime_usec();      t = gettime_usec();
425      emms();      emms();
426      for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);      for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);
427      emms();      emms();
428      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
429      printf( "%s - dev16   %.3f usec       sad=%d\n", cpu->name, t, s );                  printf( "%s - dev16   %.3f usec       sad=%d %s\n",
430      if (s!=3344) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
431                                    (s!=3344)?"| ERROR": "" );
432    
433      printf( " --- \n" );      printf( " --- \n" );
434    }    }
# Line 264  Line 446 
446  #define LEAVE \  #define LEAVE \
447      emms();                             \      emms();                             \
448      t = (gettime_usec() - t) / nb_tests;  \      t = (gettime_usec() - t) / nb_tests;  \
449      iCrc = 0;                           \          iCrc = calc_crc((uint8_t*)Dst, sizeof(Dst), CRC32_INITIAL)
     for(i=0; i<16*8; ++i) { iCrc += Dst[i]^i; }  
450    
451  #define TEST_MB(FUNC, R)                \  #define TEST_MB(FUNC, R)                \
452      ENTER                               \      ENTER                               \
# Line 283  Line 464 
464    const int nb_tests = 2000*speed_ref;    const int nb_tests = 2000*speed_ref;
465    CPU *cpu;    CPU *cpu;
466    const uint8_t Src0[16*9] = {    const uint8_t Src0[16*9] = {
467          // try to have every possible combinaison of rounding...                  /* try to have every possible combinaison of rounding... */
468        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,
469      , 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,
470      , 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,
471      , 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,
472      , 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,
473      , 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,
474      , 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,
475      , 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,
476      , 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
477    };    };
478    uint8_t Dst[16*8] = {0};    uint8_t Dst[16*8] = {0};
479    
# Line 307  Line 488 
488        continue;        continue;
489    
490      TEST_MB(interpolate8x8_halfpel_h, 0);      TEST_MB(interpolate8x8_halfpel_h, 0);
491      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",
492      if (iCrc!=8107) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
493                               (iCrc!=0x115381ba)?"| ERROR": "" );
494    
495      TEST_MB(interpolate8x8_halfpel_h, 1);      TEST_MB(interpolate8x8_halfpel_h, 1);
496      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
497      if (iCrc!=8100) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
498                               (iCrc!=0x2b1f528f)?"| ERROR": "" );
499    
500    
501      TEST_MB(interpolate8x8_halfpel_v, 0);      TEST_MB(interpolate8x8_halfpel_v, 0);
502      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",
503      if (iCrc!=8108) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
504                               (iCrc!=0x423cdcc7)?"| ERROR": "" );
505    
506      TEST_MB(interpolate8x8_halfpel_v, 1);      TEST_MB(interpolate8x8_halfpel_v, 1);
507      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
508      if (iCrc!=8105) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
509                               (iCrc!=0x42202efe)?"| ERROR": "" );
510    
511    
512      TEST_MB(interpolate8x8_halfpel_hv, 0);      TEST_MB(interpolate8x8_halfpel_hv, 0);
513      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",
514      if (iCrc!=8112) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
515                               (iCrc!=0xd198d387)?"| ERROR": "" );
516    
517      TEST_MB(interpolate8x8_halfpel_hv, 1);      TEST_MB(interpolate8x8_halfpel_hv, 1);
518      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
519      if (iCrc!=8103) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
520                               (iCrc!=0x9ecfd921)?"| ERROR": "" );
521    
522    
523                    /* this is a new function, as of 06.06.2002 */
524    #if 0
525                    TEST_MB2(interpolate8x8_avrg);
526                    printf("%s - interpolate8x8_c %.3f usec       crc32=0x%08x %s\n",
527                               cpu->name, t, iCrc,
528                               (iCrc!=8107)?"| ERROR": "" );
529    #endif
530    
531        /* New functions for field prediction by CK 1.10.2005 */
532    #pragma NEW8X4
533                    TEST_MB(interpolate8x4_halfpel_h, 0);
534                    printf("%s - interpfield-h -round0 %.3f usec       crc32=0x%08x %s\n",
535                               cpu->name, t, iCrc,
536                               (iCrc!=0x9538d6df)?"| ERROR": "" );
537    
538                    TEST_MB(interpolate8x4_halfpel_h, 1);
539                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
540                               cpu->name, t, iCrc,
541                               (iCrc!=0xde5f1db4)?"| ERROR": "" );
542    
543    
544                    TEST_MB(interpolate8x4_halfpel_v, 0);
545                    printf("%s - interpfield- v-round0 %.3f usec       crc32=0x%08x %s\n",
546                               cpu->name, t, iCrc,
547                               (iCrc!=0xea5a69ef)?"| ERROR": "" );
548    
549                    TEST_MB(interpolate8x4_halfpel_v, 1);
550                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
551                               cpu->name, t, iCrc,
552                               (iCrc!=0x4f10ec0f)?"| ERROR": "" );
553    
554    
555                    TEST_MB(interpolate8x4_halfpel_hv, 0);
556                    printf("%s - interpfield-hv-round0 %.3f usec       crc32=0x%08x %s\n",
557                               cpu->name, t, iCrc,
558                               (iCrc!=0xf97ee367)?"| ERROR": "" );
559    
560                    TEST_MB(interpolate8x4_halfpel_hv, 1);
561                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
562                               cpu->name, t, iCrc,
563                               (iCrc!=0xb6a9f581)?"| ERROR": "" );
564    /* End of 8x4 functions */
565    
566      printf( " --- \n" );      printf( " --- \n" );
567    }    }
568  }  }
569    
570    #undef ENTER
571    #undef LEAVE
572    #undef TEST_MB
573    #undef TEST_MB2
574    
575  /*********************************************************************  /*********************************************************************
576   * test transfer   * test transfer
577   *********************************************************************/   *********************************************************************/
# Line 365  Line 601 
601      }                                         \      }                                         \
602      emms();                                   \      emms();                                   \
603      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
604      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]));  \
605    s = calc_crc((uint8_t*)(DST), 8*32*sizeof((DST)[0]), CRC32_INITIAL)
606    
607  #define TEST_TRANSFER(FUNC, DST, SRC)         \  #define TEST_TRANSFER(FUNC, DST, SRC)         \
608      TEST_TRANSFER_BEGIN(DST);                 \      TEST_TRANSFER_BEGIN(DST);                 \
# Line 391  Line 628 
628      }                                         \      }                                         \
629      emms();                                   \      emms();                                   \
630      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
631      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]));  \
632    s = calc_crc((uint8_t*)(DST), 8*32*sizeof((DST)[0]), CRC32_INITIAL)
633    
634  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \
635      TEST_TRANSFER2_BEGIN(DST,SRC);            \      TEST_TRANSFER2_BEGIN(DST,SRC);            \
# Line 408  Line 646 
646    const int nb_tests = 4000*speed_ref;    const int nb_tests = 4000*speed_ref;
647    int i;    int i;
648    CPU *cpu;    CPU *cpu;
649    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];
650    int16_t Src16[8*32], Dst16[8*32];  //      int16_t Src16[8*32], Dst16[8*32];
651      DECLARE_ALIGNED_MATRIX(Src8, 8, 32, uint8_t, CACHE_LINE);
652      DECLARE_ALIGNED_MATRIX(Dst8, 8, 32, uint8_t, CACHE_LINE);
653      DECLARE_ALIGNED_MATRIX(Ref1, 8, 32, uint8_t, CACHE_LINE);
654      DECLARE_ALIGNED_MATRIX(Ref2, 8, 32, uint8_t, CACHE_LINE);
655      DECLARE_ALIGNED_MATRIX(Src16, 8, 32, uint16_t, CACHE_LINE);
656      DECLARE_ALIGNED_MATRIX(Dst16, 8, 32, uint16_t, CACHE_LINE);
657    
658    printf( "\n ===  test transfer ===\n" );    printf( "\n ===  test transfer ===\n" );
659    
660    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
661    {    {
662      double t, overhead;      double t, overhead;
663      int tst, s;      int tst, s;
# Line 422  Line 666 
666        continue;        continue;
667    
668      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);
669      printf( "%s - 8to16     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16     %.3f usec       crc32=0x%08x %s\n",
670      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
671                               (s!=0x115814bb)?"| ERROR": "");
672    
673      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);
674      printf( "%s - 16to8     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf( "%s - 16to8     %.3f usec       crc32=0x%08x %s\n",
675      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
676                                    (s!=0xee7ccbb4)?"| ERROR": "");
677    
678        /* New functions for field prediction by CK 1.10.2005 */
679    #pragma NEW8X4
680                    TEST_TRANSFER(transfer8x4_copy, Dst8, Src8);
681                    printf("%s - 8to4      %.3f usec       crc32=0x%08x %s\n",
682                               cpu->name, t, s,
683                               (s!=0xbb9c3db5)?"| ERROR": "");
684    /* End of new functions */
685    
686      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);
687      printf( "%s - 8to8      %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to8      %.3f usec       crc32=0x%08x %s\n",
688      if (s!=20352) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
689                               (s!=0xd37b3295)?"| ERROR": "");
690    
691      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);
692      printf( "%s - 16to8add  %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 16to8add  %.3f usec       crc32=0x%08x %s\n",
693      if (s!=25536) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
694                               (s!=0xdd817bf4)?"| ERROR": "" );
695    
696      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);
697      printf( "%s - 8to16sub  %.3f usec       crc1=%d ", cpu->name, t, s );                  {
698      if (s!=28064) printf( "*** CRC ERROR! ***\n" );                          int s1, s2;
699      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);
700      printf( "crc2=%d\n", s);                          s2 = calc_crc((uint8_t*)Src8, 8*32*sizeof(Src8[0]), CRC32_INITIAL);
701      if (s!=16256) printf( "*** CRC ERROR! ***\n" );                          printf("%s - 8to16sub  %.3f usec       crc32(1)=0x%08x crc32(2)=0x%08x %s %s\n",
702                                       cpu->name, t, s1, s2,
703                                       (s1!=0xa1e07163)?"| ERROR1": "",
704                                       (s2!=0xd86c5d23)?"| ERROR2": "" );
705                    }
706    
707      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);
708      printf( "%s - 8to16sub2 %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16sub2 %.3f usec       crc32=0x%08x %s\n",
709      if (s!=20384) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
710                               (s!=0x99b6c4c7)?"| ERROR": "" );
711    
712      printf( " --- \n" );      printf( " --- \n" );
713    }    }
# Line 458  Line 719 
719    
720  #define TEST_QUANT(FUNC, DST, SRC)            \  #define TEST_QUANT(FUNC, DST, SRC)            \
721      t = gettime_usec();                       \      t = gettime_usec();                       \
722    for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
723      for(i=0; i<8*8; ++i) Quant[i] = qm;       \
724      set_inter_matrix( mpeg_quant_matrices, Quant );                \
725      emms();                                   \      emms();                                   \
726      for(q=1; q<=max_Q; ++q) {                 \
727      for(tst=0; tst<nb_tests; ++tst)           \      for(tst=0; tst<nb_tests; ++tst)           \
728        for(s=0, q=1; q<=max_Q; ++q) {          \            (FUNC)((DST), (SRC), q, mpeg_quant_matrices);              \
729          (FUNC)((DST), (SRC), q);              \          byte_swap((uint8_t*)(DST), 64*sizeof((DST)[0]), sizeof((DST)[0]));  \
730          for(i=0; i<64; ++i) s+=(DST)[i]^i;    \          s = calc_crc((uint8_t*)(DST), 64*sizeof((DST)[0]), s); \
731        }                                       \        }                                       \
732      emms();                                   \      emms();                                   \
733      t = (gettime_usec()-t-overhead)/nb_tests;  }                                           \
734    t = (gettime_usec()-t-overhead)/nb_tests/qm
735    
736  #define TEST_QUANT2(FUNC, DST, SRC, MULT)     \  #define TEST_QUANT2(FUNC, DST, SRC)             \
737      t = gettime_usec();                       \      t = gettime_usec();                       \
738    for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
739      for(i=0; i<8*8; ++i) Quant[i] = qm;       \
740      set_intra_matrix( mpeg_quant_matrices, Quant );                \
741      emms();                                   \      emms();                                   \
742      for(q=1; q<=max_Q; ++q) {                 \
743            init_intra_matrix( mpeg_quant_matrices, q ); \
744      for(tst=0; tst<nb_tests; ++tst)           \      for(tst=0; tst<nb_tests; ++tst)           \
745        for(s=0, q=1; q<=max_Q; ++q) {          \            (FUNC)((DST), (SRC), q, q, mpeg_quant_matrices);           \
746          (FUNC)((DST), (SRC), q, MULT);        \          byte_swap((uint8_t*)(DST), 64*sizeof((DST)[0]), sizeof((DST)[0]));  \
747          for(i=0; i<64; ++i) s+=(DST)[i]^i;    \          s = calc_crc((uint8_t*)(DST), 64*sizeof((DST)[0]), s); \
748        }                                       \        }                                       \
749      emms();                                   \      emms();                                   \
750      t = (gettime_usec()-t-overhead)/nb_tests;  }                                           \
751    t = (gettime_usec()-t-overhead)/nb_tests/qm
752    
753    #define TEST_INTRA(REFFUNC, NEWFUNC, RANGE)              \
754    { int32_t i,q,s;\
755            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16); \
756      DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16); \
757      DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16); \
758      for(q=1;q<=max_Q;q++)          \
759        for(s=-RANGE;s<RANGE;s++) { \
760          for(i=0;i<64;i++) Src[i]=s; \
761          (REFFUNC)((Dst),(Src),q,q,mpeg_quant_matrices);   \
762          (NEWFUNC)((Dst2),(Src),q,q,mpeg_quant_matrices);  \
763          for(i=0;i<64;i++)     \
764            if(Dst[i]!=Dst2[i]) printf("ERROR : " #NEWFUNC " i%d quant:%d input:%d C_result:%d ASM_result:%d\n",i,q,s,Dst[i],Dst2[i]);  \
765        }      \
766    }
767    
768    #define TEST_INTER(REFFUNC, NEWFUNC, RANGE)              \
769    { int i,q,s;  \
770            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16); \
771      DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16); \
772      DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16); \
773      for(q=1;q<=max_Q;q++)  \
774        for(s=-RANGE;s<RANGE;s++) {   \
775          for(i=0;i<64;i++) Src[i]=s; \
776          (REFFUNC)((Dst),(Src),q,mpeg_quant_matrices);  \
777          (NEWFUNC)((Dst2),(Src),q,mpeg_quant_matrices); \
778          emms();           \
779          for(i=0;i<64;i++) \
780            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]); \
781        } \
782    }
783    
784  void test_quant()  void test_quant()
785  {  {
786    const int nb_tests = 150*speed_ref;          const int32_t nb_tests = 1*speed_ref;
787    const int max_Q = 31;          const int32_t max_Q = 31;
788    int i;          DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
789    
790            int32_t i, qm;
791    CPU *cpu;    CPU *cpu;
792    int16_t  Src[8*8], Dst[8*8];          DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
793            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
794            DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16);
795            uint8_t Quant[8*8];
796    
797    printf( "\n =====  test quant =====\n" );    printf( "\n =====  test quant =====\n" );
798    
799    /* we deliberately enfringe the norm's specified range [-127,127], */
800    /* to test the robustness of the iquant module */
801    for(i=0; i<64; ++i) {    for(i=0; i<64; ++i) {
802      Src[i] = i-32;                  Src[i] = 1 + (i-32) * (i&6);
803      Dst[i] = 0;      Dst[i] = 0;
804    }    }
805    
806            for(cpu = cpu_list; cpu->name!=0; ++cpu)
   for(cpu = cpu_short_list; cpu->name!=0; ++cpu)  
807    {    {
808      double t, overhead;      double t, overhead;
809      int tst, s, q;                  int32_t tst, q;
810                    uint32_t s;
811    
812      if (!init_cpu(cpu))      if (!init_cpu(cpu))
813        continue;        continue;
814    
815      set_inter_matrix( get_default_inter_matrix() );                  // exhaustive tests to compare against the (ref) C-version
816      set_intra_matrix( get_default_intra_matrix() );                  TEST_INTRA(quant_h263_intra_c,   quant_h263_intra,    2048);
817                    TEST_INTRA(dequant_h263_intra_c, dequant_h263_intra , 512 );
818                    TEST_INTER(quant_h263_inter_c,   quant_h263_inter ,   2048);
819                    TEST_INTER(dequant_h263_inter_c, dequant_h263_inter , 512 );
820    
821      overhead = -gettime_usec();      overhead = -gettime_usec();
822      for(tst=0; tst<nb_tests; ++tst)                  for(s=0,qm=1; qm<=255; ++qm) {
823        for(s=0, q=1; q<=max_Q; ++q)                          for(i=0; i<8*8; ++i) Quant[i] = qm;
824          for(i=0; i<64; ++i) s+=Dst[i]^i;                          set_inter_matrix(mpeg_quant_matrices, Quant );
825                            for(q=1; q<=max_Q; ++q)
826                                    for(i=0; i<64; ++i) s+=Dst[i]^i^qm;
827                    }
828      overhead += gettime_usec();      overhead += gettime_usec();
829    
830      TEST_QUANT2(quant4_intra, Dst, Src, 7);                  TEST_QUANT2(quant_mpeg_intra, Dst, Src);
831      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",
832      if (s!=55827) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
833                               (s!=0x3b999af6)? "| ERROR": "");
834      TEST_QUANT(quant4_inter, Dst, Src);  
835      printf( "%s -   quant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT(quant_mpeg_inter, Dst, Src);
836      if (s!=58201) printf( "*** CRC ERROR! ***\n" );                  printf("%s -   quant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
837                               cpu->name, t, s,
838                               (s!=0xf6de7757)?"| ERROR": "");
839      TEST_QUANT2(dequant4_intra, Dst, Src, 7);  
840      printf( "%s - dequant4_intra %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(dequant_mpeg_intra, Dst, Src);
841      if (s!=193340) printf( "*** CRC ERROR! ***\n" );                  printf("%s - dequant_mpeg_intra %.3f usec       crc32=0x%08x %s\n",
842                               cpu->name, t, s,
843      TEST_QUANT(dequant4_inter, Dst, Src);                             (s!=0x2def7bc7)?"| ERROR": "");
844      printf( "%s - dequant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );  
845      if (s!=116483) printf( "*** CRC ERROR! ***\n" );                  TEST_QUANT(dequant_mpeg_inter, Dst, Src);
846                    printf("%s - dequant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
847      TEST_QUANT2(quant_intra, Dst, Src, 7);                             cpu->name, t, s,
848      printf( "%s -    quant_intra %.3f usec       crc=%d\n", cpu->name, t, s );                             (s!=0xd878c722)?"| ERROR": "");
849      if (s!=56885) printf( "*** CRC ERROR! ***\n" );  
850                    TEST_QUANT2(quant_h263_intra, Dst, Src);
851      TEST_QUANT(quant_inter, Dst, Src);                  printf("%s -   quant_h263_intra %.3f usec       crc32=0x%08x %s\n",
852      printf( "%s -    quant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                             cpu->name, t, s,
853      if (s!=58056) printf( "*** CRC ERROR! ***\n" );                             (s!=0x2eba9d43)?"| ERROR": "");
854    
855      TEST_QUANT2(dequant_intra, Dst, Src, 7);                  TEST_QUANT(quant_h263_inter, Dst, Src);
856      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",
857      if (s!=-7936) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
858                               (s!=0xbd315a7e)?"| ERROR": "");
859      TEST_QUANT(dequant_inter, Dst, Src);  
860      printf( "%s -  dequant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(dequant_h263_intra, Dst, Src);
861  //    { 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",
862      if (s!=-33217) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
863                               (s!=0x9841212a)?"| ERROR": "");
864    
865                    TEST_QUANT(dequant_h263_inter, Dst, Src);
866                    printf("%s - dequant_h263_inter %.3f usec       crc32=0x%08x %s\n",
867                               cpu->name, t, s,
868                               (s!=0xe7df8fba)?"| ERROR": "");
869    
870                    printf( " --- \n" );
871            }
872    }
873    
874    /*********************************************************************
875     * test distortion operators
876     *********************************************************************/
877    
878    static void ieee_reseed(long s);
879    static long ieee_rand(int Min, int Max);
880    
881    #define TEST_SSE(FUNCTION, SRC1, SRC2, STRIDE) \
882      do { \
883        t = gettime_usec(); \
884        tst = nb_tests; \
885        while((tst--)>0) sse = (FUNCTION)((SRC1), (SRC2), (STRIDE)); \
886        emms(); \
887        t = (gettime_usec() - t)/(double)nb_tests;  \
888      } while(0)
889    
890    
891    void test_sse()
892    {
893            const int nb_tests = 100000*speed_ref;
894            int i;
895            CPU *cpu;
896            DECLARE_ALIGNED_MATRIX(Src1, 8, 8, int16_t, 16);
897            DECLARE_ALIGNED_MATRIX(Src2, 8, 8, int16_t, 16);
898            DECLARE_ALIGNED_MATRIX(Src3, 8, 8, int16_t, 16);
899            DECLARE_ALIGNED_MATRIX(Src4, 8, 8, int16_t, 16);
900    
901            printf( "\n =====  test sse =====\n" );
902    
903            ieee_reseed(1);
904            for(i=0; i<64; ++i) {
905                    Src1[i] = ieee_rand(-2048, 2047);
906                    Src2[i] = ieee_rand(-2048, 2047);
907                    Src3[i] = ieee_rand(-2048, 2047);
908                    Src4[i] = ieee_rand(-2048, 2047);
909            }
910    
911            for(cpu = cpu_list; cpu->name!=0; ++cpu)
912            {
913                    double t;
914                    int tst, sse;
915    
916                    if (!init_cpu(cpu))
917                            continue;
918    
919                    /* 16 bit element blocks */
920                    TEST_SSE(sse8_16bit, Src1, Src2, 16);
921                    printf("%s -   sse8_16bit#1 %.3f usec       sse=%d %s\n",
922                               cpu->name, t, sse, (sse!=182013834)?"| ERROR": "");
923                    TEST_SSE(sse8_16bit, Src1, Src3, 16);
924                    printf("%s -   sse8_16bit#2 %.3f usec       sse=%d %s\n",
925                               cpu->name, t, sse, (sse!=142545203)?"| ERROR": "");
926                    TEST_SSE(sse8_16bit, Src1, Src4, 16);
927                    printf("%s -   sse8_16bit#3 %.3f usec       sse=%d %s\n",
928                               cpu->name, t, sse, (sse!=146340935)?"| ERROR": "");
929                    TEST_SSE(sse8_16bit, Src2, Src3, 16);
930                    printf("%s -   sse8_16bit#4 %.3f usec       sse=%d %s\n",
931                               cpu->name, t, sse, (sse!=130136661)?"| ERROR": "");
932                    TEST_SSE(sse8_16bit, Src2, Src4, 16);
933                    printf("%s -   sse8_16bit#5 %.3f usec       sse=%d %s\n",
934                               cpu->name, t, sse, (sse!=136870353)?"| ERROR": "");
935                    TEST_SSE(sse8_16bit, Src3, Src4, 16);
936                    printf("%s -   sse8_16bit#6 %.3f usec       sse=%d %s\n",
937                               cpu->name, t, sse, (sse!=164107772)?"| ERROR": "");
938    
939                    /* 8 bit element blocks */
940                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src2, 8);
941                    printf("%s -    sse8_8bit#1 %.3f usec       sse=%d %s\n",
942                               cpu->name, t, sse, (sse!=1356423)?"| ERROR": "");
943                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src3, 8);
944                    printf("%s -    sse8_8bit#2 %.3f usec       sse=%d %s\n",
945                               cpu->name, t, sse, (sse!=1173074)?"| ERROR": "");
946                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src4, 8);
947                    printf("%s -    sse8_8bit#3 %.3f usec       sse=%d %s\n",
948                               cpu->name, t, sse, (sse!=1092357)?"| ERROR": "");
949                    TEST_SSE(sse8_8bit, (int8_t*)Src2, (int8_t*)Src3, 8);
950                    printf("%s -    sse8_8bit#4 %.3f usec       sse=%d %s\n",
951                               cpu->name, t, sse, (sse!=1360239)?"| ERROR": "");
952                    TEST_SSE(sse8_8bit, (int8_t*)Src2, (int8_t*)Src4, 8);
953                    printf("%s -    sse8_8bit#5 %.3f usec       sse=%d %s\n",
954                               cpu->name, t, sse, (sse!=1208414)?"| ERROR": "");
955                    TEST_SSE(sse8_8bit, (int8_t*)Src3, (int8_t*)Src4, 8);
956                    printf("%s -    sse8_8bit#6 %.3f usec       sse=%d %s\n",
957                               cpu->name, t, sse, (sse!=1099285)?"| ERROR": "");
958    
959      printf( " --- \n" );      printf( " --- \n" );
960    }    }
# Line 552  Line 964 
964   * test non-zero AC counting   * test non-zero AC counting
965   *********************************************************************/   *********************************************************************/
966    
967  #define TEST_CBP(FUNC, SRC)                   \  #define TEST_CBP(FUNC, SRC, NB)           \
968      t = gettime_usec();                       \      t = gettime_usec();                       \
969      emms();                                   \      emms();                                   \
970      for(tst=0; tst<nb_tests; ++tst) {         \  for(tst=0; tst<NB; ++tst) {         \
971        cbp = (FUNC)((SRC));                    \        cbp = (FUNC)((SRC));                    \
972      }                                         \      }                                         \
973      emms();                                   \      emms();                                   \
# Line 564  Line 976 
976  void test_cbp()  void test_cbp()
977  {  {
978    const int nb_tests = 10000*speed_ref;    const int nb_tests = 10000*speed_ref;
979    int i;          int i, n, m;
980    CPU *cpu;    CPU *cpu;
981    int16_t  Src1[6*64], Src2[6*64], Src3[6*64], Src4[6*64];          DECLARE_ALIGNED_MATRIX(Src1, 6, 64, int16_t, 16);
982            DECLARE_ALIGNED_MATRIX(Src2, 6, 64, int16_t, 16);
983            DECLARE_ALIGNED_MATRIX(Src3, 6, 64, int16_t, 16);
984            DECLARE_ALIGNED_MATRIX(Src4, 6, 64, int16_t, 16);
985      DECLARE_ALIGNED_MATRIX(Src5, 6, 64, int16_t, 16);
986    
987    printf( "\n =====  test cbp =====\n" );    printf( "\n =====  test cbp =====\n" );
988    
989    for(i=0; i<6*64; ++i) {    for(i=0; i<6*64; ++i) {
990      Src1[i] = (i*i*3/8192)&(i/64)&1;  // 'random'                  Src1[i] = (i*i*3/8192)&(i/64)&1;  /* 'random' */
991      Src2[i] = (i<3*64);               // half-full                  Src2[i] = (i<3*64);               /* half-full */
992      Src3[i] = ((i+32)>3*64);      Src3[i] = ((i+32)>3*64);
993      Src4[i] = (i==(3*64+2) || i==(5*64+9));      Src4[i] = (i==(3*64+2) || i==(5*64+9));
994        Src5[i] = ieee_rand(0,1) ? -1 : 1;  /* +/- test */
995    }    }
996    
997    for(cpu = cpu_short_list2; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
998    {    {
999      double t;      double t;
1000      int tst, cbp;      int tst, cbp;
# Line 585  Line 1002 
1002      if (!init_cpu(cpu))      if (!init_cpu(cpu))
1003        continue;        continue;
1004    
1005      TEST_CBP(calc_cbp, Src1);                  TEST_CBP(calc_cbp, Src1, nb_tests);
1006      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",
1007      if (cbp!=0x15) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x15)?"| ERROR": "");
1008      TEST_CBP(calc_cbp, Src2);                  TEST_CBP(calc_cbp, Src2, nb_tests);
1009      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",
1010      if (cbp!=0x38) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x38)?"| ERROR": "");
1011      TEST_CBP(calc_cbp, Src3);                  TEST_CBP(calc_cbp, Src3, nb_tests);
1012      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",
1013      if (cbp!=0x0f) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x0f)?"| ERROR": "" );
1014      TEST_CBP(calc_cbp, Src4);                  TEST_CBP(calc_cbp, Src4, nb_tests);
1015      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",
1016      if (cbp!=0x05) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x05)?"| ERROR": "" );
1017                    TEST_CBP(calc_cbp, Src5, nb_tests);
1018                    printf("%s -   calc_cbp#4 %.3f usec       cbp=0x%02x %s\n",
1019                               cpu->name, t, cbp, (cbp!=0x3f)?"| ERROR": "" );
1020      printf( " --- \n" );      printf( " --- \n" );
1021    }    }
1022    
1023            for(cpu = cpu_list; cpu->name!=0; ++cpu)  /* bench suggested by Carlo (carlo dot bramix at libero dot it) */
1024            {
1025                    double t;
1026                    int tst, cbp, err;
1027    
1028                    if (!init_cpu(cpu))
1029                            continue;
1030    
1031        err = 0;
1032        for(n=0; n<6; ++n)
1033        {
1034          for(m=0; m<64; ++m)
1035          {
1036            for(i=0; i<6*64; ++i)
1037              Src1[i] = (i== (m + n*64));
1038    
1039            TEST_CBP(calc_cbp, Src1, 1);
1040            if (cbp!= (((m!=0)<<(5-n))))
1041            {
1042              printf( "%s -   calc_cbp#5: ERROR at pos %d / %d!\n", cpu->name, n, m);
1043              err = 1;
1044              break;
1045            }
1046          }
1047        }
1048        if (!err)
1049          printf( " %s -    calc_cbp#5 : OK\n", cpu->name );
1050    
1051            }
1052    }
1053    
1054    /*********************************************************************
1055     * fdct/idct IEEE1180 compliance
1056     *********************************************************************/
1057    
1058    typedef struct {
1059            long Errors[64];
1060            long Sqr_Errors[64];
1061            long Max_Errors[64];
1062            long Nb;
1063    } STATS_8x8;
1064    
1065    void init_stats(STATS_8x8 *S)
1066    {
1067            int i;
1068            for(i=0; i<64; ++i) {
1069                    S->Errors[i]     = 0;
1070                    S->Sqr_Errors[i] = 0;
1071                    S->Max_Errors[i] = 0;
1072            }
1073            S->Nb = 0;
1074    }
1075    
1076    void store_stats(STATS_8x8 *S, short Blk[64], short Ref[64])
1077    {
1078            int i;
1079            for(i=0; i<64; ++i)
1080            {
1081                    short Err = Blk[i] - Ref[i];
1082                    S->Errors[i] += Err;
1083                    S->Sqr_Errors[i] += Err * Err;
1084                    if (Err<0) Err = -Err;
1085                    if (S->Max_Errors[i]<Err)
1086                            S->Max_Errors[i] = Err;
1087            }
1088            S->Nb++;
1089    }
1090    
1091    void print_stats(STATS_8x8 *S)
1092    {
1093            int i;
1094            double Norm;
1095    
1096            assert(S->Nb>0);
1097            Norm = 1. / (double)S->Nb;
1098            printf("\n== Max absolute values of errors ==\n");
1099            for(i=0; i<64; i++) {
1100                    printf("  %4ld", S->Max_Errors[i]);
1101                    if ((i&7)==7) printf("\n");
1102            }
1103    
1104            printf("\n== Mean square errors ==\n");
1105            for(i=0; i<64; i++)
1106            {
1107                    double Err = Norm * (double)S->Sqr_Errors[i];
1108                    printf(" %.3f", Err);
1109                    if ((i&7)==7) printf("\n");
1110            }
1111    
1112            printf("\n== Mean errors ==\n");
1113            for(i=0; i<64; i++)
1114            {
1115                    double Err = Norm * (double)S->Errors[i];
1116                    printf(" %.3f", Err);
1117                    if ((i&7)==7) printf("\n");
1118            }
1119            printf("\n");
1120    }
1121    
1122    static const char *CHECK(double v, double l) {
1123            if (fabs(v)<=l) return "ok";
1124            else return "FAIL!";
1125    }
1126    
1127    void report_stats(STATS_8x8 *S, const double *Limits)
1128    {
1129            int i;
1130            double Norm, PE, PMSE, OMSE, PME, OME;
1131    
1132            assert(S->Nb>0);
1133            Norm = 1. / (double)S->Nb;
1134            PE = 0.;
1135            for(i=0; i<64; i++) {
1136                    if (PE<S->Max_Errors[i])
1137                            PE = S->Max_Errors[i];
1138            }
1139    
1140            PMSE = 0.;
1141            OMSE = 0.;
1142            for(i=0; i<64; i++)
1143            {
1144                    double Err = Norm * (double)S->Sqr_Errors[i];
1145                    OMSE += Err;
1146                    if (PMSE < Err) PMSE = Err;
1147            }
1148            OMSE /= 64.;
1149    
1150            PME = 0.;
1151            OME = 0.;
1152            for(i=0; i<64; i++)
1153            {
1154                    double Err = Norm * (double)S->Errors[i];
1155                    OME += Err;
1156                    Err = fabs(Err);
1157                    if (PME < Err) PME = Err;
1158            }
1159            OME /= 64.;
1160    
1161            printf( "Peak error:   %4.4f\n", PE );
1162            printf( "Peak MSE:     %4.4f\n", PMSE );
1163            printf( "Overall MSE:  %4.4f\n", OMSE );
1164            printf( "Peak ME:      %4.4f\n", PME );
1165            printf( "Overall ME:   %4.4f\n", OME );
1166    
1167            if (Limits!=0)
1168            {
1169                    printf( "[PE<=%.4f %s]  ", Limits[0], CHECK(PE,   Limits[0]) );
1170                    printf( "\n" );
1171                    printf( "[PMSE<=%.4f %s]", Limits[1], CHECK(PMSE, Limits[1]) );
1172                    printf( "[OMSE<=%.4f %s]", Limits[2], CHECK(OMSE, Limits[2]) );
1173                    printf( "\n" );
1174                    printf( "[PME<=%.4f %s] ", Limits[3], CHECK(PME , Limits[3]) );
1175                    printf( "[OME<=%.4f %s] ", Limits[4], CHECK(OME , Limits[4]) );
1176                    printf( "\n" );
1177            }
1178    }
1179    
1180    ///* ////////////////////////////////////////////////////// */
1181    /* Pseudo-random generator specified by IEEE 1180 */
1182    
1183    static long ieee_seed = 1;
1184    static void ieee_reseed(long s) {
1185            ieee_seed = s;
1186    }
1187    static long ieee_rand(int Min, int Max)
1188    {
1189            static double z = (double) 0x7fffffff;
1190    
1191            long i,j;
1192            double x;
1193    
1194            ieee_seed = (ieee_seed * 1103515245) + 12345;
1195            i = ieee_seed & 0x7ffffffe;
1196            x = ((double) i) / z;
1197            x *= (Max-Min+1);
1198            j = (long)x;
1199            j = j + Min;
1200            assert(j>=Min && j<=Max);
1201            return (short)j;
1202    }
1203    
1204    #define CLAMP(x, M)   (x) = ((x)<-(M)) ? (-(M)) : ((x)>=(M) ? ((M)-1) : (x))
1205    
1206    static double Cos[8][8];
1207    static void init_ref_dct()
1208    {
1209            int i, j;
1210            for(i=0; i<8; i++)
1211            {
1212                    double scale = (i == 0) ? sqrt(0.125) : 0.5;
1213                    for (j=0; j<8; j++)
1214                            Cos[i][j] = scale*cos( (M_PI/8.0)*i*(j + 0.5) );
1215            }
1216    }
1217    
1218    void ref_idct(short *M)
1219    {
1220            int i, j, k;
1221            double Tmp[8][8];
1222    
1223            for(i=0; i<8; i++) {
1224                    for(j=0; j<8; j++)
1225                    {
1226                            double Sum = 0.0;
1227                            for (k=0; k<8; k++) Sum += Cos[k][j]*M[8*i+k];
1228                            Tmp[i][j] = Sum;
1229                    }
1230            }
1231            for(i=0; i<8; i++) {
1232                    for(j=0; j<8; j++) {
1233                            double Sum = 0.0;
1234                            for (k=0; k<8; k++) Sum += Cos[k][i]*Tmp[k][j];
1235                            M[8*i+j] = (short)floor(Sum + .5);
1236                    }
1237            }
1238    }
1239    
1240    void ref_fdct(short *M)
1241    {
1242            int i, j, k;
1243            double Tmp[8][8];
1244    
1245            for(i=0; i<8; i++) {
1246                    for(j=0; j<8; j++)
1247                    {
1248                            double Sum = 0.0;
1249                            for (k=0; k<8; k++) Sum += Cos[j][k]*M[8*i+k];
1250                            Tmp[i][j] = Sum;
1251                    }
1252            }
1253            for(i=0; i<8; i++) {
1254                    for(j=0; j<8; j++) {
1255                            double Sum = 0.0;
1256                            for (k=0; k<8; k++) Sum += Cos[i][k]*Tmp[k][j];
1257                            M[8*i+j] = (short)floor(Sum + 0.5);
1258                    }
1259            }
1260    }
1261    
1262    void test_IEEE1180_compliance(int Min, int Max, int Sign)
1263    {
1264            static const double ILimits[5] = { 1., 0.06, 0.02, 0.015, 0.0015 };
1265            int Loops = 10000;
1266            int i, m, n;
1267            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, short, 16); /* reference */
1268            DECLARE_ALIGNED_MATRIX(Blk,  8, 8, short, 16);
1269            DECLARE_ALIGNED_MATRIX(iBlk, 8, 8, short, 16);
1270            DECLARE_ALIGNED_MATRIX(Ref_FDCT, 8, 8, short, 16);
1271            DECLARE_ALIGNED_MATRIX(Ref_IDCT, 8, 8, short, 16);
1272    
1273            STATS_8x8 FStats; /* forward dct stats */
1274            STATS_8x8 IStats; /* inverse dct stats */
1275    
1276            CPU *cpu;
1277    
1278            init_ref_dct();
1279    
1280            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1281            {
1282                    if (!init_cpu(cpu))
1283                            continue;
1284    
1285                    printf( "\n===== IEEE test for %s ==== (Min=%d Max=%d Sign=%d Loops=%d)\n",
1286                                    cpu->name, Min, Max, Sign, Loops);
1287    
1288                    init_stats(&IStats);
1289                    init_stats(&FStats);
1290    
1291                    ieee_reseed(1);
1292                    for(n=0; n<Loops; ++n)
1293                    {
1294                            for(i=0; i<64; ++i)
1295                                    Blk0[i] = (short)ieee_rand(Min,Max) * Sign;
1296    
1297                            /* hmm, I'm not quite sure this is exactly */
1298                            /* the tests described in the norm. check... */
1299    
1300                            memcpy(Ref_FDCT, Blk0, 64*sizeof(short));
1301                            ref_fdct(Ref_FDCT);
1302                            for(i=0; i<64; i++) CLAMP( Ref_FDCT[i], 2048 );
1303    
1304                            memcpy(Blk, Blk0, 64*sizeof(short));
1305                            emms(); fdct(Blk); emms();
1306                            for(i=0; i<64; i++) CLAMP( Blk[i], 2048 );
1307    
1308                            store_stats(&FStats, Blk, Ref_FDCT);
1309    
1310    
1311                            memcpy(Ref_IDCT, Ref_FDCT, 64*sizeof(short));
1312                            ref_idct(Ref_IDCT);
1313                            for (i=0; i<64; i++) CLAMP( Ref_IDCT[i], 256 );
1314    
1315                            memcpy(iBlk, Ref_FDCT, 64*sizeof(short));
1316                            emms(); idct(iBlk); emms();
1317                            for(i=0; i<64; i++) CLAMP( iBlk[i], 256 );
1318    
1319                            store_stats(&IStats, iBlk, Ref_IDCT);
1320                    }
1321    
1322    
1323                    printf( "\n  -- FDCT report --\n" );
1324    //    print_stats(&FStats);
1325                    report_stats(&FStats, 0); /* so far I know, IEEE1180 says nothing for fdct */
1326    
1327                    for(i=0; i<64; i++) Blk[i] = 0;
1328                    emms(); fdct(Blk); emms();
1329                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1330                    printf( "FDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1331    
1332                    printf( "\n  -- IDCT report --\n" );
1333    //    print_stats(&IStats);
1334                    report_stats(&IStats, ILimits);
1335    
1336    
1337                    for(i=0; i<64; i++) Blk[i] = 0;
1338                    emms(); idct(Blk); emms();
1339                    for(m=i=0; i<64; i++) if (Blk[i]!=0) m++;
1340                    printf( "IDCT(0) == 0 ?  %s\n", (m!=0) ? "NOPE!" : "yup." );
1341            }
1342    }
1343    
1344    
1345    void test_dct_saturation(int Min, int Max)
1346    {
1347    /* test behaviour on input range fringe */
1348    
1349            int i, n, p;
1350            CPU *cpu;
1351    //  const short IDCT_MAX =  2047;  /* 12bits input */
1352    //  const short IDCT_MIN = -2048;
1353    //  const short IDCT_OUT =   256;  /* 9bits ouput */
1354            const int Partitions = 4;
1355            const int Loops = 10000 / Partitions;
1356    
1357            init_ref_dct();
1358    
1359            for(cpu = cpu_list; cpu->name!=0; ++cpu)
1360            {
1361                    short Blk0[64], Blk[64];
1362                    STATS_8x8 Stats;
1363    
1364                    if (!init_cpu(cpu))
1365                            continue;
1366    
1367                    printf( "\n===== IEEE test for %s Min=%d Max=%d =====\n",
1368                                    cpu->name, Min, Max );
1369    
1370                    /* FDCT tests // */
1371    
1372                    init_stats(&Stats);
1373    
1374                    /* test each computation channels separately */
1375                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Max : 0;
1376                    ref_fdct(Blk0);
1377                    emms(); fdct(Blk); emms();
1378                    store_stats(&Stats, Blk, Blk0);
1379    
1380                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Min : 0;
1381                    ref_fdct(Blk0);
1382                    emms(); fdct(Blk); emms();
1383                    store_stats(&Stats, Blk, Blk0);
1384    
1385                    /* randomly saturated inputs */
1386                    for(p=0; p<Partitions; ++p)
1387                    {
1388                            for(n=0; n<Loops; ++n)
1389                            {
1390                                    for(i=0; i<64; ++i)
1391                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? Max : Min;
1392                                    ref_fdct(Blk0);
1393                                    emms(); fdct(Blk); emms();
1394                                    store_stats(&Stats, Blk, Blk0);
1395                            }
1396                    }
1397                    printf( "\n  -- FDCT saturation report --\n" );
1398                    report_stats(&Stats, 0);
1399    
1400    
1401                    /* IDCT tests // */
1402    #if 0
1403                    /* no finished yet */
1404    
1405                    init_stats(&Stats);
1406    
1407    /* test each computation channel separately */
1408                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MAX : 0;
1409                    ref_idct(Blk0);
1410                    emms(); idct(Blk); emms();
1411                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1412                    store_stats(&Stats, Blk, Blk0);
1413    
1414                    for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MIN : 0;
1415                    ref_idct(Blk0);
1416                    emms(); idct(Blk); emms();
1417                    for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1418                    store_stats(&Stats, Blk, Blk0);
1419    
1420                    /* randomly saturated inputs */
1421                    for(p=0; p<Partitions; ++p)
1422                    {
1423                            for(n=0; n<Loops; ++n)
1424                            {
1425                                    for(i=0; i<64; ++i)
1426                                            Blk0[i] = Blk[i] = (ieee_rand(0,Partitions)>=p)? IDCT_MAX : IDCT_MIN;
1427                                    ref_idct(Blk0);
1428                                    emms(); idct(Blk); emms();
1429                                    for(i=0; i<64; i++) { CLAMP(Blk0[i],IDCT_OUT); CLAMP(Blk[i],IDCT_OUT); }
1430                                    store_stats(&Stats, Blk, Blk0);
1431                            }
1432                    }
1433    
1434                    printf( "\n  -- IDCT saturation report --\n" );
1435                    print_stats(&Stats);
1436                    report_stats(&Stats, 0);
1437    #endif
1438            }
1439  }  }
1440    
1441  /*********************************************************************  /*********************************************************************
1442   * measure raw decoding speed   * measure raw decoding speed
1443   *********************************************************************/   *********************************************************************/
1444    
1445  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)
1446  {  {
1447    FILE *f = 0;    FILE *f = 0;
1448    void *dechandle = 0;    void *dechandle = 0;
1449    int xerr;    int xerr;
1450          XVID_INIT_PARAM xinit;          xvid_gbl_init_t xinit;
1451          XVID_DEC_PARAM xparam;          xvid_dec_create_t xparam;
1452          XVID_DEC_FRAME xframe;          xvid_dec_frame_t xframe;
1453          double t = 0.;          double t = 0.;
1454          int nb = 0;          int nb = 0;
1455    uint8_t *buf = 0;    uint8_t *buf = 0;
1456    uint8_t *rgb_out = 0;          uint8_t *yuv_out = 0;
1457    int buf_size, pos;    int buf_size, pos;
1458    uint32_t chksum = 0;    uint32_t chksum = 0;
1459            int bps = (width+31) & ~31;
1460    
1461          xinit.cpu_flags = 0;          memset(&xinit, 0, sizeof(xinit));
1462          xvid_init(NULL, 0, &xinit, NULL);          xinit.cpu_flags = cpu_mask;
1463          printf( "API version: %d, core build:%d\n", xinit.api_version, xinit.core_build);          xinit.version = XVID_VERSION;
1464            xvid_global(NULL, 0, &xinit, NULL);
1465    
1466            memset(&xparam, 0, sizeof(xparam));
1467          xparam.width = width;          xparam.width = width;
1468          xparam.height = height;          xparam.height = height;
1469            xparam.version = XVID_VERSION;
1470          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
1471          if (xerr!=XVID_ERR_OK) {          if (xerr==XVID_ERR_FAIL) {
1472            printf("can't init decoder (err=%d)\n", xerr);                  printf("ERROR: can't init decoder (err=%d)\n", xerr);
1473            return;            return;
1474          }          }
1475          dechandle = xparam.handle;          dechandle = xparam.handle;
# Line 637  Line 1477 
1477    
1478          f = fopen(name, "rb");          f = fopen(name, "rb");
1479    if (f==0) {    if (f==0) {
1480      printf( "can't open file '%s'\n", name);                  printf( "ERROR: can't open file '%s'\n", name);
1481      return;      return;
1482    }    }
1483    fseek(f, 0, SEEK_END);    fseek(f, 0, SEEK_END);
1484    buf_size = ftell(f);    buf_size = ftell(f);
1485    fseek(f, 0, SEEK_SET);    fseek(f, 0, SEEK_SET);
1486    if (buf_size<=0) {    if (buf_size<=0) {
1487      printf("error while stating file\n");                  printf("ERROR: error while stating file\n");
1488      goto End;      goto End;
1489    }    }
   else printf( "Input size: %d\n", buf_size);  
1490    
1491    buf = malloc(buf_size); // should be enuf'          buf = malloc(buf_size);
1492    rgb_out = calloc(4, width*height);  // <-room for _RGB24          yuv_out = calloc(1, bps*height*3/2 + 15);
1493    if (buf==0 || rgb_out==0) {          if (buf==0 || yuv_out==0) {
1494      printf( "malloc failed!\n" );                  printf( "ERROR: malloc failed!\n" );
1495      goto End;      goto End;
1496    }    }
1497    
1498    if (fread(buf, buf_size, 1, f)!=1) {    if (fread(buf, buf_size, 1, f)!=1) {
1499      printf( "file-read failed\n" );                  printf( "ERROR: file-read failed\n" );
1500      goto End;      goto End;
1501    }    }
1502    
# Line 665  Line 1504 
1504    pos = 0;    pos = 0;
1505    t = -gettime_usec();    t = -gettime_usec();
1506    while(1) {    while(1) {
1507              int y;
1508    
1509                    memset(&xframe, 0, sizeof(xframe));
1510                    xframe.version = XVID_VERSION;
1511      xframe.bitstream = buf + pos;      xframe.bitstream = buf + pos;
1512      xframe.length = buf_size - pos;      xframe.length = buf_size - pos;
1513      xframe.image = rgb_out;                  xframe.output.plane[0] = (uint8_t*)(((size_t)yuv_out + 15) & ~15);
1514      xframe.stride = width;                  xframe.output.plane[1] = (uint8_t*)xframe.output.plane[0] + bps*height;
1515      xframe.colorspace = XVID_CSP_RGB24;                  xframe.output.plane[2] = (uint8_t*)xframe.output.plane[1] + bps/2;
1516                    xframe.output.stride[0] = bps;
1517                    xframe.output.stride[1] = bps;
1518                    xframe.output.stride[2] = bps;
1519                    xframe.output.csp = XVID_CSP_I420;
1520      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);
1521                    if (xerr<0) {
1522                            printf("ERROR: decoding failed for frame #%d (err=%d)!\n", nb, xerr);
1523                            break;
1524                    }
1525                    else if (xerr==0)
1526                      break;
1527        else if (verbose>0) printf("#%d %d\n", nb, xerr );
1528    
1529                    pos += xerr;
1530      nb++;      nb++;
1531      pos += xframe.length;  
1532      if (with_chksum) {      for(y=0; y<height/2; ++y) {
1533        int k = width*height;                    chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+0)*bps, width, chksum);
1534        uint32_t *ptr = (uint32_t *)rgb_out;                          chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+1)*bps, width, chksum);
1535        while(k-->0) chksum += *ptr++;                          chksum = calc_crc((uint8_t*)xframe.output.plane[1] + y*bps, width/2, chksum);
1536                            chksum = calc_crc((uint8_t*)xframe.output.plane[2] + y*bps, width/2, chksum);
1537      }      }
1538      if (pos==buf_size)      if (pos==buf_size)
1539        break;        break;
     if (xerr!=XVID_ERR_OK) {  
           printf("decoding failed for frame #%d (err=%d)!\n", nb, xerr);  
           break;  
         }  
1540    }    }
1541    t += gettime_usec();    t += gettime_usec();
1542            if (ref_chksum==0) {
1543    if (t>0.)    if (t>0.)
1544      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 );
1545    if (with_chksum)    }
1546      printf("checksum: 0x%.8x\n", chksum);    else {
1547                    printf("FPS:%.1f Checksum: 0x%.8x Expected:0x%.8x | %s\n",
1548                      t>0. ? (float)(nb*1.e6f/t) : 0.f, chksum, ref_chksum, (chksum==ref_chksum) ? "OK" : "ERROR");
1549      }
1550    
1551  End:  End:
1552    if (rgb_out!=0) free(rgb_out);          if (yuv_out!=0) free(yuv_out);
1553    if (buf!=0) free(buf);    if (buf!=0) free(buf);
1554    if (dechandle!=0) {    if (dechandle!=0) {
1555      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);
1556      if (xerr!=XVID_ERR_OK)                  if (xerr==XVID_ERR_FAIL)
1557              printf("destroy-decoder failed (err=%d)!\n", xerr);                          printf("ERROR: destroy-decoder failed (err=%d)!\n", xerr);
1558    }    }
1559    if (f!=0) fclose(f);    if (f!=0) fclose(f);
1560  }  }
# Line 709  Line 1566 
1566  void test_bugs1()  void test_bugs1()
1567  {  {
1568    CPU *cpu;    CPU *cpu;
1569            uint16_t mpeg_quant_matrices[64*8];
1570    
1571    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );
1572    
1573    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1574    {    {
1575      int i;      int i;
1576      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 721  Line 1579 
1579        continue;        continue;
1580    
1581      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1582      set_intra_matrix( get_default_intra_matrix() );                  set_intra_matrix( mpeg_quant_matrices, get_default_intra_matrix() );
1583      dequant4_intra(Dst, Src, 32, 5);                  dequant_mpeg_intra(Dst, Src, 31, 5, mpeg_quant_matrices);
1584      printf( "dequant4_intra with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_intra with CPU=%s:  ", cpu->name);
1585      printf( "  Out[]= " );      printf( "  Out[]= " );
1586      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1587      printf( "\n" );      printf( "\n" );
# Line 731  Line 1589 
1589    
1590    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );
1591    
1592    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1593    {    {
1594      int i;      int i;
1595      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 740  Line 1598 
1598        continue;        continue;
1599    
1600      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1601      set_inter_matrix( get_default_inter_matrix() );                  set_inter_matrix( mpeg_quant_matrices, get_default_inter_matrix() );
1602      dequant4_inter(Dst, Src, 32);                  dequant_mpeg_inter(Dst, Src, 31, mpeg_quant_matrices);
1603      printf( "dequant4_inter with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_inter with CPU=%s:  ", cpu->name);
1604      printf( "  Out[]= " );      printf( "  Out[]= " );
1605      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1606      printf( "\n" );      printf( "\n" );
# Line 752  Line 1610 
1610  void test_dct_precision_diffs()  void test_dct_precision_diffs()
1611  {  {
1612    CPU *cpu;    CPU *cpu;
1613    short Blk[8*8], Blk0[8*8];          DECLARE_ALIGNED_MATRIX(Blk, 8, 8, int16_t, 16);
1614            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, int16_t, 16);
1615    
1616    printf( "\n =====  fdct/idct saturation diffs =====\n" );          printf( "\n =====  fdct/idct precision diffs =====\n" );
1617    
1618    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1619    {    {
1620      int i;      int i;
1621    
# Line 780  Line 1639 
1639    }    }
1640  }  }
1641    
1642    void test_quant_bug()
1643    {
1644            const int max_Q = 31;
1645            int i, n, qm, q;
1646            CPU *cpu;
1647            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
1648            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
1649            uint8_t Quant[8*8];
1650            CPU cpu_bug_list[] = { { "PLAINC", 0 }, { "MMX   ", XVID_CPU_MMX }, {0,0} };
1651            uint16_t Crcs_Inter[2][32];
1652            uint16_t Crcs_Intra[2][32];
1653            DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
1654    
1655            printf( "\n =====  test MPEG4-quantize bug =====\n" );
1656    
1657            for(i=0; i<64; ++i) Src[i] = 2048*(i-32)/32;
1658    
1659    #if 1
1660            for(qm=1; qm<=255; ++qm)
1661            {
1662                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1663                    set_inter_matrix( mpeg_quant_matrices, Quant );
1664    
1665                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1666                    {
1667                            uint16_t s;
1668    
1669                            if (!init_cpu(cpu))
1670                                    continue;
1671    
1672                            for(q=1; q<=max_Q; ++q) {
1673                                    emms();
1674                                    quant_mpeg_inter( Dst, Src, q, mpeg_quant_matrices );
1675                                    emms();
1676                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1677                                    Crcs_Inter[n][q] = s;
1678                            }
1679                    }
1680    
1681                    for(q=1; q<=max_Q; ++q)
1682                            for(i=0; i<n-1; ++i)
1683                                    if (Crcs_Inter[i][q]!=Crcs_Inter[i+1][q])
1684                                            printf( "Discrepancy Inter: qm=%d, q=%d  -> %d/%d !\n",
1685                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1686            }
1687    #endif
1688    
1689    #if 1
1690            for(qm=1; qm<=255; ++qm)
1691            {
1692                    for(i=0; i<8*8; ++i) Quant[i] = qm;
1693                    set_intra_matrix( mpeg_quant_matrices, Quant );
1694    
1695                    for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1696                    {
1697                            uint16_t s;
1698    
1699                            if (!init_cpu(cpu))
1700                                    continue;
1701    
1702                            for(q=1; q<=max_Q; ++q) {
1703                                    emms();
1704                                    quant_mpeg_intra( Dst, Src, q, q, mpeg_quant_matrices);
1705                                    emms();
1706                                    for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1707                                    Crcs_Intra[n][q] = s;
1708                            }
1709                    }
1710    
1711                    for(q=1; q<=max_Q; ++q)
1712                            for(i=0; i<n-1; ++i)
1713                                    if (Crcs_Intra[i][q]!=Crcs_Intra[i+1][q])
1714                                            printf( "Discrepancy Intra: qm=%d, q=%d  -> %d/%d!\n",
1715                                                            qm, q, Crcs_Inter[i][q], Crcs_Inter[i+1][q]);
1716            }
1717    #endif
1718    }
1719    
1720    /*********************************************************************
1721     * test some YUV func
1722     *********************************************************************/
1723    
1724    #define ENTER \
1725    for(i=0; i<(int)sizeof(Dst0); ++i) Dst0[0][i] = 0;   \
1726    t = gettime_usec();                   \
1727    emms();
1728    
1729    #define LEAVE \
1730    emms();                             \
1731    t = (gettime_usec() - t) / nb_tests;  \
1732            iCrc = calc_crc((uint8_t*)Dst0, sizeof(Dst0), CRC32_INITIAL)
1733    
1734    #define TEST_YUYV(FUNC, S, FLIP)                \
1735    ENTER                               \
1736    for(tst=0; tst<nb_tests; ++tst) (FUNC)(Dst0[0], S*WIDTH, Src0[0], Src0[1], Src0[2], WIDTH, WIDTH/2, WIDTH, HEIGHT, (FLIP)); \
1737    LEAVE
1738    
1739    static const int yuv_CRCs[6][2] = {
1740            {0x0f4fb96b,0x780b6a68}
1741    ,       {0xa986b289,0x65e49b76}
1742    ,       {0x7f19c152,0xd539b86e}
1743    ,       {0x0f4fb96b,0x780b6a68}
1744    ,       {0xa986b289,0x65e49b76}
1745    ,       {0x36ab8b57,0x1cd92fee}
1746    };
1747    
1748    #define WIDTH 128
1749    #define HEIGHT 32
1750    void test_yuv()
1751    {
1752            const int nb_tests = 200*speed_ref;
1753            CPU *cpu;
1754            uint8_t Src0[3][WIDTH*HEIGHT];
1755            uint8_t Dst0[4][WIDTH*HEIGHT];
1756            int i, j, with_flip;
1757            double t;
1758            int tst, iCrc;
1759    
1760            colorspace_init();
1761            ieee_reseed(1);
1762            for(i=0; i<(int)sizeof(Src0); ++i) Src0[0][i] = ieee_rand(0,255);
1763            for(i=0; i<(int)sizeof(Dst0); ++i) Dst0[0][i] = 0x5a;
1764    
1765            printf( "\n ===  test YUV ===\n" );
1766    
1767            for(with_flip=0; with_flip<=1; ++with_flip) {
1768    
1769                    init_cpu(&cpu_list[0]);
1770                    TEST_YUYV(yv12_to_yuyv_c, 4, with_flip);
1771                    printf(" yv12_to_yuyv_c %.3f usec       crc32=0x%08x %s\n",
1772                               t, iCrc, (iCrc!=yuv_CRCs[0][with_flip])?"| ERROR": "" );
1773                    TEST_YUYV(yv12_to_uyvy_c, 4, with_flip);
1774                    printf(" yv12_to_uyvy_c %.3f usec       crc32=0x%08x %s\n",
1775                            t, iCrc, (iCrc!=yuv_CRCs[1][with_flip])?"| ERROR": "" );
1776    
1777                    TEST_YUYV(yv12_to_bgra_c, 4, with_flip);
1778                    printf(" yv12_to_bgra_c %.3f usec       crc32=0x%08x %s\n",
1779                            t, iCrc, (iCrc!=yuv_CRCs[2][with_flip])?"| ERROR": "" );
1780    
1781    #if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
1782                    init_cpu(&cpu_list[1]);
1783                    TEST_YUYV(yv12_to_yuyv_mmx, 4, with_flip);
1784                    printf(" yv12_to_yuyv_mmx %.3f usec       crc32=0x%08x %s\n",
1785                            t, iCrc, (iCrc!=yuv_CRCs[3][with_flip])?"| ERROR": "" );
1786    
1787                    TEST_YUYV(yv12_to_uyvy_mmx, 4, with_flip);
1788                    printf(" yv12_to_uyvy_mmx %.3f usec       crc32=0x%08x %s\n",
1789                            t, iCrc, (iCrc!=yuv_CRCs[4][with_flip])?"| ERROR": "" );
1790    
1791                    TEST_YUYV(yv12_to_bgra_mmx, 4, with_flip);
1792                    printf(" yv12_to_bgra_mmx %.3f usec       crc32=0x%08x %s\n",
1793                            t, iCrc, (iCrc!=yuv_CRCs[5][with_flip])?"| ERROR": "" );
1794    
1795    #endif
1796    
1797    #ifdef ARCH_IS_PPC
1798                    init_cpu(&cpu_list[1]);
1799                    TEST_YUYV(yv12_to_yuyv_altivec_c, 4, with_flip);
1800                    printf(" yv12_to_yuyv_altivec_c %.3f usec       crc32=0x%08x %s\n",
1801                            t, iCrc, (iCrc!=yuv_CRCs[3][with_flip])?"| ERROR": "" );
1802    
1803                    TEST_YUYV(yv12_to_uyvy_altivec_c, 4, with_flip);
1804                    printf(" yv12_to_uyvy_altivec_c %.3f usec       crc32=0x%08x %s\n",
1805                            t, iCrc, (iCrc!=yuv_CRCs[4][with_flip])?"| ERROR": "" );
1806    #endif
1807            }
1808            printf( " --- \n" );
1809    }
1810    
1811    #define TEST_YV2(FUNC, WITH_UV, WITH_FLIP)        \
1812    ENTER                               \
1813    for(tst=0; tst<nb_tests; ++tst) (FUNC)(Dst0[0], Dst0[1], Dst0[2], WIDTH, WIDTH, \
1814            Src0[0], (WITH_UV) ? Src0[1] : 0, (WITH_UV) ? Src0[2] : 0,  WIDTH, WIDTH, \
1815            WIDTH-2, HEIGHT-2, WITH_FLIP); \
1816    LEAVE
1817    
1818    #define PRINT_NxN(DATA,W,H,STR)   {   \
1819            int i,j; \
1820            for(j=0; j<(H); ++j) { \
1821                    for(i=0; i<(W); ++i) printf( "0x%.2x ", (DATA)[i+j*(STR)] );\
1822                    printf("\n"); \
1823            } \
1824            printf("---\n"); \
1825    }
1826    
1827    static const int yv12_CRCs[2][2] = {
1828            {0x5cab7cf0,0xdab46541}
1829    ,       {0xe8bae865,0x1faf77b7}
1830    };
1831    
1832    void test_yuv2()
1833    {
1834            const int nb_tests = 800*speed_ref;
1835            CPU *cpu;
1836            uint8_t Src0[3][WIDTH*HEIGHT];
1837            uint8_t Dst0[3][WIDTH*HEIGHT];
1838            int with_uv, with_flip;
1839            int i, j;
1840            double t;
1841            int tst, iCrc;
1842    
1843            colorspace_init();
1844            ieee_reseed(1);
1845            for(i=0; i<(int)sizeof(Src0); ++i) Src0[0][i] = ieee_rand(0,255);
1846    
1847            printf( "\n ===  test YV2 ===\n" );
1848            for(with_flip=0; with_flip<=1; ++with_flip) {
1849                    for(with_uv=0; with_uv<=1; ++with_uv) {
1850                            init_cpu(&cpu_list[0]);
1851                            TEST_YV2(yv12_to_yv12_c, with_uv, with_flip);
1852                            printf(" yv12_to_yv12_c   %.3f usec      \tcrc32=0x%08x %s\n",
1853                                    t, iCrc, (iCrc!=yv12_CRCs[with_flip][with_uv])?"| ERROR": "" );
1854                            /* if (!with_uv) PRINT_NxN(Dst0[1], WIDTH/2, HEIGHT/2, WIDTH ); */
1855    
1856    #if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
1857                            init_cpu(&cpu_list[1]);
1858                            TEST_YV2(yv12_to_yv12_mmx, with_uv, with_flip);
1859                            printf(" yv12_to_yv12_mmx %.3f usec     \tcrc32=0x%08x %s\n",
1860                                    t, iCrc, (iCrc!=yv12_CRCs[with_flip][with_uv])?"| ERROR": "" );
1861                            /* if (!with_uv) PRINT_NxN(Dst0[1], WIDTH/2, HEIGHT/2, WIDTH ); */
1862    
1863                            TEST_YV2(yv12_to_yv12_xmm, with_uv, with_flip);
1864                            printf(" yv12_to_yv12_xmm %.3f usec     \tcrc32=0x%08x %s\n",
1865                                    t, iCrc, (iCrc!=yv12_CRCs[with_flip][with_uv])?"| ERROR": "" );
1866    #endif
1867                    }
1868    
1869                    printf( " --- \n" );
1870            }
1871            printf( " ===== \n" );
1872    }
1873    
1874    #undef WIDTH
1875    #undef HEIGHT
1876    #undef ENTER
1877    #undef LEAVE
1878    
1879    /*********************************************************************/
1880    
1881    static uint32_t __inline log2bin_v1(uint32_t value)
1882    {
1883      int n = 0;
1884      while (value) {
1885        value >>= 1;
1886        n++;
1887      }
1888      return n;
1889    }
1890    
1891    static const uint8_t log2_tab_16[16] =  { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
1892    
1893    static uint32_t __inline log2bin_v2(uint32_t value)
1894    {
1895      int n = 0;
1896      if (value & 0xffff0000) {
1897        value >>= 16;
1898        n += 16;
1899      }
1900      if (value & 0xff00) {
1901        value >>= 8;
1902        n += 8;
1903      }
1904      if (value & 0xf0) {
1905        value >>= 4;
1906        n += 4;
1907      }
1908     return n + log2_tab_16[value];
1909    }
1910    
1911    void test_log2bin()
1912    {
1913            const int nb_tests = 3000*speed_ref;
1914      int n, crc1=0, crc2=0;
1915      uint32_t s, s0;
1916      double t1, t2;
1917    
1918      t1 = gettime_usec();
1919      s0 = (int)(t1*31.241);
1920      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1921        crc1 += log2bin_v1(s);
1922      t1 = (gettime_usec()-t1) / nb_tests;
1923    
1924      t2 = gettime_usec();
1925      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1926        crc2 += log2bin_v2(s);
1927      t2 = (gettime_usec() - t2) / nb_tests;
1928    
1929      printf( "log2bin_v1: %.3f sec  crc=%d\n", t1, crc1 );
1930      printf( "log2bin_v2: %.3f sec  crc=%d\n", t2, crc2 );
1931      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1932    }
1933    
1934    /*********************************************************************/
1935    
1936    static void __inline old_gcd(int *num, int *den)
1937    {
1938     int i = *num;
1939      while (i > 1) {
1940        if (*num % i == 0 && *den % i == 0) {
1941          *num /= i;
1942          *den /= i;
1943          i = *num;
1944          continue;
1945        }
1946        i--;
1947      }
1948    }
1949    
1950    static uint32_t gcd(int num, int den)
1951    {
1952      int tmp;
1953      while( (tmp=num%den) ) { num = den; den = tmp; }
1954      return den;
1955    }
1956    static void __inline new_gcd(int *num, int *den)
1957    {
1958      const int div = gcd(*num, *den);
1959      if (num) {
1960        *num /= div;
1961        *den /= div;
1962      }
1963    }
1964    
1965    void test_gcd()
1966    {
1967      const int nb_tests = 10*speed_ref;
1968      int i;
1969      uint32_t crc1=0, crc2=0;
1970      uint32_t n0, n, d0, d;
1971      double t1, t2;
1972    
1973      t1 = gettime_usec();
1974      n0 = 0xfffff & (int)(t1*31.241);
1975      d0 = 0xfffff & (int)( ((n0*4123)%17) | 1 );
1976      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1977        old_gcd(&n, &d);
1978        crc1 = (((crc1>>4)^d) + ((crc1<<2)^n) ) & 0xffffff;
1979        n = d;
1980        d = (d*12363+31) & 0xffff;
1981        d |= !d;
1982      }
1983      t1 = (gettime_usec()-t1) / nb_tests;
1984    
1985      t2 = gettime_usec();
1986      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1987        new_gcd(&n, &d);
1988        crc2 = (((crc2>>4)^d) + ((crc2<<2)^n) ) & 0xffffff;
1989        n = d;
1990        d = (d*12363+31) & 0xffff;
1991        d |= !d;
1992      }
1993      t2 = (gettime_usec() - t2) / nb_tests;
1994    
1995      printf( "old_gcd: %.3f sec  crc=%d\n", t1, crc1 );
1996      printf( "new_gcd: %.3f sec  crc=%d\n", t2, crc2 );
1997      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1998    }
1999    
2000    /*********************************************************************
2001     * test compiler
2002     *********************************************************************/
2003    
2004    void test_compiler() {
2005      int nb_err = 0;
2006      int32_t v;
2007      if (sizeof(uint16_t)<2) {
2008        printf( "ERROR: sizeof(uint16_t)<2 !!\n" );
2009        nb_err++;
2010      }
2011      if (sizeof(int16_t)<2) {
2012        printf( "ERROR: sizeof(int16_t)<2 !!\n" );
2013        nb_err++;
2014      }
2015      if (sizeof(uint8_t)!=1) {
2016        printf( "ERROR: sizeof(uint8_t)!=1 !!\n" );
2017        nb_err++;
2018      }
2019      if (sizeof(int8_t)!=1) {
2020        printf( "ERROR: sizeof(int8_t)!=1 !!\n" );
2021        nb_err++;
2022      }
2023      if (sizeof(uint32_t)<4) {
2024        printf( "ERROR: sizeof(uint32_t)<4 !!\n" );
2025        nb_err++;
2026      }
2027      if (sizeof(int32_t)<4) {
2028        printf( "ERROR: sizeof(int32_t)<4 !!\n" );
2029        nb_err++;
2030      }
2031             /* yes, i know, this test is silly. But better be safe than sorry. :) */
2032      for(v=1000; v>=0; v--) {
2033        if ( (v>>2) != v/4)
2034          nb_err++;
2035      }
2036      for(v=-1000; v!=-1; v++) {
2037        if ( (v>>2) != (v/4)-!!(v%4))
2038          nb_err++;
2039      }
2040      if (nb_err!=0) {
2041        printf( "ERROR! please post your platform/compiler specs to xvid-devel@xvid.org !\n" );
2042      }
2043    }
2044    
2045    /*********************************************************************
2046     * test SSIM functions
2047     *********************************************************************/
2048    
2049    typedef int (*lumfunc)(uint8_t* ptr, int stride);
2050    typedef void (*csfunc)(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr);
2051    
2052    extern int lum_8x8_c(uint8_t* ptr, int stride);
2053    extern int lum_8x8_mmx(uint8_t* ptr, int stride);
2054    extern int lum_2x8_c(uint8_t* ptr, int stride);
2055    extern void consim_c(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr);
2056    extern void consim_mmx(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr);
2057    extern void consim_sse2(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr);
2058    
2059    void test_SSIM()
2060    {
2061            const int nb_tests = 3000*speed_ref;
2062            int tst;
2063            CPU *cpu;
2064            int i;
2065            int devs[3];
2066            long lumo, lumc;
2067            DECLARE_ALIGNED_MATRIX(Ref1, 16, 16, uint8_t, 16);
2068            DECLARE_ALIGNED_MATRIX(Ref2, 16, 16, uint8_t, 16);
2069            lumfunc lum8x8;
2070            lumfunc lum2x8;
2071            csfunc  csim;
2072    
2073            ieee_reseed(1);
2074            printf( "\n ======  test SSIM ======\n" );
2075            for(i=0; i<16*16;++i) {
2076                    long v1, v2;
2077                    v1 = ieee_rand(-256, 511);
2078                    v2 = ieee_rand(-256, 511);
2079                    Ref1[i] = (v1<0) ? 0 : (v1>255) ? 255 : v1;
2080                    Ref2[i] = (v2<0) ? 0 : (v2>255) ? 255 : v2;
2081            }
2082            lumc = ieee_rand(0, 255);
2083            lumo = ieee_rand(0, 255);
2084    
2085            for(cpu = cpu_list; cpu->name!=0; ++cpu)
2086            {
2087                    double t;
2088                    int m;
2089                    if (!init_cpu(cpu))
2090                            continue;
2091                    lum8x8 = lum_8x8_c;
2092                    lum2x8 = lum_2x8_c;
2093                    csim   = consim_c;
2094    #if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
2095                    if (cpu->cpu & XVID_CPU_MMX){
2096                            lum8x8 = lum_8x8_mmx;
2097                            csim = consim_mmx;
2098                    }
2099                    if (cpu->cpu & XVID_CPU_MMX){
2100                            csim = consim_sse2;
2101                    }
2102    #endif
2103                    t = gettime_usec();
2104                    emms();
2105                    for(tst=0; tst<nb_tests; ++tst) m = lum8x8(Ref1, 16);
2106                    emms();
2107                    t = (gettime_usec() - t) / nb_tests;
2108                    printf("%s - ssim-lum8x8    %.3f usec       m=%d %s\n",
2109                               cpu->name, t, m,
2110                               (m!=8230)?"| ERROR": "" );
2111    
2112                    t = gettime_usec();
2113                    emms();
2114                    for(tst=0; tst<nb_tests; ++tst) m = lum2x8(Ref1+8, 16);
2115                    emms();
2116                    t = (gettime_usec() - t) / nb_tests;
2117                    printf("%s - ssim-lum2x8    %.3f usec       m=%d %s\n",
2118                               cpu->name, t, m,
2119                               (m!=681)?"| ERROR": "" );
2120    
2121                    t = gettime_usec();
2122                    emms();
2123                    for(tst=0; tst<nb_tests; ++tst) csim(Ref1, Ref2, 16, lumo, lumc, devs+0, devs+1, devs+2);
2124                    emms();
2125                    t = (gettime_usec() - t) / nb_tests;
2126                    printf("%s - ssim-consim    %.3f usec       devs=[0x%x 0x%x 0x%x] %s\n",
2127                               cpu->name, t, devs[0], devs[1], devs[2],
2128                               (devs[0]!=0x1bdf0f || devs[1]!=0x137258 ||  devs[2]!=0xcdb13)?"| ERROR": "" );
2129                    printf( " --- \n" );
2130            }
2131    }
2132    
2133    /*********************************************************************
2134     * test bitstream functions
2135     *********************************************************************/
2136    
2137    #define BIT_BUF_SIZE 2000
2138    
2139    static void test_bits()
2140    {
2141      const int nb_tests = 50*speed_ref;
2142      int tst;
2143      uint32_t Crc;
2144      uint8_t Buf[BIT_BUF_SIZE];
2145      uint32_t Extracted[BIT_BUF_SIZE*8]; /* worst case: bits read 1 by 1 */
2146      int Lens[BIT_BUF_SIZE*8];
2147      double t1;
2148    
2149    
2150      printf( "\n ===  test bitstream ===\n" );
2151      ieee_reseed(1);
2152      Crc = 0;
2153    
2154      t1 = gettime_usec();
2155      for(tst=0; tst<nb_tests; ++tst) {
2156            Bitstream bs;
2157            int m, m2, l, l2;
2158    
2159            for(l=0; l<BIT_BUF_SIZE; ++l)
2160                    Buf[l] = (uint8_t)ieee_rand(0,255);
2161    
2162            l = BIT_BUF_SIZE - ieee_rand(1,BIT_BUF_SIZE/10);
2163            BitstreamInit(&bs, (void*)(Buf+BIT_BUF_SIZE-l), l);
2164    
2165    
2166            BitstreamReset(&bs);
2167            for(l2=l*8, m=0; l2>0; m++) {
2168                    const int b = ieee_rand(1,32);
2169                    Lens[m] = b;
2170                    l2 -= b;
2171                    if (l2<0) break;
2172                    Extracted[m] = BitstreamShowBits(&bs, b);
2173                    BitstreamSkip(&bs, b);
2174    //              printf( "<= %d: %d 0x%x\n", m, b, Extracted[m]);
2175            }
2176    
2177            BitstreamReset(&bs);
2178            for(m2=0; m2<m; ++m2) {
2179                    const int b = Lens[m2];
2180                    const uint32_t v = BitstreamGetBits(&bs, b);
2181                    Crc |= (v!=Extracted[m2]);
2182    //              printf( "=> %d: %d 0x%x %c\n", m2, b, v, " *"[Crc]);
2183            }
2184      }
2185      t1 = (gettime_usec() - t1) / nb_tests;
2186      printf(" test_bits   %.3f usec   %s\n", t1, (Crc!=0)?"| ERROR": "" );
2187    }
2188    
2189  /*********************************************************************  /*********************************************************************
2190   * main   * main
2191   *********************************************************************/   *********************************************************************/
2192    
2193  int main(int argc, char *argv[])  static void arg_missing(const char *opt)
2194  {  {
2195    int what = 0;    printf( "missing argument after option '%s'\n", opt);
2196    if (argc>1) what = atoi(argv[1]);    exit(-1);
2197    }
2198    
2199    int main(int argc, const char *argv[])
2200    {
2201            int c, what = 0;
2202            int width, height;
2203            uint32_t chksum = 0;
2204            const char * test_bitstream = 0;
2205    #if defined(WIN32) && defined(ARCH_IS_X86_64)
2206            DECLARE_ALIGNED_MATRIX(xmm_save, 2, 4, uint64_t, 16);
2207            // assumes xmm6 and xmm7 won't be falsely preserved by C code
2208            for(c=0;c<4;c++)
2209                    xmm_save[c] = read_counter();
2210            prime_xmm(xmm_save);
2211    #endif
2212    
2213            cpu_mask = 0;  // default => will use autodectect
2214            for(c=1; c<argc; ++c)
2215            {
2216              if (!strcmp(argv[c], "-v")) verbose++;
2217              else if (!strcmp(argv[c], "-c"))      cpu_mask = 0 /* PLAIN_C */ | XVID_CPU_FORCE;
2218              else if (!strcmp(argv[c], "-mmx"))    cpu_mask = XVID_CPU_MMX    | XVID_CPU_FORCE;
2219              else if (!strcmp(argv[c], "-mmxext")) cpu_mask = XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
2220              else if (!strcmp(argv[c], "-sse2"))   cpu_mask = XVID_CPU_SSE2   | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
2221              else if (!strcmp(argv[c], "-sse3"))   cpu_mask = XVID_CPU_SSE3   | XVID_CPU_SSE2 | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
2222              else if (!strcmp(argv[c], "-sse4"))   cpu_mask = XVID_CPU_SSE41  | XVID_CPU_SSE3 | XVID_CPU_SSE2 | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
2223          else if (!strcmp(argv[c], "-3dnow"))  cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_FORCE;
2224              else if (!strcmp(argv[c], "-3dnowe")) cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_3DNOWEXT | XVID_CPU_FORCE;
2225              else if (!strcmp(argv[c], "-altivec")) cpu_mask = XVID_CPU_ALTIVEC | XVID_CPU_FORCE;
2226              else if (!strcmp(argv[c], "-spd")) {
2227          if (++c==argc) arg_missing( argv[argc-1] );
2228          speed_ref = atoi(argv[c]);
2229        }
2230              else if (argv[c][0]!='-') {
2231                what = atoi(argv[c]);
2232                if (what==9) {
2233                  if (c+4>argc) {
2234                    printf("usage: %s %d bitstream width height (checksum)\n", argv[0], what);
2235                    exit(-1);
2236            }
2237            test_bitstream = argv[++c];
2238                  width  = atoi(argv[++c]);
2239                  height = atoi(argv[++c]);
2240                  if (c+1<argc && argv[c+1][0]!='-') {
2241                    if (sscanf(argv[c+1], "0x%x", &chksum)!=1) {
2242                      printf( "can't read checksum value.\n" );
2243                      exit(-1);
2244              }
2245              else c++;
2246            }
2247    //        printf( "[%s] %dx%d (0x%.8x)\n", test_bitstream, width, height, chksum);
2248          }
2249        }
2250        else {
2251          printf( "unrecognized option '%s'\n", argv[c]);
2252          exit(-1);
2253        }
2254      }
2255    
2256    
2257    if (what==0 || what==1) test_dct();    if (what==0 || what==1) test_dct();
2258    if (what==0 || what==2) test_mb();    if (what==0 || what==2) test_mb();
2259    if (what==0 || what==3) test_sad();    if (what==0 || what==3) test_sad();
2260    if (what==0 || what==4) test_transfer();    if (what==0 || what==4) test_transfer();
2261    if (what==0 || what==5) test_quant();    if (what==0 || what==5) test_quant();
2262    if (what==0 || what==6) test_cbp();    if (what==0 || what==6) test_cbp();
2263            if (what==0 || what==10) test_sse();
2264    if (what==8) {          if (what==0 || what==11) test_log2bin();
2265      int width, height;          if (what==0 || what==12) test_gcd();
2266      if (argc<5) {          if (what==0 || what==13) test_compiler();
2267        printf("usage: %s %d [bitstream] [width] [height]\n", argv[0], what);          if (what==0 || what==14) test_yuv();
2268        return 1;          if (what==0 || what==15) test_SSIM();
2269      }          if (what==0 || what==16) test_yuv2();
2270      width = atoi(argv[3]);          if (what==0 || what==17) test_bits();
2271      height = atoi(argv[4]);  
2272      test_dec(argv[2], width, height, (argc>5));          if (what==7) {
2273                    test_IEEE1180_compliance(-256, 255, 1);
2274                    test_IEEE1180_compliance(-256, 255,-1);
2275                    test_IEEE1180_compliance(  -5,   5, 1);
2276                    test_IEEE1180_compliance(  -5,   5,-1);
2277                    test_IEEE1180_compliance(-300, 300, 1);
2278                    test_IEEE1180_compliance(-300, 300,-1);
2279    }    }
2280            if (what==8) test_dct_saturation(-256, 255);
2281    
2282            if (test_bitstream)
2283              test_dec(test_bitstream, width, height, chksum);
2284    if (what==-1) {    if (what==-1) {
     test_bugs1();  
2285      test_dct_precision_diffs();      test_dct_precision_diffs();
2286                    test_bugs1();
2287    }    }
2288    return 0;          if (what==-2)
2289                    test_quant_bug();
2290    
2291    #if defined(WIN32) && defined(ARCH_IS_X86_64)
2292            get_xmm(xmm_save+4);
2293            if (memcmp(xmm_save, xmm_save+4, 4*sizeof(int64_t))) {
2294                    printf("\nWIN64 ERROR: XMM6 and XMM7 contents not preserved!\n"
2295                           "        XMM6                             XMM7\n"
2296                           "Before: %.16I64X%.16I64X %.16I64X%.16I64X\n"
2297                           "After:  %.16I64X%.16I64X %.16I64X%.16I64X",
2298                            xmm_save[0],xmm_save[1],xmm_save[2],xmm_save[3],
2299                            xmm_save[4],xmm_save[5],xmm_save[6],xmm_save[7]);
2300            } else {
2301                    printf("\nWIN64: XMM6 and XMM7 contents preserved correctly.\n");
2302            }
2303    #endif
2304    
2305            if ((what >= 0 && what <= 6) || what == 10) {
2306                    printf("\n\n"
2307                               "NB: If a function isn't optimised for a specific set of intructions,\n"
2308                               "    a C function is used instead. So don't panic if some functions\n"
2309                               "    may appear to be slow.\n");
2310            }
2311    
2312    #if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
2313            if (what == 0 || what == 5) {
2314                    printf("\n"
2315                               "NB: MMX mpeg4 quantization is known to have very small errors (+/-1 magnitude)\n"
2316                               "    for 1 or 2 coefficients a block. This is mainly caused by the fact the unit\n"
2317                               "    test goes far behind the usual limits of real encoding. Please do not report\n"
2318                               "    this error to the developers.\n");
2319  }  }
2320    #endif
2321    
2322  /*********************************************************************          return 0;
2323   * 'Reference' output (except for timing) on a PIII 1.13Ghz/linux  }
  *********************************************************************/  
 /*  
2324    
2325   ===== 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.2021

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