x264_mb_predict_mv_ref16x16 函数分析

来源:互联网 发布:mac休眠后无法唤醒 编辑:程序博客网 时间:2024/06/07 10:28

//  http://hi.baidu.com/cuihuanyubupt/item/a32ccedbd47d01fc93a9743b

 

//函数功能:寻找其它候选运动矢量。这些候选者包括://        空间相邻的左、左上、上、右上块的MV;第0个参考帧中的当前块、右边块、下边快运动矢量乘以时间差权重。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] = h->mb.mvr[i_list][i_ref];    int i = 0;#define SET_MVP(mvp) \    { \        CP32( mvc[i], mvp ); \        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 )//如果进行了下采样,并且i_ref==0    {        int idx = i_list ? h->fref1[0]->i_frame-h->fenc->i_frame-1                         : h->fenc->i_frame-h->fref0[0]->i_frame-1;  //取fref1 或fref0 的偏移当前帧的距离        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; //赋值为mvc[i]                i++;            }        }    }    /* spatial predictors */ //空间预测    SET_MVP( mvr[h->mb.i_mb_left_xy] );//取参考帧对应当前宏块的左方,上方,左上,右上的mv    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_MVP    /* temporal predictors */ //时间预测    if( h->fref0[0]->i_ref[0] > 0 )    {        x264_frame_t *l0 = h->fref0[0];        x264_frame_t **fref = i_list ? h->fref1 : h->fref0;//取参考帧list0 或者list1        int field = h->mb.i_mb_y&1;        int curpoc = h->fdec->i_poc + field*h->sh.i_delta_poc_bottom;//计算当前poc        int refpoc = fref[i_ref>>h->sh.b_mbaff]->i_poc;//计算参考帧poc        if( h->sh.b_mbaff && field^(i_ref&1) )            refpoc += h->sh.i_delta_poc_bottom;#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[h->mb.b_interlaced&field]; \             mvc[i][0] = (l0->mv16x16[mb_index][0]*scale + 128) >> 8; \  //进行加权计算mvc            mvc[i][1] = (l0->mv16x16[mb_index][1]*scale + 128) >> 8; \            i++; \        }        SET_TMVP(0,0);//取当前中心点        if( h->mb.i_mb_x < h->mb.i_mb_width-1 )//取当前中心点右侧点            SET_TMVP(1,0);        if( h->mb.i_mb_y < h->mb.i_mb_height-1 )  //取当前中心点下侧点            SET_TMVP(0,1);#undef SET_TMVP    }    *i_mvc = i;//mvc 的个数}


 

原创粉丝点击