您的位置:首页 > 其它

x264 - x264_mb_predict_mv_ref16x16

2014-06-11 15:12 645 查看
void x264_mb_predict_mv_ref16x16( x264_t *h, int i_list, int i_ref, int16_t mvc[9][2], int *i_mvc )

{

// int16_t (*mvr[2][X264_REF_MAX*2])[2];/* 16x16 mv for each possible ref */

// mb.mvr 是一个指针数组, 指向一块int16_t[2]的数组

// 数组的每一个item保存的是该索引对应的宏块的最佳预测运动向量

// 因此mb.mvr保存的是每个参考list中每个参考帧每个16x16宏块的最佳预测运动向量

int16_t (*mvr)[2] = h->mb.mvr[i_list][i_ref];

int i = 0;

// SET_MVP宏就是拷贝mvp到mvc数组,并将mvc索引增加1

#define SET_MVP(mvp) \

{ \

CP32( mvc[i], mvp ); \

i++; \

}

// 专为SLICE_MBAFF定义的宏

#define SET_IMVP(xy) \

if( xy >= 0 ) \

{ \

int shift = 1 + MB_INTERLACED - h->mb.field[xy]; \

int16_t *mvp = h->mb.mvr[i_list][i_ref<<1>>shift][xy]; \

mvc[i][0] = mvp[0]; \

mvc[i][1] = mvp[1]<<1>>shift; \

i++; \

}

/* b_direct */

if( h->sh.i_type == SLICE_TYPE_B

&& h->mb.cache.ref[i_list][x264_scan8[12]] == i_ref )

{

SET_MVP( h->mb.cache.mv[i_list][x264_scan8[12]] );

}

if( i_ref == 0 && h->frames.b_have_lowres )

{

int idx = i_list ? h->fref[1][0]->i_frame-h->fenc->i_frame-1

: h->fenc->i_frame-h->fref[0][0]->i_frame-1;

if( idx <= h->param.i_bframe )

{

int16_t (*lowres_mv)[2] = h->fenc->lowres_mvs[i_list][idx];

if( lowres_mv[0][0] != 0x7fff )

{

M32( mvc[i] ) = (M32( lowres_mv[h->mb.i_mb_xy] )*2)&0xfffeffff;

i++;

}

}

}

/* spatial predictors */

if( SLICE_MBAFF )

{

SET_IMVP( h->mb.i_mb_left_xy[0] );

SET_IMVP( h->mb.i_mb_top_xy );

SET_IMVP( h->mb.i_mb_topleft_xy );

SET_IMVP( h->mb.i_mb_topright_xy );

}

else

{

// 保存参考list 为i_list, 参考帧索引号为i_ref

// 对应宏块的左宏块的mv到mvc数组

SET_MVP( mvr[h->mb.i_mb_left_xy[0]] );

// 顶宏块

SET_MVP( mvr[h->mb.i_mb_top_xy] );

// 顶左宏块

SET_MVP( mvr[h->mb.i_mb_topleft_xy] );

// 顶右宏块

SET_MVP( mvr[h->mb.i_mb_topright_xy] );

}

#undef SET_IMVP

#undef SET_MVP

// 时间预测

/* temporal predictors */

if( h->fref[0][0]->i_ref[0] > 0 )

{

x264_frame_t *l0 = h->fref[0][0];

int field = h->mb.i_mb_y&1;

// calc poc of reconstruct frame

int curpoc = h->fdec->i_poc + h->fdec->i_delta_poc[field];

// calc poc of reference frame

int refpoc = h->fref[i_list][i_ref>>SLICE_MBAFF]->i_poc;

refpoc += l0->i_delta_poc[field^(i_ref&1)];

#define SET_TMVP( dx, dy ) \

{ \

int mb_index = h->mb.i_mb_xy + dx + dy*h->mb.i_mb_stride; \

int scale = (curpoc - refpoc) * l0->inv_ref_poc[MB_INTERLACED&field]; \

mvc[i][0] = (l0->mv16x16[mb_index][0]*scale + 128) >> 8; \

mvc[i][1] = (l0->mv16x16[mb_index][1]*scale + 128) >> 8; \

i++; \

}

SET_TMVP(0,0); // 当前宏块预测运动向量进行 scale

if( h->mb.i_mb_x < h->mb.i_mb_width-1 )

SET_TMVP(1,0); // 当前宏块右宏块预测向量进行 scale

if( h->mb.i_mb_y < h->mb.i_mb_height-1 )

SET_TMVP(0,1); // 当前宏块底宏块预测向量进行 scale

#undef SET_TMVP

}

*i_mvc = i; // 返回 候选的 mv 数目

}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: