]> git.sesse.net Git - x264/commitdiff
shave a couple cycles off cabac functions
authorLoren Merritt <pengvado@videolan.org>
Sun, 27 Jan 2008 10:05:20 +0000 (10:05 +0000)
committerLoren Merritt <pengvado@videolan.org>
Sun, 27 Jan 2008 10:05:20 +0000 (10:05 +0000)
git-svn-id: svn://svn.videolan.org/x264/trunk@724 df754926-b1dd-0310-bc7b-ec298dee348c

common/cabac.c
common/cabac.h
encoder/cabac.c
encoder/encoder.c
encoder/rdo.c

index 695b411de3862eef4e553c7dbc382d9b4fc2b3c3..612eedae4bd1feeec0bd7e07422771c9747804fe 100644 (file)
@@ -865,7 +865,8 @@ static inline void x264_cabac_putbyte( x264_cabac_t *cb )
         else
         {
             int carry = out & 0x100;
-            if( cb->p + cb->i_bytes_outstanding + 1 >= cb->p_end )
+            int bytes_outstanding = cb->i_bytes_outstanding;
+            if( cb->p + bytes_outstanding + 1 >= cb->p_end )
                 return;
             if( carry )
             {
@@ -875,12 +876,13 @@ static inline void x264_cabac_putbyte( x264_cabac_t *cb )
                 // are in bytes_outstanding and thus not written yet.
                 cb->p[-1]++;
             }
-            while( cb->i_bytes_outstanding > 0 )
+            while( bytes_outstanding > 0 )
             {
-                *(cb->p++) = carry ? 0 : 0xff;
-                cb->i_bytes_outstanding--;
+                *(cb->p++) = (carry >> 8) - 1;
+                bytes_outstanding--;
             }
             *(cb->p++) = out;
+            cb->i_bytes_outstanding = 0;
         }
     }
 }
@@ -915,36 +917,29 @@ void x264_cabac_encode_decision( x264_cabac_t *cb, int i_ctx, int b )
 void x264_cabac_encode_bypass( x264_cabac_t *cb, int b )
 {
     cb->i_low <<= 1;
-    cb->i_low += (((int32_t)b<<31)>>31) & cb->i_range;
+    cb->i_low += -b & cb->i_range;
     cb->i_queue += 1;
     x264_cabac_putbyte( cb );
 }
 
-void x264_cabac_encode_terminal( x264_cabac_t *cb, int b )
+void x264_cabac_encode_terminal( x264_cabac_t *cb )
 {
     cb->i_range -= 2;
-    if( b )
-    {
-        cb->i_low += cb->i_range;
-        cb->i_range  = 2<<7;
-        cb->i_low  <<= 7;
-        cb->i_queue += 7;
-        x264_cabac_putbyte( cb );
-    }
-    else
-    {
-        x264_cabac_encode_renorm( cb );
-    }
+    x264_cabac_encode_renorm( cb );
 }
 
-void x264_cabac_encode_flush( x264_cabac_t *cb )
+void x264_cabac_encode_flush( x264_t *h, x264_cabac_t *cb )
 {
-    cb->i_low |= 0x80;
-    cb->i_low <<= 10;
-    cb->i_queue += 10;
+    cb->i_low += cb->i_range - 2;
+    cb->i_low |= 1;
+    cb->i_low <<= 9;
+    cb->i_queue += 9;
+    x264_cabac_putbyte( cb );
     x264_cabac_putbyte( cb );
+    cb->i_low <<= 8 - cb->i_queue;
+    cb->i_low |= (0x35a4e4f5 >> (h->i_frame & 31) & 1) << 10;
+    cb->i_queue = 8;
     x264_cabac_putbyte( cb );
-    cb->i_queue = 0;
 
     if( cb->p + cb->i_bytes_outstanding + 1 >= cb->p_end )
         return; //FIXME throw an error instead of silently truncating the frame
index 5b598fef92924ba2dea44e42695e457eb917e980..affd25439af54fbd00c7f79c4c0069e46307e747 100644 (file)
@@ -51,8 +51,8 @@ void x264_cabac_context_init( x264_cabac_t *cb, int i_slice_type, int i_qp, int
 void x264_cabac_encode_init ( x264_cabac_t *cb, uint8_t *p_data, uint8_t *p_end );
 void x264_cabac_encode_decision( x264_cabac_t *cb, int i_ctx_idx, int b );
 void x264_cabac_encode_bypass( x264_cabac_t *cb, int b );
-void x264_cabac_encode_terminal( x264_cabac_t *cb, int b );
-void x264_cabac_encode_flush( x264_cabac_t *cb );
+void x264_cabac_encode_terminal( x264_cabac_t *cb );
+void x264_cabac_encode_flush( x264_t *h, x264_cabac_t *cb );
 
 /* internal only. these don't write the bitstream, just calculate bit cost: */
 void x264_cabac_size_decision( x264_cabac_t *cb, int i_ctx, int b );
index 6b3a0180fbc3ed29be63731ac7ed14310fe2a8f2..d02ee93989f18c1627c7bcb30796c94cc194a12f 100644 (file)
@@ -51,15 +51,14 @@ static inline void x264_cabac_mb_type_intra( x264_t *h, x264_cabac_t *cb, int i_
     else if( i_mb_type == I_PCM )
     {
         x264_cabac_encode_decision( cb, ctx0, 1 );
-        x264_cabac_encode_terminal( cb,       1 );
-        x264_cabac_encode_flush( cb );
+        x264_cabac_encode_flush( h, cb );
     }
     else
     {
         int i_pred = x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode];
 
         x264_cabac_encode_decision( cb, ctx0, 1 );
-        x264_cabac_encode_terminal( cb,       0 );
+        x264_cabac_encode_terminal( cb );
 
         x264_cabac_encode_decision( cb, ctx1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
         if( h->mb.i_cbp_chroma == 0 )
index 4b8647c6e75415093819bc3cf555f0333e7042a1..1715c68f1a11979c76cf8f351c65b6f57edc757d 100644 (file)
@@ -1075,7 +1075,7 @@ static void x264_slice_write( x264_t *h )
         if( h->param.b_cabac )
         {
             if( mb_xy > h->sh.i_first_mb && !(h->sh.b_mbaff && (i_mb_y&1)) )
-                x264_cabac_encode_terminal( &h->cabac, 0 );
+                x264_cabac_encode_terminal( &h->cabac );
 
             if( IS_SKIP( h->mb.i_type ) )
                 x264_cabac_mb_skip( h, 1 );
@@ -1153,21 +1153,13 @@ static void x264_slice_write( x264_t *h )
 
     if( h->param.b_cabac )
     {
-        /* end of slice */
-        x264_cabac_encode_terminal( &h->cabac, 1 );
-    }
-    else if( i_skip > 0 )
-    {
-        bs_write_ue( &h->out.bs, i_skip );  /* last skip run */
-    }
-
-    if( h->param.b_cabac )
-    {
-        x264_cabac_encode_flush( &h->cabac );
+        x264_cabac_encode_flush( h, &h->cabac );
         h->out.bs.p = h->cabac.p;
     }
     else
     {
+        if( i_skip > 0 )
+            bs_write_ue( &h->out.bs, i_skip );  /* last skip run */
         /* rbsp_slice_trailing_bits */
         bs_rbsp_trailing( &h->out.bs );
     }
index 4861b2429b587008f942532e88aea5d4f06463a6..e4cb45aef26b3b1efbb2aa1b5c2f1472d31b0879 100644 (file)
@@ -42,9 +42,9 @@ static int cabac_prefix_size[15][128];
 /* CABAC: not exactly the same. x264_cabac_size_decision() keeps track of
  * fractional bits, but only finite precision. */
 #define x264_cabac_encode_decision(c,x,v) x264_cabac_size_decision(c,x,v)
-#define x264_cabac_encode_terminal(c,v)   x264_cabac_size_decision(c,276,v)
+#define x264_cabac_encode_terminal(c)     x264_cabac_size_decision(c,276,0)
 #define x264_cabac_encode_bypass(c,v)     ((c)->f8_bits_encoded += 256)
-#define x264_cabac_encode_flush(c)
+#define x264_cabac_encode_flush(h,c)
 #define x264_macroblock_write_cabac  x264_macroblock_size_cabac
 #define x264_cabac_mb_skip  x264_cabac_mb_size_skip_unused
 #include "cabac.c"