From a917444b2e9639832c9e89c88226e385bbfb0855 Mon Sep 17 00:00:00 2001 From: sijchen Date: Tue, 1 Apr 2014 15:52:13 +0800 Subject: [PATCH] [Encoder ME] add memory allocation basics for FME --- codec/encoder/core/inc/picture.h | 21 ++--- codec/encoder/core/inc/svc_motion_estimate.h | 12 +++ .../encoder/core/src/svc_motion_estimate.cpp | 78 ++++++++++++++++++- 3 files changed, 98 insertions(+), 13 deletions(-) diff --git a/codec/encoder/core/inc/picture.h b/codec/encoder/core/inc/picture.h index d57ef8ed..7e409e16 100644 --- a/codec/encoder/core/inc/picture.h +++ b/codec/encoder/core/inc/picture.h @@ -42,25 +42,26 @@ namespace WelsSVCEnc { #define LIST_SIZE 0x10000 //(256*256) typedef struct TagScreenBlockFeatureStorage { - uint16_t* pFeatureOfBlock; // Feature of every block (8x8), begin with the point uint32_t* pTimesOfFeatureValue; // times of every value in Feature uint16_t** pLocationOfFeature; // uint16_t *pLocationOfFeature[LIST_SIZE], pLocationOfFeature[i] saves all the location(x,y) whose Feature = i; uint16_t* pLocationPointer; // buffer of position array - int32_t iActualListSize; // actual list size (8x8 based) -} SScreenBlockFeatureStorage; + int32_t iActualListSize; // actual list size -typedef struct TagScreenContentStorage{ - SScreenBlockFeatureStorage sRefBlockFeature[MAX_MULTI_REF_PIC_COUNT]; - uint32_t uiSadCostThreshold[BLOCK_SIZE_ALL]; + uint32_t uiSadCostThreshold[BLOCK_SIZE_ALL]; + bool bRefBlockFeatureCalculated; // flag of whether pre-process is done +} SScreenBlockFeatureStorage; //should be stored with RefPic, one for each frame - bool bRefBlockFeatureCalculated; // flag of whether pre-process is done - uint8_t uiFeatureStrategyIndex;// index of hash strategy +typedef struct TagFeatureSearchPreparation{ + SScreenBlockFeatureStorage* pRefBlockFeature;//point the the ref frame storage + + uint16_t* pFeatureOfBlock; // Feature of every block (8x8), begin with the point + uint8_t uiFeatureStrategyIndex;// index of hash strategy /* for FME frame-level switch */ - bool bFMESwitchFlag; + bool bFMESwitchFlag; uint8_t uiFMEGoodFrameCount; int32_t iHighFreMbCount; -}SScreenContentStorage; +}SFeatureSearchPreparation;//maintain only one /* diff --git a/codec/encoder/core/inc/svc_motion_estimate.h b/codec/encoder/core/inc/svc_motion_estimate.h index f067db8e..ac811b99 100644 --- a/codec/encoder/core/inc/svc_motion_estimate.h +++ b/codec/encoder/core/inc/svc_motion_estimate.h @@ -54,6 +54,18 @@ namespace WelsSVCEnc { #define EXPANDED_MV_RANGE (504) //=512-8 rather than 511 to sacrifice same edge point but save complexity in assemblys #define EXPANDED_MVD_RANGE ((504+1)<<1) +enum +{ + ME_DIA = 0x01, // LITTLE DIAMOND= 0x01 + ME_CROSS = 0x02, // CROSS= 0x02 + ME_FME = 0x04, // FME = 0x04 + ME_FULL = 0x10, // FULL + + // derived ME methods combination + ME_DIA_CROSS = (ME_DIA|ME_CROSS), // DIA+CROSS + ME_DIA_CROSS_FME = (ME_DIA_CROSS|ME_FME), // DIA+CROSS+FME +}; + union SadPredISatdUnit { uint32_t uiSadPred; uint32_t uiSatd; //reuse the sad_pred as a temp satd pData diff --git a/codec/encoder/core/src/svc_motion_estimate.cpp b/codec/encoder/core/src/svc_motion_estimate.cpp index be20fe4a..976c238c 100644 --- a/codec/encoder/core/src/svc_motion_estimate.cpp +++ b/codec/encoder/core/src/svc_motion_estimate.cpp @@ -369,6 +369,78 @@ void WelsMotionCrossSearch(SWelsFuncPtrList *pFuncList, SDqLayer* pCurLayer, SW ///////////////////////// // Feature Search Basics ///////////////////////// +//memory related +int32_t RequestFeatureSearchPreparation( CMemoryAlign *pMa, const int32_t kiFeatureStrategyIndex, + const int32_t kiFrameWidth, const int32_t kiFrameHeight, const bool bFme8x8, + uint16_t*& pFeatureOfBlock) { + const int32_t kiMarginSize = bFme8x8?8:16; + const int32_t kiFrameSize = (kiFrameWidth-kiMarginSize) * (kiFrameHeight-kiMarginSize); + int32_t iListOfFeatureOfBlock; + + if (0==kiFeatureStrategyIndex) { + iListOfFeatureOfBlock =sizeof(uint16_t) * kiFrameSize; + } else { + iListOfFeatureOfBlock = sizeof(uint16_t) * kiFrameSize + + (kiFrameWidth-kiMarginSize) * sizeof(uint32_t) + kiFrameWidth * 8 * sizeof(uint8_t); + } + pFeatureOfBlock = + (uint16_t *)pMa->WelsMalloc(iListOfFeatureOfBlock, "pFeatureOfBlock"); + WELS_VERIFY_RETURN_IF(ENC_RETURN_MEMALLOCERR, NULL == pFeatureOfBlock) + + return ENC_RETURN_SUCCESS; +} +int32_t ReleaseFeatureSearchPreparation( CMemoryAlign *pMa, uint16_t*& pFeatureOfBlock) { + if ( pMa && pFeatureOfBlock ) { + pMa->WelsFree( pFeatureOfBlock, "pFeatureOfBlock"); + pFeatureOfBlock=NULL; + return ENC_RETURN_SUCCESS; + } + return ENC_RETURN_UNEXPECTED; +} +int32_t RequestScreenBlockFeatureStorage( CMemoryAlign *pMa, const int32_t kiFeatureStrategyIndex, + const int32_t kiFrameWidth, const int32_t kiFrameHeight, const int32_t kiMe16x16, const int32_t kiMe8x8, + SScreenBlockFeatureStorage* pScreenBlockFeatureStorage) { +#define LIST_SIZE_SUM_16x16 0x0FF01 //(256*255+1) +#define LIST_SIZE_SUM_8x8 0x03FC1 //(64*255+1) + + if (((kiMe8x8&ME_FME)==ME_FME) && ((kiMe16x16&ME_FME)==ME_FME)) { + return ENC_RETURN_UNSUPPORTED_PARA; + //the following memory allocation cannot support when FME at both size + } + + const bool bIsBlock8x8 = ((kiMe8x8 & ME_FME)==ME_FME); + const int32_t kiMarginSize = bIsBlock8x8?8:16; + const int32_t kiFrameSize = (kiFrameWidth-kiMarginSize) * (kiFrameHeight-kiMarginSize); + const int32_t kiListSize = (0==kiFeatureStrategyIndex)?(bIsBlock8x8 ? LIST_SIZE_SUM_8x8 : LIST_SIZE_SUM_16x16):256; + + pScreenBlockFeatureStorage->pTimesOfFeatureValue = (uint32_t*)pMa->WelsMalloc(kiListSize*sizeof(uint32_t),"pScreenBlockFeatureStorage->pTimesOfFeatureValue"); + WELS_VERIFY_RETURN_IF(ENC_RETURN_MEMALLOCERR, NULL == pScreenBlockFeatureStorage->pTimesOfFeatureValue) + + pScreenBlockFeatureStorage->pLocationOfFeature = (uint16_t**)pMa->WelsMalloc(kiListSize*sizeof(uint16_t*),"pScreenBlockFeatureStorage->pLocationOfFeature"); + WELS_VERIFY_RETURN_IF(ENC_RETURN_MEMALLOCERR, NULL == pScreenBlockFeatureStorage->pLocationOfFeature) + + pScreenBlockFeatureStorage->pLocationPointer = (uint16_t*)pMa->WelsMalloc(2*kiFrameSize*sizeof(uint16_t), "pScreenBlockFeatureStorage->pLocationPointer"); + WELS_VERIFY_RETURN_IF(ENC_RETURN_MEMALLOCERR, NULL == pScreenBlockFeatureStorage->pLocationPointer) + + pScreenBlockFeatureStorage->iActualListSize = kiListSize; + return ENC_RETURN_SUCCESS; +} +int32_t ReleaseScreenBlockFeatureStorage( CMemoryAlign *pMa, SScreenBlockFeatureStorage* pScreenBlockFeatureStorage ) { + if ( pMa && pScreenBlockFeatureStorage ) { + pMa->WelsFree( pScreenBlockFeatureStorage->pTimesOfFeatureValue, "pScreenBlockFeatureStorage->pTimesOfFeatureValue"); + pScreenBlockFeatureStorage->pTimesOfFeatureValue=NULL; + + pMa->WelsFree( pScreenBlockFeatureStorage->pLocationOfFeature, "pScreenBlockFeatureStorage->pLocationOfFeature"); + pScreenBlockFeatureStorage->pLocationOfFeature=NULL; + + pMa->WelsFree( pScreenBlockFeatureStorage->pLocationPointer, "pScreenBlockFeatureStorage->pLocationPointer"); + pScreenBlockFeatureStorage->pLocationPointer=NULL; + + return ENC_RETURN_SUCCESS; + } + return ENC_RETURN_UNEXPECTED; +} +//search related void SetFeatureSearchIn( SWelsFuncPtrList *pFunc, const SWelsME& sMe, const SSlice *pSlice, SScreenBlockFeatureStorage* pRefFeatureStorage, const int32_t kiEncStride, const int32_t kiRefStride, @@ -490,7 +562,7 @@ void MotionEstimateFeatureFullSearch( SFeatureSearchIn &sFeatureSearchIn, } ///////////////////////// -// Search function option +// Search function options ///////////////////////// void WelsDiamondCrossSearch(SWelsFuncPtrList *pFunc, void* vpLayer, void* vpMe, void* vpSlice) { SDqLayer* pCurLayer = static_cast(vpLayer); @@ -501,8 +573,8 @@ void WelsDiamondCrossSearch(SWelsFuncPtrList *pFunc, void* vpLayer, void* vpMe, WelsMotionEstimateIterativeSearch(pFunc, pMe, pCurLayer->iEncStride[0], pCurLayer->pRefPic->iLineSize[0], pMe->pRefMb); // Step 2: CROSS search - SScreenContentStorage tmpScreenContentStorage; //TODO: use this structure from Ref - pMe->uiSadCostThreshold = tmpScreenContentStorage.uiSadCostThreshold[pMe->uiBlockSize]; + SScreenBlockFeatureStorage pRefBlockFeature; //TODO: use this structure from Ref + pMe->uiSadCostThreshold = pRefBlockFeature.uiSadCostThreshold[pMe->uiBlockSize]; if (pMe->uiSadCost >= pMe->uiSadCostThreshold) { WelsMotionCrossSearch(pFunc, pCurLayer, pMe, pSlice); }