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

Legend:
Removed from v.824  
changed lines
  Added in v.1839

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