Merge pull request #609 from sijchen/fme_merge32

[Encoder ME] add memory allocation basics for FME
This commit is contained in:
Licai Guo 2014-04-01 16:12:04 +08:00
commit fb5700bd5c
3 changed files with 98 additions and 13 deletions

View File

@ -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
/*

View File

@ -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

View File

@ -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<SDqLayer *>(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);
}