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)