/*
分析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;
}
};