diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2003-05-30 01:05:48 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2003-05-30 01:05:48 +0000 |
commit | 61ccfcc00950ae53725abc50435b2cce72ec8deb (patch) | |
tree | 209e59d4a37eea0ec72c8f247db41f2f255749d2 | |
parent | cf713bb8624d3e56e5077d51283f4e1ae02a5910 (diff) | |
download | ffmpeg-streaming-61ccfcc00950ae53725abc50435b2cce72ec8deb.zip ffmpeg-streaming-61ccfcc00950ae53725abc50435b2cce72ec8deb.tar.gz |
(truncated) unary binerization
unary k-th order exp golomb binarization
Originally committed as revision 1920 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/cabac.c | 44 | ||||
-rw-r--r-- | libavcodec/cabac.h | 134 |
2 files changed, 169 insertions, 9 deletions
diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 4d01882..c4bd274 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -127,49 +127,75 @@ void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4], int main(){ CABACContext c; uint8_t b[9*SIZE]; - uint8_t bit[9*SIZE]; + uint8_t r[9*SIZE]; int i; - uint8_t state= 0; + uint8_t state[10]= {0}; ff_init_cabac_encoder(&c, b, SIZE); ff_init_cabac_states(&c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); for(i=0; i<SIZE; i++){ - bit[i]= (random()%7)&1; + r[i]= random()%7; } for(i=0; i<SIZE; i++){ START_TIMER - put_cabac_bypass(&c, bit[i]); + put_cabac_bypass(&c, r[i]&1); STOP_TIMER("put_cabac_bypass") } for(i=0; i<SIZE; i++){ START_TIMER - put_cabac(&c, &state, bit[i]); + put_cabac(&c, state, r[i]&1); STOP_TIMER("put_cabac") } + for(i=0; i<SIZE; i++){ +START_TIMER + put_cabac_u(&c, state, r[i], 6, 3, i&1); +STOP_TIMER("put_cabac_u") + } + + for(i=0; i<SIZE; i++){ +START_TIMER + put_cabac_ueg(&c, state, r[i], 0, 3, 0, 1, 2); +STOP_TIMER("put_cabac_ueg") + } + put_cabac_terminate(&c, 1); ff_init_cabac_decoder(&c, b, SIZE); - state=0; + memset(state, 0, sizeof(state)); for(i=0; i<SIZE; i++){ START_TIMER - if( bit[i] != get_cabac_bypass(&c) ) + if( (r[i]&1) != get_cabac_bypass(&c) ) printf("CABAC bypass failure at %d\n", i); STOP_TIMER("get_cabac_bypass") } for(i=0; i<SIZE; i++){ START_TIMER - if( bit[i] != get_cabac(&c, &state) ) + if( (r[i]&1) != get_cabac(&c, state) ) printf("CABAC failure at %d\n", i); STOP_TIMER("get_cabac") } - + + for(i=0; i<SIZE; i++){ +START_TIMER + if( r[i] != get_cabac_u(&c, state, (i&1) ? 6 : 7, 3, i&1) ) + printf("CABAC unary (truncated) binarization failure at %d\n", i); +STOP_TIMER("get_cabac_u") + } + + for(i=0; i<SIZE; i++){ +START_TIMER + if( r[i] != get_cabac_ueg(&c, state, 3, 0, 1, 2)) + printf("CABAC unary (truncated) binarization failure at %d\n", i); +STOP_TIMER("get_cabac_ueg") + } + if(!get_cabac_terminate(&c)) printf("where's the Terminator?\n"); diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 69f6697..1377c61 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -113,6 +113,9 @@ static inline void put_cabac_static(CABACContext *c, int RangeLPS, int bit){ #endif } +/** + * @param bit 0 -> write zero bit, !=0 write one bit + */ static inline void put_cabac_bypass(CABACContext *c, int bit){ c->low += c->low; @@ -158,6 +161,82 @@ static inline void put_cabac_terminate(CABACContext *c, int bit){ #endif } +/** + * put (truncated) unary binarization. + */ +static inline void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){ + int i; + + assert(v <= max); + +#if 1 + 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); +#else + if(v <= max_index){ + for(i=0; i<v; i++){ + put_cabac(c, state+i, 1); + } + if(truncated==0 || v<max) + put_cabac(c, state+i, 0); + }else{ + for(i=0; i<=max_index; i++){ + put_cabac(c, state+i, 1); + } + for(; i<v; i++){ + put_cabac(c, state+max_index, 1); + } + if(truncated==0 || v<max) + put_cabac(c, state+max_index, 0); + } +#endif +} + +/** + * put unary exp golomb k-th order binarization. + */ +static inline void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int sign, int max, int is_signed, int k, int max_index){ + int i; + + if(v==0) + put_cabac(c, state, 0); + else{ + 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); + } +} + static inline void renorm_cabac_decoder(CABACContext *c){ while(c->range < 0x10000){ c->range+= c->range; @@ -230,3 +309,58 @@ static inline int get_cabac_terminate(CABACContext *c){ } } +/** + * get (truncated) unnary binarization. + */ +static inline int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){ + int i; + + for(i=0; i<max; i++){ + if(get_cabac(c, state)==0) + return i; + + if(i< max_index) state++; + } + + return truncated ? max : -1; +} + +/** + * get unary exp golomb k-th order binarization. + */ +static inline int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){ + int i, v; + int m= 1<<k; + + if(get_cabac(c, state)==0) + return 0; + + if(0 < max_index) state++; + + for(i=1; i<max; i++){ + if(get_cabac(c, state)==0){ + if(is_signed && get_cabac_bypass(c)){ + return -i; + }else + return i; + } + + if(i < max_index) state++; + } + + while(get_cabac_bypass(c)){ + i+= m; + m+= m; + } + + v=0; + while(m>>=1){ + v+= v + get_cabac_bypass(c); + } + i += v; + + if(is_signed && get_cabac_bypass(c)){ + return -i; + }else + return i; +} |