logo资料库

JMVM2.1运动估计相关内容.pdf

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
仅供学习参考用途 070702 主题:运动估计相关内容 摘要:本文先介绍运动矢量搜索类,解释类中关于运动矢量搜索的参数含义和用法;接着介绍运动估计 类,简要解释了其中的主要函数的作用;最后主要函数 MotionEstimation::estimateBlockWithStart 的流程 图,此函数包含了运动估计的整个流程。 MotionVectorSearchParams 类,解释该类中运动矢量搜索的参数含义 class H264AVCENCODERLIB_API MotionVectorSearchParams { public: MotionVectorSearchParams() : m_eSearchMode(FAST_SEARCH), m_eFullPelDFunc(DF_SAD), m_eSubPelDFunc(DF_SAD), m_uiSearchRange(64), m_uiDirectMode(0) {} //具体默认参数的构造函数 ErrVal check() const; const SearchMode getSearchMode() const { return m_eSearchMode; } //确定搜索模式 Search Mode 0==Block,1==Spiral,2==Log,3==Fast, 4==NewFast const DFunc getFullPelDFunc() const { return m_eFullPelDFunc; } //整像素搜索时的函数 Search Func (Full Pel) 0==SAD,1==SSE,2==Hadamard,3==YUV-SAD" const DFunc getSubPelDFunc() const { return m_eSubPelDFunc; } //半像素搜索时的函数 Search Func (Sub Pel) 0==SAD,1==SSE,2==Hadamard" const UInt getSearchRange() const { return m_uiSearchRange; } //确定搜索范围 UInt getNumMaxIter () const { return m_uiNumMaxIter; } UInt getIterSearchRange() const { return m_uiIterSearchRange; } const UInt getDirectMode() const { return m_uiDirectMode; } //Direct 模式选择 0==Temporal, 1==Spatial Void setSearchMode( UInt uiSearchMode ) { m_eSearchMode = SearchMode(uiSearchMode); } Void setFullPelDFunc( UInt uiFullPelDFunc ) { m_eFullPelDFunc = DFunc(uiFullPelDFunc); } Void setSubPelDFunc( UInt uiSubPelDFunc ) { m_eSubPelDFunc = DFunc(uiSubPelDFunc); } Void setSearchRange ( UInt uiSearchRange) { m_uiSearchRange = uiSearchRange; } Void setNumMaxIter ( UInt uiNumMaxIter ) { m_uiNumMaxIter = uiNumMaxIter; } Void setIterSearchRange ( UInt uiIterSearchRange ) { m_uiIterSearchRange = uiIterSearchRange; } Void setDirectMode( UInt uiDirectMode) { m_uiDirectMode = uiDirectMode; } public: SearchMode m_eSearchMode; // 配置文件读取,默认值 0==Block DFunc m_eFullPelDFunc; // 配置文件读取,默认值 0==SAD DFunc m_eSubPelDFunc; // 配置文件读取,默认值 0==SAD UInt m_uiSearchRange; // 配置文件读取,默认值 96 UInt m_uiNumMaxIter; // 配置文件读取,默认值 4 UInt m_uiIterSearchRange; // 配置文件读取,默认值 8 UInt m_uiDirectMode; // 0 temporal, 1 spatial }; Copyright © qtluck & Institute of Circuits and Systems, Ningbo University 1/8
仅供学习参考用途 运动估计类 MotionEstimation class MotionEstimation : public MotionCompensation , public MotionEstimationCost { public: class MEBiSearchParameters //运动估计双向搜索参数 { public: IntYuvMbBuffer* pcAltRefPelData; // the prediction signal for the opposite list (not weighted) UInt uiL1Search; // 1 if current search is L1 search, else false const IntFrame* pcAltRefFrame; // the reference frame of the opposite list const PW* apcWeight[2]; // { list 0 prediction weight, list 1 prediction weight } }; protected: typedef struct { Void init( Short sLimit, Mv& rcMvPel, Mv cMin, Mv cMax) { cMin >>= 2; cMax >>= 2; Short sPosV = cMax.getVer() - rcMvPel.getVer(); Short sNegV = rcMvPel.getVer() - cMin.getVer(); iNegVerLimit = min( sLimit, sNegV) - rcMvPel.getVer(); iPosVerLimit = min( sLimit, sPosV) + rcMvPel.getVer(); Short sPosH = cMax.getHor() - rcMvPel.getHor(); Short sNegH = rcMvPel.getHor() - cMin.getHor(); iNegHorLimit = min( sLimit, sNegH) - rcMvPel.getHor(); iPosHorLimit = min( sLimit, sPosH) + rcMvPel.getHor(); } Int iNegVerLimit; Int iPosVerLimit; Int iNegHorLimit; Int iPosHorLimit; } SearchRect; //结构体 SearchRect,用于根据搜索范围确定搜索矩阵 typedef struct { XPel* pucYRef; XPel* pucURef; XPel* pucVRef; Int iYStride; Int iCStride; Copyright © qtluck & Institute of Circuits and Systems, Ningbo University 2/8
仅供学习参考用途 Int iBestX; Int iBestY; UInt uiBestRound; UInt uiBestDistance; UInt uiBestSad; UChar ucPointNr; #if TMS_SE_MVC_IC IcpInMs sBestIcpInMs; #endif } IntTZSearchStrukt; //快速搜索 TZ 方法的一些参数 protected: MotionEstimation(); //构造函数 virtual ~MotionEstimation(); //析构函数 public: ErrVal destroy(); virtual ErrVal uninit(); SampleWeighting* getSW() { return m_pcSampleWeighting; } ErrVal initMb( UInt uiMbPosY, UInt uiMbPosX, MbDataAccess& rcMbDataAccess ); //宏块初始化 virtual ErrVal init( XDistortion* pcXDistortion, CodingParameter* pcCodingParameter, RateDistortionIf* pcRateDistortionIf, QuarterPelFilter* pcQuarterPelFilter, Transform* pcTransform, SampleWeighting* pcSampleWeighting); UInt getRateCost ( UInt uiBits, Bool bSad) { xGetMotionCost( bSad, 0 ); return xGetCost( uiBits ); } ErrVal estimateBlockWithStart( const MbDataAccess& rcMbDataAccess, // estimateBlockWithStart const IntFrame& rcRefFrame, Mv& rcMv, // <-- MVSTART / --> MV Mv& rcMvPred, UInt& ruiBits, UInt& ruiCost, UInt uiBlk, UInt uiMode, Bool bQPelRefinementOnly, UInt uiSearchRange, const PW* pcPW, Copyright © qtluck & Institute of Circuits and Systems, Ningbo University 3/8
仅供学习参考用途 MEBiSearchParameters* pcBSP = 0 ); #if TMS_SE_MVC_IC ErrVal estimateBlockWithStart( Icp& rcIcp, // …. 此函数与上面 estimateBlockWithStart 功能相同。 #endif virtual ErrVal compensateBlock( IntYuvMbBuffer *pcRecPelData, UInt uiBlk, UInt uiMode, IntYuvMbBuffer *pcRefPelData2 = NULL ) = 0; DFunc getDistortionFunction() { return m_cParams.getSubPelDFunc(); } //块补偿函数 //TMM_WP Void setLstIdx( ListIdx eLstIdx) {m_eLstIdx = eLstIdx;} ListIdx getLstIdx() {return m_eLstIdx;} //TMM_WP protected: //TZ 快速搜索系列函数 Void xTZSearch ( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, UInt uiSearchRange = 0 ); __inline Void xTZSearchHelp ( IntTZSearchStrukt& rcStrukt, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance ); __inline Void xTZ2PointSearch ( IntTZSearchStrukt& rcStrukt, SearchRect rcSearchRect ); __inline Void xTZ8PointSquareSearch ( IntTZSearchStrukt& rcStrukt, SearchRect rcSearchRect, const Int iStartX, const Int iStartY, const Int iDist ); __inline Void xTZ8PointDiamondSearch( IntTZSearchStrukt& rcStrukt, SearchRect rcSearchRect, const Int iStartX, const Int iStartY, const Int iDist ); Void UInt uiSearchRange = 0 ); //块搜索函数 Search Mode 0 调用此函数 Void UInt uiSearchRange = 0 ); //螺旋搜索函数 Search Mode 1 调用此函数 Void xPelLogSearch ( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, Bool bFme, UInt uiStep = 4, UInt uiSearchRange = 0 ); //对数搜索 Search Mode 2 调用此函数 virtual Void xSubPelSearch ( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, UInt uiBlk, UInt uiMode, Bool bQPelOnly ) = 0; //半像素搜索函数 //TMM_WP Int getDistScaleFactor(Int iCurrPoc, Int iL0Poc, Int iL1Poc ) const; //TMM_WP #if TMS_SE_MVC_IC xPelBlockSearch ( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, xPelSpiralSearch( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, // ….该模式下搜索模式比较少 #endif protected: QuarterPelFilter* m_pcQuarterPelFilter; Copyright © qtluck & Institute of Circuits and Systems, Ningbo University 4/8
仅供学习参考用途 MotionVectorSearchParams m_cParams; Int m_iMaxLogStep; Mv *m_pcMvSpiralSearch; UInt m_uiSpiralSearchEntries; Mv m_cLastPelMv; Mv m_acMvPredictors[3]; XDistortion* m_pcXDistortion; XDistSearchStruct m_cXDSS; //TMM_WP ListIdx m_eLstIdx; //TMM_WP }; //主要函数 MotionEstimation::estimateBlockWithStart 的流程图 ErrVal MotionEstimation::estimateBlockWithStart( const MbDataAccess& rcMbDataAccess, const IntFrame& rcRefFrame, //参考帧 Mv& rcMv, // <-- MVSTART / --> MV Mv& rcMvPred, //Pred Mv UInt& ruiBits, //bits UInt& ruiCost, //cost UInt uiBlk, UInt uiMode, //searchmode Bool bQPelRefinementOnly, UInt uiSearchRange, //searchrange const PW* pcPW, MEBiSearchParameters* pcBSP ) { const LumaIdx cIdx = B4x4Idx(uiBlk); IntYuvMbBuffer* pcWeightedYuvBuffer = NULL; IntYuvPicBuffer* pcRefPelData[2]; IntYuvMbBuffer cWeightedYuvBuffer; pcRefPelData[0] = const_cast(rcRefFrame).getFullPelYuvBuffer(); pcRefPelData[1] = const_cast(rcRefFrame).getHalfPelYuvBuffer(); m_pcXDistortion->set4x4Block( cIdx ); pcRefPelData[0]->set4x4Block( cIdx ); pcRefPelData[1]->set4x4Block( cIdx ); if( bQPelRefinementOnly )rcMv = rcMvPred; Copyright © qtluck & Institute of Circuits and Systems, Ningbo University 5/8
仅供学习参考用途 UInt uiMinSAD = MSYS_UINT_MAX; Mv cMv = rcMv; Double fWeight = 1.0; Double afCW[2] = { 1.0, 1.0 }; Bool bOriginalSearchModeIsYUVSAD = ( m_cParams.getFullPelDFunc() == DF_YUV_SAD ); const Int iXSize = m_pcXDistortion->getBlockWidth ( uiMode ); const Int iYSize = m_pcXDistortion->getBlockHeight ( uiMode ); if( pcBSP ) // bi prediction { //…….双向预测 } else // unidirectional prediction 单向预测 { } //===== FULL-PEL ESTIMATION ====== if( bOriginalSearchModeIsYUVSAD && ( pcBSP /* bi-prediction */ || fWeight != afCW[0] || fWeight != afCW[1] /* different component weights */ ) ) { m_cParams.setFullPelDFunc( DF_SAD ); // set to normal SAD } // <<< heiko.schwarz@hhi.fhg.de (fix for uninitialized memory with YUV_SAD and bi-directional search) xGetMotionCost( ( 1 != m_cParams.getFullPelDFunc() ), 0 ); m_pcXDistortion->getDistStruct( uiMode, m_cParams.getFullPelDFunc(), false, m_cXDSS ); m_cXDSS.pYOrg = pcWeightedYuvBuffer->getLumBlk(); m_cXDSS.pUOrg = pcWeightedYuvBuffer->getCbBlk (); m_cXDSS.pVOrg = pcWeightedYuvBuffer->getCrBlk (); xSetPredictor( rcMvPred ); xSetCostScale( 2 ); if( ! bQPelRefinementOnly ) //这个参数不清楚 { if( uiSearchRange ) { xPelBlockSearch ( pcRefPelData[0], cMv, uiMinSAD, uiSearchRange ); } else { switch( m_cParams.getSearchMode() ) { case 0: Copyright © qtluck & Institute of Circuits and Systems, Ningbo University 6/8
仅供学习参考用途 { xPelBlockSearch ( pcRefPelData[0], cMv, uiMinSAD ); } break; case 1: { xPelSpiralSearch( pcRefPelData[0], cMv, uiMinSAD ); } break; case 2: { xPelLogSearch ( pcRefPelData[0], cMv, uiMinSAD, false, m_iMaxLogStep << ((NULL == pcBSP) ? 1 : 0) ); } break; case 3: { rcMbDataAccess.getMvPredictors( m_acMvPredictors ); xPelLogSearch ( pcRefPelData[0], cMv, uiMinSAD, true, (NULL == pcBSP) ? 2 : 1 ); } break; case 4: { rcMbDataAccess.getMvPredictors( m_acMvPredictors ); xTZSearch( pcRefPelData[0], cMv, uiMinSAD ); } break; default: RERR(); break; } } cMv <<= 2; } else { Mv cMvBase = cMv; cMv.limitComponents( m_cMin, m_cMax ); if( ! ( cMvBase == cMv ) ) { // don't refine in that case rcMv = cMvBase; ruiBits += 2; ruiCost = MSYS_UINT_MAX / 2; // >>>> bug fix by H.Schwarz 19/9/05 Copyright © qtluck & Institute of Circuits and Systems, Ningbo University 7/8
仅供学习参考用途 if( bOriginalSearchModeIsYUVSAD ) { m_cParams.setFullPelDFunc( DF_YUV_SAD ); } // <<<< bug fix by H.Schwarz 19/9/05 return Err::m_nOK; } } //===== SUB-PEL ESTIMATION ===== xGetMotionCost( 1 != ( 1 & m_cParams.getSubPelDFunc() ), 0 ); m_pcXDistortion->getDistStruct( uiMode, m_cParams.getSubPelDFunc(), false, m_cXDSS ); m_cXDSS.pYOrg = pcWeightedYuvBuffer->getLumBlk(); xSetCostScale( 0 ); xSubPelSearch( pcRefPelData[1], cMv, uiMinSAD, uiBlk, uiMode, bQPelRefinementOnly ); Short sHor = cMv.getHor(); Short sVer = cMv.getVer(); UInt uiMvBits = xGetBits( sHor, sVer ); ruiBits += uiMvBits; ruiCost = (UInt)floor( fWeight * (Double)( uiMinSAD - xGetCost( uiMvBits ) ) ) + xGetCost( ruiBits ); rcMv = cMv; return Err::m_nOK; } Copyright © qtluck & Institute of Circuits and Systems, Ningbo University 8/8
分享到:
收藏