先采用半径为2的大六边形模版搜索,若最优点是原点则采用半径为1的正方形模版搜索得出最优点,否则以最优点为中心继续以半径为2的大六边形模版搜索。
case X264_ME_HEX:
me_hex2:
/* hexagon search, radius 2 */
#if 0
for( i = 0; i < i_me_range/2; i++ )
{
omx = bmx; omy = bmy;
COST_MV( omx-2, omy ); //计算除原点之外的6个点的cost,并进行比较把最优值存于bcost,最优点位置存于bmx,bmy
COST_MV( omx-1, omy+2 );
COST_MV( omx+1, omy+2 );
COST_MV( omx+2, omy );
COST_MV( omx+1, omy-2 );
COST_MV( omx-1, omy-2 );
if( bmx == omx && bmy == omy ) //如果比较后的最优点仍是原点,则退出大六边形模版搜索
break;
if( !CHECK_MVRANGE(bmx, bmy) ) //如果已出界则停止搜索
break;
}
#else
/* equivalent to the above, but eliminates duplicate candidates */ //和上面一样,不同之处则只需计算新的3个点的cost,避免重复计算
/* hexagon */
COST_MV_X3_DIR( -2,0, -1, 2, 1, 2, costs ); //接下来两步计算6个点的cost存于costs数组
COST_MV_X3_DIR( 2,0, 1,-2, -1,-2, costs+3 );
bcost <<= 3;
COPY1_IF_LT( bcost, (costs[0]<<3)+2 ); //比较7个点的cost,并记录最优值和最优点的位置
COPY1_IF_LT( bcost, (costs[1]<<3)+3 );
COPY1_IF_LT( bcost, (costs[2]<<3)+4 );
COPY1_IF_LT( bcost, (costs[3]<<3)+5 );
COPY1_IF_LT( bcost, (costs[4]<<3)+6 );
COPY1_IF_LT( bcost, (costs[5]<<3)+7 );
if( bcost&7 ) //如果最优点不是原点,则以最优点为原点进行大六边形搜索
{
dir = (bcost&7)-2;
bmx += hex2[dir+1][0]; //记录新原点的位置
bmy += hex2[dir+1][1];
/* half hexagon, not overlapping the previous iteration */
for( i = 1; i < i_me_range/2 && CHECK_MVRANGE(bmx, bmy); i++ )
{
COST_MV_X3_DIR( hex2[dir+0][0], hex2[dir+0][1], //只需再计算3个点的cost
hex2[dir+1][0], hex2[dir+1][1],
hex2[dir+2][0], hex2[dir+2][1],
costs );
bcost &= ~7;
COPY1_IF_LT( bcost, (costs[0]<<3)+1 ); //只需拿原点和新3点的cost比较
COPY1_IF_LT( bcost, (costs[1]<<3)+2 );
COPY1_IF_LT( bcost, (costs[2]<<3)+3 );
if( !(bcost&7) ) //如果是原点则退出大六边形搜索
break;
dir += (bcost&7)-2;
dir = mod6m1[dir+1];
bmx += hex2[dir+1][0]; //否则记录最优点的位置,准备下一次搜索
bmy += hex2[dir+1][1];
}
}
bcost >>= 3;
#endif
/* square refine */ //正方形搜索,总共计算除原点之外的8个点的cost
dir = 0;
COST_MV_X4_DIR( 0,-1, 0,1, -1,0, 1,0, costs );
COPY2_IF_LT( bcost, costs[0], dir, 1 );
COPY2_IF_LT( bcost, costs[1], dir, 2 );
COPY2_IF_LT( bcost, costs[2], dir, 3 );
COPY2_IF_LT( bcost, costs[3], dir, 4 );
COST_MV_X4_DIR( -1,-1, -1,1, 1,-1, 1,1, costs );
COPY2_IF_LT( bcost, costs[0], dir, 5 );
COPY2_IF_LT( bcost, costs[1], dir, 6 );
COPY2_IF_LT( bcost, costs[2], dir, 7 );
COPY2_IF_LT( bcost, costs[3], dir, 8 );
bmx += square1[dir][0];
bmy += square1[dir][1];
break;