x264 - x264_mb_predict_mv_ref16x16





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 数目
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值