ref: fb5700bd5cc18dd33c120ce9dd5f79b8f1f35f3a
parent: 9c1c208ae68b0234ec383cff78bb8c19520bd9ec
parent: a917444b2e9639832c9e89c88226e385bbfb0855
author: Licai Guo <[email protected]>
date: Tue Apr 1 12:12:04 EDT 2014
Merge pull request #609 from sijchen/fme_merge32 [Encoder ME] add memory allocation basics for FME
--- a/codec/encoder/core/inc/picture.h
+++ b/codec/encoder/core/inc/picture.h
@@ -42,25 +42,26 @@
#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
/*
--- a/codec/encoder/core/inc/svc_motion_estimate.h
+++ b/codec/encoder/core/inc/svc_motion_estimate.h
@@ -54,6 +54,18 @@
#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
--- a/codec/encoder/core/src/svc_motion_estimate.cpp
+++ b/codec/encoder/core/src/svc_motion_estimate.cpp
@@ -369,6 +369,78 @@
/////////////////////////
// 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 @@
}
/////////////////////////
-// 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 @@
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);
}