X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fcabac.h;h=426f338e34e653ebf3a135280641be0b0a021568;hb=bfe1cd80ebeab58cbc1c91ac766a96fce8e4ec1e;hp=126064276ad5a891dfaecf49953ab591506a017b;hpb=fd065d3e799033ed0159f766067f3deefecaf48a;p=ffmpeg diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 126064276ad..426f338e34e 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -27,12 +27,15 @@ #ifndef AVCODEC_CABAC_H #define AVCODEC_CABAC_H -#include +#include #include "put_bits.h" -//#undef NDEBUG -#include +extern uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63]; +#define H264_NORM_SHIFT_OFFSET 0 +#define H264_LPS_RANGE_OFFSET 512 +#define H264_MLPS_STATE_OFFSET 1024 +#define H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET 1280 #define CABAC_BITS 16 #define CABAC_MASK ((1<pb, 1, b); - for(;c->outstanding_count; c->outstanding_count--){ - put_bits(&c->pb, 1, 1-b); - } -} - -static inline void renorm_cabac_encoder(CABACContext *c){ - while(c->range < 0x100){ - //FIXME optimize - if(c->low<0x100){ - put_cabac_bit(c, 0); - }else if(c->low<0x200){ - c->outstanding_count++; - c->low -= 0x100; - }else{ - put_cabac_bit(c, 1); - c->low -= 0x200; - } - - c->range+= c->range; - c->low += c->low; - } -} - -static void refill(CABACContext *c){ -#if CABAC_BITS == 16 - c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); -#else - c->low+= c->bytestream[0]<<1; -#endif - c->low -= CABAC_MASK; - c->bytestream+= CABAC_BITS/8; -} - -static inline void renorm_cabac_decoder(CABACContext *c){ - while(c->range < 0x100){ - c->range+= c->range; - c->low+= c->low; - if(!(c->low & CABAC_MASK)) - refill(c); - } -} - -static inline void renorm_cabac_decoder_once(CABACContext *c){ - int shift= (uint32_t)(c->range - 0x100)>>31; - c->range<<= shift; - c->low <<= shift; - if(!(c->low & CABAC_MASK)) - refill(c); -} - -#ifndef get_cabac_inline -static void refill2(CABACContext *c){ - int i, x; - - x= c->low ^ (c->low-1); - i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; - - x= -CABAC_MASK; - -#if CABAC_BITS == 16 - x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); -#else - x+= c->bytestream[0]<<1; -#endif - - c->low += x<bytestream+= CABAC_BITS/8; -} - -static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ - int s = *state; - int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; - int bit, lps_mask; - - c->range -= RangeLPS; - lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; - - c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; - c->range += (RangeLPS - c->range) & lps_mask; - - s^=lps_mask; - *state= (ff_h264_mlps_state+128)[s]; - bit= s&1; - - lps_mask= ff_h264_norm_shift[c->range]; - c->range<<= lps_mask; - c->low <<= lps_mask; - if(!(c->low & CABAC_MASK)) - refill2(c); - return bit; -} -#endif - -static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ - return get_cabac_inline(c,state); -} - -static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ - return get_cabac_inline(c,state); -} - -static int av_unused get_cabac_bypass(CABACContext *c){ - int range; - c->low += c->low; - - if(!(c->low & CABAC_MASK)) - refill(c); - - range= c->range<<(CABAC_BITS+1); - if(c->low < range){ - return 0; - }else{ - c->low -= range; - return 1; - } -} - - -#ifndef get_cabac_bypass_sign -static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ - int range, mask; - c->low += c->low; - - if(!(c->low & CABAC_MASK)) - refill(c); - - range= c->range<<(CABAC_BITS+1); - c->low -= range; - mask= c->low >> 31; - range &= mask; - c->low += range; - return (val^mask)-mask; -} -#endif - -/** - * - * @return the number of bytes read or 0 if no end - */ -static int av_unused get_cabac_terminate(CABACContext *c){ - c->range -= 2; - if(c->low < c->range<<(CABAC_BITS+1)){ - renorm_cabac_decoder_once(c); - return 0; - }else{ - return c->bytestream - c->bytestream_start; - } -} - -#if 0 -/** - * Get (truncated) unary binarization. - */ -static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){ - int i; - - for(i=0; i>=1){ - v+= v + get_cabac_bypass(c); - } - i += v; - - if(is_signed && get_cabac_bypass(c)){ - return -i; - }else - return i; -} -#endif /* 0 */ +void ff_init_cabac_states(void); #endif /* AVCODEC_CABAC_H */