一 首先了解几个概念
这两种块类型都是帧间块
mv:运动向量 = mvd + mvp
mvd:运动向量差值
mvp:运动向量预测值,有周围的块的mv预测出来
skip宏块,是即没有mvd,也没有残差。
Direct块,没有mvd,但是有残差。
二 Direct块cost计算
static void mb_analyse_inter_direct( x264_t *h, x264_mb_analysis_t *a )
{
/* Assumes that fdec still contains the results of
* x264_mb_predict_mv_direct16x16 and x264_mb_mc */
pixel *p_fenc = h->mb.pic.p_fenc[0];//当前像素数据
pixel *p_fdec = h->mb.pic.p_fdec[0];//参考像素数据
a->i_cost16x16direct = a->i_lambda * i_mb_b_cost_table[B_DIRECT];
if( h->param.analyse.inter & X264_ANALYSE_BSUB16x16 )
{
int chromapix = h->luma2chroma_pixel[PIXEL_8x8];
for( int i = 0; i < 4; i++ )
{// 4个 8x8的块
const int x = (i&1)*8;// 通过循环的index, 找到对应的像素在当前宏块中的坐标位置,比如(0,0)(0,8)(8,0)(8,8)
const int y = (i>>1)*8;
a->i_cost8x8direct[i] = h->pixf.mbcmp[PIXEL_8x8]( &p_fenc[x+y*FENC_STRIDE], FENC_STRIDE, &p_fdec[x+y*FDEC_STRIDE], FDEC_STRIDE );
if( h->mb.b_chroma_me )
{
int fenc_offset = (x>>CHROMA_H_SHIFT) + (y>>CHROMA_V_SHIFT)*FENC_STRIDE;
int fdec_offset = (x>>CHROMA_H_SHIFT) + (y>>CHROMA_V_SHIFT)*FDEC_STRIDE;
a->i_cost8x8direct[i] += h->pixf.mbcmp[chromapix]( &h->mb.pic.p_fenc[1][fenc_offset], FENC_STRIDE, &h->mb.pic.p_fdec[1][fdec_offset], FDEC_STRIDE ) + h->pixf.mbcmp[chromapix]( &h->mb.pic.p_fenc[2][fenc_offset], FENC_STRIDE,
&h->mb.pic.p_fdec[2][fdec_offset], FDEC_STRIDE );
}
a->i_cost16x16direct += a->i_cost8x8direct[i];
/* mb type cost */
a->i_cost8x8direct[i] += a->i_lambda * i_sub_mb_b_cost_table[D_DIRECT_8x8];//把四个8x8的Direct块的向量额外开销加起来,
}
}
else
{
a->i_cost16x16direct += h->pixf.mbcmp[PIXEL_16x16]( p_fenc, FENC_STRIDE, p_fdec, FDEC_STRIDE );//计算 16x16satd
if( h->mb.b_chroma_me )
{
int chromapix = h->luma2chroma_pixel[PIXEL_16x16];
a->i_cost16x16direct += h->pixf.mbcmp[chromapix]( h->mb.pic.p_fenc[1], FENC_STRIDE, h->mb.pic.p_fdec[1], FDEC_STRIDE )
+ h->pixf.mbcmp[chromapix]( h->mb.pic.p_fenc[2], FENC_STRIDE, h->mb.pic.p_fdec[2], FDEC_STRIDE );//计算16x16的Direct块残差
}
}
}