shithub: openh264

Download patch

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);
     }