📄 cabac.c
字号:
FIX8(1.6015), FIX8(1.6767), FIX8(1.7519), FIX8(1.8271), FIX8(1.9023), FIX8(1.9775), FIX8(2.0527), FIX8(2.1278), FIX8(2.2030), FIX8(2.2782), FIX8(2.3534), FIX8(2.4286), FIX8(2.5038), FIX8(2.5790), FIX8(2.6542), FIX8(2.7294), FIX8(2.8046), FIX8(2.8797), FIX8(2.9549), FIX8(3.0301), FIX8(3.1053), FIX8(3.1805), FIX8(3.2557), FIX8(3.3309), FIX8(3.4061), FIX8(3.4813), FIX8(3.5565), FIX8(3.6316), FIX8(3.7068), FIX8(3.7820), FIX8(3.8572), FIX8(3.9324), FIX8(4.0076), FIX8(4.0828), FIX8(4.1580), FIX8(4.2332), FIX8(4.3083), FIX8(4.3836), FIX8(4.4588), FIX8(4.5339), FIX8(4.6091), FIX8(4.6843), FIX8(4.7595), FIX8(4.8347), FIX8(4.9099), FIX8(4.9851), FIX8(5.0602), FIX8(5.1354), FIX8(5.2106), FIX8(5.2859), FIX8(5.3610), FIX8(5.4362), FIX8(5.5114), FIX8(5.5866), FIX8(5.6618), FIX8(5.7370)};#undef FIX8/***************************************************************************** * *****************************************************************************/void x264_cabac_context_init( x264_cabac_t *cb, int i_slice_type, int i_qp, int i_model ){ const int (*cabac_context_init)[399][2]; int i; if( i_slice_type == SLICE_TYPE_I ) { cabac_context_init = &x264_cabac_context_init_I; } else { cabac_context_init = &x264_cabac_context_init_PB[i_model]; } for( i = 0; i < 399; i++ ) { int i_pre_state; i_pre_state = x264_clip3( (((*cabac_context_init)[i][0] * i_qp) >> 4) + (*cabac_context_init)[i][1], 1, 126 ); if( i_pre_state <= 63 ) { cb->ctxstate[i].i_state = 63 - i_pre_state; cb->ctxstate[i].i_mps = 0; } else { cb->ctxstate[i].i_state = i_pre_state - 64; cb->ctxstate[i].i_mps = 1; } cb->ctxstate[i].i_count = 0; }}/***************************************************************************** * *****************************************************************************/void x264_cabac_decode_init( x264_cabac_t *cb, bs_t *s ){ cb->i_range = 0x01fe; cb->i_low = bs_read( s, 9 ); cb->s = s;}static inline void x264_cabac_decode_renorm( x264_cabac_t *cb ){ while( cb->i_range < 0x0100 ) { cb->i_range <<= 1; cb->i_low = ( cb->i_low << 1 )|bs_read( cb->s, 1 ); }}int x264_cabac_decode_decision( x264_cabac_t *cb, int i_ctx ){ int i_state = cb->ctxstate[i_ctx].i_state; int i_mps = cb->ctxstate[i_ctx].i_mps; int i_range_lps = x264_cabac_range_lps[i_state][(cb->i_range>>6)&0x03]; int val; cb->i_range -= i_range_lps; if( cb->i_low >= cb->i_range ) { val = 1 - i_mps; cb->i_low -= cb->i_range; cb->i_range= i_range_lps; if( i_state == 0 ) { cb->ctxstate[i_ctx].i_mps = 1 - i_mps; } cb->ctxstate[i_ctx].i_state = x264_transition_lps[i_state]; } else { val = i_mps; cb->ctxstate[i_ctx].i_state = x264_transition_mps[i_state]; } x264_cabac_decode_renorm( cb ); return val;}int x264_cabac_decode_bypass( x264_cabac_t *cb ){ cb->i_low = (cb->i_low << 1)|bs_read( cb->s, 1 ); if( cb->i_low >= cb->i_range ) { cb->i_low -= cb->i_range; return 1; } return 0;}int x264_cabac_decode_terminal( x264_cabac_t *cb ){ if( cb->i_low >= cb->i_range - 2 ) { return 1; } cb->i_range -= 2; x264_cabac_decode_renorm( cb ); return 0;}/***************************************************************************** * *****************************************************************************/void x264_cabac_model_init( x264_cabac_t *cb ){ int i; for( i = 0; i < 3; i++ ) { cb->slice[i].i_model = 0; cb->slice[i].i_cost = -1; }}int x264_cabac_model_get ( x264_cabac_t *cb, int i_slice_type ){ return cb->slice[i_slice_type].i_model;}void x264_cabac_model_update( x264_cabac_t *cb, int i_slice_type, int i_qp ){ int i; if( i_slice_type == SLICE_TYPE_I ) { return; } cb->slice[i_slice_type].i_cost = -1; for( i = 0; i < 3; i++ ) { int i_ctx; int i_cost; i_cost = 0; /* fix8 */ for( i_ctx = 0; i_ctx < 399; i_ctx++ ) { int i_weight; int i_model_state; int i_ctx_state; i_weight = X264_MIN( (1<<8), (cb->ctxstate[i_ctx].i_count<<8) / 32 ); i_model_state = x264_clip3( ((x264_cabac_context_init_PB[i][i_ctx][0] * i_qp)>>4) + x264_cabac_context_init_PB[i][i_ctx][1], 0, 127 ); i_ctx_state = cb->ctxstate[i_ctx].i_mps ? 64 + cb->ctxstate[i_ctx].i_state : 63 - cb->ctxstate[i_ctx].i_state; i_cost += (i_weight * (( x264_cabac_probability[ i_ctx_state] * x264_cabac_entropy[ i_model_state] + x264_cabac_probability[127 - i_ctx_state] * x264_cabac_entropy[127 - i_model_state] ) >> 8))>>8; } if( cb->slice[i_slice_type].i_cost == -1 || cb->slice[i_slice_type].i_cost > i_cost ) { cb->slice[i_slice_type].i_model= i; cb->slice[i_slice_type].i_cost = i_cost; } }}void x264_cabac_encode_init( x264_cabac_t *cb, bs_t *s ){ cb->i_low = 0; cb->i_range = 0x01FE; cb->b_first_bit= 1; cb->i_bits_outstanding = 0; cb->i_sym_cnt = 0; cb->s = s;}static inline void x264_cabac_putbit( x264_cabac_t *cb, int b ){ if( cb->b_first_bit ) { cb->b_first_bit = 0; } else { bs_write1( cb->s, b ); } while( cb->i_bits_outstanding > 0 ) { bs_write1( cb->s, 1 - b ); cb->i_bits_outstanding--; }}static inline void x264_cabac_encode_renorm( x264_cabac_t *cb ){ /* RenormE */ while( cb->i_range < 0x0100 ) { if( cb->i_low < 0x100 ) { x264_cabac_putbit( cb, 0 ); } else { if( cb->i_low >= 0x200 ) { cb->i_low -= 0x200; x264_cabac_putbit( cb, 1 ); } else { cb->i_low -= 0x100; cb->i_bits_outstanding++; } } cb->i_range <<= 1; cb->i_low <<= 1; }}void x264_cabac_encode_decision( x264_cabac_t *cb, int i_ctx, int b ){ int i_state = cb->ctxstate[i_ctx].i_state; int i_mps = cb->ctxstate[i_ctx].i_mps; int i_range_lps = x264_cabac_range_lps[i_state][(cb->i_range>>6)&0x03];#ifdef TRACE if( binCount >= 0 ) { fprintf( stderr, "%d ctx=%d b=%d\n", binCount, i_ctx, b ); } fprintf( stderr, "%d 0x%04x %d %d\n", binCount++, cb->i_range, i_state, i_mps );#endif cb->i_range -= i_range_lps; if( b != i_mps ) { cb->i_low += cb->i_range; cb->i_range = i_range_lps; if( i_state == 0 ) { cb->ctxstate[i_ctx].i_mps = 1 - i_mps; } cb->ctxstate[i_ctx].i_state = x264_transition_lps[i_state]; } else { cb->ctxstate[i_ctx].i_state = x264_transition_mps[i_state]; } cb->ctxstate[i_ctx].i_count++; x264_cabac_encode_renorm( cb ); cb->i_sym_cnt++;}void x264_cabac_encode_bypass( x264_cabac_t *cb, int b ){#ifdef TRACE fprintf( stderr, "%d 0x%04x\n", binCount++, cb->i_range );#endif cb->i_low <<= 1; if( b ) { cb->i_low += cb->i_range; } if( cb->i_low >= 0x400 ) { x264_cabac_putbit( cb, 1 ); cb->i_low -= 0x400; } else { if( cb->i_low < 0x200 ) { x264_cabac_putbit( cb, 0 ); } else { cb->i_low -= 0x200; cb->i_bits_outstanding++; } } cb->i_sym_cnt++;}void x264_cabac_encode_terminal( x264_cabac_t *cb, int b ){#ifdef TRACE fprintf( stderr, "%d 0x%04x\n", binCount++, cb->i_range );#endif cb->i_range -= 2; if( b ) { cb->i_low += cb->i_range; cb->i_range = 2; } x264_cabac_encode_renorm( cb ); cb->i_sym_cnt++;}void x264_cabac_encode_flush( x264_cabac_t *cb ){ x264_cabac_putbit( cb, (cb->i_low >> 9)&0x01 ); bs_write1( cb->s, (cb->i_low >> 8)&0x01 ); /* check that */ bs_write1( cb->s, 0x01 ); bs_align_0( cb->s );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -