Merge pull request from sijchen/me_refactor22

refactor ME for easier adding other search methods
This commit is contained in:
volvet 2014-03-14 17:53:10 +08:00
commit 6da9a9e5c8
4 changed files with 59 additions and 44 deletions

View File

@ -83,10 +83,7 @@ SMVUnitXY sMv;
*
* \return NONE
*/
void WelsMotionEstimateSearchSatd (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
void WelsMotionEstimateSearchSad (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
/*!
@ -112,7 +109,7 @@ void WelsMotionEstimateSearchSad (SWelsFuncPtrList* pFuncList, void* pLplayer, v
* \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);
/*!
@ -130,6 +127,9 @@ void WelsMotionEstimateIterativeSearch (SWelsFuncPtrList* pFuncList, SWelsME* pM
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,
SMVUnitXY* pMvMin, SMVUnitXY* pMvMax)

View File

@ -112,8 +112,6 @@ typedef int32_t (*PIntraFineMdFunc) (void* pEncCtx, void* pWelsMd, SMB* pCurMb,
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 (*PIntraPred4x4Combined3Func) (uint8_t*, int32_t, uint8_t*, int3
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 @@ struct TagWelsFuncPointerList {
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

View File

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

View File

@ -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 @@ namespace WelsSVCEnc {
* \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,24 +76,11 @@ void WelsMotionEstimateSearchSatd (SWelsFuncPtrList* pFuncList, void* pLplayer,
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);
}
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);
pFuncList->pfCalculateSatd( pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiPixel], pMe, iStrideEnc, iStrideRef );
}
/*!
@ -90,7 +93,7 @@ void WelsMotionEstimateSearchSad (SWelsFuncPtrList* pFuncList, void* pLplayer, v
*
* \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 @@ void WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
}
}
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,
@ -231,4 +226,15 @@ void WelsMotionEstimateIterativeSearch (SWelsFuncPtrList* pFuncList, SWelsME* pM
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