编解码里面我觉得最核心的就运动估计这块了,一般JM代码会提供全搜索、快速搜索,以及非对称十字型多层六边形格点搜索算法(简称UMHS)是清华几个牛人搞出来的,比起全搜索节省90%的运算量,由于物体的运动千变万化,很难用一种简单的模型去描述,也很难用一种单一的算法来搜索最佳运动矢量,因此实际上大多采用多种搜索算法相组合的方法来提高预测的有效性。
UMHS运动估计步骤:
1. 搜索过程的起始搜索点搜索,一般开始是(0,0)
2. 非对称的十字交叉搜索。 原因:由于自然界物体运动水平方向要比垂直方向剧烈一些。
3. 5*5小矩形全搜索。
4. 扩展的多层次大六边形搜索
5. 菱形搜索。
UMHS关键代码:
void UMHexagonSOnePt( umhs_img *img, int iMvX, int iMvY, umhs_stat *p_state )
{
clipMv( &iMvX, &iMvY, img );
// should be in the search window
if( abs(iMvX - p_state->iCentX) <= p_state->iRange && abs(iMvY - p_state->iCentY) <= p_state->iRange )
{
// check if already searched
if ( img->m_pcSearch->m_ppiMcostState [iMvY - p_state->iCentY + p_state->iRange][iMvX - p_state->iCentX + p_state->iRange] == 0 )
{
// axis of the pixel of the current MB.
int pix_x_t = (img->m_iMBX << LOG2_MB_SIZE) + IMG_PAD_SIZE;
int pix_y_t = (img->m_iMBY << LOG2_MB_SIZE) + IMG_PAD_SIZE;
int iCost = 0;
Pel *src = img->m_cPic[1].m_pPixY + pix_x_t + pix_y_t * img->m_cPic[1].m_iStrideY;
Pel *dst = img->m_cPic[0].m_pPixY + pix_x_t + iMvX + (pix_y_t + iMvY) * img->m_cPic[0].m_iStrideY;
// cost = SAD + lambda*bits
iCost = GetSAD ( src, dst, img->m_cPic[1].m_iStrideY, img->m_cPic[0].m_iStrideY, 1 << LOG2_MB_SIZE, 1 << LOG2_MB_SIZE, p_state->iMinCost);
iCost += MV_COST ( img->m_dLambdaMotion, iMvY - p_state->iCentY, iMvX - p_state->iCentX );
if( iCost < p_state->iMinCost )
{
p_state->iMinCost = iCost;
p_state->iBestX = iMvX;
p_state->iBestY = iMvY;
}
img->m_pcSearch->m_ppiMcostState [iMvY - p_state->iCentY + p_state->iRange][iMvX - p_state->iCentX + p_state->iRange] = 1;
}
}
}