]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dct-test.c
Check available size before writing in decode_frame()
[ffmpeg] / libavcodec / dct-test.c
index dd8099b2e29bfdc7e0097eb4246840b8eb10c7b3..f3f9408d984f0f55d3bcb1e0ca621649dc6f4f5d 100644 (file)
 #include <unistd.h>
 #include <math.h>
 
-#include "dsputil.h"
+#include "libavutil/common.h"
 
 #include "simple_idct.h"
 #include "faandct.h"
 #include "faanidct.h"
-
-#ifndef MAX
-#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
-#endif
+#include "i386/idct_xvid.h"
 
 #undef printf
 #undef random
@@ -50,8 +47,6 @@ void *fast_memcpy(void *a, const void *b, size_t c){return memcpy(a,b,c);};
 /* reference fdct/idct */
 extern void fdct(DCTELEM *block);
 extern void idct(DCTELEM *block);
-extern void ff_idct_xvid_mmx(DCTELEM *block);
-extern void ff_idct_xvid_mmx2(DCTELEM *block);
 extern void init_fdct();
 
 extern void ff_mmx_idct(DCTELEM *data);
@@ -69,11 +64,12 @@ extern void fdct_altivec (DCTELEM *block);
 
 
 struct algo {
-  char *name;
+  const char *name;
   enum { FDCT, IDCT } is_idct;
   void (* func) (DCTELEM *block);
   void (* ref)  (DCTELEM *block);
-  enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM } format;
+  enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM } format;
+  int  mm_support;
 };
 
 #ifndef FAAN_POSTSCALE
@@ -82,41 +78,41 @@ struct algo {
 #define FAAN_SCALE NO_PERM
 #endif
 
-#define DCT_ERROR(name,is_idct,func,ref,form) {name,is_idct,func,ref,form}
-
+static int cpu_flags;
 
 struct algo algos[] = {
-  DCT_ERROR( "REF-DBL",        0, fdct,               fdct, NO_PERM),
-  DCT_ERROR("FAAN",            0, ff_faandct,         fdct, FAAN_SCALE),
-  DCT_ERROR("FAANI",           1, ff_faanidct,        idct, NO_PERM),
-  DCT_ERROR("IJG-AAN-INT",     0, fdct_ifast,         fdct, SCALE_PERM),
-  DCT_ERROR("IJG-LLM-INT",     0, ff_jpeg_fdct_islow, fdct, NO_PERM),
-  DCT_ERROR("REF-DBL",         1, idct,               idct, NO_PERM),
-  DCT_ERROR("INT",             1, j_rev_dct,          idct, MMX_PERM),
-  DCT_ERROR("SIMPLE-C",        1, ff_simple_idct,     idct, NO_PERM),
+  {"REF-DBL",         0, fdct,               fdct, NO_PERM},
+  {"FAAN",            0, ff_faandct,         fdct, FAAN_SCALE},
+  {"FAANI",           1, ff_faanidct,        idct, NO_PERM},
+  {"IJG-AAN-INT",     0, fdct_ifast,         fdct, SCALE_PERM},
+  {"IJG-LLM-INT",     0, ff_jpeg_fdct_islow, fdct, NO_PERM},
+  {"REF-DBL",         1, idct,               idct, NO_PERM},
+  {"INT",             1, j_rev_dct,          idct, MMX_PERM},
+  {"SIMPLE-C",        1, ff_simple_idct,     idct, NO_PERM},
 
 #ifdef HAVE_MMX
-  DCT_ERROR("MMX",             0, ff_fdct_mmx,        fdct, NO_PERM),
+  {"MMX",             0, ff_fdct_mmx,        fdct, NO_PERM, MM_MMX},
 #ifdef HAVE_MMX2
-  DCT_ERROR("MMX2",            0, ff_fdct_mmx2,       fdct, NO_PERM),
+  {"MMX2",            0, ff_fdct_mmx2,       fdct, NO_PERM, MM_MMXEXT},
 #endif
 
 #ifdef CONFIG_GPL
-  DCT_ERROR("LIBMPEG2-MMX",    1, ff_mmx_idct,        idct, MMX_PERM),
-  DCT_ERROR("LIBMPEG2-MMXEXT", 1, ff_mmxext_idct,     idct, MMX_PERM),
+  {"LIBMPEG2-MMX",    1, ff_mmx_idct,        idct, MMX_PERM, MM_MMX},
+  {"LIBMPEG2-MMXEXT", 1, ff_mmxext_idct,     idct, MMX_PERM, MM_MMXEXT},
 #endif
-  DCT_ERROR("SIMPLE-MMX",      1, ff_simple_idct_mmx, idct, MMX_SIMPLE_PERM),
-  DCT_ERROR("XVID-MMX",        1, ff_idct_xvid_mmx,   idct, NO_PERM),
-  DCT_ERROR("XVID-MMX2",       1, ff_idct_xvid_mmx2,  idct, NO_PERM),
+  {"SIMPLE-MMX",      1, ff_simple_idct_mmx, idct, MMX_SIMPLE_PERM, MM_MMX},
+  {"XVID-MMX",        1, ff_idct_xvid_mmx,   idct, NO_PERM, MM_MMX},
+  {"XVID-MMX2",       1, ff_idct_xvid_mmx2,  idct, NO_PERM, MM_MMXEXT},
+  {"XVID-SSE2",       1, ff_idct_xvid_sse2,  idct, SSE2_PERM, MM_SSE2},
 #endif
 
 #ifdef HAVE_ALTIVEC
-  DCT_ERROR("altivecfdct",     0, fdct_altivec,       fdct, NO_PERM),
+  {"altivecfdct",     0, fdct_altivec,       fdct, NO_PERM, MM_ALTIVEC},
 #endif
 
 #ifdef ARCH_BFIN
-  DCT_ERROR("BFINfdct",        0, ff_bfin_fdct,       fdct, NO_PERM),
-  DCT_ERROR("BFINidct",        1, ff_bfin_idct,       idct, NO_PERM),
+  {"BFINfdct",        0, ff_bfin_fdct,       fdct, NO_PERM},
+  {"BFINidct",        1, ff_bfin_idct,       idct, NO_PERM},
 #endif
 
   { 0 }
@@ -160,6 +156,8 @@ static short idct_simple_mmx_perm[64]={
         0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,
 };
 
+static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7};
+
 void idct_mmx_init(void)
 {
     int i;
@@ -171,10 +169,18 @@ void idct_mmx_init(void)
     }
 }
 
-static DCTELEM block[64] __attribute__ ((aligned (8)));
+static DCTELEM block[64] __attribute__ ((aligned (16)));
 static DCTELEM block1[64] __attribute__ ((aligned (8)));
 static DCTELEM block_org[64] __attribute__ ((aligned (8)));
 
+static inline void mmx_emms(void)
+{
+#ifdef HAVE_MMX
+    if (cpu_flags & MM_MMX)
+        asm volatile ("emms\n\t");
+#endif
+}
+
 void dct_error(const char *name, int is_idct,
                void (*fdct_func)(DCTELEM *block),
                void (*fdct_ref)(DCTELEM *block), int form, int test)
@@ -235,6 +241,9 @@ void dct_error(const char *name, int is_idct,
             for(i=0;i<64;i++)
                 block[idct_simple_mmx_perm[i]] = block1[i];
 
+        } else if (form == SSE2_PERM) {
+            for(i=0; i<64; i++)
+                block[(i&0x38) | idct_sse2_row_perm[i&7]] = block1[i];
         } else {
             for(i=0; i<64; i++)
                 block[i]= block1[i];
@@ -249,7 +258,7 @@ void dct_error(const char *name, int is_idct,
 #endif
 
         fdct_func(block);
-        emms_c(); /* for ff_mmx_idct */
+        mmx_emms();
 
         if (form == SCALE_PERM) {
             for(i=0; i<64; i++) {
@@ -285,7 +294,7 @@ void dct_error(const char *name, int is_idct,
         }
 #endif
     }
-    for(i=0; i<64; i++) sysErrMax= MAX(sysErrMax, FFABS(sysErr[i]));
+    for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i]));
 
 #if 1 // dump systematic errors
     for(i=0; i<64; i++){
@@ -346,7 +355,7 @@ void dct_error(const char *name, int is_idct,
         it1 += NB_ITS_SPEED;
         ti1 = gettime() - ti;
     } while (ti1 < 1000000);
-    emms_c();
+    mmx_emms();
 
     printf("%s %s: %0.1f kdct/s\n",
            is_idct ? "IDCT" : "DCT",
@@ -506,7 +515,7 @@ void idct248_error(const char *name,
         it1 += NB_ITS_SPEED;
         ti1 = gettime() - ti;
     } while (ti1 < 1000000);
-    emms_c();
+    mmx_emms();
 
     printf("%s %s: %0.1f kdct/s\n",
            1 ? "IDCT248" : "DCT248",
@@ -528,10 +537,10 @@ int main(int argc, char **argv)
     int test_idct = 0, test_248_dct = 0;
     int c,i;
     int test=1;
+    cpu_flags = mm_support();
 
     init_fdct();
     idct_mmx_init();
-    mm_flags = mm_support();
 
     for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
     for(i=0;i<MAX_NEG_CROP;i++) {
@@ -565,7 +574,7 @@ int main(int argc, char **argv)
         idct248_error("SIMPLE-C", ff_simple_idct248_put);
     } else {
       for (i=0;algos[i].name;i++)
-        if (algos[i].is_idct == test_idct) {
+        if (algos[i].is_idct == test_idct && !(~cpu_flags & algos[i].mm_support)) {
           dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test);
         }
     }