*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
-
+
/**
* @file cabac.h
* Context Adaptive Binary Arithmetic Coder.
*/
-#undef NDEBUG
+//#undef NDEBUG
#include <assert.h>
#define CABAC_BITS 8
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
-void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4],
+void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4],
uint8_t const *mps_state, uint8_t const *lps_state, int state_count);
static inline void put_cabac_bit(CABACContext *c, int b){
- put_bits(&c->pb, 1, b);
- for(;c->outstanding_count; c->outstanding_count--){
+ put_bits(&c->pb, 1, b);
+ for(;c->outstanding_count; c->outstanding_count--){
put_bits(&c->pb, 1, 1-b);
}
}
put_cabac_bit(c, 1);
c->low -= 0x200;
}
-
+
c->range+= c->range;
c->low += c->low;
}
static inline void put_cabac(CABACContext *c, uint8_t * const state, int bit){
int RangeLPS= c->lps_range[*state][c->range>>6];
-
+
if(bit == ((*state)&1)){
c->range -= RangeLPS;
*state= c->mps_state[*state];
c->range = RangeLPS;
*state= c->lps_state[*state];
}
-
+
renorm_cabac_encoder(c);
#ifdef STRICT_LIMITS
put_cabac_bit(c, 1);
c->low -= 0x400;
}
-
+
#ifdef STRICT_LIMITS
c->symCount++;
#endif
}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
*/
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);
*/
static inline 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= ABS(v);
-
+
if(v<max){
for(i=0; i<v; i++){
put_cabac(c, state, 1);
}
static void refill(CABACContext *c){
- if(c->bytestream < c->bytestream_end)
+ if(c->bytestream <= c->bytestream_end)
#if CABAC_BITS == 16
c->low+= ((c->bytestream[0]<<9) + (c->bytestream[1])<<1);
#else
i= 8 - ff_h264_norm_shift[x>>(CABAC_BITS+1)];
x= -CABAC_MASK;
-
+
if(c->bytestream < c->bytestream_end)
#if CABAC_BITS == 16
x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
#else
x+= c->bytestream[0]<<1;
#endif
-
+
c->low += x<<i;
c->bytestream+= CABAC_BITS/8;
}
static inline int get_cabac(CABACContext *c, uint8_t * const state){
int RangeLPS= c->lps_range[*state][c->range>>(CABAC_BITS+7)]<<(CABAC_BITS+1);
int bit, lps_mask attribute_unused;
-
+
c->range -= RangeLPS;
#if 1
if(c->low < c->range){
}
#else
lps_mask= (c->range - c->low)>>31;
-
+
c->low -= c->range & lps_mask;
c->range += (RangeLPS - c->range) & lps_mask;
-
+
bit= ((*state)^lps_mask)&1;
*state= c->mps_state[(*state) - (128&lps_mask)];
-
+
lps_mask= ff_h264_norm_shift[c->range>>(CABAC_BITS+2)];
c->range<<= lps_mask;
c->low <<= lps_mask;
refill2(c);
#endif
- return bit;
+ return bit;
}
static inline int get_cabac_bypass(CABACContext *c){
if(!(c->low & CABAC_MASK))
refill(c);
-
+
if(c->low < c->range){
return 0;
}else{
return 0;
}else{
return c->bytestream - c->bytestream_start;
- }
+ }
}
/**
*/
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++){
+
+ for(i=0; i<max; i++){
if(get_cabac(c, state)==0)
return i;
-
+
if(i< max_index) state++;
}
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)
+
+ if(get_cabac(c, state)==0)
return 0;
-
+
if(0 < max_index) state++;
-
- for(i=1; i<max; i++){
+
+ for(i=1; i<max; i++){
if(get_cabac(c, state)==0){
if(is_signed && get_cabac_bypass(c)){
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);