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

📄 macroblock.c

📁 H.264编码器
💻 C
📖 第 1 页 / 共 5 页
字号:
                x264_cabac_encode_decision( &h->cabac, 15, 1 );
                x264_cabac_encode_decision( &h->cabac, 17, 0 );
            }
        }
        else if( mb->i_type == P_8x8 )
        {
            x264_cabac_encode_decision( &h->cabac, 14, 0 );
            x264_cabac_encode_decision( &h->cabac, 15, 0 );
            x264_cabac_encode_decision( &h->cabac, 16, 1 );
        }
        else if( mb->i_type == I_4x4 )
        {
            /* prefix */
            x264_cabac_encode_decision( &h->cabac, 14, 1 );

            x264_cabac_encode_decision( &h->cabac, 17, 0 );
        }
        else if( mb->i_type == I_PCM )
        {
            /* prefix */
            x264_cabac_encode_decision( &h->cabac, 14, 1 );

            x264_cabac_encode_decision( &h->cabac, 17, 1 );
            x264_cabac_encode_terminal( &h->cabac, 1 ); /*ctxIdx == 276 */
        }
        else /* intra 16x16 */
        {
            /* prefix */
            x264_cabac_encode_decision( &h->cabac, 14, 1 );

            /* suffix */
            x264_cabac_encode_decision( &h->cabac, 17, 1 );
            x264_cabac_encode_terminal( &h->cabac, 0 ); /*ctxIdx == 276 */

            x264_cabac_encode_decision( &h->cabac, 17+1, ( mb->i_cbp_luma == 0 ? 0 : 1 ));
            if( mb->i_cbp_chroma == 0 )
            {
                x264_cabac_encode_decision( &h->cabac, 17+2, 0 );
            }
            else
            {
                x264_cabac_encode_decision( &h->cabac, 17+2, 1 );
                x264_cabac_encode_decision( &h->cabac, 17+2, ( mb->i_cbp_chroma == 1 ? 0 : 1 ) );
            }
            x264_cabac_encode_decision( &h->cabac, 17+3, ( (mb->i_intra16x16_pred_mode / 2) ? 1 : 0 ));
            x264_cabac_encode_decision( &h->cabac, 17+3, ( (mb->i_intra16x16_pred_mode % 2) ? 1 : 0 ));
        }
    }
    else
    {
        fprintf( stderr, "SLICE_TYPE_B unsupported in x264_macroblock_write_cabac\n" );
        return;
    }
}

static void x264_cabac_mb_intra4x4_pred_mode( x264_t *h, x264_macroblock_t *mb, int i_pred, int i_mode )
{
    if( i_pred == i_mode )
    {
        /* b_prev_intra4x4_pred_mode */
        x264_cabac_encode_decision( &h->cabac, 68, 1 );
    }
    else
    {
        /* b_prev_intra4x4_pred_mode */
        x264_cabac_encode_decision( &h->cabac, 68, 0 );
        if( i_mode > i_pred  )
        {
            i_mode--;
        }
        x264_cabac_encode_decision( &h->cabac, 69, (i_mode     )&0x01 );
        x264_cabac_encode_decision( &h->cabac, 69, (i_mode >> 1)&0x01 );
        x264_cabac_encode_decision( &h->cabac, 69, (i_mode >> 2)&0x01 );
    }
}
static void x264_cabac_mb_intra8x8_pred_mode( x264_t *h, x264_macroblock_t *mb )
{
    x264_macroblock_t *mba = mb->context->mba;
    x264_macroblock_t *mbb = mb->context->mbb;

    int i_ctxIdxInc    = 0;

    if( mba != NULL && ( mba->i_type == I_4x4 || mba->i_type == I_16x16 ) && mba->i_chroma_pred_mode != 0 )
    {
        i_ctxIdxInc++;
    }
    if( mbb != NULL && ( mbb->i_type == I_4x4 || mbb->i_type == I_16x16 ) && mbb->i_chroma_pred_mode != 0 )
    {
        i_ctxIdxInc++;
    }
    if( mb->i_chroma_pred_mode == 0 )
    {
        x264_cabac_encode_decision( &h->cabac, 64 + i_ctxIdxInc, 0 );
    }
    else
    {
        x264_cabac_encode_decision( &h->cabac, 64 + i_ctxIdxInc, 1 );
        x264_cabac_encode_decision( &h->cabac, 64 + 3, ( mb->i_chroma_pred_mode == 1 ? 0 : 1 ) );
        if( mb->i_chroma_pred_mode > 1 )
        {
            x264_cabac_encode_decision( &h->cabac, 64 + 3, ( mb->i_chroma_pred_mode == 2 ? 0 : 1 ) );
        }
    }
}

static void x264_cabac_mb_cbp_luma( x264_t *h, x264_macroblock_t *mb )
{
    int idx;
    x264_macroblock_t *mba;
    x264_macroblock_t *mbb;

    for( idx = 0;idx < 16; idx+=4 )
    {
        int i_ctxIdxInc;
        int i8x8a, i8x8b;
        int x, y;

        mba = mb->context->block[idx].mba;
        mbb = mb->context->block[idx].mbb;

        x = block_idx_x[idx]; y = block_idx_y[idx];

        i8x8a = block_idx_xy[(x-1)&0x03][y]/4;
        i8x8b = block_idx_xy[x][(y-1)&0x03]/4;

        i_ctxIdxInc = 0;
        if( mba != NULL && mba->i_type != I_PCM &&
           ( IS_SKIP( mba->i_type ) || ((mba->i_cbp_luma >> i8x8a)&0x01) == 0 ) )
        {
            i_ctxIdxInc++;
        }
        if( mbb != NULL && mbb->i_type != I_PCM &&
           ( IS_SKIP( mbb->i_type ) || ((mbb->i_cbp_luma >> i8x8b)&0x01) == 0 ) )
        {
            i_ctxIdxInc += 2;
        }
        x264_cabac_encode_decision( &h->cabac, 73 + i_ctxIdxInc, (mb->i_cbp_luma  >> (idx/4))&0x01 );
    }
}

static void x264_cabac_mb_cbp_chroma( x264_t *h, x264_macroblock_t *mb )
{
    x264_macroblock_t *mba = mb->context->mba;
    x264_macroblock_t *mbb = mb->context->mbb;
    int i_ctxIdxInc = 0;

    if( mba != NULL && !IS_SKIP( mba->i_type ) &&
        ( mba->i_type == I_PCM || mba->i_cbp_chroma != 0 ) )
    {
        i_ctxIdxInc++;
    }
    if( mbb != NULL && !IS_SKIP( mbb->i_type ) &&
        ( mbb->i_type == I_PCM || mbb->i_cbp_chroma != 0 ) )
    {
        i_ctxIdxInc += 2;
    }
    x264_cabac_encode_decision( &h->cabac, 77 + i_ctxIdxInc, (mb->i_cbp_chroma > 0 ? 1 : 0) );
    if( mb->i_cbp_chroma > 0 )
    {
        i_ctxIdxInc = 4;
        if( mba != NULL && !IS_SKIP( mba->i_type ) &&
            ( mba->i_type == I_PCM || mba->i_cbp_chroma == 2 ) )
        {
            i_ctxIdxInc++;
        }
        if( mbb != NULL && !IS_SKIP( mbb->i_type ) &&
            ( mbb->i_type == I_PCM || mbb->i_cbp_chroma == 2 ) )
        {
            i_ctxIdxInc += 2;
        }
        x264_cabac_encode_decision( &h->cabac, 77 + i_ctxIdxInc, (mb->i_cbp_chroma > 1 ? 1 : 0) );
    }
}

/* TODO check it with != qp per mb */
static void x264_cabac_mb_qp_delta( x264_t *h, x264_macroblock_t *mb )
{
    x264_macroblock_t *mbp = NULL;
    int i_slice_qp =  h->pps->i_pic_init_qp + h->sh.i_qp_delta;
    int i_last_dqp = 0;
    int i_ctxIdxInc = 0;
    int val;

    if( mb->i_mb_x > 0 || mb->i_mb_y > 0 )
    {
        mbp = mb - 1;
        if( mbp->i_mb_x > 0 || mbp->i_mb_y > 0 )
        {
            i_last_dqp = mbp->i_qp - (mbp-1)->i_qp;
        }
        else
        {
            i_last_dqp = mbp->i_qp - i_slice_qp;
        }
    }

    if( mbp != NULL &&
        !IS_SKIP( mbp->i_type ) && mbp->i_type != I_PCM &&
        i_last_dqp != 0 &&
        ( mbp->i_type == I_16x16 || mbp->i_cbp_luma != 0 || mbp->i_cbp_chroma != 0 ) )
    {
        i_ctxIdxInc = 1;
    }
    if( mbp )
        val = (mb->i_qp - mbp->i_qp) <= 0 ? (-2*(mb->i_qp - mbp->i_qp)) : (2*(mb->i_qp - mbp->i_qp)-1);
    else
        val = (mb->i_qp - i_slice_qp) <= 0 ? (-2*(mb->i_qp -i_slice_qp)) : (2*(mb->i_qp - i_slice_qp)-1);

    while( val > 0 )
    {
        x264_cabac_encode_decision( &h->cabac,  60 + i_ctxIdxInc, 1 );
        if( i_ctxIdxInc < 2 )
        {
            i_ctxIdxInc = 2;
        }
        else
        {
            i_ctxIdxInc = 3;
        }
        val--;
    }
    x264_cabac_encode_decision( &h->cabac,  60 + i_ctxIdxInc, 0 );
}

static int x264_cabac_mb_cbf_ctxidxinc( x264_macroblock_t *mb, int i_ctxBlockCat, int i_idx )
{
    x264_mb_context_t *ctx = mb->context;
    x264_macroblock_t *a = NULL;
    x264_macroblock_t *b = NULL;
    int i_nza = -1;
    int i_nzb = -1;

    int i_ctxIdxInc = 0;

    if( i_ctxBlockCat == 0 )
    {
        a = ctx->mba;
        b = ctx->mbb;

        if( a !=NULL && a->i_type == I_16x16 )
        {
            i_nza = array_non_zero_count( a->luma16x16_dc, 16 );
        }
        if( b !=NULL && b->i_type == I_16x16 )
        {
            i_nzb = array_non_zero_count( b->luma16x16_dc, 16 );
        }
    }
    else if( i_ctxBlockCat == 1 || i_ctxBlockCat == 2 )
    {
        int i8x8a, i8x8b;
        int x, y;

        a = ctx->block[i_idx].mba;
        b = ctx->block[i_idx].mbb;

        x = block_idx_x[i_idx];
        y = block_idx_y[i_idx];

        i8x8a = block_idx_xy[(x-1)&0x03][y]/4;
        i8x8b = block_idx_xy[x][(y-1)&0x03]/4;

        /* FIXME is &0x01 correct ? */
        if( a != NULL && !IS_SKIP( a->i_type ) && a->i_type != I_PCM &&
            ((a->i_cbp_luma >> i8x8a)) != 0 )
        {
            i_nza = ctx->block[i_idx].bka->i_non_zero_count;
        }
        if( b != NULL && !IS_SKIP( b->i_type ) && b->i_type != I_PCM &&
            ((b->i_cbp_luma >>i8x8b)) != 0 )
        {
            i_nzb = ctx->block[i_idx].bkb->i_non_zero_count;
        }
    }
    else if( i_ctxBlockCat == 3 )
    {
        a = ctx->mba;
        b = ctx->mbb;

        if( a != NULL && !IS_SKIP( a->i_type ) && a->i_type != I_PCM &&
            a->i_cbp_chroma != 0 )
        {
            i_nza = array_non_zero_count( a->chroma_dc[i_idx], 4 );
        }
        if( b != NULL && !IS_SKIP( b->i_type ) && b->i_type != I_PCM &&
            b->i_cbp_chroma != 0 )
        {
            i_nzb = array_non_zero_count( b->chroma_dc[i_idx], 4 );
        }
    }
    else if( i_ctxBlockCat == 4 )
    {
        a = ctx->block[16+i_idx].mba;
        b = ctx->block[16+i_idx].mbb;

        if( a != NULL && !IS_SKIP( a->i_type ) && a->i_type != I_PCM &&
            a->i_cbp_chroma == 2 )
        {
            i_nza = ctx->block[16+i_idx].bka->i_non_zero_count;
        }
        if( b != NULL && !IS_SKIP( b->i_type ) && b->i_type != I_PCM &&
            b->i_cbp_chroma == 2 )
        {
            i_nzb = ctx->block[16+i_idx].bkb->i_non_zero_count;
        }
    }

    if( ( a == NULL && IS_INTRA( mb->i_type ) ) || ( a != NULL && a->i_type == I_PCM ) || i_nza > 0 )
    {
        i_ctxIdxInc++;
    }
    if( ( b == NULL && IS_INTRA( mb->i_type ) ) || ( b != NULL && b->i_type == I_PCM ) || i_nzb > 0 )
    {
        i_ctxIdxInc += 2;
    }

    return i_ctxIdxInc + 4 * i_ctxBlockCat;
}

void x264_cabac_mb_skip( x264_t *h, x264_macroblock_t *mb, int b_skip )
{
    x264_macroblock_t *mba = mb->context->mba;
    x264_macroblock_t *mbb = mb->context->mbb;
    int i_ctxIdxInc = 0;

    if( mba != NULL && !IS_SKIP( mba->i_type ) )
    {
        i_ctxIdxInc++;
    }
    if( mbb != NULL && !IS_SKIP( mbb->i_type ) )
    {
        i_ctxIdxInc++;
    }

    if( h->sh.i_type == SLICE_TYPE_P )
    {
        x264_cabac_encode_decision( &h->cabac, 11 + i_ctxIdxInc, b_skip ? 1 : 0 );
    }
    else /* SLICE_TYPE_B */
    {
        x264_cabac_encode_decision( &h->cabac, 24 + i_ctxIdxInc, b_skip ? 1 : 0 );
    }
}

static void x264_cabac_mb_ref( x264_t *h, x264_macroblock_t *mb, int i_list, int i_part )
{
    x264_macroblock_t *a;
    x264_macroblock_t *b;

    int i_ctxIdxInc = 0;
    int i_ref;
    int i_refa = -1;
    int i_refb = -1;

    int x, y, xn, yn;

    x264_mb_partition_getxy( mb, i_part, 0, &x, &y );
    i_ref = mb->partition[x][y].i_ref[i_list];


    /* Left  pixel (-1,0)*/
    xn = x - 1;
    a = mb;
    if( xn < 0 )
    {
        xn += 4;
        a = mb->context->mba;
    }
    if( a && !IS_INTRA( a->i_type ) )
    {
        i_refa = a->partition[xn][y].i_ref[i_list];
    }

    /* Up ( pixel(0,-1)*/
    yn = y - 1;
    b = mb;
    if( yn < 0 )
    {
        yn += 4;
        b = mb->context->mbb;
    }
    if( b && !IS_INTRA( b->i_type ) )
    {
        i_refb = b->partition[x][yn].i_ref[i_list];
    }

    /* FIXME not complete for B frame (B_DIRECT and B_DIRECT 8x8 sub */
    if( i_refa > 0 && !IS_SKIP( a->i_type ) )
    {
        i_ctxIdxInc++;
    }
    if( i_refb > 0 && !IS_SKIP( b->i_type ) )
    {
        i_ctxIdxInc += 2;
    }

    while( i_ref > 0 )
    {
        x264_cabac_encode_decision( &h->cabac, 54 + i_ctxIdxInc, 1 );
        if( i_ctxIdxInc < 4 )
        {
            i_ctxIdxInc = 4;
        }
        else
        {
            i_ctxIdxInc = 5;
        }
        i_ref--;
    }
    x264_cabac_encode_decision( &h->cabac, 54 + i_ctxIdxInc, 0 );
}

static void  x264_cabac_mb_mvd( x264_t *h, int i_ctx, int i_ctx_inc, int mvd )
{
    int i_abs = abs( mvd );
    int i_prefix = X264_MIN( i_abs, 9 );
    int i;

    for( i = 0; i < i_prefix; i++ )
    {
        x264_cabac_encode_decision( &h->cabac, i_ctx + i_ctx_inc, 1 );
        if( i_ctx_inc < 3 )
        {
            i_ctx_inc = 3;
        }
        else if( i_ctx_inc < 6 )
        {
            i_ctx_inc++;
        }
    }
    if( i_prefix < 9 )
    {
        x264_cabac_encode_decision( &h->cabac, i_ctx + i_ctx_inc, 0 );
    }

    if( i_prefix >= 9 )
    {

⌨️ 快捷键说明

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