HEVC代码追踪(十一。六):运动估计/补偿之xTZSearchHelp


/*
分析xTZSearch这个函数,xTZSearchHelp是当中最为重要的子函数之一。它实现最基本的功能:根据输入的搜索点坐标,
参考图像首地址,原始图像首地址,以及当前PU大小等相关信息,计算出SAD,并与之前保存的最佳值进行比较,更新到
目前为止的最佳值相关参数,如uiBestSad,搜索点坐标,搜索步长等。其他的函数如xTZ8PointSearch等搜索函数,最终
都是调用xTZSearchHelp进行误差匹配的。
*/
__inline Void TEncSearch::xTZSearchHelp( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance )
{
  UInt  uiSad;
  
  Pel*  piRefSrch;
  
  piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iYStride + iSearchX;//!< 参考图像Y分量的起始地址  
  
  //-- jclee for using the SAD function pointer
  m_pcRdCost->setDistParam( pcPatternKey, piRefSrch, rcStruct.iYStride,  m_cDistParam );//!< 该函数主要职能是设置计算SAD的函数指针,下面会更为详细地分析该函数  
  
  // fast encoder decision: use subsampled SAD when rows > 8 for integer ME
  if ( m_pcEncCfg->getUseFastEnc() )
  {
    if ( m_cDistParam.iRows > 8 )
    {
      m_cDistParam.iSubShift = 1;
    }
  }

  setDistParamComp(0);  // Y component

  // distortion
  m_cDistParam.bitDepth = g_bitDepthY;//!< 位深
  uiSad = m_cDistParam.DistFunc( &m_cDistParam );//!< 计算SAD
  
  // motion cost
  uiSad += m_pcRdCost->getCost( iSearchX, iSearchY );//!< 考虑上mv本身带来的开销
  
  if( uiSad < rcStruct.uiBestSad )//!< 更新最佳值
  {
    rcStruct.uiBestSad      = uiSad;//!< SAD
    rcStruct.iBestX         = iSearchX; //!< mv_x
    rcStruct.iBestY         = iSearchY;//!< mv_y
    rcStruct.uiBestDistance = uiDistance;//!< 搜索步长
    rcStruct.uiBestRound    = 0;//!< 搜索次数
    rcStruct.ucPointNr      = ucPointNr;//!< 搜索点序号
  }
}

// Setting the Distortion Parameter for Inter (ME)
Void TComRdCost::setDistParam( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, DistParam& rcDistParam )
{
  // set Original & Curr Pointer / Stride
  rcDistParam.pOrg = pcPatternKey->getROIY();//!< 感兴趣区即待搜索的原始图像首地址
  rcDistParam.pCur = piRefY;//!< 参考图像首地址
  
  rcDistParam.iStrideOrg = pcPatternKey->getPatternLStride();//!< 原始图像跨度
  rcDistParam.iStrideCur = iRefStride;//!< 参考图像跨度
  
  // set Block Width / Height
  rcDistParam.iCols    = pcPatternKey->getROIYWidth();//!< PU宽度
  rcDistParam.iRows    = pcPatternKey->getROIYHeight();//!< PU高度
  rcDistParam.DistFunc = m_afpDistortFunc[DF_SAD + g_aucConvertToBit[ rcDistParam.iCols ] + 1 ];//!< 根据PU的大小选择相应的失真计算函数  
  
#if AMP_SAD
  if (rcDistParam.iCols == 12)
  {
    rcDistParam.DistFunc = m_afpDistortFunc[43 ];
  }
  else if (rcDistParam.iCols == 24)
  {
    rcDistParam.DistFunc = m_afpDistortFunc[44 ];
  }
  else if (rcDistParam.iCols == 48)
  {
    rcDistParam.DistFunc = m_afpDistortFunc[45 ];
  }
#endif

  // initialize
  rcDistParam.iSubShift  = 0;
}


/// distortion parameter class
class DistParam
{
public:
  Pel*  pOrg;//!< 原始图像首地址
  Pel*  pCur;//!< 参考图像首地址
  Int   iStrideOrg;//!< 原始图像跨度
  Int   iStrideCur;//!< 参考图像跨度
  Int   iRows;//!< PU的宽度
  Int   iCols;//!< PU的高度
  Int   iStep;
  FpDistFunc DistFunc;//!< 计算失真的函数指针
  Int   bitDepth; //!< 位深 

  Bool            bApplyWeight;     // whether weithed prediction is used or not
  wpScalingParam  *wpCur;           // weithed prediction scaling parameters for current ref
  UInt            uiComp;           // uiComp = 0 (luma Y), 1 (chroma U), 2 (chroma V)

  // (vertical) subsampling shift (for reducing complexity)
  // - 0 = no subsampling, 1 = even rows, 2 = every 4th, etc.
  Int   iSubShift;//!< 下采样
  
  DistParam()
  {
    pOrg = NULL;
    pCur = NULL;
    iStrideOrg = 0;
    iStrideCur = 0;
    iRows = 0;
    iCols = 0;
    iStep = 1;
    DistFunc = NULL;
    iSubShift = 0;
    bitDepth = 0;
  }
};







你可能感兴趣的:(HEVC,运动估计)