[Ffmpeg-cvslog] r6732 - in trunk/libavcodec: cabac.h h264.c

michael subversion
Thu Oct 19 03:19:04 CEST 2006


Author: michael
Date: Thu Oct 19 03:19:03 2006
New Revision: 6732

Modified:
   trunk/libavcodec/cabac.h
   trunk/libavcodec/h264.c

Log:
optimize sign decoding code in decode_residual()
x86 is 4% faster on P3
C sign stuff + x86 code for everything else is also faster then before (sorry forgot to test pure C)
... and if i replace the second occurance of the sign decoding in decode_residual by the asm too then everything gets slower iam starting to think that it might be best to write the whole function in asm, playing this avoid random deoptimizations game with gcc is not fun at all


Modified: trunk/libavcodec/cabac.h
==============================================================================
--- trunk/libavcodec/cabac.h	(original)
+++ trunk/libavcodec/cabac.h	Thu Oct 19 03:19:03 2006
@@ -575,6 +575,36 @@
 }
 
 static int get_cabac_bypass(CABACContext *c){
+#if 0 //not faster
+    int bit;
+    asm volatile(
+        "movl "RANGE    "(%1), %%ebx            \n\t"
+        "movl "LOW      "(%1), %%eax            \n\t"
+        "shl $17, %%ebx                         \n\t"
+        "add %%eax, %%eax                       \n\t"
+        "sub %%ebx, %%eax                       \n\t"
+        "cdq                                    \n\t"
+        "and %%edx, %%ebx                       \n\t"
+        "add %%ebx, %%eax                       \n\t"
+        "test %%ax, %%ax                        \n\t"
+        " jnz 1f                                \n\t"
+        "movl "BYTE     "(%1), %%ebx            \n\t"
+        "subl $0xFFFF, %%eax                    \n\t"
+        "movzwl (%%ebx), %%ecx                  \n\t"
+        "bswap %%ecx                            \n\t"
+        "shrl $15, %%ecx                        \n\t"
+        "addl $2, %%ebx                         \n\t"
+        "addl %%ecx, %%eax                      \n\t"
+        "movl %%ebx, "BYTE     "(%1)            \n\t"
+        "1:                                     \n\t"
+        "movl %%eax, "LOW      "(%1)            \n\t"
+
+        :"=&d"(bit)
+        :"r"(c)
+        : "%eax", "%ebx", "%ecx", "memory"
+    );
+    return bit+1;
+#else
     int range;
     c->low += c->low;
 
@@ -588,7 +618,58 @@
         c->low -= range;
         return 1;
     }
+#endif
+}
+
+
+static always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
+#ifdef ARCH_X86
+    int bit;
+    asm volatile(
+        "movl "RANGE    "(%1), %%ebx            \n\t"
+        "movl "LOW      "(%1), %%eax            \n\t"
+        "shl $17, %%ebx                         \n\t"
+        "add %%eax, %%eax                       \n\t"
+        "sub %%ebx, %%eax                       \n\t"
+        "cdq                                    \n\t"
+        "and %%edx, %%ebx                       \n\t"
+        "add %%ebx, %%eax                       \n\t"
+        "xor %%edx, %%ecx                       \n\t"
+        "sub %%edx, %%ecx                       \n\t"
+        "test %%ax, %%ax                        \n\t"
+        " jnz 1f                                \n\t"
+        "movl "BYTE     "(%1), %%ebx            \n\t"
+        "subl $0xFFFF, %%eax                    \n\t"
+        "movzwl (%%ebx), %%edx                  \n\t"
+        "bswap %%edx                            \n\t"
+        "shrl $15, %%edx                        \n\t"
+        "addl $2, %%ebx                         \n\t"
+        "addl %%edx, %%eax                      \n\t"
+        "movl %%ebx, "BYTE     "(%1)            \n\t"
+        "1:                                     \n\t"
+        "movl %%eax, "LOW      "(%1)            \n\t"
+
+        :"+c"(val)
+        :"r"(c)
+        : "%eax", "%ebx", "%edx", "memory"
+    );
+    return val;
+#else
+    int range, mask;
+    c->low += c->low;
+
+    if(!(c->low & CABAC_MASK))
+        refill(c);
+
+    range= c->range<<17;
+    c->low -= range;
+    mask= c->low >> 31;
+    range &= mask;
+    c->low += range;
+    return (val^mask)-mask;
+#endif
 }
+
 //FIXME the x86 code from this file should be moved into i386/h264 or cabac something.c/h (note ill kill you if you move my code away from under my fingers before iam finished with it!)
 //FIXME use some macros to avoid duplicatin get_cabac (cant be done yet as that would make optimization work hard)
 #ifdef ARCH_X86

Modified: trunk/libavcodec/h264.c
==============================================================================
--- trunk/libavcodec/h264.c	(original)
+++ trunk/libavcodec/h264.c	Thu Oct 19 03:19:03 2006
@@ -6168,11 +6168,9 @@
 
         if( get_cabac( CC, ctx ) == 0 ) {
             if( !qmul ) {
-                if( get_cabac_bypass( CC ) ) block[j] = -1;
-                else                                block[j] =  1;
+                block[j] = get_cabac_bypass_sign( CC, -1);
             }else{
-                if( get_cabac_bypass( CC ) ) block[j] = (-qmul[j] + 32) >> 6;
-                else                                block[j] = ( qmul[j] + 32) >> 6;
+                block[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6;;
             }
 
             abslevel1++;




More information about the ffmpeg-cvslog mailing list