📄 macroblock.c
字号:
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 + -