[svn] / branches / release-1_1-branch / xvidcore / examples / xvid_bench.c Repository:
ViewVC logotype

Diff of /branches/release-1_1-branch/xvidcore/examples/xvid_bench.c

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

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

Legend:
Removed from v.225  
changed lines
  Added in v.1749

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