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

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

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