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

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