libavcodec/cabac.h
d592f67f
 /*
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
b78e7197
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
d592f67f
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
b78e7197
  * version 2.1 of the License, or (at your option) any later version.
d592f67f
  *
b78e7197
  * FFmpeg is distributed in the hope that it will be useful,
d592f67f
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
b78e7197
  * License along with FFmpeg; if not, write to the Free Software
5509bffa
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d592f67f
  */
115329f1
 
d592f67f
 /**
ba87f080
  * @file
d592f67f
  * Context Adaptive Binary Arithmetic Coder.
  */
 
98790382
 #ifndef AVCODEC_CABAC_H
 #define AVCODEC_CABAC_H
26b4fe82
 
6b712acc
 #include <stddef.h>
 
b2755007
 #include "put_bits.h"
d592f67f
 
2848ce84
 //#undef NDEBUG
d592f67f
 #include <assert.h>
 
5659b509
 #define CABAC_BITS 16
ec7eb896
 #define CABAC_MASK ((1<<CABAC_BITS)-1)
 
d592f67f
 typedef struct CABACContext{
     int low;
     int range;
     int outstanding_count;
 #ifdef STRICT_LIMITS
     int symCount;
 #endif
e96682e6
     const uint8_t *bytestream_start;
     const uint8_t *bytestream;
bba83349
     const uint8_t *bytestream_end;
d592f67f
     PutBitContext pb;
 }CABACContext;
 
68a205ed
 extern uint8_t ff_h264_mlps_state[4*64];
a0f2c6ba
 extern uint8_t ff_h264_lps_range[4*2*64];  ///< rangeTabLPS
d61c4e73
 extern uint8_t ff_h264_mps_state[2*64];     ///< transIdxMPS
 extern uint8_t ff_h264_lps_state[2*64];     ///< transIdxLPS
f24a5159
 extern const uint8_t ff_h264_norm_shift[512];
ec7eb896
 
2143d69b
 #if ARCH_X86
 #   include "x86/cabac.h"
 #endif
d592f67f
 
 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
e96682e6
 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
d61c4e73
 void ff_init_cabac_states(CABACContext *c);
d592f67f
 
 
 static inline void put_cabac_bit(CABACContext *c, int b){
115329f1
     put_bits(&c->pb, 1, b);
     for(;c->outstanding_count; c->outstanding_count--){
d592f67f
         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;
         }
115329f1
 
d592f67f
         c->range+= c->range;
         c->low += c->low;
     }
 }
 
c46e2874
 #ifdef TEST
938dd846
 static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
f24a5159
     int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
115329f1
 
d592f67f
     if(bit == ((*state)&1)){
         c->range -= RangeLPS;
d61c4e73
         *state= ff_h264_mps_state[*state];
d592f67f
     }else{
         c->low += c->range - RangeLPS;
         c->range = RangeLPS;
d61c4e73
         *state= ff_h264_lps_state[*state];
d592f67f
     }
115329f1
 
d592f67f
     renorm_cabac_encoder(c);
 
 #ifdef STRICT_LIMITS
     c->symCount++;
 #endif
 }
 
938dd846
 static void put_cabac_static(CABACContext *c, int RangeLPS, int bit){
d592f67f
     assert(c->range > RangeLPS);
 
     if(!bit){
         c->range -= RangeLPS;
     }else{
         c->low += c->range - RangeLPS;
         c->range = RangeLPS;
     }
 
     renorm_cabac_encoder(c);
 
 #ifdef STRICT_LIMITS
     c->symCount++;
 #endif
 }
 
61ccfcc0
 /**
  * @param bit 0 -> write zero bit, !=0 write one bit
  */
938dd846
 static void put_cabac_bypass(CABACContext *c, int bit){
d592f67f
     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;
     }
115329f1
 
d592f67f
 #ifdef STRICT_LIMITS
     c->symCount++;
 #endif
 }
 
5e20f836
 /**
  *
  * @return the number of bytes written
  */
938dd846
 static int put_cabac_terminate(CABACContext *c, int bit){
d592f67f
     c->range -= 2;
 
     if(!bit){
         renorm_cabac_encoder(c);
     }else{
         c->low += c->range;
         c->range= 2;
115329f1
 
d592f67f
         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);
115329f1
 
d592f67f
         flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
     }
115329f1
 
d592f67f
 #ifdef STRICT_LIMITS
     c->symCount++;
 #endif
5e20f836
 
b46243ed
     return (put_bits_count(&c->pb)+7)>>3;
d592f67f
 }
 
61ccfcc0
 /**
  * put (truncated) unary binarization.
  */
938dd846
 static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){
61ccfcc0
     int i;
115329f1
 
61ccfcc0
     assert(v <= max);
115329f1
 
61ccfcc0
 #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.
  */
938dd846
 static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){
61ccfcc0
     int i;
115329f1
 
61ccfcc0
     if(v==0)
         put_cabac(c, state, 0);
     else{
8f8c0800
         const int sign= v < 0;
115329f1
 
c26abfa5
         if(is_signed) v= FFABS(v);
115329f1
 
61ccfcc0
         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);
     }
 }
c46e2874
 #endif /* TEST */
61ccfcc0
 
ec7eb896
 static void refill(CABACContext *c){
 #if CABAC_BITS == 16
2ae7569d
         c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
ec7eb896
 #else
         c->low+= c->bytestream[0]<<1;
 #endif
     c->low -= CABAC_MASK;
     c->bytestream+= CABAC_BITS/8;
 }
 
d592f67f
 static inline void renorm_cabac_decoder(CABACContext *c){
f24a5159
     while(c->range < 0x100){
d592f67f
         c->range+= c->range;
         c->low+= c->low;
ec7eb896
         if(!(c->low & CABAC_MASK))
             refill(c);
d592f67f
     }
 }
 
ec7eb896
 static inline void renorm_cabac_decoder_once(CABACContext *c){
f24a5159
     int shift= (uint32_t)(c->range - 0x100)>>31;
bfe328ca
     c->range<<= shift;
     c->low  <<= shift;
ec7eb896
     if(!(c->low & CABAC_MASK))
         refill(c);
 }
 
2143d69b
 #ifndef get_cabac_inline
ec7eb896
 static void refill2(CABACContext *c){
     int i, x;
1f4d5e9f
 
ec7eb896
     x= c->low ^ (c->low-1);
f24a5159
     i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)];
ec7eb896
 
     x= -CABAC_MASK;
115329f1
 
ec7eb896
 #if CABAC_BITS == 16
         x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
1f4d5e9f
 #else
ec7eb896
         x+= c->bytestream[0]<<1;
1f4d5e9f
 #endif
115329f1
 
ec7eb896
     c->low += x<<i;
     c->bytestream+= CABAC_BITS/8;
 }
 
5a6a6cc7
 static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
bfe328ca
     int s = *state;
a0f2c6ba
     int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s];
8fcc0e79
     int bit, lps_mask;
115329f1
 
d592f67f
     c->range -= RangeLPS;
3b6dc9ca
     lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31;
115329f1
 
3b6dc9ca
     c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask;
ec7eb896
     c->range += (RangeLPS - c->range) & lps_mask;
115329f1
 
2e1aee80
     s^=lps_mask;
68a205ed
     *state= (ff_h264_mlps_state+128)[s];
2e1aee80
     bit= s&1;
115329f1
 
f24a5159
     lps_mask= ff_h264_norm_shift[c->range];
ec7eb896
     c->range<<= lps_mask;
     c->low  <<= lps_mask;
     if(!(c->low & CABAC_MASK))
         refill2(c);
115329f1
     return bit;
d592f67f
 }
2143d69b
 #endif
d592f67f
 
ab210908
 static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){
851ded89
     return get_cabac_inline(c,state);
 }
 
ab210908
 static int av_unused get_cabac(CABACContext *c, uint8_t * const state){
851ded89
     return get_cabac_inline(c,state);
 }
 
ab210908
 static int av_unused get_cabac_bypass(CABACContext *c){
f24a5159
     int range;
d592f67f
     c->low += c->low;
 
ec7eb896
     if(!(c->low & CABAC_MASK))
         refill(c);
115329f1
 
3b6dc9ca
     range= c->range<<(CABAC_BITS+1);
f24a5159
     if(c->low < range){
d592f67f
         return 0;
     }else{
f24a5159
         c->low -= range;
d592f67f
         return 1;
     }
ebd624b6
 }
 
 
2143d69b
 #ifndef get_cabac_bypass_sign
849f1035
 static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
ebd624b6
     int range, mask;
     c->low += c->low;
 
     if(!(c->low & CABAC_MASK))
         refill(c);
 
3b6dc9ca
     range= c->range<<(CABAC_BITS+1);
ebd624b6
     c->low -= range;
     mask= c->low >> 31;
     range &= mask;
     c->low += range;
     return (val^mask)-mask;
d592f67f
 }
2143d69b
 #endif
ebd624b6
 
5e20f836
 /**
  *
  * @return the number of bytes read or 0 if no end
  */
ab210908
 static int av_unused get_cabac_terminate(CABACContext *c){
f24a5159
     c->range -= 2;
3b6dc9ca
     if(c->low < c->range<<(CABAC_BITS+1)){
ec7eb896
         renorm_cabac_decoder_once(c);
d592f67f
         return 0;
     }else{
5e20f836
         return c->bytestream - c->bytestream_start;
115329f1
     }
d592f67f
 }
 
0f26eec2
 #if 0
61ccfcc0
 /**
1fe2d0fd
  * Get (truncated) unary binarization.
61ccfcc0
  */
938dd846
 static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){
61ccfcc0
     int i;
115329f1
 
     for(i=0; i<max; i++){
61ccfcc0
         if(get_cabac(c, state)==0)
             return i;
115329f1
 
61ccfcc0
         if(i< max_index) state++;
     }
 
     return truncated ? max : -1;
 }
 
 /**
  * get unary exp golomb k-th order binarization.
  */
938dd846
 static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){
61ccfcc0
     int i, v;
     int m= 1<<k;
115329f1
 
     if(get_cabac(c, state)==0)
61ccfcc0
         return 0;
115329f1
 
61ccfcc0
     if(0 < max_index) state++;
115329f1
 
     for(i=1; i<max; i++){
61ccfcc0
         if(get_cabac(c, state)==0){
             if(is_signed && get_cabac_bypass(c)){
                 return -i;
             }else
                 return i;
         }
 
         if(i < max_index) state++;
     }
115329f1
 
61ccfcc0
     while(get_cabac_bypass(c)){
         i+= m;
         m+= m;
     }
115329f1
 
61ccfcc0
     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;
 }
0f26eec2
 #endif /* 0 */
26b4fe82
 
98790382
 #endif /* AVCODEC_CABAC_H */