shithub: openh264

Download patch

ref: 6c3d83a8ac4df68f0df1fd1edd6f96ce49ddca50
parent: 8492aac917af81807ca7b3c33d27b318e44ee3e7
author: sijchen <sijchen@cisco.com>
date: Fri Mar 14 11:04:35 EDT 2014

refactor ME for easier adding other search methods

--- a/codec/encoder/core/inc/svc_motion_estimate.h
+++ b/codec/encoder/core/inc/svc_motion_estimate.h
@@ -83,12 +83,9 @@
  *
  * \return	NONE
  */
-void WelsMotionEstimateSearchSatd (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
+void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
 
-void WelsMotionEstimateSearchSad (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
 
-
-
 /*!
  * \brief	BL mb motion estimate initial point testing
  *
@@ -112,7 +109,7 @@
  * \return	NONE
  */
 
-void WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice,
+bool WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice,
                                      const int32_t kiStrideEnc, const int32_t kiStrideRef);
 
 /*!
@@ -129,6 +126,9 @@
 
 bool WelsMeSadCostSelect (int32_t* pSadCost, const uint16_t* kpMvdCost, int32_t* pBestCost, const int32_t kiDx,
                             const int32_t kiDy, int32_t* pIx, int32_t* pIy);
+
+void CalculateSatdCost( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride );
+void NotCalculateSatdCost( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride );
 
 inline void SetMvWithinMvRange( const int32_t kiMbWidth, const int32_t kiMbHeight, const int32_t kiMbX, const int32_t kiMbY,
                         const int32_t kiMaxMvRange,
--- a/codec/encoder/core/inc/wels_func_ptr_def.h
+++ b/codec/encoder/core/inc/wels_func_ptr_def.h
@@ -112,8 +112,6 @@
 typedef void (*PInterFineMdFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb, int32_t bestCost);
 typedef bool (*PInterMdFirstIntraModeFunc) (void* pEncCtx, void* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
 
-typedef void (*PMotionSearchFunc) (SWelsFuncPtrList* pFuncList, void* pCurDqLayer, void* pMe,
-                                   void* pSlice);  // here after reset all function pointers, will set as right parameter type
 typedef void (*PFillInterNeighborCacheFunc) (SMbCache* pMbCache, SMB* pCurMb, int32_t iMbWidth, int8_t* pVaaBgMbFlag);
 typedef void (*PAccumulateSadFunc) (uint32_t* pSumDiff, int32_t* pGomForegroundBlockNum, int32_t* iSad8x8,
                                     int8_t* pVaaBgMbFlag);//for RC
@@ -134,6 +132,11 @@
 typedef int32_t (*PIntraPred16x16Combined3Func) (uint8_t*, int32_t, uint8_t*, int32_t, int32_t*, int32_t, uint8_t*);
 typedef int32_t (*PIntraPred8x8Combined3Func) (uint8_t*, int32_t, uint8_t*, int32_t, int32_t*, int32_t, uint8_t*,
     uint8_t*, uint8_t*);
+
+typedef void (*PMotionSearchFunc) (SWelsFuncPtrList* pFuncList, void* pCurDqLayer, void* pMe,
+                                   void* pSlice);  // here after reset all function pointers, will set as right parameter type
+typedef void (*PCalculateSatdFunc) ( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride );
+
 #define     MAX_BLOCK_TYPE 5 // prev 7
 typedef struct TagSampleDealingFunc {
   PSampleSadSatdCostFunc            pfSampleSad[MAX_BLOCK_TYPE];
@@ -181,8 +184,10 @@
   PGetIntraPredFunc 		pfGetLumaI16x16Pred[I16_PRED_DC_A];
   PGetIntraPredFunc 		pfGetLumaI4x4Pred[I4_PRED_A];
   PGetIntraPredFunc 		pfGetChromaPred[C_PRED_A];
+
   PMotionSearchFunc
   pfMotionSearch; //svc_encode_slice.c svc_mode_decision.c svc_enhance_layer_md.c svc_base_layer_md.c
+  PCalculateSatdFunc pfCalculateSatd;
 
   PCopyFunc      pfCopy16x16Aligned;		//svc_encode_slice.c svc_mode_decision.c svc_base_layer_md.c
   PCopyFunc      pfCopy16x16NotAligned;	//md.c
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -2471,7 +2471,8 @@
   if (P_SLICE == pCtx->eSliceType) {
     if (kbBaseAvail) {
       if (pCtx->pSvcParam->iSpatialLayerNum == (pCurLayer->sLayerInfo.sNalHeaderExt.uiDependencyId + 1)) { //
-        pCtx->pFuncList->pfMotionSearch = WelsMotionEstimateSearchSad;
+        pCtx->pFuncList->pfMotionSearch = WelsMotionEstimateSearch;
+        pCtx->pFuncList->pfCalculateSatd = NotCalculateSatdCost;
         pCtx->pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
         pCtx->pFuncList->pfIntraFineMd = WelsMdIntraFinePartitionVaa;
         pCtx->pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaa;
@@ -2480,7 +2481,8 @@
           pCtx->pFuncList->sSampleDealingFuncs.pfIntra16x16Combined3Sad;
         pCtx->pFuncList->sSampleDealingFuncs.pfMdCost = pCtx->pFuncList->sSampleDealingFuncs.pfSampleSad;
       } else {
-        pCtx->pFuncList->pfMotionSearch  = WelsMotionEstimateSearchSatd;
+        pCtx->pFuncList->pfMotionSearch  = WelsMotionEstimateSearch;
+        pCtx->pFuncList->pfCalculateSatd = CalculateSatdCost;
         pCtx->pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
         pCtx->pFuncList->pfIntraFineMd = WelsMdIntraFinePartition;
         pCtx->pFuncList->pfInterFineMd = WelsMdInterFinePartition;
@@ -2494,7 +2496,8 @@
     } else {
       //case 3: pBase layer MD + encoding
       if (pCurLayer->sLayerInfo.sNalHeaderExt.uiDependencyId + 1 == pCtx->pSvcParam->iSpatialLayerNum) {
-        pCtx->pFuncList->pfMotionSearch  = WelsMotionEstimateSearchSad;
+        pCtx->pFuncList->pfMotionSearch  = WelsMotionEstimateSearch;
+        pCtx->pFuncList->pfCalculateSatd = NotCalculateSatdCost;
         pCtx->pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
         pCtx->pFuncList->pfIntraFineMd = WelsMdIntraFinePartitionVaa;
         pCtx->pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaa;
@@ -2503,7 +2506,8 @@
           pCtx->pFuncList->sSampleDealingFuncs.pfIntra16x16Combined3Sad;
         pCtx->pFuncList->sSampleDealingFuncs.pfIntra8x8Combined3 = pCtx->pFuncList->sSampleDealingFuncs.pfIntra8x8Combined3Sad;
       } else {
-        pCtx->pFuncList->pfMotionSearch  = WelsMotionEstimateSearchSatd;
+        pCtx->pFuncList->pfMotionSearch  = WelsMotionEstimateSearch;
+        pCtx->pFuncList->pfCalculateSatd = CalculateSatdCost;
         pCtx->pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
         pCtx->pFuncList->pfIntraFineMd = WelsMdIntraFinePartition;
         pCtx->pFuncList->pfInterFineMd = WelsMdInterFinePartition;
--- a/codec/encoder/core/src/svc_motion_estimate.cpp
+++ b/codec/encoder/core/src/svc_motion_estimate.cpp
@@ -43,6 +43,22 @@
 #include "svc_motion_estimate.h"
 
 namespace WelsSVCEnc {
+
+inline void UpdateMeResults( const SMVUnitXY ksBestMv, const uint32_t kiBestSadCost, uint8_t* pRef, SWelsME * pMe )
+{
+  pMe->sMv = ksBestMv;
+  pMe->pRefMb = pRef;
+  pMe->uiSadCost = kiBestSadCost;
+}
+inline void SvcMeEndSearch( SWelsME * pMe, const uint32_t kuiBestSadCost )
+{
+    /* -> qpel mv */
+    pMe->sMv.iMvX <<= 2;
+    pMe->sMv.iMvY <<= 2;
+    pMe->uiSatdCost = kuiBestSadCost;
+}
+
+
 /*!
  * \brief	BL mb motion estimate search
  *
@@ -52,7 +68,7 @@
  * \return	NONE
  */
 
-void WelsMotionEstimateSearchSatd (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice) {
+void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice) {
   SDqLayer* pCurDqLayer			= (SDqLayer*)pLplayer;
   SWelsME* pMe						= (SWelsME*)pLpme;
   SSlice* pSlice					= (SSlice*)pLpslice;
@@ -60,26 +76,13 @@
   int32_t iStrideRef = pCurDqLayer->pRefPic->iLineSize[0];
 
   //  Step 1: Initial point prediction
-  WelsMotionEstimateInitialPoint (pFuncList, pMe, pSlice, iStrideEnc, iStrideRef);
+  if ( !WelsMotionEstimateInitialPoint (pFuncList, pMe, pSlice, iStrideEnc, iStrideRef) ) {
+    WelsMotionEstimateIterativeSearch (pFuncList, pMe, iStrideEnc, iStrideRef, pMe->pRefMb);
+  }
 
-  pMe->uSadPredISatd.uiSatd = pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiPixel] (pMe->pEncMb, iStrideEnc,
-                              pMe->pRefMb, iStrideRef);
-  pMe->uiSatdCost = pMe->uSadPredISatd.uiSatd + COST_MVD (pMe->pMvdCost, pMe->sMv.iMvX - pMe->sMvp.iMvX,
-                    pMe->sMv.iMvY - pMe->sMvp.iMvY);
+  pFuncList->pfCalculateSatd( pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiPixel], pMe, iStrideEnc, iStrideRef );
 }
 
-
-void WelsMotionEstimateSearchSad (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice) {
-  SDqLayer* pCurDqLayer			= (SDqLayer*)pLplayer;
-  SWelsME* pMe						= (SWelsME*)pLpme;
-  SSlice* slice					= (SSlice*)pLpslice;
-  int32_t iStrideEnc			= pCurDqLayer->iEncStride[0];
-  int32_t iStrideRef			= pCurDqLayer->pRefPic->iLineSize[0];
-
-  //  Step 1: Initial point prediction
-  WelsMotionEstimateInitialPoint (pFuncList, pMe, slice, iStrideEnc, iStrideRef);
-}
-
 /*!
  * \brief	EL mb motion estimate initial point testing
  *
@@ -90,7 +93,7 @@
  *
  * \return	NONE
  */
-void WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice, int32_t iStrideEnc,
+bool WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice, int32_t iStrideEnc,
                                      int32_t iStrideRef) {
   PSampleSadSatdCostFunc pSad		= pFuncList->sSampleDealingFuncs.pfSampleSad[pMe->uiPixel];
   const uint16_t* kpMvdCost	= pMe->pMvdCost;
@@ -138,21 +141,13 @@
     }
   }
 
-  pMe->sMv = sMv;
-  pMe->uiSadCost = iBestSadCost;
-  if (iBestSadCost < pMe->uSadPredISatd.uiSadPred) {
-    //  Step 2: Initial early Stop
-    /* -> qpel mv */
-    pMe->sMv.iMvX <<= 2;
-    pMe->sMv.iMvY <<= 2;
-    /* -> pRef */
-    pMe->pRefMb = pRefMb;
-    /* compute the real cost */
-    pMe->uiSatdCost = iBestSadCost;
-  } else {
-    //  Step 3: Fast search pattern
-    WelsMotionEstimateIterativeSearch (pFuncList, pMe, iStrideEnc, iStrideRef, pRefMb);
+  UpdateMeResults( sMv, iBestSadCost, pRefMb, pMe );
+  if ( iBestSadCost < static_cast<int32_t>(pMe->uSadPredISatd.uiSadPred) ) {
+    //Initial point early Stop
+    SvcMeEndSearch(pMe, iBestSadCost);
+    return true;
   }
+  return false;
 }
 
 bool WelsMeSadCostSelect (int32_t* iSadCost, const uint16_t* kpMvdCost, int32_t* pBestCost, const int32_t kiDx,
@@ -229,6 +224,17 @@
   pMe->sMv.iMvY = (iMvDy + pMe->sMvp.iMvY) & 0xFFFC;
   pMe->uiSatdCost = pMe->uiSadCost = (iBestCost);
   pMe->pRefMb = pRefMb;
+}
+
+void CalculateSatdCost( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride )
+{
+  SWelsME* pMe						 = static_cast<SWelsME *>(vpMe);
+  pMe->uSadPredISatd.uiSatd = pSatd(pMe->pEncMb, kiEncStride, pMe->pRefMb, kiRefStride);
+  pMe->uiSatdCost = pMe->uSadPredISatd.uiSatd + COST_MVD (pMe->pMvdCost, pMe->sMv.iMvX - pMe->sMvp.iMvX,
+                                                            pMe->sMv.iMvY - pMe->sMvp.iMvY);
+}
+void NotCalculateSatdCost( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride )
+{
 }
 
 } // namespace WelsSVCEnc