⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t264enc.c

📁 h.264编码库 (T264)..........................
💻 C
📖 第 1 页 / 共 5 页
字号:
        }
        T264_cabac_encode_decision( &t->cabac, 69, (i_mode     )&0x01 );
        T264_cabac_encode_decision( &t->cabac, 69, (i_mode >> 1)&0x01 );
        T264_cabac_encode_decision( &t->cabac, 69, (i_mode >> 2)&0x01 );
    }
}

static void T264_cabac_mb_intra8x8_pred_mode( T264_t *t )
{
    const int i_mode  = t->mb.mb_mode_uv;
	T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);

	int ctx = 0;
	if( t->mb.mb_x > 0 && mb_ctxs[t->mb.mb_xy-1].mb_mode_uv != Intra_8x8_DC)
	{
		ctx++;
	}
	if( t->mb.mb_y > 0 && mb_ctxs[t->mb.mb_xy - t->mb_stride].mb_mode_uv != Intra_8x8_DC )
	{
		ctx++;
	}
	
    if( i_mode == Intra_8x8_DC )
    {
        T264_cabac_encode_decision( &t->cabac, 64 + ctx, Intra_8x8_DC );
    }
    else
    {
        T264_cabac_encode_decision( &t->cabac, 64 + ctx, 1 );
        T264_cabac_encode_decision( &t->cabac, 64 + 3, ( i_mode == 1 ? 0 : 1 ) );
        if( i_mode > 1 )
        {
            T264_cabac_encode_decision( &t->cabac, 64 + 3, ( i_mode == 2 ? 0 : 1 ) );
        }
    }
}

static void T264_cabac_mb_cbp_luma( T264_t *t )
{
    /* TODO: clean up and optimize */
	T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
    int i8x8;
    for( i8x8 = 0; i8x8 < 4; i8x8++ )
    {
        int i_mba_xy = -1;
        int i_mbb_xy = -1;
        int x = luma_inverse_x[4*i8x8];
        int y = luma_inverse_y[4*i8x8];
        int ctx = 0;

        if( x > 0 )
            i_mba_xy = t->mb.mb_xy;
        else if( t->mb.mb_x > 0 )
            i_mba_xy = t->mb.mb_xy - 1;

        if( y > 0 )
            i_mbb_xy = t->mb.mb_xy;
        else if( t->mb.mb_y > 0 )
            i_mbb_xy = t->mb.mb_xy - t->mb_stride;


        /* No need to test for PCM and SKIP */
        if( i_mba_xy >= 0 )
        {
            const int i8x8a = block_idx_xy[(x-1)&0x03][y]/4;
            if( ((mb_ctxs[i_mba_xy].cbp_y >> i8x8a)&0x01) == 0 )
            {
                ctx++;
            }
        }

        if( i_mbb_xy >= 0 )
        {
            const int i8x8b = block_idx_xy[x][(y-1)&0x03]/4;
            if( ((mb_ctxs[i_mbb_xy].cbp_y >> i8x8b)&0x01) == 0 )
            {
                ctx += 2;
            }
        }
															   
        T264_cabac_encode_decision( &t->cabac, 73 + ctx, (t->mb.cbp_y >> i8x8)&0x01 );
    }
}

static void T264_cabac_mb_cbp_chroma( T264_t *t )
{
    int cbp_a = -1;
    int cbp_b = -1;
    int ctx;
	T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
    /* No need to test for SKIP/PCM */
    if( t->mb.mb_x > 0 )
    {
        cbp_a = (mb_ctxs[t->mb.mb_xy - 1].cbp_c)&0x3;
    }

    if( t->mb.mb_y > 0 )
    {
        cbp_b = (mb_ctxs[t->mb.mb_xy - t->mb_stride].cbp_c)&0x3;
    }

    ctx = 0;
    if( cbp_a > 0 ) ctx++;
    if( cbp_b > 0 ) ctx += 2;
    if( t->mb.cbp_c == 0 )
    {
        T264_cabac_encode_decision( &t->cabac, 77 + ctx, 0 );
    }
    else
    {
        T264_cabac_encode_decision( &t->cabac, 77 + ctx, 1 );

        ctx = 4;
        if( cbp_a == 2 ) ctx++;
        if( cbp_b == 2 ) ctx += 2;
        T264_cabac_encode_decision( &t->cabac, 77 + ctx, t->mb.cbp_c > 1 ? 1 : 0 );
    }
}

/* TODO check it with != qp per mb */
static void T264_cabac_mb_qp_delta( T264_t *t )
{
    int i_mbn_xy = t->mb.mb_xy - 1;
    int i_dqp = t->mb.mb_qp_delta;
    int val = i_dqp <= 0 ? (-2*i_dqp) : (2*i_dqp - 1);
    int ctx;
	T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);

    /* No need to test for PCM / SKIP */
    if( i_mbn_xy >= 0 && mb_ctxs[i_mbn_xy].mb_qp_delta != 0 &&
        ( mb_ctxs[i_mbn_xy].mb_mode == I_16x16 || mb_ctxs[i_mbn_xy].cbp_y || mb_ctxs[i_mbn_xy].cbp_c) )
        ctx = 1;
    else
        ctx = 0;

    while( val > 0 )
    {
        T264_cabac_encode_decision( &t->cabac,  60 + ctx, 1 );
        if( ctx < 2 )
            ctx = 2;
        else
            ctx = 3;
        val--;
    }
    T264_cabac_encode_decision( &t->cabac,  60 + ctx, 0 );
}

void T264_cabac_mb_skip( T264_t *t, int b_skip )
{
	T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
    int ctx = 0;

    if( t->mb.mb_x > 0 && !IS_SKIP( mb_ctxs[t->mb.mb_xy -1].mb_mode) )
    {
        ctx++;
    }
    if( t->mb.mb_y > 0 && !IS_SKIP( mb_ctxs[t->mb.mb_xy - t->mb_stride].mb_mode) )
    {
        ctx++;
    }

    if( t->slice_type == SLICE_P )
        T264_cabac_encode_decision( &t->cabac, 11 + ctx, b_skip ? 1 : 0 );
    else /* SLICE_TYPE_B */
        T264_cabac_encode_decision( &t->cabac, 24 + ctx, b_skip ? 1 : 0 );
}

static __inline  void T264_cabac_mb_sub_p_partition( T264_t *t, int i_sub )
{
    if( i_sub == MB_8x8 )
    {
            T264_cabac_encode_decision( &t->cabac, 21, 1 );
    }
    else if( i_sub == MB_8x4 )
    {
            T264_cabac_encode_decision( &t->cabac, 21, 0 );
            T264_cabac_encode_decision( &t->cabac, 22, 0 );
    }
    else if( i_sub == MB_4x8 )
    {
            T264_cabac_encode_decision( &t->cabac, 21, 0 );
            T264_cabac_encode_decision( &t->cabac, 22, 1 );
            T264_cabac_encode_decision( &t->cabac, 23, 1 );
    }
    else if( i_sub == MB_4x4 )
    {
            T264_cabac_encode_decision( &t->cabac, 21, 0 );
            T264_cabac_encode_decision( &t->cabac, 22, 1 );
            T264_cabac_encode_decision( &t->cabac, 23, 0 );
    }
}

static __inline  void T264_cabac_mb_sub_b_partition( T264_t *t, int i_sub )
{
    if( i_sub == B_DIRECT_8x8 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 0 );
    }
    else if( i_sub == B_L0_8x8 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
    }
    else if( i_sub == B_L1_8x8 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
    }
    else if( i_sub == B_Bi_8x8 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
    }
    else if( i_sub == B_L0_8x4 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
    }
    else if( i_sub == B_L0_4x8 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
    }
    else if( i_sub == B_L1_8x4 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
    }
    else if( i_sub == B_L1_4x8 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
    }
    else if( i_sub == B_Bi_8x4 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
    }
    else if( i_sub == B_Bi_4x8 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
    }
    else if( i_sub == B_L0_4x4 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
    }
    else if( i_sub == B_L1_4x4 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 0 );
    }
    else if( i_sub == B_Bi_4x4 )
    {
        T264_cabac_encode_decision( &t->cabac, 36, 1 );
        T264_cabac_encode_decision( &t->cabac, 37, 1 );
        T264_cabac_encode_decision( &t->cabac, 38, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
        T264_cabac_encode_decision( &t->cabac, 39, 1 );
    }
}


static __inline  void T264_cabac_mb_ref( T264_t *t, int i_list, int idx )
{
	const int i8    = T264_scan8[idx];
	T264_mb_context_t *mb_ctxs = &(t->rec->mb[0]);
	const int i_refa = t->mb.vec_ref[i8 - 1].vec[i_list].refno;
    const int i_refb = t->mb.vec_ref[i8 - 8].vec[i_list].refno;
    int i_ref  = t->mb.vec_ref[i8].vec[i_list].refno;
	int a_direct, b_direct;
	int ctx  = 0;
	int luma_idx = luma_index[idx];
	if( t->slice_type==SLICE_B && t->mb.mb_x > 0 && (mb_ctxs[t->mb.mb_xy-1].mb_mode == B_SKIP||mb_ctxs[t->mb.mb_xy-1].is_copy ) && (luma_idx&0x03)==0)
	{
		a_direct = 1;
	}
	else
		a_direct = 0;
	if( t->slice_type==SLICE_B && t->mb.mb_y > 0 && (mb_ctxs[t->mb.mb_xy - t->mb_stride].mb_mode == B_SKIP||mb_ctxs[t->mb.mb_xy - t->mb_stride].is_copy) && luma_idx<4)
	{
		b_direct = 1;
	}
	else
		b_direct = 0;

    if( i_refa>0 && !a_direct)
        ctx++;
    if( i_refb>0 && !b_direct)
        ctx += 2;

    while( i_ref > 0 )
    {
        T264_cabac_encode_decision( &t->cabac, 54 + ctx, 1 );
        if( ctx < 4 )
            ctx = 4;
        else
            ctx = 5;

        i_ref--;
    }
    T264_cabac_encode_decision( &t->cabac, 54 + ctx, 0 );
}


static __inline  void  T264_cabac_mb_mvd_cpn( T264_t *t, int i_list, int i8, int l, int mvd )
{
    const int amvd = abs( t->mb.mvd_ref[i_list][i8 - 1][l] ) +
                     abs( t->mb.mvd_ref[i_list][i8 - 8][l] );
    const int i_abs = abs( mvd );
    const int i_prefix = T264_MIN( i_abs, 9 );
    const int ctxbase = (l == 0 ? 40 : 47);
    int ctx;
    int i;


    if( amvd < 3 )
        ctx = 0;
    else if( amvd > 32 )
        ctx = 2;
    else
        ctx = 1;

    for( i = 0; i < i_prefix; i++ )
    {
        T264_cabac_encode_decision( &t->cabac, ctxbase + ctx, 1 );
        if( ctx < 3 )
            ctx = 3;
        else if( ctx < 6 )
            ctx++;
    }
    if( i_prefix < 9 )
    {
        T264_cabac_encode_decision( &t->cabac, ctxbase + ctx, 0 );
    }

    if( i_prefix >= 9 )
    {
        int i_suffix = i_abs - 9;
        int k = 3;

        while( i_suffix >= (1<<k) )
        {
            T264_cabac_encode_bypass( &t->cabac, 1 );
            i_suffix -= 1 << k;
            k++;
        }
        T264_cabac_encode_bypass( &t->cabac, 0 );
        while( k-- )
        {
            T264_cabac_encode_bypass( &t->cabac, (i_suffix >> k)&0x01 );
        }
    }

    /* sign */
    if( mvd > 0 )
        T264_cabac_encode_bypass( &t->cabac, 0 );
    else if( mvd < 0 )
        T264_cabac_encode_bypass( &t->cabac, 1 );
}

static __inline  void  T264_cabac_mb_mvd( T264_t *t, int i_list, int idx, int width, int height )
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -