diff options
author | Diego Biurrun <diego@biurrun.de> | 2011-07-07 23:16:56 +0200 |
---|---|---|
committer | Diego Biurrun <diego@biurrun.de> | 2011-07-17 12:56:42 +0200 |
commit | fd065d3e799033ed0159f766067f3deefecaf48a (patch) | |
tree | 2f7e209b612cec175425ec7c7b9a9191faff1cf5 /libavcodec/cabac.c | |
parent | 0a858048af695e0d5788f0613fc2dc490572e1de (diff) | |
download | ffmpeg-fd065d3e799033ed0159f766067f3deefecaf48a.tar.gz |
cabac: Move code only used in the cabac test program to cabac.c.
Diffstat (limited to 'libavcodec/cabac.c')
-rw-r--r-- | libavcodec/cabac.c | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 4846b32e87..57ab395ed7 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -166,6 +166,140 @@ void ff_init_cabac_states(CABACContext *c){ #include "avcodec.h" #include "cabac.h" +static void put_cabac(CABACContext *c, uint8_t * const state, int bit){ + int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state]; + + if(bit == ((*state)&1)){ + c->range -= RangeLPS; + *state= ff_h264_mps_state[*state]; + }else{ + c->low += c->range - RangeLPS; + c->range = RangeLPS; + *state= ff_h264_lps_state[*state]; + } + + renorm_cabac_encoder(c); + +#ifdef STRICT_LIMITS + c->symCount++; +#endif +} + +/** + * @param bit 0 -> write zero bit, !=0 write one bit + */ +static void put_cabac_bypass(CABACContext *c, int bit){ + c->low += c->low; + + if(bit){ + c->low += c->range; + } +//FIXME optimize + if(c->low<0x200){ + put_cabac_bit(c, 0); + }else if(c->low<0x400){ + c->outstanding_count++; + c->low -= 0x200; + }else{ + put_cabac_bit(c, 1); + c->low -= 0x400; + } + +#ifdef STRICT_LIMITS + c->symCount++; +#endif +} + +/** + * + * @return the number of bytes written + */ +static int put_cabac_terminate(CABACContext *c, int bit){ + c->range -= 2; + + if(!bit){ + renorm_cabac_encoder(c); + }else{ + c->low += c->range; + c->range= 2; + + renorm_cabac_encoder(c); + + assert(c->low <= 0x1FF); + put_cabac_bit(c, c->low>>9); + put_bits(&c->pb, 2, ((c->low>>7)&3)|1); + + flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong + } + +#ifdef STRICT_LIMITS + c->symCount++; +#endif + + return (put_bits_count(&c->pb)+7)>>3; +} + +/** + * put (truncated) unary binarization. + */ +static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){ + int i; + + assert(v <= max); + + for(i=0; i<v; i++){ + put_cabac(c, state, 1); + if(i < max_index) state++; + } + if(truncated==0 || v<max) + put_cabac(c, state, 0); +} + +/** + * put unary exp golomb k-th order binarization. + */ +static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){ + int i; + + if(v==0) + put_cabac(c, state, 0); + else{ + const int sign= v < 0; + + if(is_signed) v= FFABS(v); + + if(v<max){ + for(i=0; i<v; i++){ + put_cabac(c, state, 1); + if(i < max_index) state++; + } + + put_cabac(c, state, 0); + }else{ + int m= 1<<k; + + for(i=0; i<max; i++){ + put_cabac(c, state, 1); + if(i < max_index) state++; + } + + v -= max; + while(v >= m){ //FIXME optimize + put_cabac_bypass(c, 1); + v-= m; + m+= m; + } + put_cabac_bypass(c, 0); + while(m>>=1){ + put_cabac_bypass(c, v&m); + } + } + + if(is_signed) + put_cabac_bypass(c, sign); + } +} + int main(void){ CABACContext c; uint8_t b[9*SIZE]; |