Merge pull request #489 from sijchen/me_refactor22
refactor ME for easier adding other search methods
This commit is contained in:
commit
6da9a9e5c8
codec/encoder/core
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user