x264运动估计六边形搜索源代码解析

先采用半径为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;

你可能感兴趣的:(search,hex)