您的位置:首页 > 其它

x264 - x264_mb_analyse_inter_p16x16

2014-06-14 13:39 501 查看
static void x264_mb_analyse_inter_p16x16( x264_t *h, x264_mb_analysis_t *a )

{

x264_me_t m;

int i_mvc;

ALIGNED_4( int16_t mvc[8][2] );

int i_halfpel_thresh = INT_MAX;

int *p_halfpel_thresh = (a->b_early_terminate && h->mb.pic.i_fref[0]>1) ? &i_halfpel_thresh : NULL;

/* 16x16 Search on all ref frame */

m.i_pixel = PIXEL_16x16;

// 将m的YUV 3个平面的编码指针指向h->mb.pic.p_fenc的YUV 3 个平面

LOAD_FENC( &m, h->mb.pic.p_fenc, 0, 0 );

// 初始化l0 最大估计值

a->l0.me16x16.cost = INT_MAX;

// 遍历l0 参考帧

for( int i_ref = 0; i_ref < h->mb.pic.i_fref[0]; i_ref++ )

{

// 得到 l0 参考帧 i_ref的代价

m.i_ref_cost = REF_COST( 0, i_ref );

i_halfpel_thresh -= m.i_ref_cost;

/* search with ref */

// i_ref 为参考帧序号

// 装载半像素平面, 见LOAD_HPELS

LOAD_HPELS( &m, h->mb.pic.p_fref[0][i_ref], 0, i_ref, 0, 0 );

LOAD_WPELS( &m, h->mb.pic.p_fref_w[i_ref], 0, i_ref, 0, 0 );

// 用当前宏块的邻块的运动矢量作为当前宏块的预测运动矢量

// left, top, topright, or topleft

// or median of left, top and (topright or topleft)

x264_mb_predict_mv_16x16( h, 0, i_ref, m.mvp );

if( h->mb.ref_blind_dupe == i_ref )

{

CP32( m.mv, a->l0.mvc[0][0] );

x264_me_refine_qpel_refdupe( h, &m, p_halfpel_thresh );

}

else

{

// 寻找其他候选运动矢量作为候选的预测运动矢量

// 参考帧 i_ref 对应宏块的left, top, topleft, topright mb 的运动矢量

// 次采样

// 时间预测

x264_mb_predict_mv_ref16x16( h, 0, i_ref, mvc, &i_mvc );

// 搜索最佳预测运动向量

x264_me_search_ref( h, &m, mvc, i_mvc, p_halfpel_thresh );

}

// 保存最佳运动向量

/* save mv for predicting neighbors */

CP32( h->mb.mvr[0][i_ref][h->mb.i_mb_xy], m.mv );

CP32( a->l0.mvc[i_ref][0], m.mv );

/* early termination

* SSD threshold would probably be better than SATD */

if( i_ref == 0

&& a->b_try_skip

&& m.cost-m.cost_mv < 300*a->i_lambda

&& abs(m.mv[0]-h->mb.cache.pskip_mv[0])

+ abs(m.mv[1]-h->mb.cache.pskip_mv[1]) <= 1

&& x264_macroblock_probe_pskip( h ) )

{

h->mb.i_type = P_SKIP;

x264_analyse_update_cache( h, a );

assert( h->mb.cache.pskip_mv[1] <= h->mb.mv_max_spel[1] || h->i_thread_frames == 1 );

return;

}

m.cost += m.i_ref_cost;

i_halfpel_thresh += m.i_ref_cost;

if( m.cost < a->l0.me16x16.cost )

h->mc.memcpy_aligned( &a->l0.me16x16, &m, sizeof(x264_me_t) );

}

x264_macroblock_cache_ref( h, 0, 0, 4, 4, 0, a->l0.me16x16.i_ref );

assert( a->l0.me16x16.mv[1] <= h->mb.mv_max_spel[1] || h->i_thread_frames == 1 );

h->mb.i_type = P_L0;

if( a->i_mbrd )

{

x264_mb_init_fenc_cache( h, a->i_mbrd >= 2 || h->param.analyse.inter & X264_ANALYSE_PSUB8x8 );

if( a->l0.me16x16.i_ref == 0 && M32( a->l0.me16x16.mv ) == M32( h->mb.cache.pskip_mv ) && !a->b_force_intra )

{

h->mb.i_partition = D_16x16;

x264_macroblock_cache_mv_ptr( h, 0, 0, 4, 4, 0, a->l0.me16x16.mv );

a->l0.i_rd16x16 = x264_rd_cost_mb( h, a->i_lambda2 );

if( !(h->mb.i_cbp_luma|h->mb.i_cbp_chroma) )

h->mb.i_type = P_SKIP;

}

}

}

#define LOAD_HPELS(m, src, list, ref, xoff, yoff) \

{ \

// 指向整像素平面Yn

(m)->p_fref_w = (m)->p_fref[0] = &(src)[0][(xoff)+(yoff)*(m)->i_stride[0]]; \

// 指向水平半像素平面 Yh

(m)->p_fref[1] = &(src)[1][(xoff)+(yoff)*(m)->i_stride[0]]; \

// 指向垂直半像素平面 Yv

(m)->p_fref[2] = &(src)[2][(xoff)+(yoff)*(m)->i_stride[0]]; \

// 指向斜对角半像素平面 Yhv

(m)->p_fref[3] = &(src)[3][(xoff)+(yoff)*(m)->i_stride[0]]; \

if( CHROMA444 ) \

{ \

// 指向整像素平面 Un

(m)->p_fref[ 4] = &(src)[ 4][(xoff)+(yoff)*(m)->i_stride[1]]; \

// 指向水平半像素平面 Uh

(m)->p_fref[ 5] = &(src)[ 5][(xoff)+(yoff)*(m)->i_stride[1]]; \

// 指向垂直半像素平面 Uv

(m)->p_fref[ 6] = &(src)[ 6][(xoff)+(yoff)*(m)->i_stride[1]]; \

// 指向斜对角半像素平面 Uhv

(m)->p_fref[ 7] = &(src)[ 7][(xoff)+(yoff)*(m)->i_stride[1]]; \

// 指向整像素平面 Vn

(m)->p_fref[ 8] = &(src)[ 8][(xoff)+(yoff)*(m)->i_stride[2]]; \

// 指向水平半像素平面 Vh

(m)->p_fref[ 9] = &(src)[ 9][(xoff)+(yoff)*(m)->i_stride[2]]; \

// 指向垂直半像素平面 Vv

(m)->p_fref[10] = &(src)[10][(xoff)+(yoff)*(m)->i_stride[2]]; \

// 指向斜对角半像素平面 Vhv

(m)->p_fref[11] = &(src)[11][(xoff)+(yoff)*(m)->i_stride[2]]; \

} \

else \

// 指向整像素平面 UV

(m)->p_fref[4] = &(src)[4][(xoff)+((yoff)>>CHROMA_V_SHIFT)*(m)->i_stride[1]]; \

(m)->integral = &h->mb.pic.p_integral[list][ref][(xoff)+(yoff)*(m)->i_stride[0]]; \

(m)->weight = x264_weight_none; \

(m)->i_ref = ref; \

}


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