From f98a8e20888847527edcff6a9244de2dc714e42c Mon Sep 17 00:00:00 2001 From: Loren Merritt Date: Sun, 27 Jan 2008 10:05:20 +0000 Subject: [PATCH] shave a couple cycles off cabac functions git-svn-id: svn://svn.videolan.org/x264/trunk@724 df754926-b1dd-0310-bc7b-ec298dee348c --- common/cabac.c | 41 ++++++++++++++++++----------------------- common/cabac.h | 4 ++-- encoder/cabac.c | 5 ++--- encoder/encoder.c | 16 ++++------------ encoder/rdo.c | 4 ++-- 5 files changed, 28 insertions(+), 42 deletions(-) diff --git a/common/cabac.c b/common/cabac.c index 695b411d..612eedae 100644 --- a/common/cabac.c +++ b/common/cabac.c @@ -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 diff --git a/common/cabac.h b/common/cabac.h index 5b598fef..affd2543 100644 --- a/common/cabac.h +++ b/common/cabac.h @@ -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 ); diff --git a/encoder/cabac.c b/encoder/cabac.c index 6b3a0180..d02ee939 100644 --- a/encoder/cabac.c +++ b/encoder/cabac.c @@ -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 ) diff --git a/encoder/encoder.c b/encoder/encoder.c index 4b8647c6..1715c68f 100644 --- a/encoder/encoder.c +++ b/encoder/encoder.c @@ -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 ); } diff --git a/encoder/rdo.c b/encoder/rdo.c index 4861b242..e4cb45ae 100644 --- a/encoder/rdo.c +++ b/encoder/rdo.c @@ -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" -- 2.40.0