cabac.c.svn-base

来自「H.264 source codes」· SVN-BASE 代码 · 共 1,045 行 · 第 1/3 页

SVN-BASE
1,045
字号
    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 + =
减小字号Ctrl + -
显示快捷键?