add funtion pointer for search methods
This commit is contained in:
parent
d8080adb4c
commit
f695227b00
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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++;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user