diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-07-17 19:52:05 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-07-17 20:12:02 +0200 |
commit | 78accb876c173c881082018b169b5cf9fa13e6e1 (patch) | |
tree | 5dbcaf2ae14a012dafaaf418a650d697f3ef8ea4 /libavcodec/cabac.c | |
parent | fc096e2e861e821a743bf9c42abee0fb41fff5d6 (diff) | |
parent | 08e09ed7db732ebc53b8c60d7a39ac0abd49694f (diff) | |
download | ffmpeg-78accb876c173c881082018b169b5cf9fa13e6e1.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
ffmpeg: fix some indentation
ffmpeg: fix operation with --disable-avfilter
simple_idct: remove disabled code
motion_est: remove disabled code
vc1: remove disabled code
fate: separate lavf-mxf_d10 test from lavf-mxf
cabac: Move code only used in the cabac test program to cabac.c.
ffplay: warn that -pix_fmt is no longer working, suggest alternative
ffplay: warn that -s is no longer working, suggest alternative
lavf: rename enc variable in utils.c:has_codec_parameters()
lavf: use designated initialisers for all (de)muxers.
wav: remove a use of deprecated AV_METADATA_ macro
rmdec: remove useless ap parameter from rm_read_header_old()
dct-test: remove write-only variable
des: fix #if conditional around P_shuffle
Use LOCAL_ALIGNED in ff_check_alignment()
Conflicts:
ffmpeg.c
libavformat/avidec.c
libavformat/matroskaenc.c
libavformat/mp3enc.c
libavformat/oggenc.c
libavformat/utils.c
tests/ref/lavf/mxf
Merged-by: Michael Niedermayer <michaelni@gmx.at>
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 558622bfce..5632bf811e 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]; |