shithub: openh264

Download patch

ref: c12edefcd371fcd64d6985d17404ac600e4f2d39
parent: ea5b6b49b423dc14913a62426bf7923c45185a0d
parent: f695227b00afb8cb318fbf0a4f45b4a95e014091
author: Licai Guo <licaguo@cisco.com>
date: Wed Apr 2 09:07:21 EDT 2014

Merge pull request #616 from sijchen/fme_merge81

[Encoder ME] add function pointer for search methods

--- a/codec/encoder/core/inc/svc_motion_estimate.h
+++ b/codec/encoder/core/inc/svc_motion_estimate.h
@@ -179,8 +179,7 @@
  *
  * \return	NONE
  */
-void WelsMotionEstimateIterativeSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, const int32_t kiStrideEnc,
-                                        const int32_t kiStrideRef, uint8_t* pRef);
+void WelsDiamondSearch (SWelsFuncPtrList* pFuncList, void* pLpme, void* pLpslice, const int32_t kiEncStride, const int32_t kiRefStride);
 
 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);
--- a/codec/encoder/core/inc/wels_func_ptr_def.h
+++ b/codec/encoder/core/inc/wels_func_ptr_def.h
@@ -43,6 +43,7 @@
 #include "svc_enc_frame.h"
 #include "expand_pic.h"
 #include "rc.h"
+#include "IWelsVP.h"
 
 namespace WelsSVCEnc {
 
@@ -135,7 +136,8 @@
 
 typedef void (*PMotionSearchFunc) (SWelsFuncPtrList* pFuncList, void* pCurDqLayer, void* pMe,
                                    void* pSlice);
-typedef void (*PCalculateSatdFunc) ( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride );
+typedef void (*PSearchMethodFunc) (SWelsFuncPtrList* pFuncList, void* pMe, void* pSlice, const int32_t kiEncStride, const int32_t kiRefStride);
+typedef void (*PCalculateSatdFunc) ( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride);
 typedef bool (*PCheckDirectionalMv) (PSampleSadSatdCostFunc pSad, void * vpMe,
                       const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
                       int32_t& iBestSadCost);
@@ -198,7 +200,8 @@
   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
+  pfMotionSearch[BLOCK_STATIC_IDC_ALL]; //svc_encode_slice.c svc_mode_decision.c svc_enhance_layer_md.c svc_base_layer_md.c
+  PSearchMethodFunc pfSearchMethod[BLOCK_SIZE_ALL];
   PCalculateSatdFunc pfCalculateSatd;
   PCheckDirectionalMv pfCheckDirectionalMv;
   PLineFullSearchFunc pfLineFullSearch;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -2366,7 +2366,12 @@
   }
 
   if (P_SLICE == pCtx->eSliceType) {
-    pFuncList->pfMotionSearch  = WelsMotionEstimateSearch;
+    pFuncList->pfMotionSearch[0]  = WelsMotionEstimateSearch;
+    pFuncList->pfSearchMethod[BLOCK_16x16]  =
+      pFuncList->pfSearchMethod[BLOCK_16x8] =
+      pFuncList->pfSearchMethod[BLOCK_8x16] =
+      pFuncList->pfSearchMethod[BLOCK_8x8] =
+      pFuncList->pfSearchMethod[BLOCK_4x4] = WelsDiamondSearch;
     pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
     pFuncList->sSampleDealingFuncs.pfMeCost = pCtx->pFuncList->sSampleDealingFuncs.pfSampleSatd;
     if (kbHighestSpatialLayer) {
--- a/codec/encoder/core/src/svc_base_layer_md.cpp
+++ b/codec/encoder/core/src/svc_base_layer_md.cpp
@@ -1018,8 +1018,7 @@
   }
 
   PredMv (&pMbCache->sMvComponents, 0, 4, 0, & (pMe16x16->sMvp));
-  pFunc->pfMotionSearch (pFunc, pCurLayer, pMe16x16, pSlice);
-//	update_p16x16_motion2cache(pMbCache, pWelsMd->uiRef, &(pMe16x16->mv));
+  pFunc->pfMotionSearch[0] (pFunc, pCurLayer, pMe16x16, pSlice);
 
   pCurMb->sP16x16Mv = pMe16x16->sMv;
   pCurLayer->pDecPic->sMvList[pCurMb->iMbXY] = pMe16x16->sMv;
@@ -1048,7 +1047,7 @@
     pSlice->uiMvcNum = 1;
 
     PredInter16x8Mv (pMbCache, i << 3, 0, & (sMe16x8->sMvp));
-    pFunc->pfMotionSearch (pFunc, pCurDqLayer, sMe16x8, pSlice);
+    pFunc->pfMotionSearch[0] (pFunc, pCurDqLayer, sMe16x8, pSlice);
     UpdateP16x8Motion2Cache (pMbCache, i << 3, pWelsMd->uiRef, & (sMe16x8->sMv));
     iCostP16x8 += sMe16x8->uiSatdCost;
     ++i;
@@ -1075,10 +1074,9 @@
     pSlice->uiMvcNum = 1;
 
     PredInter8x16Mv (pMbCache, i << 2, 0, & (sMe8x16->sMvp));
-    pFunc->pfMotionSearch (pFunc, pCurLayer, sMe8x16, pSlice);
+    pFunc->pfMotionSearch[0] (pFunc, pCurLayer, sMe8x16, pSlice);
     UpdateP8x16Motion2Cache (pMbCache, i << 2, pWelsMd->uiRef, & (sMe8x16->sMv));
     iCostP8x16 += sMe8x16->uiSatdCost;
-//		sMe8x16++;
     ++i;
   } while (i < 2);
   return iCostP8x16;
@@ -1113,7 +1111,7 @@
     pSlice->uiMvcNum = 1;
 
     PredMv (&pMbCache->sMvComponents, i << 2, 2, pWelsMd->uiRef, & (sMe8x8->sMvp));
-    pFunc->pfMotionSearch (pFunc, pCurDqLayer, sMe8x8, pSlice);
+    pFunc->pfMotionSearch[0] (pFunc, pCurDqLayer, sMe8x8, pSlice);
     UpdateP8x8Motion2Cache (pMbCache, i << 2, pWelsMd->uiRef, & (sMe8x8->sMv));
     iCostP8x8 += sMe8x8->uiSatdCost;
 //		sMe8x8++;
--- a/codec/encoder/core/src/svc_motion_estimate.cpp
+++ b/codec/encoder/core/src/svc_motion_estimate.cpp
@@ -83,16 +83,16 @@
   SDqLayer* pCurDqLayer			= (SDqLayer*)pLplayer;
   SWelsME* pMe						= (SWelsME*)pLpme;
   SSlice* pSlice					= (SSlice*)pLpslice;
-  int32_t iStrideEnc = pCurDqLayer->iEncStride[0];
-  int32_t iStrideRef = pCurDqLayer->pRefPic->iLineSize[0];
+  const int32_t kiStrideEnc = pCurDqLayer->iEncStride[0];
+  const int32_t kiStrideRef = pCurDqLayer->pRefPic->iLineSize[0];
 
   //  Step 1: Initial point prediction
-  if ( !WelsMotionEstimateInitialPoint (pFuncList, pMe, pSlice, iStrideEnc, iStrideRef) ) {
-    WelsMotionEstimateIterativeSearch (pFuncList, pMe, iStrideEnc, iStrideRef, pMe->pRefMb);
+  if ( !WelsMotionEstimateInitialPoint (pFuncList, pMe, pSlice, kiStrideEnc, kiStrideRef) ) {
+    pFuncList->pfSearchMethod[pMe->uiBlockSize] (pFuncList, pMe, pSlice, kiStrideEnc, kiStrideRef);
     MeEndIntepelSearch(pMe);
   }
 
-  pFuncList->pfCalculateSatd( pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiBlockSize], pMe, iStrideEnc, iStrideRef );
+  pFuncList->pfCalculateSatd( pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiBlockSize], pMe, kiStrideEnc, kiStrideRef );
 }
 
 /*!
@@ -219,10 +219,12 @@
   return (*pBestCost == iInputSadCost);
 }
 
-void WelsMotionEstimateIterativeSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, const int32_t kiStrideEnc,
-                                        const int32_t kiStrideRef, uint8_t* pFref) {
+void WelsDiamondSearch (SWelsFuncPtrList* pFuncList, void* pLpme, void* pLpslice,
+                        const int32_t kiStrideEnc,  const int32_t kiStrideRef) {
+  SWelsME* pMe						= (SWelsME*)pLpme;
   PSample4SadCostFunc			pSad					=  pFuncList->sSampleDealingFuncs.pfSample4Sad[pMe->uiBlockSize];
 
+  uint8_t* pFref = pMe->pRefMb;
   uint8_t* const kpEncMb = pMe->pEncMb;
   const uint16_t* kpMvdCost = pMe->pMvdCost;
 
@@ -334,12 +336,10 @@
   }
 }
 
-void WelsMotionCrossSearch(SWelsFuncPtrList *pFuncList,  SDqLayer* pCurLayer, SWelsME * pMe,
-											const SSlice* pSlice) {
+void WelsMotionCrossSearch(SWelsFuncPtrList *pFuncList,  SWelsME * pMe,
+											const SSlice* pSlice, const int32_t kiEncStride,  const int32_t kiRefStride) {
   PLineFullSearchFunc pfVerticalFullSearchFunc	= pFuncList->pfLineFullSearch;
   PLineFullSearchFunc pfHorizontalFullSearchFunc	= pFuncList->pfLineFullSearch;
-  const int32_t kiEncStride = pCurLayer->iEncStride[0];
-  const int32_t kiRefStride = pCurLayer->pRefPic->iLineSize[0];
 
   const int32_t iCurMeBlockPixX = pMe->iCurMeBlockPixX;
   const int32_t iCurMeBlockQpelPixX = ((iCurMeBlockPixX)<<2);
@@ -564,28 +564,26 @@
 /////////////////////////
 // Search function options
 /////////////////////////
-void WelsDiamondCrossSearch(SWelsFuncPtrList *pFunc, void* vpLayer, void* vpMe, void* vpSlice) {
-    SDqLayer* pCurLayer = static_cast<SDqLayer *>(vpLayer);
+void WelsDiamondCrossSearch(SWelsFuncPtrList *pFunc, void* vpMe, void* vpSlice, const int32_t kiEncStride,  const int32_t kiRefStride) {
     SWelsME* pMe			 = static_cast<SWelsME *>(vpMe);
     SSlice* pSlice				 = static_cast<SSlice *>(vpSlice);
 
     //  Step 1: diamond search
-    WelsMotionEstimateIterativeSearch(pFunc, pMe, pCurLayer->iEncStride[0], pCurLayer->pRefPic->iLineSize[0], pMe->pRefMb);
+    WelsDiamondSearch(pFunc, vpMe, vpSlice, kiEncStride, kiRefStride);
 
     //  Step 2: CROSS search
     SScreenBlockFeatureStorage pRefBlockFeature; //TODO: use this structure from Ref
     pMe->uiSadCostThreshold = pRefBlockFeature.uiSadCostThreshold[pMe->uiBlockSize];
     if (pMe->uiSadCost >= pMe->uiSadCostThreshold) {
-      WelsMotionCrossSearch(pFunc, pCurLayer, pMe, pSlice);
+      WelsMotionCrossSearch(pFunc, pMe, pSlice, kiEncStride, kiRefStride);
     }
 }
-void WelsDiamondCrossFeatureSearch(SWelsFuncPtrList *pFunc, void* vpLayer, void* vpMe, void* vpSlice) {
-    SDqLayer* pCurLayer = static_cast<SDqLayer *>(vpLayer);
+void WelsDiamondCrossFeatureSearch(SWelsFuncPtrList *pFunc, void* vpMe, void* vpSlice, const int32_t kiEncStride, const int32_t kiRefStride) {
     SWelsME* pMe			 = static_cast<SWelsME *>(vpMe);
     SSlice* pSlice				 = static_cast<SSlice *>(vpSlice);
 
     //  Step 1: diamond search + cross
-    WelsDiamondCrossSearch(pFunc, pCurLayer, pMe, pSlice);
+    WelsDiamondCrossSearch(pFunc, pMe, pSlice, kiEncStride, kiRefStride);
 
     // Step 2: FeatureSearch
     if (pMe->uiSadCost >= pMe->uiSadCostThreshold) {
@@ -595,7 +593,7 @@
         uint32_t uiMaxSearchPoint = INT_MAX;//TODO: change it according to computational-complexity setting
         SFeatureSearchIn sFeatureSearchIn = {0};
         SetFeatureSearchIn(pFunc, *pMe, pSlice, &tmpScreenBlockFeatureStorage,
-          pCurLayer->iEncStride[0], pCurLayer->pRefPic->iLineSize[0],
+          kiEncStride, kiRefStride,
           &sFeatureSearchIn);
         MotionEstimateFeatureFullSearch( sFeatureSearchIn, uiMaxSearchPoint, pMe);
 
--- a/codec/processing/interface/IWelsVP.h
+++ b/codec/processing/interface/IWelsVP.h
@@ -148,6 +148,7 @@
   NO_STATIC,  // motion block
   COLLOCATED_STATIC, // collocated static block
   SCROLLED_STATIC,  // scrolled static block
+  BLOCK_STATIC_IDC_ALL,
 } EStaticBlockIdc;
 
 typedef struct {
--- a/test/encoder/EncUT_MotionEstimate.cpp
+++ b/test/encoder/EncUT_MotionEstimate.cpp
@@ -75,6 +75,7 @@
   const int32_t kiMaxBlock16Sad = 72000;//a rough number
   SWelsFuncPtrList sFuncList;
   SWelsME sMe;
+  SSlice sSlice;
 
   srand((uint32_t)time(NULL));
   const uint8_t kuiQp = rand()%52;
@@ -106,8 +107,7 @@
       sMe.pRefMb = pRefPicCenter;
       sMe.sMv.iMvX = sMe.sMv.iMvY = 0;
       sMe.uiSadCost = sMe.uiSatdCost = kiMaxBlock16Sad;
-      WelsMotionEstimateIterativeSearch (&sFuncList, &sMe, m_iMaxSearchBlock,
-                                         m_iWidth, pRefPicCenter);
+      WelsDiamondSearch (&sFuncList, &sMe, &sSlice, m_iMaxSearchBlock, m_iWidth);
 
       //the last selection may be affected by MVDcost, that is when (0,0) will be better
       //when comparing (1,1) and (1,0), due to the difference between MVD cost, it is possible that (1,0) is selected while the best match is (1,1)