x264源码,运动补偿get_ref函数
get_ref函数,用于构建当前宏块参考宏块的半像素数据, 首先看调用的地方很多,
例如:
x264_mb_analyse_inter_b8x8_mixed_ref->
{
src[0] = h->mc.get_ref( pix[0], &stride[0], a->l0.me8x8[i].p_fref, a->l0.me8x8[i].i_stride[0],
a->l0.me8x8[i].mv[0], a->l0.me8x8[i].mv[1], 8, 8, x264_weight_none );
src[1] = h->mc.get_ref( pix[1], &stride[1], a->l1.me8x8[i].p_fref, a->l1.me8x8[i].i_stride[0],
a->l1.me8x8[i].mv[0], a->l1.me8x8[i].mv[1], 8, 8, x264_weight_none );
}
static pixel *get_ref( pixel *dst, intptr_t *i_dst_stride,
pixel *src[4], intptr_t i_src_stride,
int mvx, int mvy,
int i_width, int i_height, const x264_weight_t *weight )
{
int qpel_idx = ((mvy&3)<<2) + (mvx&3);// 半像素index
index表示p(0,0)周围的三个半像素点的坐标index
int offset = (mvy>>2)*i_src_stride + (mvx>>2);// i_src_stride 为一行像素个数 mvy,mvx为当前宏块相对运动矢量
这里通过src(像素数据偏移绝对地址)和mvx,mvy。计算当前宏块参考块的绝对像素数据地址
pixel *src1 = src[x264_hpel_ref0[qpel_idx]] + offset + ((mvy&3) == 3) * i_src_stride;
if( qpel_idx & 5 ) /* qpel interpolation needed */
{
pixel *src2 = src[x264_hpel_ref1[qpel_idx]] + offset + ((mvx&3) == 3);
pixel_avg( dst, *i_dst_stride, src1, i_src_stride,
src2, i_src_stride, i_width, i_height );// 半像素插值
if( weight->weightfn )
{
mc_weight( dst, *i_dst_stride, dst, *i_dst_stride, weight, i_width, i_height );
//带权运动补偿,前面有博客讲解
}
return dst;
}
else if( weight->weightfn )
{
mc_weight( dst, *i_dst_stride, src1, i_src_stride, weight, i_width, i_height );
return dst;
}
else
{
*i_dst_stride = i_src_stride;
return src1;
}
}