// 从缓存的mb.cache.ref[l], mb.cache.mv[l]
// 得到当前宏块左,顶, 顶右宏块参考帧序号,及其对应的运动向量
// 依据当前宏块与其左,顶,顶右宏块参考帧序号相同的情况
// 取某个mv 或 三者的median 作为候选的预测运动向量
//
void x264_mb_predict_mv_16x16( x264_t *h, int i_list, int i_ref, int16_t mvp[2] )
{
// left of ref
int i_refa = h->mb.cache.ref[i_list][X264_SCAN8_0 - 1];
// left of mv
int16_t *mv_a = h->mb.cache.mv[i_list][X264_SCAN8_0 - 1];
// top of ref
int i_refb = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8];
// top of mv
int16_t *mv_b = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8];
// topright of ref
int i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 + 4];
// topright of mv
int16_t *mv_c = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 + 4];
if( i_refc == -2 )
{ // topleft
i_refc = h->mb.cache.ref[i_list][X264_SCAN8_0 - 8 - 1];
mv_c = h->mb.cache.mv[i_list][X264_SCAN8_0 - 8 - 1];
}
// count the number of the same reference frame seqno of adjacent mb to current mb
int i_count = (i_refa == i_ref) + (i_refb == i_ref) + (i_refc == i_ref);
if( i_count > 1 )
{
median:
// let mvp = median of mv_a, mv_b, mv_c
x264_median_mv( mvp, mv_a, mv_b, mv_c );
}
else if( i_count == 1 )
{
if( i_refa == i_ref )
CP32( mvp, mv_a ); // mvp = mv_a
else if( i_refb == i_ref )
CP32( mvp, mv_b ); // mvp = mv_b
else
CP32( mvp, mv_c ); // mvp = mv_c
}
else if( i_refb == -2 && i_refc == -2 && i_refa != -2 )
CP32( mvp, mv_a ); // mvp = mv_a
else
goto median; // mvp = median of mv_a, mv_b, mv_c
}