add funtion pointer for search methods

This commit is contained in:
sijchen 2014-04-02 10:12:39 +08:00
parent d8080adb4c
commit f695227b00
7 changed files with 36 additions and 32 deletions

View File

@ -179,8 +179,7 @@ bool WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
*
* \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);

View File

@ -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 int32_t (*PIntraPred8x8Combined3Func) (uint8_t*, int32_t, uint8_t*, int3
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 @@ struct TagWelsFuncPointerList {
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;

View File

@ -2366,7 +2366,12 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
}
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) {

View File

@ -1018,8 +1018,7 @@ int32_t WelsMdP16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWe
}
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 @@ int32_t WelsMdP16x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pW
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 @@ int32_t WelsMdP8x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWel
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 @@ int32_t WelsMdP8x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWe
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++;

View File

@ -83,16 +83,16 @@ void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void
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 @@ bool WelsMeSadCostSelect (int32_t* iSadCost, const uint16_t* kpMvdCost, int32_t*
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 LineFullSearch_c( void *pFunc, void *vpMe,
}
}
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 @@ void MotionEstimateFeatureFullSearch( SFeatureSearchIn &sFeatureSearchIn,
/////////////////////////
// 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 @@ void WelsDiamondCrossFeatureSearch(SWelsFuncPtrList *pFunc, void* vpLayer, void*
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);

View File

@ -148,6 +148,7 @@ typedef enum {
NO_STATIC, // motion block
COLLOCATED_STATIC, // collocated static block
SCROLLED_STATIC, // scrolled static block
BLOCK_STATIC_IDC_ALL,
} EStaticBlockIdc;
typedef struct {

View File

@ -75,6 +75,7 @@ TEST_F(MotionEstimateTest, TestDiamondSearch) {
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 @@ TEST_F(MotionEstimateTest, TestDiamondSearch) {
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)