HEVC幀間預測之五——運動估計(二)
阿新 • • 發佈:2019-01-29
分析xTZSearch這個函式,xTZSearchHelp是當中最為重要的子函式之一。它實現最基本的功能:根據輸入的搜尋點座標,參考影象首地址,原始影象首地址,以及當前PU大小等相關資訊,計算出SAD,並與之前儲存的最佳值進行比較,更新到目前為止的最佳值相關引數,如uiBestSad,搜尋點座標,搜尋步長等。其他的函式如xTZ8PointSearch等搜尋函式,最終都是呼叫xTZSearchHelp進行誤差匹配的。因此,我們有必要先來了解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 //!< 為非對稱分割槽AMP預測模式提供專用的失真函式 if (rcDistParam.iCols == 12) { rcDistParam.DistFunc = m_afpDistortFunc[43 ]; //!< TComRdCost::xGetSAD12 } else if (rcDistParam.iCols == 24) { rcDistParam.DistFunc = m_afpDistortFunc[44 ]; //!< TComRdCost::xGetSAD24 } else if (rcDistParam.iCols == 48) { rcDistParam.DistFunc = m_afpDistortFunc[45 ]; //!< TComRdCost::xGetSAD48 } #endif // initialize rcDistParam.iSubShift = 0; //!< (vertical) subsampling shift (for reducing complexity) }
/// 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) #if NS_HAD Bool bUseNSHAD; #endif // (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; #if NS_HAD bUseNSHAD = false; #endif } };
具體的SAD計算函式這裡不一一列舉,功能其實很簡單,就是根據PU所包含的總的畫素數計算參考影象與原始影象的畫素差的絕對值的總和。