@ -24,41 +24,51 @@
# include "libavutil/lfg.h"
# include "libavcodec/avcodec.h"
# include "libavcodec/put_bits.h"
static inline void put_cabac_bit ( CABACContext * c , int b ) {
typedef struct CABACTestContext {
CABACContext dec ;
int outstanding_count ;
PutBitContext pb ;
} CABACTestContext ;
static inline void put_cabac_bit ( CABACTestContext * c , int b )
{
put_bits ( & c - > pb , 1 , b ) ;
for ( ; c - > outstanding_count ; c - > outstanding_count - - ) {
put_bits ( & c - > pb , 1 , 1 - b ) ;
}
}
static inline void renorm_cabac_encoder ( CABACContext * c ) {
while ( c - > range < 0x100 ) {
static inline void renorm_cabac_encoder ( CABACTestContext * c )
{
while ( c - > dec . range < 0x100 ) {
//FIXME optimize
if ( c - > low < 0x100 ) {
if ( c - > dec . low < 0x100 ) {
put_cabac_bit ( c , 0 ) ;
} else if ( c - > low < 0x200 ) {
} else if ( c - > dec . low < 0x200 ) {
c - > outstanding_count + + ;
c - > low - = 0x100 ;
c - > dec . low - = 0x100 ;
} else {
put_cabac_bit ( c , 1 ) ;
c - > low - = 0x200 ;
c - > dec . low - = 0x200 ;
}
c - > range + = c - > range ;
c - > low + = c - > low ;
c - > dec . range + = c - > dec . range ;
c - > dec . low + = c - > dec . low ;
}
}
static void put_cabac ( CABACContext * c , uint8_t * const state , int bit ) {
int RangeLPS = ff_h264_lps_range [ 2 * ( c - > range & 0xC0 ) + * state ] ;
static void put_cabac ( CABACTestContext * c , uint8_t * const state , int bit )
{
int RangeLPS = ff_h264_lps_range [ 2 * ( c - > dec . range & 0xC0 ) + * state ] ;
if ( bit = = ( ( * state ) & 1 ) ) {
c - > range - = RangeLPS ;
c - > dec . range - = RangeLPS ;
* state = ff_h264_mlps_state [ 128 + * state ] ;
} else {
c - > low + = c - > range - RangeLPS ;
c - > range = RangeLPS ;
c - > dec . low + = c - > dec . range - RangeLPS ;
c - > dec . range = RangeLPS ;
* state = ff_h264_mlps_state [ 127 - * state ] ;
}
@ -68,21 +78,22 @@ static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
/**
* @ param bit 0 - > write zero bit , ! = 0 write one bit
*/
static void put_cabac_bypass ( CABACContext * c , int bit ) {
c - > low + = c - > low ;
static void put_cabac_bypass ( CABACTestContext * c , int bit )
{
c - > dec . low + = c - > dec . low ;
if ( bit ) {
c - > low + = c - > range ;
c - > dec . low + = c - > dec . range ;
}
//FIXME optimize
if ( c - > low < 0x200 ) {
if ( c - > dec . low < 0x200 ) {
put_cabac_bit ( c , 0 ) ;
} else if ( c - > low < 0x400 ) {
} else if ( c - > dec . low < 0x400 ) {
c - > outstanding_count + + ;
c - > low - = 0x200 ;
c - > dec . low - = 0x200 ;
} else {
put_cabac_bit ( c , 1 ) ;
c - > low - = 0x400 ;
c - > dec . low - = 0x400 ;
}
}
@ -90,20 +101,21 @@ static void put_cabac_bypass(CABACContext *c, int bit){
*
* @ return the number of bytes written
*/
static int put_cabac_terminate ( CABACContext * c , int bit ) {
c - > range - = 2 ;
static int put_cabac_terminate ( CABACTestContext * c , int bit )
{
c - > dec . range - = 2 ;
if ( ! bit ) {
renorm_cabac_encoder ( c ) ;
} else {
c - > low + = c - > range ;
c - > range = 2 ;
c - > dec . low + = c - > dec . range ;
c - > dec . range = 2 ;
renorm_cabac_encoder ( c ) ;
av_assert0 ( c - > low < = 0x1FF ) ;
put_cabac_bit ( c , c - > low > > 9 ) ;
put_bits ( & c - > pb , 2 , ( ( c - > low > > 7 ) & 3 ) | 1 ) ;
av_assert0 ( c - > dec . low < = 0x1FF ) ;
put_cabac_bit ( c , c - > dec . low > > 9 ) ;
put_bits ( & c - > pb , 2 , ( ( c - > dec . low > > 7 ) & 3 ) | 1 ) ;
flush_put_bits ( & c - > pb ) ; //FIXME FIXME FIXME XXX wrong
}
@ -111,8 +123,21 @@ static int put_cabac_terminate(CABACContext *c, int bit){
return ( put_bits_count ( & c - > pb ) + 7 ) > > 3 ;
}
/**
* @ param buf_size size of buf in bits
*/
static void init_cabac_encoder ( CABACTestContext * c , uint8_t * buf , int buf_size )
{
init_put_bits ( & c - > pb , buf , buf_size ) ;
c - > dec . low = 0 ;
c - > dec . range = 0x1FE ;
c - > outstanding_count = 0 ;
c - > pb . bit_left + + ; //avoids firstBitFlag
}
int main ( void ) {
CABACContext c ;
CABACTest Context c ;
uint8_t b [ 9 * SIZE ] ;
uint8_t r [ 9 * SIZE ] ;
int i , ret = 0 ;
@ -120,7 +145,7 @@ int main(void){
AVLFG prng ;
av_lfg_init ( & prng , 1 ) ;
ff_ init_cabac_encoder( & c , b , SIZE ) ;
init_cabac_encoder ( & c , b , SIZE ) ;
for ( i = 0 ; i < SIZE ; i + + ) {
if ( 2 * i < SIZE ) r [ i ] = av_lfg_get ( & prng ) % 7 ;
@ -139,24 +164,24 @@ int main(void){
b [ i + + ] = av_lfg_get ( & prng ) ;
b [ i ] = av_lfg_get ( & prng ) ;
ff_init_cabac_decoder ( & c , b , SIZE ) ;
ff_init_cabac_decoder ( & c . dec , b , SIZE ) ;
memset ( state , 0 , sizeof ( state ) ) ;
for ( i = 0 ; i < SIZE ; i + + ) {
if ( ( r [ i ] & 1 ) ! = get_cabac_bypass ( & c ) ) {
if ( ( r [ i ] & 1 ) ! = get_cabac_bypass ( & c . dec ) ) {
av_log ( NULL , AV_LOG_ERROR , " CABAC bypass failure at %d \n " , i ) ;
ret = 1 ;
}
}
for ( i = 0 ; i < SIZE ; i + + ) {
if ( ( r [ i ] & 1 ) ! = get_cabac_noinline ( & c , state ) ) {
if ( ( r [ i ] & 1 ) ! = get_cabac_noinline ( & c . dec , state ) ) {
av_log ( NULL , AV_LOG_ERROR , " CABAC failure at %d \n " , i ) ;
ret = 1 ;
}
}
if ( ! get_cabac_terminate ( & c ) ) {
if ( ! get_cabac_terminate ( & c . de c) ) {
av_log ( NULL , AV_LOG_ERROR , " where's the Terminator? \n " ) ;
ret = 1 ;
}