[svn] / trunk / xvidcore / examples / xvid_bench.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/examples/xvid_bench.c

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

revision 860, Sun Feb 16 05:11:39 2003 UTC revision 1794, Fri Nov 14 15:43:28 2008 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.36 2008-11-14 15:43:27 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 (should plug some .md5 here)...  
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 <string.h>    // for memset  #include <string.h>    /* for memset */
38  #include <assert.h>  #include <assert.h>
39    
40  #ifndef WIN32  #ifndef WIN32
41  #include <sys/time.h>   // for gettimeofday  #include <sys/time.h>   /* for gettimeofday */
42  #else  #else
43  #include <time.h>  #include <time.h>
44  #endif  #endif
# Line 53  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  #include <math.h>  #include <math.h>
64    
# Line 67  Line 66 
66  #define M_PI            3.14159265358979323846  #define M_PI            3.14159265358979323846
67  #endif  #endif
68    
69  const int speed_ref = 100;  // on slow machines, decrease this value  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 83  Line 84 
84  #else  #else
85          clock_t clk;          clock_t clk;
86          clk = clock();          clk = clock();
87          return clk * 1000000 / CLOCKS_PER_SEC;          return clk * 1000. / CLOCKS_PER_SEC;  /* clock() returns time in Milliseconds */
88  #endif  #endif
89  }  }
90    
# Line 112  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 }          { "SSE3   ", XVID_CPU_SSE3 | XVID_CPU_SSE2 | XVID_CPU_MMX },
123  , { "IA64  ", XVID_CPU_IA64 }          { "SSE41  ", XVID_CPU_SSE41| XVID_CPU_SSE3 | XVID_CPU_SSE2 | XVID_CPU_MMX },
124  //, { "TSC   ", XVID_CPU_TSC }      { "3DNOW  ", XVID_CPU_3DNOW },
125  , { 0, 0 } }          { "3DNOWE ", XVID_CPU_3DNOW | XVID_CPU_3DNOWEXT },
126    #endif
127  , cpu_short_list[] =  #ifdef ARCH_IS_PPC
128  { { "PLAINC", 0 }          { "ALTIVEC", XVID_CPU_ALTIVEC },
129  , { "MMX   ", XVID_CPU_MMX }  #endif
130  //, { "MMXEXT", XVID_CPU_MMXEXT | XVID_CPU_MMX }  #ifdef ARCH_IS_X86_64
131  , { "IA64  ", XVID_CPU_IA64 }          { "X86_64 ", XVID_CPU_ASM},
132  , { 0, 0 } }  #endif
133    #ifdef ARCH_IS_IA64
134  , cpu_short_list2[] =  //      { "IA64   ", XVID_CPU_IA64 },
135  { { "PLAINC", 0 }  #endif
136  , { "MMX   ", XVID_CPU_MMX }  //      { "TSC    ", XVID_CPU_TSC },
137  , { "SSE2  ", XVID_CPU_SSE2 | XVID_CPU_MMX }          { 0, 0 }
138  , { 0, 0 } };  };
139    
140    
141  int init_cpu(CPU *cpu)  int init_cpu(CPU *cpu)
142  {  {
143    int xerr, cpu_type;          xvid_gbl_info_t xinfo;
144    XVID_INIT_PARAM xinit;  
145            /* Get the available CPU flags */
146            memset(&xinfo, 0, sizeof(xinfo));
147            xinfo.version = XVID_VERSION;
148            xvid_global(NULL, XVID_GBL_INFO, &xinfo, NULL);
149    
150    cpu_type = check_cpu_features() & cpu->cpu;          /* Are we trying to test a subset of the host CPU features */
151    xinit.cpu_flags = cpu_type | XVID_CPU_FORCE;          if ((xinfo.cpu_flags & cpu->cpu) == cpu->cpu) {
152    //    xinit.cpu_flags = XVID_CPU_MMX | XVID_CPU_FORCE;                  int xerr;
153    xerr = xvid_init(NULL, 0, &xinit, NULL);                  xvid_gbl_init_t xinit;
154    if (cpu->cpu>0 && (cpu_type==0 || xerr!=XVID_ERR_OK)) {                  memset(&xinit, 0, sizeof(xinit));
155      printf( "%s - skipped...\n", cpu->name );                  xinit.cpu_flags = cpu->cpu | XVID_CPU_FORCE;
156                    xinit.version = XVID_VERSION;
157                    xerr = xvid_global(NULL, XVID_GBL_INIT, &xinit, NULL);
158                    if (xerr==XVID_ERR_FAIL) {
159                            /* libxvidcore failed to init */
160      return 0;      return 0;
161    }    }
162            } else {
163                    /* The host CPU doesn't support some required feature for this test */
164                    return(0);
165            }
166    return 1;    return 1;
167  }  }
168    
169    #define CRC32_REMAINDER 0xCBF43926
170    #define CRC32_INITIAL 0xffffffff
171    
172    #define DO1(c, crc) ((crc) = crc32tab[((unsigned int)((crc)>>24) ^ (*c++)) & 0xff] ^ ((crc) << 8))
173    #define DO2(c, crc)  DO1(c, crc); DO1(c, crc);
174    #define DO4(c, crc)  DO2(c, crc); DO2(c, crc);
175    #define DO8(c, crc)  DO4(c, crc); DO4(c, crc);
176    
177    /******************************************************************************
178    * Precomputed AAL5 CRC32 lookup table
179    ******************************************************************************/
180    
181    static unsigned long crc32tab[256] = {
182    
183            0x00000000L, 0x04C11DB7L, 0x09823B6EL, 0x0D4326D9L,
184            0x130476DCL, 0x17C56B6BL, 0x1A864DB2L, 0x1E475005L,
185            0x2608EDB8L, 0x22C9F00FL, 0x2F8AD6D6L, 0x2B4BCB61L,
186            0x350C9B64L, 0x31CD86D3L, 0x3C8EA00AL, 0x384FBDBDL,
187            0x4C11DB70L, 0x48D0C6C7L, 0x4593E01EL, 0x4152FDA9L,
188            0x5F15ADACL, 0x5BD4B01BL, 0x569796C2L, 0x52568B75L,
189            0x6A1936C8L, 0x6ED82B7FL, 0x639B0DA6L, 0x675A1011L,
190            0x791D4014L, 0x7DDC5DA3L, 0x709F7B7AL, 0x745E66CDL,
191            0x9823B6E0L, 0x9CE2AB57L, 0x91A18D8EL, 0x95609039L,
192            0x8B27C03CL, 0x8FE6DD8BL, 0x82A5FB52L, 0x8664E6E5L,
193            0xBE2B5B58L, 0xBAEA46EFL, 0xB7A96036L, 0xB3687D81L,
194            0xAD2F2D84L, 0xA9EE3033L, 0xA4AD16EAL, 0xA06C0B5DL,
195            0xD4326D90L, 0xD0F37027L, 0xDDB056FEL, 0xD9714B49L,
196            0xC7361B4CL, 0xC3F706FBL, 0xCEB42022L, 0xCA753D95L,
197            0xF23A8028L, 0xF6FB9D9FL, 0xFBB8BB46L, 0xFF79A6F1L,
198            0xE13EF6F4L, 0xE5FFEB43L, 0xE8BCCD9AL, 0xEC7DD02DL,
199            0x34867077L, 0x30476DC0L, 0x3D044B19L, 0x39C556AEL,
200            0x278206ABL, 0x23431B1CL, 0x2E003DC5L, 0x2AC12072L,
201            0x128E9DCFL, 0x164F8078L, 0x1B0CA6A1L, 0x1FCDBB16L,
202            0x018AEB13L, 0x054BF6A4L, 0x0808D07DL, 0x0CC9CDCAL,
203            0x7897AB07L, 0x7C56B6B0L, 0x71159069L, 0x75D48DDEL,
204            0x6B93DDDBL, 0x6F52C06CL, 0x6211E6B5L, 0x66D0FB02L,
205            0x5E9F46BFL, 0x5A5E5B08L, 0x571D7DD1L, 0x53DC6066L,
206            0x4D9B3063L, 0x495A2DD4L, 0x44190B0DL, 0x40D816BAL,
207            0xACA5C697L, 0xA864DB20L, 0xA527FDF9L, 0xA1E6E04EL,
208            0xBFA1B04BL, 0xBB60ADFCL, 0xB6238B25L, 0xB2E29692L,
209            0x8AAD2B2FL, 0x8E6C3698L, 0x832F1041L, 0x87EE0DF6L,
210            0x99A95DF3L, 0x9D684044L, 0x902B669DL, 0x94EA7B2AL,
211            0xE0B41DE7L, 0xE4750050L, 0xE9362689L, 0xEDF73B3EL,
212            0xF3B06B3BL, 0xF771768CL, 0xFA325055L, 0xFEF34DE2L,
213            0xC6BCF05FL, 0xC27DEDE8L, 0xCF3ECB31L, 0xCBFFD686L,
214            0xD5B88683L, 0xD1799B34L, 0xDC3ABDEDL, 0xD8FBA05AL,
215            0x690CE0EEL, 0x6DCDFD59L, 0x608EDB80L, 0x644FC637L,
216            0x7A089632L, 0x7EC98B85L, 0x738AAD5CL, 0x774BB0EBL,
217            0x4F040D56L, 0x4BC510E1L, 0x46863638L, 0x42472B8FL,
218            0x5C007B8AL, 0x58C1663DL, 0x558240E4L, 0x51435D53L,
219            0x251D3B9EL, 0x21DC2629L, 0x2C9F00F0L, 0x285E1D47L,
220            0x36194D42L, 0x32D850F5L, 0x3F9B762CL, 0x3B5A6B9BL,
221            0x0315D626L, 0x07D4CB91L, 0x0A97ED48L, 0x0E56F0FFL,
222            0x1011A0FAL, 0x14D0BD4DL, 0x19939B94L, 0x1D528623L,
223            0xF12F560EL, 0xF5EE4BB9L, 0xF8AD6D60L, 0xFC6C70D7L,
224            0xE22B20D2L, 0xE6EA3D65L, 0xEBA91BBCL, 0xEF68060BL,
225            0xD727BBB6L, 0xD3E6A601L, 0xDEA580D8L, 0xDA649D6FL,
226            0xC423CD6AL, 0xC0E2D0DDL, 0xCDA1F604L, 0xC960EBB3L,
227            0xBD3E8D7EL, 0xB9FF90C9L, 0xB4BCB610L, 0xB07DABA7L,
228            0xAE3AFBA2L, 0xAAFBE615L, 0xA7B8C0CCL, 0xA379DD7BL,
229            0x9B3660C6L, 0x9FF77D71L, 0x92B45BA8L, 0x9675461FL,
230            0x8832161AL, 0x8CF30BADL, 0x81B02D74L, 0x857130C3L,
231            0x5D8A9099L, 0x594B8D2EL, 0x5408ABF7L, 0x50C9B640L,
232            0x4E8EE645L, 0x4A4FFBF2L, 0x470CDD2BL, 0x43CDC09CL,
233            0x7B827D21L, 0x7F436096L, 0x7200464FL, 0x76C15BF8L,
234            0x68860BFDL, 0x6C47164AL, 0x61043093L, 0x65C52D24L,
235            0x119B4BE9L, 0x155A565EL, 0x18197087L, 0x1CD86D30L,
236            0x029F3D35L, 0x065E2082L, 0x0B1D065BL, 0x0FDC1BECL,
237            0x3793A651L, 0x3352BBE6L, 0x3E119D3FL, 0x3AD08088L,
238            0x2497D08DL, 0x2056CD3AL, 0x2D15EBE3L, 0x29D4F654L,
239            0xC5A92679L, 0xC1683BCEL, 0xCC2B1D17L, 0xC8EA00A0L,
240            0xD6AD50A5L, 0xD26C4D12L, 0xDF2F6BCBL, 0xDBEE767CL,
241            0xE3A1CBC1L, 0xE760D676L, 0xEA23F0AFL, 0xEEE2ED18L,
242            0xF0A5BD1DL, 0xF464A0AAL, 0xF9278673L, 0xFDE69BC4L,
243            0x89B8FD09L, 0x8D79E0BEL, 0x803AC667L, 0x84FBDBD0L,
244            0x9ABC8BD5L, 0x9E7D9662L, 0x933EB0BBL, 0x97FFAD0CL,
245            0xAFB010B1L, 0xAB710D06L, 0xA6322BDFL, 0xA2F33668L,
246            0xBCB4666DL, 0xB8757BDAL, 0xB5365D03L, 0xB1F740B4L
247    
248    };
249    
250    uint32_t
251    calc_crc(uint8_t *mem, int len, uint32_t crc)
252    {
253            while( len >= 8) {
254                    DO8(mem, crc);
255                    len -= 8;
256            }
257    
258            while( len ) {
259                    DO1(mem, crc);
260                    len--;
261            }
262    
263            return crc;
264    }
265    
266    void byte_swap(uint8_t *mem, int len, int element_size) {
267    #ifdef ARCH_IS_BIG_ENDIAN
268            int i;
269    
270            if(element_size == 1) {
271                    /* No need to swap */
272            } else if(element_size == 2) {
273                    uint8_t temp[2];
274    
275                    for(i=0; i < (len/2); i++ ) {
276                            temp[0] = mem[0];
277                            temp[1] = mem[1];
278                            mem[0] = temp[1];
279                            mem[1] = temp[0];
280    
281                            mem += 2;
282                    }
283            } else if(element_size == 4) {
284                    uint8_t temp[4];
285    
286                    for(i=0; i < (len/4); i++ ) {
287                            temp[0] = mem[0];
288                            temp[1] = mem[1];
289                            temp[2] = mem[2];
290                            temp[3] = mem[3];
291                            mem[0] = temp[3];
292                            mem[1] = temp[2];
293                            mem[2] = temp[1];
294                            mem[3] = temp[0];
295    
296                            mem += 4;
297                    }
298            } else {
299                    printf("ERROR: byte_swap unsupported element_size(%u)\n", element_size);
300            }
301    #endif
302    }
303    
304  /*********************************************************************  /*********************************************************************
305   * test DCT   * test DCT
306   *********************************************************************/   *********************************************************************/
# Line 165  Line 313 
313    int tst;    int tst;
314    CPU *cpu;    CPU *cpu;
315    int i;    int i;
316    short iDst0[8*8], iDst[8*8], fDst[8*8];          DECLARE_ALIGNED_MATRIX(iDst0, 8, 8, short, 16);
317            DECLARE_ALIGNED_MATRIX(iDst,  8, 8, short, 16);
318            DECLARE_ALIGNED_MATRIX(fDst,  8, 8, short, 16);
319    double overhead;    double overhead;
320    
321    printf( "\n ===== test fdct/idct =====\n" );    printf( "\n ===== test fdct/idct =====\n" );
# Line 203  Line 353 
353        MSE += delta*delta;        MSE += delta*delta;
354      }      }
355      PSNR = (MSE==0.) ? 1.e6 : -4.3429448*log( MSE/64. );      PSNR = (MSE==0.) ? 1.e6 : -4.3429448*log( MSE/64. );
356      printf( "%s -  %.3f usec       PSNR=%.3f  MSE=%.3f\n",                  printf( "%s -  %.3f usec       PSNR=%.3f  MSE=%.3f %s\n",
357        cpu->name, t, PSNR, MSE );                                  cpu->name, t, PSNR, MSE,
358      if (ABS(MSE)>=64) printf( "*** CRC ERROR! ***\n" );                                  (ABS(MSE)>=64)? "| ERROR" :"");
359    }    }
360  }  }
361    
# Line 219  Line 369 
369    int tst;    int tst;
370    CPU *cpu;    CPU *cpu;
371    int i;    int i;
372    uint8_t Cur[16*16], Ref1[16*16], Ref2[16*16];          DECLARE_ALIGNED_MATRIX(Cur,  16, 16, uint8_t, 16);
373            DECLARE_ALIGNED_MATRIX(Ref1, 16, 16, uint8_t, 16);
374            DECLARE_ALIGNED_MATRIX(Ref2, 16, 16, uint8_t, 16);
375    
376    printf( "\n ======  test SAD ======\n" );    printf( "\n ======  test SAD ======\n" );
377    for(i=0; i<16*16;++i) {    for(i=0; i<16*16;++i) {
# Line 240  Line 392 
392      for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);      for(tst=0; tst<nb_tests; ++tst) s = sad8(Cur, Ref1, 16);
393      emms();      emms();
394      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
395      printf( "%s - sad8    %.3f usec       sad=%d\n", cpu->name, t, s );                  printf("%s - sad8    %.3f usec       sad=%d %s\n",
396      if (s!=3776) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
397                               (s!=3776)?"| ERROR": "" );
398    
399      t = gettime_usec();      t = gettime_usec();
400      emms();      emms();
401      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);
402      emms();      emms();
403      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
404      printf( "%s - sad16   %.3f usec       sad=%d\n", cpu->name, t, s );                  printf("%s - sad16   %.3f usec       sad=%d %s\n",
405      if (s!=27214) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
406                               (s!=27214)?"| ERROR": "" );
407    
408      t = gettime_usec();      t = gettime_usec();
409      emms();      emms();
410      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);
411      emms();      emms();
412      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
413      printf( "%s - sad16bi %.3f usec       sad=%d\n", cpu->name, t, s );                  printf( "%s - sad16bi %.3f usec       sad=%d %s\n",
414      if (s!=26274) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
415                                    (s!=26274)?"| ERROR": "" );
416    
417      t = gettime_usec();      t = gettime_usec();
418      emms();      emms();
419      for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);      for(tst=0; tst<nb_tests; ++tst) s = dev16(Cur, 16);
420      emms();      emms();
421      t = (gettime_usec() - t) / nb_tests;      t = (gettime_usec() - t) / nb_tests;
422      printf( "%s - dev16   %.3f usec       sad=%d\n", cpu->name, t, s );                  printf( "%s - dev16   %.3f usec       sad=%d %s\n",
423      if (s!=3344) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
424                                    (s!=3344)?"| ERROR": "" );
425    
426      printf( " --- \n" );      printf( " --- \n" );
427    }    }
# Line 283  Line 439 
439  #define LEAVE \  #define LEAVE \
440      emms();                             \      emms();                             \
441      t = (gettime_usec() - t) / nb_tests;  \      t = (gettime_usec() - t) / nb_tests;  \
442      iCrc = 0;                           \          iCrc = calc_crc((uint8_t*)Dst, sizeof(Dst), CRC32_INITIAL)
     for(i=0; i<16*8; ++i) { iCrc += Dst[i]^i; }  
443    
444  #define TEST_MB(FUNC, R)                \  #define TEST_MB(FUNC, R)                \
445      ENTER                               \      ENTER                               \
# Line 302  Line 457 
457    const int nb_tests = 2000*speed_ref;    const int nb_tests = 2000*speed_ref;
458    CPU *cpu;    CPU *cpu;
459    const uint8_t Src0[16*9] = {    const uint8_t Src0[16*9] = {
460          // try to have every possible combinaison of rounding...                  /* try to have every possible combinaison of rounding... */
461        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,
462      , 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,
463      , 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,
464      , 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,
465      , 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,
466      , 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,
467      , 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,
468      , 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,
469      , 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
470    };    };
471    uint8_t Dst[16*8] = {0};    uint8_t Dst[16*8] = {0};
472    
# Line 326  Line 481 
481        continue;        continue;
482    
483      TEST_MB(interpolate8x8_halfpel_h, 0);      TEST_MB(interpolate8x8_halfpel_h, 0);
484      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",
485      if (iCrc!=8107) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
486                               (iCrc!=0x115381ba)?"| ERROR": "" );
487    
488      TEST_MB(interpolate8x8_halfpel_h, 1);      TEST_MB(interpolate8x8_halfpel_h, 1);
489      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
490      if (iCrc!=8100) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
491                               (iCrc!=0x2b1f528f)?"| ERROR": "" );
492    
493    
494      TEST_MB(interpolate8x8_halfpel_v, 0);      TEST_MB(interpolate8x8_halfpel_v, 0);
495      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",
496      if (iCrc!=8108) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
497                               (iCrc!=0x423cdcc7)?"| ERROR": "" );
498    
499      TEST_MB(interpolate8x8_halfpel_v, 1);      TEST_MB(interpolate8x8_halfpel_v, 1);
500      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
501      if (iCrc!=8105) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
502                               (iCrc!=0x42202efe)?"| ERROR": "" );
503    
504    
505      TEST_MB(interpolate8x8_halfpel_hv, 0);      TEST_MB(interpolate8x8_halfpel_hv, 0);
506      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",
507      if (iCrc!=8112) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
508                               (iCrc!=0xd198d387)?"| ERROR": "" );
509    
510      TEST_MB(interpolate8x8_halfpel_hv, 1);      TEST_MB(interpolate8x8_halfpel_hv, 1);
511      printf( "%s -           round1 %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s -           round1 %.3f usec       crc32=0x%08x %s\n",
512      if (iCrc!=8103) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
513                               (iCrc!=0x9ecfd921)?"| ERROR": "" );
514    
515    
516         // this is a new function, as of 06.06.2002                  /* this is a new function, as of 06.06.2002 */
517  #if 0  #if 0
518      TEST_MB2(interpolate8x8_avrg);      TEST_MB2(interpolate8x8_avrg);
519      printf( "%s - interpolate8x8_c %.3f usec       iCrc=%d\n", cpu->name, t, iCrc );                  printf("%s - interpolate8x8_c %.3f usec       crc32=0x%08x %s\n",
520      if (iCrc!=8107) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, iCrc,
521                               (iCrc!=8107)?"| ERROR": "" );
522  #endif  #endif
523    
524        /* New functions for field prediction by CK 1.10.2005 */
525    #pragma NEW8X4
526                    TEST_MB(interpolate8x4_halfpel_h, 0);
527                    printf("%s - interpfield-h -round0 %.3f usec       crc32=0x%08x %s\n",
528                               cpu->name, t, iCrc,
529                               (iCrc!=0x9538d6df)?"| ERROR": "" );
530    
531                    TEST_MB(interpolate8x4_halfpel_h, 1);
532                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
533                               cpu->name, t, iCrc,
534                               (iCrc!=0xde5f1db4)?"| ERROR": "" );
535    
536    
537                    TEST_MB(interpolate8x4_halfpel_v, 0);
538                    printf("%s - interpfield- v-round0 %.3f usec       crc32=0x%08x %s\n",
539                               cpu->name, t, iCrc,
540                               (iCrc!=0xea5a69ef)?"| ERROR": "" );
541    
542                    TEST_MB(interpolate8x4_halfpel_v, 1);
543                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
544                               cpu->name, t, iCrc,
545                               (iCrc!=0x4f10ec0f)?"| ERROR": "" );
546    
547    
548                    TEST_MB(interpolate8x4_halfpel_hv, 0);
549                    printf("%s - interpfield-hv-round0 %.3f usec       crc32=0x%08x %s\n",
550                               cpu->name, t, iCrc,
551                               (iCrc!=0xf97ee367)?"| ERROR": "" );
552    
553                    TEST_MB(interpolate8x4_halfpel_hv, 1);
554                    printf("%s -                round1 %.3f usec       crc32=0x%08x %s\n",
555                               cpu->name, t, iCrc,
556                               (iCrc!=0xb6a9f581)?"| ERROR": "" );
557    /* End of 8x4 functions */
558    
559      printf( " --- \n" );      printf( " --- \n" );
560    }    }
561  }  }
562    
563    #undef ENTER
564    #undef LEAVE
565    #undef TEST_MB
566    #undef TEST_MB2
567    
568  /*********************************************************************  /*********************************************************************
569   * test transfer   * test transfer
570   *********************************************************************/   *********************************************************************/
# Line 392  Line 594 
594      }                                         \      }                                         \
595      emms();                                   \      emms();                                   \
596      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
597      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]));  \
598    s = calc_crc((uint8_t*)(DST), 8*32*sizeof((DST)[0]), CRC32_INITIAL)
599    
600  #define TEST_TRANSFER(FUNC, DST, SRC)         \  #define TEST_TRANSFER(FUNC, DST, SRC)         \
601      TEST_TRANSFER_BEGIN(DST);                 \      TEST_TRANSFER_BEGIN(DST);                 \
# Line 418  Line 621 
621      }                                         \      }                                         \
622      emms();                                   \      emms();                                   \
623      t = (gettime_usec()-t -overhead) / nb_tests;\      t = (gettime_usec()-t -overhead) / nb_tests;\
624      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]));  \
625    s = calc_crc((uint8_t*)(DST), 8*32*sizeof((DST)[0]), CRC32_INITIAL)
626    
627  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \  #define TEST_TRANSFER2(FUNC, DST, SRC, R1)    \
628      TEST_TRANSFER2_BEGIN(DST,SRC);            \      TEST_TRANSFER2_BEGIN(DST,SRC);            \
# Line 435  Line 639 
639    const int nb_tests = 4000*speed_ref;    const int nb_tests = 4000*speed_ref;
640    int i;    int i;
641    CPU *cpu;    CPU *cpu;
642    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];
643    int16_t Src16[8*32], Dst16[8*32];  //      int16_t Src16[8*32], Dst16[8*32];
644      DECLARE_ALIGNED_MATRIX(Src8, 8, 32, uint8_t, CACHE_LINE);
645      DECLARE_ALIGNED_MATRIX(Dst8, 8, 32, uint8_t, CACHE_LINE);
646      DECLARE_ALIGNED_MATRIX(Ref1, 8, 32, uint8_t, CACHE_LINE);
647      DECLARE_ALIGNED_MATRIX(Ref2, 8, 32, uint8_t, CACHE_LINE);
648      DECLARE_ALIGNED_MATRIX(Src16, 8, 32, uint16_t, CACHE_LINE);
649      DECLARE_ALIGNED_MATRIX(Dst16, 8, 32, uint16_t, CACHE_LINE);
650    
651    printf( "\n ===  test transfer ===\n" );    printf( "\n ===  test transfer ===\n" );
652    
653    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
654    {    {
655      double t, overhead;      double t, overhead;
656      int tst, s;      int tst, s;
# Line 449  Line 659 
659        continue;        continue;
660    
661      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);      TEST_TRANSFER(transfer_8to16copy, Dst16, Src8);
662      printf( "%s - 8to16     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16     %.3f usec       crc32=0x%08x %s\n",
663      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
664                               (s!=0x115814bb)?"| ERROR": "");
665    
666      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);      TEST_TRANSFER(transfer_16to8copy, Dst8, Src16);
667      printf( "%s - 16to8     %.3f usec       crc=%d\n", cpu->name, t, s );                  printf( "%s - 16to8     %.3f usec       crc32=0x%08x %s\n",
668      if (s!=28288) printf( "*** CRC ERROR! ***\n" );                                  cpu->name, t, s,
669                                    (s!=0xee7ccbb4)?"| ERROR": "");
670    
671        /* New functions for field prediction by CK 1.10.2005 */
672    #pragma NEW8X4
673                    TEST_TRANSFER(transfer8x4_copy, Dst8, Src8);
674                    printf("%s - 8to4      %.3f usec       crc32=0x%08x %s\n",
675                               cpu->name, t, s,
676                               (s!=0xbb9c3db5)?"| ERROR": "");
677    /* End of new functions */
678    
679      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);      TEST_TRANSFER(transfer8x8_copy, Dst8, Src8);
680      printf( "%s - 8to8      %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to8      %.3f usec       crc32=0x%08x %s\n",
681      if (s!=20352) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
682                               (s!=0xd37b3295)?"| ERROR": "");
683    
684      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);      TEST_TRANSFER(transfer_16to8add, Dst8, Src16);
685      printf( "%s - 16to8add  %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 16to8add  %.3f usec       crc32=0x%08x %s\n",
686      if (s!=25536) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
687                               (s!=0xdd817bf4)?"| ERROR": "" );
688    
689      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);      TEST_TRANSFER2(transfer_8to16sub, Dst16, Src8, Ref1);
690      printf( "%s - 8to16sub  %.3f usec       crc1=%d ", cpu->name, t, s );                  {
691      if (s!=28064) printf( "*** CRC ERROR! ***\n" );                          int s1, s2;
692      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);
693      printf( "crc2=%d\n", s);                          s2 = calc_crc((uint8_t*)Src8, 8*32*sizeof(Src8[0]), CRC32_INITIAL);
694      if (s!=16256) printf( "*** CRC ERROR! ***\n" );                          printf("%s - 8to16sub  %.3f usec       crc32(1)=0x%08x crc32(2)=0x%08x %s %s\n",
695  #if 1                                     cpu->name, t, s1, s2,
696                                       (s1!=0xa1e07163)?"| ERROR1": "",
697                                       (s2!=0xd86c5d23)?"| ERROR2": "" );
698                    }
699    
700      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);      TEST_TRANSFER3(transfer_8to16sub2, Dst16, Src8, Ref1, Ref2);
701      printf( "%s - 8to16sub2 %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - 8to16sub2 %.3f usec       crc32=0x%08x %s\n",
702      if (s!=20384) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
703  //    for(i=0; i<64; ++i) printf( "[%d]", Dst16[i]);                             (s!=0x99b6c4c7)?"| ERROR": "" );
704  //    printf("\n");  
 #endif  
705      printf( " --- \n" );      printf( " --- \n" );
706    }    }
707  }  }
# Line 487  Line 712 
712    
713  #define TEST_QUANT(FUNC, DST, SRC)              \  #define TEST_QUANT(FUNC, DST, SRC)              \
714      t = gettime_usec();                         \      t = gettime_usec();                         \
715      for(s=0,qm=1; qm<=255; ++qm) {              \  for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
716        for(i=0; i<8*8; ++i) Quant[i] = qm;       \        for(i=0; i<8*8; ++i) Quant[i] = qm;       \
717        set_inter_matrix( Quant );                \    set_inter_matrix( mpeg_quant_matrices, Quant );                \
718        emms();                                   \        emms();                                   \
719        for(q=1; q<=max_Q; ++q) {                 \        for(q=1; q<=max_Q; ++q) {                 \
720          for(tst=0; tst<nb_tests; ++tst)         \          for(tst=0; tst<nb_tests; ++tst)         \
721            (FUNC)((DST), (SRC), q);              \            (FUNC)((DST), (SRC), q, mpeg_quant_matrices);              \
722          for(i=0; i<64; ++i) s+=(DST)[i]^i^qm;   \          byte_swap((uint8_t*)(DST), 64*sizeof((DST)[0]), sizeof((DST)[0]));  \
723            s = calc_crc((uint8_t*)(DST), 64*sizeof((DST)[0]), s); \
724        }                                         \        }                                         \
725        emms();                                   \        emms();                                   \
726      }                                           \      }                                           \
727      t = (gettime_usec()-t-overhead)/nb_tests/qm;\  t = (gettime_usec()-t-overhead)/nb_tests/qm
     s = (s&0xffff)^(s>>16)  
728    
729  #define TEST_QUANT2(FUNC, DST, SRC)             \  #define TEST_QUANT2(FUNC, DST, SRC)             \
730      t = gettime_usec();                         \      t = gettime_usec();                         \
731      for(s=0,qm=1; qm<=255; ++qm) {              \  for(s=CRC32_INITIAL,qm=1; qm<=255; ++qm) {              \
732        for(i=0; i<8*8; ++i) Quant[i] = qm;       \        for(i=0; i<8*8; ++i) Quant[i] = qm;       \
733        set_intra_matrix( Quant );                \    set_intra_matrix( mpeg_quant_matrices, Quant );                \
734        emms();                                   \        emms();                                   \
735        for(q=1; q<=max_Q; ++q) {                 \        for(q=1; q<=max_Q; ++q) {                 \
736          for(tst=0; tst<nb_tests; ++tst)         \          for(tst=0; tst<nb_tests; ++tst)         \
737            (FUNC)((DST), (SRC), q, q);           \            (FUNC)((DST), (SRC), q, q, mpeg_quant_matrices);           \
738          for(i=0; i<64; ++i) s+=(DST)[i]^i^qm;   \          byte_swap((uint8_t*)(DST), 64*sizeof((DST)[0]), sizeof((DST)[0]));  \
739            s = calc_crc((uint8_t*)(DST), 64*sizeof((DST)[0]), s); \
740      }                                         \
741      emms();                                   \
742    }                                           \
743    t = (gettime_usec()-t-overhead)/nb_tests/qm
744    
745    #define TEST_INTRA(REFFUNC, NEWFUNC, RANGE)              \
746    { int i,q,s;\
747            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16); \
748      DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16); \
749      DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16); \
750      for(q=1;q<=max_Q;q++)          \
751        for(s=-RANGE;s<RANGE;s++) { \
752          for(i=0;i<64;i++) Src[i]=s; \
753          (REFFUNC)((Dst),(Src),q,q,mpeg_quant_matrices);   \
754          (NEWFUNC)((Dst2),(Src),q,q,mpeg_quant_matrices);  \
755          for(i=0;i<64;i++)     \
756            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]);  \
757        }                                         \        }                                         \
758    }
759    
760    #define TEST_INTER(REFFUNC, NEWFUNC, RANGE)              \
761    { int i,q,s;  \
762            DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16); \
763      DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16); \
764      DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16); \
765      for(q=1;q<=max_Q;q++)  \
766        for(s=-RANGE;s<RANGE;s++) {   \
767          for(i=0;i<64;i++) Src[i]=s; \
768          (REFFUNC)((Dst),(Src),q,mpeg_quant_matrices);  \
769          (NEWFUNC)((Dst2),(Src),q,mpeg_quant_matrices); \
770        emms();                                   \        emms();                                   \
771          for(i=0;i<64;i++) \
772            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]); \
773      }                                           \      }                                           \
774      t = (gettime_usec()-t-overhead)/nb_tests/qm;\  }
     s = (s&0xffff)^(s>>16)  
775    
776  void test_quant()  void test_quant()
777  {  {
778    const int nb_tests = 1*speed_ref;    const int nb_tests = 1*speed_ref;
779    const int max_Q = 31;    const int max_Q = 31;
780            DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
781    
782    int i, qm;    int i, qm;
783    CPU *cpu;    CPU *cpu;
784    int16_t  Src[8*8], Dst[8*8];          DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
785            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
786            DECLARE_ALIGNED_MATRIX(Dst2,8, 8, int16_t, 16);
787    uint8_t Quant[8*8];    uint8_t Quant[8*8];
788    
789    printf( "\n =====  test quant =====\n" );    printf( "\n =====  test quant =====\n" );
790    
791      // we deliberately enfringe the norm's specified range [-127,127],  /* we deliberately enfringe the norm's specified range [-127,127], */
792      // to test the robustness of the iquant module  /* to test the robustness of the iquant module */
793    for(i=0; i<64; ++i) {    for(i=0; i<64; ++i) {
794      Src[i] = 1 + (i-32) * (i&6);      Src[i] = 1 + (i-32) * (i&6);
795      Dst[i] = 0;      Dst[i] = 0;
796    }    }
797    
798    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
799    {    {
800      double t, overhead;      double t, overhead;
801      int tst, q;      int tst, q;
# Line 544  Line 804 
804      if (!init_cpu(cpu))      if (!init_cpu(cpu))
805        continue;        continue;
806    
807                    // exhaustive tests to compare against the (ref) C-version
808                    TEST_INTRA(quant_h263_intra_c,   quant_h263_intra,    2048);
809                    TEST_INTRA(dequant_h263_intra_c, dequant_h263_intra , 512 );
810                    TEST_INTER(quant_h263_inter_c,   quant_h263_inter ,   2048);
811                    TEST_INTER(dequant_h263_inter_c, dequant_h263_inter , 512 );
812    
813      overhead = -gettime_usec();      overhead = -gettime_usec();
814      for(s=0,qm=1; qm<=255; ++qm) {      for(s=0,qm=1; qm<=255; ++qm) {
815        for(i=0; i<8*8; ++i) Quant[i] = qm;        for(i=0; i<8*8; ++i) Quant[i] = qm;
816        set_inter_matrix( Quant );                          set_inter_matrix(mpeg_quant_matrices, Quant );
817        for(q=1; q<=max_Q; ++q)        for(q=1; q<=max_Q; ++q)
818          for(i=0; i<64; ++i) s+=Dst[i]^i^qm;          for(i=0; i<64; ++i) s+=Dst[i]^i^qm;
819      }      }
820      overhead += gettime_usec();      overhead += gettime_usec();
821    
822  #if 1                  TEST_QUANT2(quant_mpeg_intra, Dst, Src);
823      TEST_QUANT2(quant4_intra, Dst, Src);                  printf("%s -   quant_mpeg_intra %.3f usec       crc32=0x%08x %s\n",
824      printf( "%s -   quant4_intra %.3f usec       crc=%d\n", cpu->name, t, s );                             cpu->name, t, s,
825      if (s!=29809) printf( "*** CRC ERROR! ***\n" );                             (s!=0xfd6a21a4)? "| ERROR": "");
826    
827      TEST_QUANT(quant4_inter, Dst, Src);                  TEST_QUANT(quant_mpeg_inter, Dst, Src);
828      printf( "%s -   quant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s -   quant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
829      if (s!=12574) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
830  #endif                             (s!=0xf6de7757)?"| ERROR": "");
831  #if 1  
832      TEST_QUANT2(dequant4_intra, Dst, Src);                  TEST_QUANT2(dequant_mpeg_intra, Dst, Src);
833      printf( "%s - dequant4_intra %.3f usec       crc=%d\n", cpu->name, t, s );                  printf("%s - dequant_mpeg_intra %.3f usec       crc32=0x%08x %s\n",
834      if (s!=24052) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, s,
835                               (s!=0x2def7bc7)?"| ERROR": "");
836      TEST_QUANT(dequant4_inter, Dst, Src);  
837      printf( "%s - dequant4_inter %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT(dequant_mpeg_inter, Dst, Src);
838      if (s!=63847) printf( "*** CRC ERROR! ***\n" );                  printf("%s - dequant_mpeg_inter %.3f usec       crc32=0x%08x %s\n",
839  #endif                             cpu->name, t, s,
840  #if 1                             (s!=0xd878c722)?"| ERROR": "");
841      TEST_QUANT2(quant_intra, Dst, Src);  
842      printf( "%s -    quant_intra %.3f usec       crc=%d\n", cpu->name, t, s );                  TEST_QUANT2(quant_h263_intra, Dst, Src);
843      if (s!=25662) printf( "*** CRC ERROR! ***\n" );                  printf("%s -   quant_h263_intra %.3f usec       crc32=0x%08x %s\n",
844                               cpu->name, t, s,
845      TEST_QUANT(quant_inter, Dst, Src);                             (s!=0x2eba9d43)?"| ERROR": "");
846      printf( "%s -    quant_inter %.3f usec       crc=%d\n", cpu->name, t, s );  
847      if (s!=23972) printf( "*** CRC ERROR! ***\n" );                  TEST_QUANT(quant_h263_inter, Dst, Src);
848  #endif                  printf("%s -   quant_h263_inter %.3f usec       crc32=0x%08x %s\n",
849  #if 1                             cpu->name, t, s,
850      TEST_QUANT2(dequant_intra, Dst, Src);                             (s!=0xbd315a7e)?"| ERROR": "");
851      printf( "%s -  dequant_intra %.3f usec       crc=%d\n", cpu->name, t, s );  
852      if (s!=49900) printf( "*** CRC ERROR! ***\n" );                  TEST_QUANT2(dequant_h263_intra, Dst, Src);
853                    printf("%s - dequant_h263_intra %.3f usec       crc32=0x%08x %s\n",
854      TEST_QUANT(dequant_inter, Dst, Src);                             cpu->name, t, s,
855      printf( "%s -  dequant_inter %.3f usec       crc=%d\n", cpu->name, t, s );                             (s!=0x9841212a)?"| ERROR": "");
856      if (s!=48899) printf( "*** CRC ERROR! ***\n" );  
857  #endif                  TEST_QUANT(dequant_h263_inter, Dst, Src);
858                    printf("%s - dequant_h263_inter %.3f usec       crc32=0x%08x %s\n",
859                               cpu->name, t, s,
860                               (s!=0xe7df8fba)?"| ERROR": "");
861    
862                    printf( " --- \n" );
863            }
864    }
865    
866    /*********************************************************************
867     * test distortion operators
868     *********************************************************************/
869    
870    static void ieee_reseed(long s);
871    static long ieee_rand(int Min, int Max);
872    
873    #define TEST_SSE(FUNCTION, SRC1, SRC2, STRIDE) \
874      do { \
875        t = gettime_usec(); \
876        tst = nb_tests; \
877        while((tst--)>0) sse = (FUNCTION)((SRC1), (SRC2), (STRIDE)); \
878        emms(); \
879        t = (gettime_usec() - t)/(double)nb_tests;  \
880      } while(0)
881    
882    
883    void test_sse()
884    {
885            const int nb_tests = 100000*speed_ref;
886            int i;
887            CPU *cpu;
888            DECLARE_ALIGNED_MATRIX(Src1, 8, 8, int16_t, 16);
889            DECLARE_ALIGNED_MATRIX(Src2, 8, 8, int16_t, 16);
890            DECLARE_ALIGNED_MATRIX(Src3, 8, 8, int16_t, 16);
891            DECLARE_ALIGNED_MATRIX(Src4, 8, 8, int16_t, 16);
892    
893            printf( "\n =====  test sse =====\n" );
894    
895            ieee_reseed(1);
896            for(i=0; i<64; ++i) {
897                    Src1[i] = ieee_rand(-2048, 2047);
898                    Src2[i] = ieee_rand(-2048, 2047);
899                    Src3[i] = ieee_rand(-2048, 2047);
900                    Src4[i] = ieee_rand(-2048, 2047);
901            }
902    
903            for(cpu = cpu_list; cpu->name!=0; ++cpu)
904            {
905                    double t;
906                    int tst, sse;
907    
908                    if (!init_cpu(cpu))
909                            continue;
910    
911                    /* 16 bit element blocks */
912                    TEST_SSE(sse8_16bit, Src1, Src2, 16);
913                    printf("%s -   sse8_16bit#1 %.3f usec       sse=%d %s\n",
914                               cpu->name, t, sse, (sse!=182013834)?"| ERROR": "");
915                    TEST_SSE(sse8_16bit, Src1, Src3, 16);
916                    printf("%s -   sse8_16bit#2 %.3f usec       sse=%d %s\n",
917                               cpu->name, t, sse, (sse!=142545203)?"| ERROR": "");
918                    TEST_SSE(sse8_16bit, Src1, Src4, 16);
919                    printf("%s -   sse8_16bit#3 %.3f usec       sse=%d %s\n",
920                               cpu->name, t, sse, (sse!=146340935)?"| ERROR": "");
921                    TEST_SSE(sse8_16bit, Src2, Src3, 16);
922                    printf("%s -   sse8_16bit#4 %.3f usec       sse=%d %s\n",
923                               cpu->name, t, sse, (sse!=130136661)?"| ERROR": "");
924                    TEST_SSE(sse8_16bit, Src2, Src4, 16);
925                    printf("%s -   sse8_16bit#5 %.3f usec       sse=%d %s\n",
926                               cpu->name, t, sse, (sse!=136870353)?"| ERROR": "");
927                    TEST_SSE(sse8_16bit, Src3, Src4, 16);
928                    printf("%s -   sse8_16bit#6 %.3f usec       sse=%d %s\n",
929                               cpu->name, t, sse, (sse!=164107772)?"| ERROR": "");
930    
931                    /* 8 bit element blocks */
932                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src2, 8);
933                    printf("%s -    sse8_8bit#1 %.3f usec       sse=%d %s\n",
934                               cpu->name, t, sse, (sse!=1356423)?"| ERROR": "");
935                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src3, 8);
936                    printf("%s -    sse8_8bit#2 %.3f usec       sse=%d %s\n",
937                               cpu->name, t, sse, (sse!=1173074)?"| ERROR": "");
938                    TEST_SSE(sse8_8bit, (int8_t*)Src1, (int8_t*)Src4, 8);
939                    printf("%s -    sse8_8bit#3 %.3f usec       sse=%d %s\n",
940                               cpu->name, t, sse, (sse!=1092357)?"| ERROR": "");
941                    TEST_SSE(sse8_8bit, (int8_t*)Src2, (int8_t*)Src3, 8);
942                    printf("%s -    sse8_8bit#4 %.3f usec       sse=%d %s\n",
943                               cpu->name, t, sse, (sse!=1360239)?"| ERROR": "");
944                    TEST_SSE(sse8_8bit, (int8_t*)Src2, (int8_t*)Src4, 8);
945                    printf("%s -    sse8_8bit#5 %.3f usec       sse=%d %s\n",
946                               cpu->name, t, sse, (sse!=1208414)?"| ERROR": "");
947                    TEST_SSE(sse8_8bit, (int8_t*)Src3, (int8_t*)Src4, 8);
948                    printf("%s -    sse8_8bit#6 %.3f usec       sse=%d %s\n",
949                               cpu->name, t, sse, (sse!=1099285)?"| ERROR": "");
950    
951      printf( " --- \n" );      printf( " --- \n" );
952    }    }
953  }  }
# Line 597  Line 956 
956   * test non-zero AC counting   * test non-zero AC counting
957   *********************************************************************/   *********************************************************************/
958    
959  #define TEST_CBP(FUNC, SRC)                   \  #define TEST_CBP(FUNC, SRC, NB)           \
960      t = gettime_usec();                       \      t = gettime_usec();                       \
961      emms();                                   \      emms();                                   \
962      for(tst=0; tst<nb_tests; ++tst) {         \  for(tst=0; tst<NB; ++tst) {         \
963        cbp = (FUNC)((SRC));                    \        cbp = (FUNC)((SRC));                    \
964      }                                         \      }                                         \
965      emms();                                   \      emms();                                   \
# Line 609  Line 968 
968  void test_cbp()  void test_cbp()
969  {  {
970    const int nb_tests = 10000*speed_ref;    const int nb_tests = 10000*speed_ref;
971    int i;          int i, n, m;
972    CPU *cpu;    CPU *cpu;
973    int16_t  Src1[6*64], Src2[6*64], Src3[6*64], Src4[6*64];          DECLARE_ALIGNED_MATRIX(Src1, 6, 64, int16_t, 16);
974            DECLARE_ALIGNED_MATRIX(Src2, 6, 64, int16_t, 16);
975            DECLARE_ALIGNED_MATRIX(Src3, 6, 64, int16_t, 16);
976            DECLARE_ALIGNED_MATRIX(Src4, 6, 64, int16_t, 16);
977      DECLARE_ALIGNED_MATRIX(Src5, 6, 64, int16_t, 16);
978    
979    printf( "\n =====  test cbp =====\n" );    printf( "\n =====  test cbp =====\n" );
980    
981    for(i=0; i<6*64; ++i) {    for(i=0; i<6*64; ++i) {
982      Src1[i] = (i*i*3/8192)&(i/64)&1;  // 'random'                  Src1[i] = (i*i*3/8192)&(i/64)&1;  /* 'random' */
983      Src2[i] = (i<3*64);               // half-full                  Src2[i] = (i<3*64);               /* half-full */
984      Src3[i] = ((i+32)>3*64);      Src3[i] = ((i+32)>3*64);
985      Src4[i] = (i==(3*64+2) || i==(5*64+9));      Src4[i] = (i==(3*64+2) || i==(5*64+9));
986        Src5[i] = ieee_rand(0,1) ? -1 : 1;  /* +/- test */
987    }    }
988    
989    for(cpu = cpu_short_list2; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
990    {    {
991      double t;      double t;
992      int tst, cbp;      int tst, cbp;
# Line 630  Line 994 
994      if (!init_cpu(cpu))      if (!init_cpu(cpu))
995        continue;        continue;
996    
997      TEST_CBP(calc_cbp, Src1);                  TEST_CBP(calc_cbp, Src1, nb_tests);
998      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",
999      if (cbp!=0x15) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x15)?"| ERROR": "");
1000      TEST_CBP(calc_cbp, Src2);                  TEST_CBP(calc_cbp, Src2, nb_tests);
1001      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",
1002      if (cbp!=0x38) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x38)?"| ERROR": "");
1003      TEST_CBP(calc_cbp, Src3);                  TEST_CBP(calc_cbp, Src3, nb_tests);
1004      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",
1005      if (cbp!=0x0f) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x0f)?"| ERROR": "" );
1006      TEST_CBP(calc_cbp, Src4);                  TEST_CBP(calc_cbp, Src4, nb_tests);
1007      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",
1008      if (cbp!=0x05) printf( "*** CRC ERROR! ***\n" );                             cpu->name, t, cbp, (cbp!=0x05)?"| ERROR": "" );
1009                    TEST_CBP(calc_cbp, Src5, nb_tests);
1010                    printf("%s -   calc_cbp#4 %.3f usec       cbp=0x%02x %s\n",
1011                               cpu->name, t, cbp, (cbp!=0x3f)?"| ERROR": "" );
1012      printf( " --- \n" );      printf( " --- \n" );
1013    }    }
1014    
1015            for(cpu = cpu_list; cpu->name!=0; ++cpu)  /* bench suggested by Carlo (carlo dot bramix at libero dot it) */
1016            {
1017                    double t;
1018                    int tst, cbp, err;
1019    
1020                    if (!init_cpu(cpu))
1021                            continue;
1022    
1023        err = 0;
1024        for(n=0; n<6; ++n)
1025        {
1026          for(m=0; m<64; ++m)
1027          {
1028            for(i=0; i<6*64; ++i)
1029              Src1[i] = (i== (m + n*64));
1030    
1031            TEST_CBP(calc_cbp, Src1, 1);
1032            if (cbp!= (((m!=0)<<(5-n))))
1033            {
1034              printf( "%s -   calc_cbp#5: ERROR at pos %d / %d!\n", cpu->name, n, m);
1035              err = 1;
1036              break;
1037            }
1038          }
1039        }
1040        if (!err)
1041          printf( " %s -    calc_cbp#5 : OK\n", cpu->name );
1042    
1043            }
1044  }  }
1045    
1046  /*********************************************************************  /*********************************************************************
# Line 772  Line 1169 
1169    }    }
1170  }  }
1171    
1172  //////////////////////////////////////////////////////////  ///* ////////////////////////////////////////////////////// */
1173  /* Pseudo-random generator specified by IEEE 1180 */  /* Pseudo-random generator specified by IEEE 1180 */
1174    
1175  static long ieee_seed = 1;  static long ieee_seed = 1;
# Line 859  Line 1256 
1256    static const double ILimits[5] = { 1., 0.06, 0.02, 0.015, 0.0015 };    static const double ILimits[5] = { 1., 0.06, 0.02, 0.015, 0.0015 };
1257    int Loops = 10000;    int Loops = 10000;
1258    int i, m, n;    int i, m, n;
1259    short Blk0[64];     // reference          DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, short, 16); /* reference */
1260    short Blk[64], iBlk[64];          DECLARE_ALIGNED_MATRIX(Blk,  8, 8, short, 16);
1261    short Ref_FDCT[64];          DECLARE_ALIGNED_MATRIX(iBlk, 8, 8, short, 16);
1262    short Ref_IDCT[64];          DECLARE_ALIGNED_MATRIX(Ref_FDCT, 8, 8, short, 16);
1263            DECLARE_ALIGNED_MATRIX(Ref_IDCT, 8, 8, short, 16);
1264    
1265    STATS_8x8 FStats; // forward dct stats          STATS_8x8 FStats; /* forward dct stats */
1266    STATS_8x8 IStats; // inverse dct stats          STATS_8x8 IStats; /* inverse dct stats */
1267    
1268    CPU *cpu;    CPU *cpu;
1269    
# Line 888  Line 1286 
1286        for(i=0; i<64; ++i)        for(i=0; i<64; ++i)
1287          Blk0[i] = (short)ieee_rand(Min,Max) * Sign;          Blk0[i] = (short)ieee_rand(Min,Max) * Sign;
1288    
1289          // hmm, I'm not quite sure this is exactly                          /* hmm, I'm not quite sure this is exactly */
1290          // the tests described in the norm. check...                          /* the tests described in the norm. check... */
1291    
1292        memcpy(Ref_FDCT, Blk0, 64*sizeof(short));        memcpy(Ref_FDCT, Blk0, 64*sizeof(short));
1293        ref_fdct(Ref_FDCT);        ref_fdct(Ref_FDCT);
# Line 916  Line 1314 
1314    
1315      printf( "\n  -- FDCT report --\n" );      printf( "\n  -- FDCT report --\n" );
1316  //    print_stats(&FStats);  //    print_stats(&FStats);
1317      report_stats(&FStats, 0); // so far I know, IEEE1180 says nothing for fdct                  report_stats(&FStats, 0); /* so far I know, IEEE1180 says nothing for fdct */
1318    
1319      for(i=0; i<64; i++) Blk[i] = 0;      for(i=0; i<64; i++) Blk[i] = 0;
1320      emms(); fdct(Blk); emms();      emms(); fdct(Blk); emms();
# Line 938  Line 1336 
1336    
1337  void test_dct_saturation(int Min, int Max)  void test_dct_saturation(int Min, int Max)
1338  {  {
1339      // test behaviour on input range fringe  /* test behaviour on input range fringe */
1340    
1341    int i, n, p;    int i, n, p;
1342    CPU *cpu;    CPU *cpu;
1343  //  const short IDCT_MAX =  2047;  // 12bits input  //  const short IDCT_MAX =  2047;  /* 12bits input */
1344  //  const short IDCT_MIN = -2048;  //  const short IDCT_MIN = -2048;
1345  //  const short IDCT_OUT =   256;  // 9bits ouput  //  const short IDCT_OUT =   256;  /* 9bits ouput */
1346    const int Partitions = 4;    const int Partitions = 4;
1347    const int Loops = 10000 / Partitions;    const int Loops = 10000 / Partitions;
1348    
# Line 961  Line 1359 
1359      printf( "\n===== IEEE test for %s Min=%d Max=%d =====\n",      printf( "\n===== IEEE test for %s Min=%d Max=%d =====\n",
1360        cpu->name, Min, Max );        cpu->name, Min, Max );
1361    
1362                // FDCT tests //                  /* FDCT tests // */
1363    
1364      init_stats(&Stats);      init_stats(&Stats);
1365    
1366        // test each computation channels separately                  /* test each computation channels separately */
1367      for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Max : 0;      for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? Max : 0;
1368      ref_fdct(Blk0);      ref_fdct(Blk0);
1369      emms(); fdct(Blk); emms();      emms(); fdct(Blk); emms();
# Line 976  Line 1374 
1374      emms(); fdct(Blk); emms();      emms(); fdct(Blk); emms();
1375      store_stats(&Stats, Blk, Blk0);      store_stats(&Stats, Blk, Blk0);
1376    
1377        // randomly saturated inputs                  /* randomly saturated inputs */
1378      for(p=0; p<Partitions; ++p)      for(p=0; p<Partitions; ++p)
1379      {      {
1380        for(n=0; n<Loops; ++n)        for(n=0; n<Loops; ++n)
# Line 992  Line 1390 
1390      report_stats(&Stats, 0);      report_stats(&Stats, 0);
1391    
1392    
1393                // IDCT tests //                  /* IDCT tests // */
1394  #if 0  #if 0
1395        // no finished yet                  /* no finished yet */
1396    
1397      init_stats(&Stats);      init_stats(&Stats);
1398    
1399      // test each computation channel separately  /* test each computation channel separately */
1400      for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MAX : 0;      for(i=0; i<64; i++) Blk[i] = Blk0[i] = ((i/8)==(i%8)) ? IDCT_MAX : 0;
1401      ref_idct(Blk0);      ref_idct(Blk0);
1402      emms(); idct(Blk); emms();      emms(); idct(Blk); emms();
# Line 1011  Line 1409 
1409      for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }      for(i=0; i<64; i++) { CLAMP(Blk0[i], IDCT_OUT); CLAMP(Blk[i], IDCT_OUT); }
1410      store_stats(&Stats, Blk, Blk0);      store_stats(&Stats, Blk, Blk0);
1411    
1412        // randomly saturated inputs                  /* randomly saturated inputs */
1413      for(p=0; p<Partitions; ++p)      for(p=0; p<Partitions; ++p)
1414      {      {
1415        for(n=0; n<Loops; ++n)        for(n=0; n<Loops; ++n)
# Line 1036  Line 1434 
1434   * measure raw decoding speed   * measure raw decoding speed
1435   *********************************************************************/   *********************************************************************/
1436    
1437  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)
1438  {  {
1439    FILE *f = 0;    FILE *f = 0;
1440    void *dechandle = 0;    void *dechandle = 0;
1441    int xerr;    int xerr;
1442          XVID_INIT_PARAM xinit;          xvid_gbl_init_t xinit;
1443          XVID_DEC_PARAM xparam;          xvid_dec_create_t xparam;
1444          XVID_DEC_FRAME xframe;          xvid_dec_frame_t xframe;
1445          double t = 0.;          double t = 0.;
1446          int nb = 0;          int nb = 0;
1447    uint8_t *buf = 0;    uint8_t *buf = 0;
1448    uint8_t *rgb_out = 0;          uint8_t *yuv_out = 0;
1449    int buf_size, pos;    int buf_size, pos;
1450    uint32_t chksum = 0;    uint32_t chksum = 0;
1451            int bps = (width+31) & ~31;
1452    
1453          xinit.cpu_flags = XVID_CPU_MMX | XVID_CPU_FORCE;          memset(&xinit, 0, sizeof(xinit));
1454          xvid_init(NULL, 0, &xinit, NULL);          xinit.cpu_flags = cpu_mask;
1455          printf( "API version: %d, core build:%d\n", xinit.api_version, xinit.core_build);          xinit.version = XVID_VERSION;
1456            xvid_global(NULL, 0, &xinit, NULL);
1457    
1458            memset(&xparam, 0, sizeof(xparam));
1459          xparam.width = width;          xparam.width = width;
1460          xparam.height = height;          xparam.height = height;
1461            xparam.version = XVID_VERSION;
1462          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);          xerr = xvid_decore(NULL, XVID_DEC_CREATE, &xparam, NULL);
1463          if (xerr!=XVID_ERR_OK) {          if (xerr==XVID_ERR_FAIL) {
1464            printf("can't init decoder (err=%d)\n", xerr);                  printf("ERROR: can't init decoder (err=%d)\n", xerr);
1465            return;            return;
1466          }          }
1467          dechandle = xparam.handle;          dechandle = xparam.handle;
# Line 1068  Line 1469 
1469    
1470          f = fopen(name, "rb");          f = fopen(name, "rb");
1471    if (f==0) {    if (f==0) {
1472      printf( "can't open file '%s'\n", name);                  printf( "ERROR: can't open file '%s'\n", name);
1473      return;      return;
1474    }    }
1475    fseek(f, 0, SEEK_END);    fseek(f, 0, SEEK_END);
1476    buf_size = ftell(f);    buf_size = ftell(f);
1477    fseek(f, 0, SEEK_SET);    fseek(f, 0, SEEK_SET);
1478    if (buf_size<=0) {    if (buf_size<=0) {
1479      printf("error while stating file\n");                  printf("ERROR: error while stating file\n");
1480      goto End;      goto End;
1481    }    }
   else printf( "Input size: %d\n", buf_size);  
1482    
1483    buf = malloc(buf_size); // should be enuf'          buf = malloc(buf_size);
1484    rgb_out = calloc(4, width*height);  // <-room for _RGB24          yuv_out = calloc(1, bps*height*3/2 + 15);
1485    if (buf==0 || rgb_out==0) {          if (buf==0 || yuv_out==0) {
1486      printf( "malloc failed!\n" );                  printf( "ERROR: malloc failed!\n" );
1487      goto End;      goto End;
1488    }    }
1489    
1490    if (fread(buf, buf_size, 1, f)!=1) {    if (fread(buf, buf_size, 1, f)!=1) {
1491      printf( "file-read failed\n" );                  printf( "ERROR: file-read failed\n" );
1492      goto End;      goto End;
1493    }    }
1494    
# Line 1096  Line 1496 
1496    pos = 0;    pos = 0;
1497    t = -gettime_usec();    t = -gettime_usec();
1498    while(1) {    while(1) {
1499              int y;
1500    
1501                    memset(&xframe, 0, sizeof(xframe));
1502                    xframe.version = XVID_VERSION;
1503      xframe.bitstream = buf + pos;      xframe.bitstream = buf + pos;
1504      xframe.length = buf_size - pos;      xframe.length = buf_size - pos;
1505      xframe.image = rgb_out;                  xframe.output.plane[0] = (uint8_t*)(((size_t)yuv_out + 15) & ~15);
1506      xframe.stride = width;                  xframe.output.plane[1] = (uint8_t*)xframe.output.plane[0] + bps*height;
1507      xframe.colorspace = XVID_CSP_RGB24;                  xframe.output.plane[2] = (uint8_t*)xframe.output.plane[1] + bps/2;
1508                    xframe.output.stride[0] = bps;
1509                    xframe.output.stride[1] = bps;
1510                    xframe.output.stride[2] = bps;
1511                    xframe.output.csp = XVID_CSP_I420;
1512      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);      xerr = xvid_decore(dechandle, XVID_DEC_DECODE, &xframe, 0);
1513                    if (xerr<0) {
1514                            printf("ERROR: decoding failed for frame #%d (err=%d)!\n", nb, xerr);
1515                            break;
1516                    }
1517                    else if (xerr==0)
1518                      break;
1519        else if (verbose>0) printf("#%d %d\n", nb, xerr );
1520    
1521                    pos += xerr;
1522      nb++;      nb++;
1523      pos += xframe.length;  
1524      if (with_chksum) {      for(y=0; y<height/2; ++y) {
1525        int k = width*height;                    chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+0)*bps, width, chksum);
1526        uint32_t *ptr = (uint32_t *)rgb_out;                          chksum = calc_crc((uint8_t*)xframe.output.plane[0] + (2*y+1)*bps, width, chksum);
1527        while(k-->0) chksum += *ptr++;                          chksum = calc_crc((uint8_t*)xframe.output.plane[1] + y*bps, width/2, chksum);
1528                            chksum = calc_crc((uint8_t*)xframe.output.plane[2] + y*bps, width/2, chksum);
1529      }      }
1530      if (pos==buf_size)      if (pos==buf_size)
1531        break;        break;
     if (xerr!=XVID_ERR_OK) {  
           printf("decoding failed for frame #%d (err=%d)!\n", nb, xerr);  
           break;  
         }  
1532    }    }
1533    t += gettime_usec();    t += gettime_usec();
1534            if (ref_chksum==0) {
1535    if (t>0.)    if (t>0.)
1536      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 );
1537    if (with_chksum)    }
1538      printf("checksum: 0x%.8x\n", chksum);    else {
1539                    printf("FPS:%.1f Checksum: 0x%.8x Expected:0x%.8x | %s\n",
1540                      t>0. ? (float)(nb*1.e6f/t) : 0.f, chksum, ref_chksum, (chksum==ref_chksum) ? "OK" : "ERROR");
1541      }
1542    
1543  End:  End:
1544    if (rgb_out!=0) free(rgb_out);          if (yuv_out!=0) free(yuv_out);
1545    if (buf!=0) free(buf);    if (buf!=0) free(buf);
1546    if (dechandle!=0) {    if (dechandle!=0) {
1547      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);      xerr= xvid_decore(dechandle, XVID_DEC_DESTROY, NULL, NULL);
1548      if (xerr!=XVID_ERR_OK)                  if (xerr==XVID_ERR_FAIL)
1549              printf("destroy-decoder failed (err=%d)!\n", xerr);                          printf("ERROR: destroy-decoder failed (err=%d)!\n", xerr);
1550    }    }
1551    if (f!=0) fclose(f);    if (f!=0) fclose(f);
1552  }  }
# Line 1140  Line 1558 
1558  void test_bugs1()  void test_bugs1()
1559  {  {
1560    CPU *cpu;    CPU *cpu;
1561            uint16_t mpeg_quant_matrices[64*8];
1562    
1563    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );    printf( "\n =====  (de)quant4_intra saturation bug? =====\n" );
1564    
1565    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1566    {    {
1567      int i;      int i;
1568      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 1152  Line 1571 
1571        continue;        continue;
1572    
1573      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1574      set_intra_matrix( get_default_intra_matrix() );                  set_intra_matrix( mpeg_quant_matrices, get_default_intra_matrix() );
1575      dequant4_intra(Dst, Src, 31, 5);                  dequant_mpeg_intra(Dst, Src, 31, 5, mpeg_quant_matrices);
1576      printf( "dequant4_intra with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_intra with CPU=%s:  ", cpu->name);
1577      printf( "  Out[]= " );      printf( "  Out[]= " );
1578      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1579      printf( "\n" );      printf( "\n" );
# Line 1162  Line 1581 
1581    
1582    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );    printf( "\n =====  (de)quant4_inter saturation bug? =====\n" );
1583    
1584    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1585    {    {
1586      int i;      int i;
1587      int16_t  Src[8*8], Dst[8*8];      int16_t  Src[8*8], Dst[8*8];
# Line 1171  Line 1590 
1590        continue;        continue;
1591    
1592      for(i=0; i<64; ++i) Src[i] = i-32;      for(i=0; i<64; ++i) Src[i] = i-32;
1593      set_inter_matrix( get_default_inter_matrix() );                  set_inter_matrix( mpeg_quant_matrices, get_default_inter_matrix() );
1594      dequant4_inter(Dst, Src, 31);                  dequant_mpeg_inter(Dst, Src, 31, mpeg_quant_matrices);
1595      printf( "dequant4_inter with CPU=%s:  ", cpu->name);                  printf( "dequant_mpeg_inter with CPU=%s:  ", cpu->name);
1596      printf( "  Out[]= " );      printf( "  Out[]= " );
1597      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);      for(i=0; i<64; ++i) printf( "[%d]", Dst[i]);
1598      printf( "\n" );      printf( "\n" );
# Line 1183  Line 1602 
1602  void test_dct_precision_diffs()  void test_dct_precision_diffs()
1603  {  {
1604    CPU *cpu;    CPU *cpu;
1605    short Blk[8*8], Blk0[8*8];          DECLARE_ALIGNED_MATRIX(Blk, 8, 8, int16_t, 16);
1606            DECLARE_ALIGNED_MATRIX(Blk0, 8, 8, int16_t, 16);
1607    
1608    printf( "\n =====  fdct/idct precision diffs =====\n" );    printf( "\n =====  fdct/idct precision diffs =====\n" );
1609    
1610    for(cpu = cpu_short_list; cpu->name!=0; ++cpu)          for(cpu = cpu_list; cpu->name!=0; ++cpu)
1611    {    {
1612      int i;      int i;
1613    
# Line 1216  Line 1636 
1636    const int max_Q = 31;    const int max_Q = 31;
1637    int i, n, qm, q;    int i, n, qm, q;
1638    CPU *cpu;    CPU *cpu;
1639    int16_t  Src[8*8], Dst[8*8];          DECLARE_ALIGNED_MATRIX(Src, 8, 8, int16_t, 16);
1640            DECLARE_ALIGNED_MATRIX(Dst, 8, 8, int16_t, 16);
1641    uint8_t Quant[8*8];    uint8_t Quant[8*8];
1642    CPU cpu_bug_list[] = { { "PLAINC", 0 }, { "MMX   ", XVID_CPU_MMX }, {0,0} };    CPU cpu_bug_list[] = { { "PLAINC", 0 }, { "MMX   ", XVID_CPU_MMX }, {0,0} };
1643    uint16_t Crcs_Inter[2][32];    uint16_t Crcs_Inter[2][32];
1644    uint16_t Crcs_Intra[2][32];    uint16_t Crcs_Intra[2][32];
1645            DECLARE_ALIGNED_MATRIX(mpeg_quant_matrices, 8, 64, uint16_t, 16);
1646    
1647    printf( "\n =====  test MPEG4-quantize bug =====\n" );    printf( "\n =====  test MPEG4-quantize bug =====\n" );
1648    
1649    for(i=0; i<64; ++i) Src[i] = 2048*(i-32)/32;    for(i=0; i<64; ++i) Src[i] = 2048*(i-32)/32;
# Line 1229  Line 1652 
1652    for(qm=1; qm<=255; ++qm)    for(qm=1; qm<=255; ++qm)
1653    {    {
1654      for(i=0; i<8*8; ++i) Quant[i] = qm;      for(i=0; i<8*8; ++i) Quant[i] = qm;
1655      set_inter_matrix( Quant );                  set_inter_matrix( mpeg_quant_matrices, Quant );
1656    
1657      for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)      for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1658      {      {
# Line 1240  Line 1663 
1663    
1664        for(q=1; q<=max_Q; ++q) {        for(q=1; q<=max_Q; ++q) {
1665          emms();          emms();
1666          quant4_inter( Dst, Src, q );                                  quant_mpeg_inter( Dst, Src, q, mpeg_quant_matrices );
1667          emms();          emms();
1668          for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;          for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1669          Crcs_Inter[n][q] = s;          Crcs_Inter[n][q] = s;
# Line 1259  Line 1682 
1682    for(qm=1; qm<=255; ++qm)    for(qm=1; qm<=255; ++qm)
1683    {    {
1684      for(i=0; i<8*8; ++i) Quant[i] = qm;      for(i=0; i<8*8; ++i) Quant[i] = qm;
1685      set_intra_matrix( Quant );                  set_intra_matrix( mpeg_quant_matrices, Quant );
1686    
1687      for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)      for(n=0, cpu = cpu_bug_list; cpu->name!=0; ++cpu, ++n)
1688      {      {
# Line 1270  Line 1693 
1693    
1694        for(q=1; q<=max_Q; ++q) {        for(q=1; q<=max_Q; ++q) {
1695          emms();          emms();
1696          quant4_intra( Dst, Src, q, q);                                  quant_mpeg_intra( Dst, Src, q, q, mpeg_quant_matrices);
1697          emms();          emms();
1698          for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;          for(s=0, i=0; i<64; ++i) s+=((uint16_t)Dst[i])^i;
1699          Crcs_Intra[n][q] = s;          Crcs_Intra[n][q] = s;
# Line 1287  Line 1710 
1710  }  }
1711    
1712  /*********************************************************************  /*********************************************************************
1713     * test some YUV func
1714     *********************************************************************/
1715    
1716    #define ENTER \
1717    for(i=0; i<(int)sizeof(Dst0); ++i) Dst0[0][i] = 0;   \
1718    t = gettime_usec();                   \
1719    emms();
1720    
1721    #define LEAVE \
1722    emms();                             \
1723    t = (gettime_usec() - t) / nb_tests;  \
1724            iCrc = calc_crc((uint8_t*)Dst0, sizeof(Dst0), CRC32_INITIAL)
1725    
1726    #define TEST_YUYV(FUNC, S)                \
1727    ENTER                               \
1728    for(tst=0; tst<nb_tests; ++tst) (FUNC)(Dst0[0], S*WIDTH, Src0[0], Src0[1], Src0[2], WIDTH, WIDTH/2, WIDTH, HEIGHT, 0); \
1729    LEAVE
1730    
1731    #define WIDTH 128
1732    #define HEIGHT 32
1733    void test_yuv()
1734    {
1735            const int nb_tests = 200*speed_ref;
1736            CPU *cpu;
1737            uint8_t Src0[3][WIDTH*HEIGHT];
1738            uint8_t Dst0[4][WIDTH*HEIGHT];
1739            int i, j;
1740            double t;
1741            int tst, iCrc;
1742    
1743            colorspace_init();
1744            ieee_reseed(1);
1745            for(i=0; i<(int)sizeof(Src0); ++i) Src0[0][i] = ieee_rand(0,255);
1746            for(i=0; i<(int)sizeof(Dst0); ++i) Dst0[0][i] = 0x5a;
1747    
1748            printf( "\n ===  test YUV ===\n" );
1749    
1750            init_cpu(&cpu_list[0]);
1751            TEST_YUYV(yv12_to_yuyv_c, 4);
1752            printf(" yv12_to_yuyv_c %.3f usec       crc32=0x%08x %s\n",
1753                       t, iCrc, (iCrc!=0xeb1a0b0a)?"| ERROR": "" );
1754            TEST_YUYV(yv12_to_uyvy_c, 4);
1755            printf(" yv12_to_uyvy_c %.3f usec       crc32=0x%08x %s\n",
1756                       t, iCrc, (iCrc!=0x6e82f55b)?"| ERROR": "" );
1757    
1758    #ifdef ARCH_IS_IA32
1759            init_cpu(&cpu_list[1]);
1760            TEST_YUYV(yv12_to_yuyv_mmx, 4);
1761            printf(" yv12_to_yuyv_mmx %.3f usec       crc32=0x%08x %s\n",
1762                    t, iCrc, (iCrc!=0xeb1a0b0a)?"| ERROR": "" );
1763    
1764            TEST_YUYV(yv12_to_uyvy_mmx, 4);
1765            printf(" yv12_to_uyvy_mmx %.3f usec       crc32=0x%08x %s\n",
1766                    t, iCrc, (iCrc!=0x6e82f55b)?"| ERROR": "" );
1767    #endif
1768    
1769    #ifdef ARCH_IS_PPC
1770            init_cpu(&cpu_list[1]);
1771            TEST_YUYV(yv12_to_yuyv_altivec_c, 4);
1772            printf(" yv12_to_yuyv_altivec_c %.3f usec       crc32=0x%08x %s\n",
1773                    t, iCrc, (iCrc!=0xeb1a0b0a)?"| ERROR": "" );
1774    
1775            TEST_YUYV(yv12_to_uyvy_altivec_c, 4);
1776            printf(" yv12_to_uyvy_altivec_c %.3f usec       crc32=0x%08x %s\n",
1777                    t, iCrc, (iCrc!=0x6e82f55b)?"| ERROR": "" );
1778    #endif
1779            printf( " --- \n" );
1780    }
1781    
1782    #define TEST_YV2(FUNC, WITH_UV, WITH_FLIP)        \
1783    ENTER                               \
1784    for(tst=0; tst<nb_tests; ++tst) (FUNC)(Dst0[0], Dst0[1], Dst0[2], WIDTH, WIDTH, \
1785            Src0[0], (WITH_UV) ? Src0[1] : 0, (WITH_UV) ? Src0[2] : 0,  WIDTH, WIDTH, \
1786            WIDTH-2, HEIGHT-2, WITH_FLIP); \
1787    LEAVE
1788    
1789    #define PRINT_NxN(DATA,W,H,STR)   {   \
1790            int i,j; \
1791            for(j=0; j<(H); ++j) { \
1792                    for(i=0; i<(W); ++i) printf( "0x%.2x ", (DATA)[i+j*(STR)] );\
1793                    printf("\n"); \
1794            } \
1795            printf("---\n"); \
1796    }
1797    
1798    static const int yv12_CRCs[2][2] = {
1799            {0x5cab7cf0,0xdab46541}
1800    ,       {0xe8bae865,0x1faf77b7}
1801    };
1802    
1803    void test_yuv2()
1804    {
1805            const int nb_tests = 800*speed_ref;
1806            CPU *cpu;
1807            uint8_t Src0[3][WIDTH*HEIGHT];
1808            uint8_t Dst0[3][WIDTH*HEIGHT];
1809            int with_uv, with_flip;
1810            int i, j;
1811            double t;
1812            int tst, iCrc;
1813    
1814            colorspace_init();
1815            ieee_reseed(1);
1816            for(i=0; i<(int)sizeof(Src0); ++i) Src0[0][i] = ieee_rand(0,255);
1817    
1818            printf( "\n ===  test YV2 ===\n" );
1819            for(with_flip=0; with_flip<=1; ++with_flip) {
1820                    for(with_uv=0; with_uv<=1; ++with_uv) {
1821                            init_cpu(&cpu_list[0]);
1822                            TEST_YV2(yv12_to_yv12_c, with_uv, with_flip);
1823                            printf(" yv12_to_yv12_c   %.3f usec      \tcrc32=0x%08x %s\n",
1824                                    t, iCrc, (iCrc!=yv12_CRCs[with_flip][with_uv])?"| ERROR": "" );
1825                            /* if (!with_uv) PRINT_NxN(Dst0[1], WIDTH/2, HEIGHT/2, WIDTH ); */
1826    
1827    #ifdef ARCH_IS_IA32
1828                            init_cpu(&cpu_list[1]);
1829                            TEST_YV2(yv12_to_yv12_mmx, with_uv, with_flip);
1830                            printf(" yv12_to_yv12_mmx %.3f usec     \tcrc32=0x%08x %s\n",
1831                                    t, iCrc, (iCrc!=yv12_CRCs[with_flip][with_uv])?"| ERROR": "" );
1832                            /* if (!with_uv) PRINT_NxN(Dst0[1], WIDTH/2, HEIGHT/2, WIDTH ); */
1833    
1834                            TEST_YV2(yv12_to_yv12_xmm, with_uv, with_flip);
1835                            printf(" yv12_to_yv12_xmm %.3f usec     \tcrc32=0x%08x %s\n",
1836                                    t, iCrc, (iCrc!=yv12_CRCs[with_flip][with_uv])?"| ERROR": "" );
1837    #endif
1838                    }
1839    
1840                    printf( " --- \n" );
1841            }
1842            printf( " ===== \n" );
1843    }
1844    
1845    #undef WIDTH
1846    #undef HEIGHT
1847    #undef ENTER
1848    #undef LEAVE
1849    
1850    /*********************************************************************/
1851    
1852    static uint32_t __inline log2bin_v1(uint32_t value)
1853    {
1854      int n = 0;
1855      while (value) {
1856        value >>= 1;
1857        n++;
1858      }
1859      return n;
1860    }
1861    
1862    static const uint8_t log2_tab_16[16] =  { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
1863    
1864    static uint32_t __inline log2bin_v2(uint32_t value)
1865    {
1866      int n = 0;
1867      if (value & 0xffff0000) {
1868        value >>= 16;
1869        n += 16;
1870      }
1871      if (value & 0xff00) {
1872        value >>= 8;
1873        n += 8;
1874      }
1875      if (value & 0xf0) {
1876        value >>= 4;
1877        n += 4;
1878      }
1879     return n + log2_tab_16[value];
1880    }
1881    
1882    void test_log2bin()
1883    {
1884            const int nb_tests = 3000*speed_ref;
1885      int n, crc1=0, crc2=0;
1886      uint32_t s, s0;
1887      double t1, t2;
1888    
1889      t1 = gettime_usec();
1890      s0 = (int)(t1*31.241);
1891      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1892        crc1 += log2bin_v1(s);
1893      t1 = (gettime_usec()-t1) / nb_tests;
1894    
1895      t2 = gettime_usec();
1896      for(s=s0, n=0; n<nb_tests; ++n, s=(s*12363+31)&0x7fffffff)
1897        crc2 += log2bin_v2(s);
1898      t2 = (gettime_usec() - t2) / nb_tests;
1899    
1900      printf( "log2bin_v1: %.3f sec  crc=%d\n", t1, crc1 );
1901      printf( "log2bin_v2: %.3f sec  crc=%d\n", t2, crc2 );
1902      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1903    }
1904    
1905    /*********************************************************************/
1906    
1907    static void __inline old_gcd(int *num, int *den)
1908    {
1909     int i = *num;
1910      while (i > 1) {
1911        if (*num % i == 0 && *den % i == 0) {
1912          *num /= i;
1913          *den /= i;
1914          i = *num;
1915          continue;
1916        }
1917        i--;
1918      }
1919    }
1920    
1921    static uint32_t gcd(int num, int den)
1922    {
1923      int tmp;
1924      while( (tmp=num%den) ) { num = den; den = tmp; }
1925      return den;
1926    }
1927    static void __inline new_gcd(int *num, int *den)
1928    {
1929      const int div = gcd(*num, *den);
1930      if (num) {
1931        *num /= div;
1932        *den /= div;
1933      }
1934    }
1935    
1936    void test_gcd()
1937    {
1938      const int nb_tests = 10*speed_ref;
1939      int i;
1940      uint32_t crc1=0, crc2=0;
1941      uint32_t n0, n, d0, d;
1942      double t1, t2;
1943    
1944      t1 = gettime_usec();
1945      n0 = 0xfffff & (int)(t1*31.241);
1946      d0 = 0xfffff & (int)( ((n0*4123)%17) | 1 );
1947      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1948        old_gcd(&n, &d);
1949        crc1 = (((crc1>>4)^d) + ((crc1<<2)^n) ) & 0xffffff;
1950        n = d;
1951        d = (d*12363+31) & 0xffff;
1952        d |= !d;
1953      }
1954      t1 = (gettime_usec()-t1) / nb_tests;
1955    
1956      t2 = gettime_usec();
1957      for(n=n0, d=d0, i=0; i<nb_tests; ++i) {
1958        new_gcd(&n, &d);
1959        crc2 = (((crc2>>4)^d) + ((crc2<<2)^n) ) & 0xffffff;
1960        n = d;
1961        d = (d*12363+31) & 0xffff;
1962        d |= !d;
1963      }
1964      t2 = (gettime_usec() - t2) / nb_tests;
1965    
1966      printf( "old_gcd: %.3f sec  crc=%d\n", t1, crc1 );
1967      printf( "new_gcd: %.3f sec  crc=%d\n", t2, crc2 );
1968      if (crc1!=crc2) printf( " CRC ERROR !\n" );
1969    }
1970    
1971    /*********************************************************************
1972     * test compiler
1973     *********************************************************************/
1974    
1975    void test_compiler() {
1976      int nb_err = 0;
1977      int32_t v;
1978      if (sizeof(uint16_t)<2) {
1979        printf( "ERROR: sizeof(uint16_t)<2 !!\n" );
1980        nb_err++;
1981      }
1982      if (sizeof(int16_t)<2) {
1983        printf( "ERROR: sizeof(int16_t)<2 !!\n" );
1984        nb_err++;
1985      }
1986      if (sizeof(uint8_t)!=1) {
1987        printf( "ERROR: sizeof(uint8_t)!=1 !!\n" );
1988        nb_err++;
1989      }
1990      if (sizeof(int8_t)!=1) {
1991        printf( "ERROR: sizeof(int8_t)!=1 !!\n" );
1992        nb_err++;
1993      }
1994      if (sizeof(uint32_t)<4) {
1995        printf( "ERROR: sizeof(uint32_t)<4 !!\n" );
1996        nb_err++;
1997      }
1998      if (sizeof(int32_t)<4) {
1999        printf( "ERROR: sizeof(int32_t)<4 !!\n" );
2000        nb_err++;
2001      }
2002             /* yes, i know, this test is silly. But better be safe than sorry. :) */
2003      for(v=1000; v>=0; v--) {
2004        if ( (v>>2) != v/4)
2005          nb_err++;
2006      }
2007      for(v=-1000; v!=-1; v++) {
2008        if ( (v>>2) != (v/4)-!!(v%4))
2009          nb_err++;
2010      }
2011      if (nb_err!=0) {
2012        printf( "ERROR! please post your platform/compiler specs to xvid-devel@xvid.org !\n" );
2013      }
2014    }
2015    
2016    /*********************************************************************
2017     * test SSIM functions
2018     *********************************************************************/
2019    
2020    typedef int (*lumfunc)(uint8_t* ptr, int stride);
2021    typedef void (*csfunc)(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr);
2022    
2023    extern int lum_8x8_c(uint8_t* ptr, int stride);
2024    extern int lum_8x8_mmx(uint8_t* ptr, int stride);
2025    extern int lum_2x8_c(uint8_t* ptr, int stride);
2026    extern void consim_c(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr);
2027    extern void consim_mmx(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr);
2028    extern void consim_sse2(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr);
2029    
2030    void test_SSIM()
2031    {
2032            const int nb_tests = 3000*speed_ref;
2033            int tst;
2034            CPU *cpu;
2035            int i;
2036            int devs[3];
2037            long lumo, lumc;
2038            DECLARE_ALIGNED_MATRIX(Ref1, 16, 16, uint8_t, 16);
2039            DECLARE_ALIGNED_MATRIX(Ref2, 16, 16, uint8_t, 16);
2040            lumfunc lum8x8;
2041            lumfunc lum2x8;
2042            csfunc  csim;
2043    
2044            ieee_reseed(1);
2045            printf( "\n ======  test SSIM ======\n" );
2046            for(i=0; i<16*16;++i) {
2047                    long v1, v2;
2048                    v1 = ieee_rand(-256, 511);
2049                    v2 = ieee_rand(-256, 511);
2050                    Ref1[i] = (v1<0) ? 0 : (v1>255) ? 255 : v1;
2051                    Ref2[i] = (v2<0) ? 0 : (v2>255) ? 255 : v2;
2052            }
2053            lumc = ieee_rand(0, 255);
2054            lumo = ieee_rand(0, 255);
2055    
2056            for(cpu = cpu_list; cpu->name!=0; ++cpu)
2057            {
2058                    double t;
2059                    int m;
2060                    if (!init_cpu(cpu))
2061                            continue;
2062                    lum8x8 = lum_8x8_c;
2063                    lum2x8 = lum_2x8_c;
2064                    csim   = consim_c;
2065    #ifdef ARCH_IS_IA32
2066                    if (cpu->cpu & XVID_CPU_MMX){
2067                            lum8x8 = lum_8x8_mmx;
2068                            csim = consim_mmx;
2069                    }
2070                    if (cpu->cpu & XVID_CPU_MMX){
2071                            csim = consim_sse2;
2072                    }
2073    #endif
2074                    t = gettime_usec();
2075                    emms();
2076                    for(tst=0; tst<nb_tests; ++tst) m = lum8x8(Ref1, 16);
2077                    emms();
2078                    t = (gettime_usec() - t) / nb_tests;
2079                    printf("%s - ssim-lum8x8    %.3f usec       m=%d %s\n",
2080                               cpu->name, t, m,
2081                               (m!=8230)?"| ERROR": "" );
2082    
2083                    t = gettime_usec();
2084                    emms();
2085                    for(tst=0; tst<nb_tests; ++tst) m = lum2x8(Ref1+8, 16);
2086                    emms();
2087                    t = (gettime_usec() - t) / nb_tests;
2088                    printf("%s - ssim-lum2x8    %.3f usec       m=%d %s\n",
2089                               cpu->name, t, m,
2090                               (m!=681)?"| ERROR": "" );
2091    
2092                    t = gettime_usec();
2093                    emms();
2094                    for(tst=0; tst<nb_tests; ++tst) csim(Ref1, Ref2, 16, lumo, lumc, devs+0, devs+1, devs+2);
2095                    emms();
2096                    t = (gettime_usec() - t) / nb_tests;
2097                    printf("%s - ssim-consim    %.3f usec       devs=[0x%x 0x%x 0x%x] %s\n",
2098                               cpu->name, t, devs[0], devs[1], devs[2],
2099                               (devs[0]!=0x1bdf0f || devs[1]!=0x137258 ||  devs[2]!=0xcdb13)?"| ERROR": "" );
2100                    printf( " --- \n" );
2101            }
2102    }
2103    
2104    /*********************************************************************
2105     * test bitstream functions
2106     *********************************************************************/
2107    
2108    #define BIT_BUF_SIZE 2000
2109    
2110    static void test_bits()
2111    {
2112      const int nb_tests = 50*speed_ref;
2113      int tst;
2114      uint32_t Crc;
2115      uint8_t Buf[BIT_BUF_SIZE];
2116      uint32_t Extracted[BIT_BUF_SIZE*8]; /* worst case: bits read 1 by 1 */
2117      int Lens[BIT_BUF_SIZE*8];
2118      double t1;
2119    
2120    
2121      printf( "\n ===  test bitstream ===\n" );
2122      ieee_reseed(1);
2123      Crc = 0;
2124    
2125      t1 = gettime_usec();
2126      for(tst=0; tst<nb_tests; ++tst) {
2127            Bitstream bs;
2128            int m, m2, l, l2;
2129    
2130            for(l=0; l<BIT_BUF_SIZE; ++l)
2131                    Buf[l] = (uint8_t)ieee_rand(0,255);
2132    
2133            l = BIT_BUF_SIZE - ieee_rand(1,BIT_BUF_SIZE/10);
2134            BitstreamInit(&bs, (void*)(Buf+BIT_BUF_SIZE-l), l);
2135    
2136    
2137            BitstreamReset(&bs);
2138            for(l2=l*8, m=0; l2>0; m++) {
2139                    const int b = ieee_rand(1,32);
2140                    Lens[m] = b;
2141                    l2 -= b;
2142                    if (l2<0) break;
2143                    Extracted[m] = BitstreamShowBits(&bs, b);
2144                    BitstreamSkip(&bs, b);
2145    //              printf( "<= %d: %d 0x%x\n", m, b, Extracted[m]);
2146            }
2147    
2148            BitstreamReset(&bs);
2149            for(m2=0; m2<m; ++m2) {
2150                    const int b = Lens[m2];
2151                    const uint32_t v = BitstreamGetBits(&bs, b);
2152                    Crc |= (v!=Extracted[m2]);
2153    //              printf( "=> %d: %d 0x%x %c\n", m2, b, v, " *"[Crc]);
2154            }
2155      }
2156      t1 = (gettime_usec() - t1) / nb_tests;
2157      printf(" test_bits   %.3f usec   %s\n", t1, (Crc!=0)?"| ERROR": "" );
2158    }
2159    
2160    /*********************************************************************
2161   * main   * main
2162   *********************************************************************/   *********************************************************************/
2163    
2164  int main(int argc, char *argv[])  static void arg_missing(const char *opt)
2165  {  {
2166    int what = 0;    printf( "missing argument after option '%s'\n", opt);
2167    if (argc>1) what = atoi(argv[1]);    exit(-1);
2168    }
2169    
2170    int main(int argc, const char *argv[])
2171    {
2172            int c, what = 0;
2173            int width, height;
2174            uint32_t chksum = 0;
2175            const char * test_bitstream = 0;
2176    
2177            cpu_mask = 0;  // default => will use autodectect
2178            for(c=1; c<argc; ++c)
2179            {
2180              if (!strcmp(argv[c], "-v")) verbose++;
2181              else if (!strcmp(argv[c], "-c"))      cpu_mask = 0 /* PLAIN_C */ | XVID_CPU_FORCE;
2182              else if (!strcmp(argv[c], "-mmx"))    cpu_mask = XVID_CPU_MMX    | XVID_CPU_FORCE;
2183              else if (!strcmp(argv[c], "-mmxext")) cpu_mask = XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
2184              else if (!strcmp(argv[c], "-sse2"))   cpu_mask = XVID_CPU_SSE2   | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
2185              else if (!strcmp(argv[c], "-sse3"))   cpu_mask = XVID_CPU_SSE3   | XVID_CPU_SSE2 | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
2186              else if (!strcmp(argv[c], "-sse4"))   cpu_mask = XVID_CPU_SSE41  | XVID_CPU_SSE3 | XVID_CPU_SSE2 | XVID_CPU_MMXEXT | XVID_CPU_MMX | XVID_CPU_FORCE;
2187          else if (!strcmp(argv[c], "-3dnow"))  cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_FORCE;
2188              else if (!strcmp(argv[c], "-3dnowe")) cpu_mask = XVID_CPU_3DNOW  | XVID_CPU_3DNOWEXT | XVID_CPU_FORCE;
2189              else if (!strcmp(argv[c], "-altivec")) cpu_mask = XVID_CPU_ALTIVEC | XVID_CPU_FORCE;
2190              else if (!strcmp(argv[c], "-spd")) {
2191          if (++c==argc) arg_missing( argv[argc-1] );
2192          speed_ref = atoi(argv[c]);
2193        }
2194              else if (argv[c][0]!='-') {
2195                what = atoi(argv[c]);
2196                if (what==9) {
2197                  if (c+4>argc) {
2198                    printf("usage: %s %d bitstream width height (checksum)\n", argv[0], what);
2199                    exit(-1);
2200            }
2201            test_bitstream = argv[++c];
2202                  width  = atoi(argv[++c]);
2203                  height = atoi(argv[++c]);
2204                  if (c+1<argc && argv[c+1][0]!='-') {
2205                    if (sscanf(argv[c+1], "0x%x", &chksum)!=1) {
2206                      printf( "can't read checksum value.\n" );
2207                      exit(-1);
2208              }
2209              else c++;
2210            }
2211    //        printf( "[%s] %dx%d (0x%.8x)\n", test_bitstream, width, height, chksum);
2212          }
2213        }
2214        else {
2215          printf( "unrecognized option '%s'\n", argv[c]);
2216          exit(-1);
2217        }
2218      }
2219    
2220    
2221    if (what==0 || what==1) test_dct();    if (what==0 || what==1) test_dct();
2222    if (what==0 || what==2) test_mb();    if (what==0 || what==2) test_mb();
2223    if (what==0 || what==3) test_sad();    if (what==0 || what==3) test_sad();
2224    if (what==0 || what==4) test_transfer();    if (what==0 || what==4) test_transfer();
2225    if (what==0 || what==5) test_quant();    if (what==0 || what==5) test_quant();
2226    if (what==0 || what==6) test_cbp();    if (what==0 || what==6) test_cbp();
2227            if (what==0 || what==10) test_sse();
2228            if (what==0 || what==11) test_log2bin();
2229            if (what==0 || what==12) test_gcd();
2230            if (what==0 || what==13) test_compiler();
2231            if (what==0 || what==14) test_yuv();
2232            if (what==0 || what==15) test_SSIM();
2233            if (what==0 || what==16) test_yuv2();
2234            if (what==0 || what==17) test_bits();
2235    
2236    if (what==7) {    if (what==7) {
2237      test_IEEE1180_compliance(-256, 255, 1);      test_IEEE1180_compliance(-256, 255, 1);
 #if 0  
2238      test_IEEE1180_compliance(-256, 255,-1);      test_IEEE1180_compliance(-256, 255,-1);
2239      test_IEEE1180_compliance(  -5,   5, 1);      test_IEEE1180_compliance(  -5,   5, 1);
2240      test_IEEE1180_compliance(  -5,   5,-1);      test_IEEE1180_compliance(  -5,   5,-1);
2241      test_IEEE1180_compliance(-300, 300, 1);      test_IEEE1180_compliance(-300, 300, 1);
2242      test_IEEE1180_compliance(-300, 300,-1);      test_IEEE1180_compliance(-300, 300,-1);
 #endif  
2243    }    }
2244    if (what==8) test_dct_saturation(-256, 255);    if (what==8) test_dct_saturation(-256, 255);
2245    
2246    if (what==9) {          if (test_bitstream)
2247      int width, height;            test_dec(test_bitstream, width, height, chksum);
     if (argc<5) {  
       printf("usage: %s %d [bitstream] [width] [height]\n", argv[0], what);  
       return 1;  
     }  
     width = atoi(argv[3]);  
     height = atoi(argv[4]);  
     test_dec(argv[2], width, height, (argc>5));  
   }  
   
2248    if (what==-1) {    if (what==-1) {
2249      test_dct_precision_diffs();      test_dct_precision_diffs();
2250      test_bugs1();      test_bugs1();
# Line 1331  Line 2252 
2252    if (what==-2)    if (what==-2)
2253      test_quant_bug();      test_quant_bug();
2254    
2255    return 0;          if ((what >= 0 && what <= 6) || what == 10) {
2256                    printf("\n\n"
2257                               "NB: If a function isn't optimised for a specific set of intructions,\n"
2258                               "    a C function is used instead. So don't panic if some functions\n"
2259                               "    may appear to be slow.\n");
2260  }  }
2261    
2262  /*********************************************************************  #ifdef ARCH_IS_IA32
2263   * 'Reference' output (except for timing) on a PIII 1.13Ghz/linux          if (what == 0 || what == 5) {
2264   *********************************************************************/                  printf("\n"
2265                               "NB: MMX mpeg4 quantization is known to have very small errors (+/-1 magnitude)\n"
2266      /* as of 07/01/2002, there's a problem with mpeg4-quantization */                             "    for 1 or 2 coefficients a block. This is mainly caused by the fact the unit\n"
2267  /*                             "    test goes far behind the usual limits of real encoding. Please do not report\n"
2268                               "    this error to the developers.\n");
2269            }
2270    #endif
2271    
2272   ===== test fdct/idct =====          return 0;
2273  PLAINC -  3.312 usec       PSNR=13.291  MSE=3.000  }
 MMX    -  0.591 usec       PSNR=13.291  MSE=3.000  
 MMXEXT -  0.577 usec       PSNR=13.291  MSE=3.000  
 SSE2   -  0.588 usec       PSNR=13.291  MSE=3.000  
 3DNOW  - skipped...  
 3DNOWE - skipped...  
   
  ===  test block motion ===  
 PLAINC - interp- h-round0 0.911 usec       iCrc=8107  
 PLAINC -           round1 0.863 usec       iCrc=8100  
 PLAINC - interp- v-round0 0.860 usec       iCrc=8108  
 PLAINC -           round1 0.857 usec       iCrc=8105  
 PLAINC - interp-hv-round0 2.103 usec       iCrc=8112  
 PLAINC -           round1 2.050 usec       iCrc=8103  
  ---  
 MMX    - interp- h-round0 0.105 usec       iCrc=8107  
 MMX    -           round1 0.106 usec       iCrc=8100  
 MMX    - interp- v-round0 0.106 usec       iCrc=8108  
 MMX    -           round1 0.106 usec       iCrc=8105  
 MMX    - interp-hv-round0 0.145 usec       iCrc=8112  
 MMX    -           round1 0.145 usec       iCrc=8103  
  ---  
 MMXEXT - interp- h-round0 0.028 usec       iCrc=8107  
 MMXEXT -           round1 0.041 usec       iCrc=8100  
 MMXEXT - interp- v-round0 0.027 usec       iCrc=8108  
 MMXEXT -           round1 0.041 usec       iCrc=8105  
 MMXEXT - interp-hv-round0 0.066 usec       iCrc=8112  
 MMXEXT -           round1 0.065 usec       iCrc=8103  
  ---  
 SSE2   - interp- h-round0 0.109 usec       iCrc=8107  
 SSE2   -           round1 0.105 usec       iCrc=8100  
 SSE2   - interp- v-round0 0.106 usec       iCrc=8108  
 SSE2   -           round1 0.109 usec       iCrc=8105  
 SSE2   - interp-hv-round0 0.145 usec       iCrc=8112  
 SSE2   -           round1 0.145 usec       iCrc=8103  
  ---  
 3DNOW  - skipped...  
 3DNOWE - skipped...  
   
  ======  test SAD ======  
 PLAINC - sad8    0.251 usec       sad=3776  
 PLAINC - sad16   1.601 usec       sad=27214  
 PLAINC - sad16bi 2.371 usec       sad=26274  
 PLAINC - dev16   1.564 usec       sad=3344  
  ---  
 MMX    - sad8    0.057 usec       sad=3776  
 MMX    - sad16   0.182 usec       sad=27214  
 MMX    - sad16bi 2.462 usec       sad=26274  
 MMX    - dev16   0.311 usec       sad=3344  
  ---  
 MMXEXT - sad8    0.036 usec       sad=3776  
 MMXEXT - sad16   0.109 usec       sad=27214  
 MMXEXT - sad16bi 0.143 usec       sad=26274  
 MMXEXT - dev16   0.192 usec       sad=3344  
  ---  
 SSE2   - sad8    0.057 usec       sad=3776  
 SSE2   - sad16   0.179 usec       sad=27214  
 SSE2   - sad16bi 2.456 usec       sad=26274  
 SSE2   - dev16   0.321 usec       sad=3344  
  ---  
 3DNOW  - skipped...  
 3DNOWE - skipped...  
   
  ===  test transfer ===  
 PLAINC - 8to16     0.151 usec       crc=28288  
 PLAINC - 16to8     1.113 usec       crc=28288  
 PLAINC - 8to8      0.043 usec       crc=20352  
 PLAINC - 16to8add  1.069 usec       crc=25536  
 PLAINC - 8to16sub  0.631 usec       crc1=28064 crc2=16256  
 PLAINC - 8to16sub2 0.597 usec       crc=20384  
  ---  
 MMX    - 8to16     0.032 usec       crc=28288  
 MMX    - 16to8     0.024 usec       crc=28288  
 MMX    - 8to8      0.020 usec       crc=20352  
 MMX    - 16to8add  0.043 usec       crc=25536  
 MMX    - 8to16sub  0.066 usec       crc1=28064 crc2=16256  
 MMX    - 8to16sub2 0.111 usec       crc=20384  
  ---  
   
  =====  test quant =====  
 PLAINC -   quant4_intra 74.248 usec       crc=29809  
 PLAINC -   quant4_inter 70.850 usec       crc=12574  
 PLAINC - dequant4_intra 40.628 usec       crc=24052  
 PLAINC - dequant4_inter 45.691 usec       crc=63847  
 PLAINC -    quant_intra 43.357 usec       crc=25662  
 PLAINC -    quant_inter 33.410 usec       crc=23972  
 PLAINC -  dequant_intra 36.384 usec       crc=49900  
 PLAINC -  dequant_inter 48.930 usec       crc=48899  
  ---  
 MMX    -   quant4_intra 7.445 usec       crc=3459  
 *** CRC ERROR! ***  
 MMX    -   quant4_inter 5.384 usec       crc=51072  
 *** CRC ERROR! ***  
 MMX    - dequant4_intra 5.515 usec       crc=24052  
 MMX    - dequant4_inter 7.745 usec       crc=63847  
 MMX    -    quant_intra 4.661 usec       crc=25662  
 MMX    -    quant_inter 4.406 usec       crc=23972  
 MMX    -  dequant_intra 4.928 usec       crc=49900  
 MMX    -  dequant_inter 4.532 usec       crc=48899  
  ---  
   
  =====  test cbp =====  
 PLAINC -   calc_cbp#1 0.371 usec       cbp=0x15  
 PLAINC -   calc_cbp#2 0.432 usec       cbp=0x38  
 PLAINC -   calc_cbp#3 0.339 usec       cbp=0xf  
 PLAINC -   calc_cbp#4 0.506 usec       cbp=0x5  
  ---  
 MMX    -   calc_cbp#1 0.136 usec       cbp=0x15  
 MMX    -   calc_cbp#2 0.134 usec       cbp=0x38  
 MMX    -   calc_cbp#3 0.138 usec       cbp=0xf  
 MMX    -   calc_cbp#4 0.135 usec       cbp=0x5  
  ---  
 SSE2   -   calc_cbp#1 0.136 usec       cbp=0x15  
 SSE2   -   calc_cbp#2 0.133 usec       cbp=0x38  
 SSE2   -   calc_cbp#3 0.133 usec       cbp=0xf  
 SSE2   -   calc_cbp#4 0.141 usec       cbp=0x5  
  ---  
2274    
2275  */  /*********************************************************************/

Legend:
Removed from v.860  
changed lines
  Added in v.1794

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