Merge pull request #676 from sijchen/fme_merge54

[Encoder ME] add memory allocation for feature search
This commit is contained in:
Licai Guo 2014-04-11 22:45:47 +08:00
commit f27b22f07c
8 changed files with 67 additions and 37 deletions

View File

@ -68,7 +68,6 @@ typedef struct TagFeatureSearchPreparation{
int32_t iHighFreMbCount;
}SFeatureSearchPreparation;//maintain only one
/*
* Reconstructed Picture definition
* It is used to express reference picture, also consequent reconstruction picture for output
@ -108,6 +107,9 @@ typedef struct TagPicture {
uint8_t uiTemporalId;
uint8_t uiSpatialId;
int32_t iFrameAverageQp;
/*******************************for screen reference frames****************************/
SScreenBlockFeatureStorage* pScreenBlockFeatureStorage;
} SPicture;
/*

View File

@ -46,13 +46,13 @@
namespace WelsSVCEnc {
/*!
* \brief alloc picture pData with borders for each plane based width and height of picture
* \param cx width of picture in pixels
* \param cy height of picture in pixels
* \param need_data need pData allocation
* \pram need_expand need borders expanding
* \param kiWidth width of picture in pixels
* \param kiHeight height of picture in pixels
* \param bNeedMbInfo need pData allocation
* \pram iNeedFeatureStorage need storage for FME
* \return successful if effective picture pointer returned, otherwise failed with NULL
*/
SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth, const int32_t kiHeight, bool bNeedMbInfo);
SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth, const int32_t kiHeight, bool bNeedMbInfo, int32_t iNeedFeatureStorage);
/*!
* \brief free picture pData planes

View File

@ -54,8 +54,7 @@ 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
{
enum {
ME_DIA = 0x01, // LITTLE DIAMOND= 0x01
ME_CROSS = 0x02, // CROSS= 0x02
ME_FME = 0x04, // FME = 0x04
@ -229,6 +228,9 @@ void SumOf8x8BlockOfFrame_c(uint8_t *pRefPicture, const int32_t kiWidth, const i
uint16_t* pFeatureOfBlock, uint32_t pTimesOfFeatureValue[]);
void SumOf16x16BlockOfFrame_c(uint8_t *pRefPicture, const int32_t kiWidth, const int32_t kiHeight, const int32_t kiRefStride,
uint16_t* pFeatureOfBlock, uint32_t pTimesOfFeatureValue[]);
int32_t RequestScreenBlockFeatureStorage( CMemoryAlign *pMa, const int32_t kiFrameWidth, const int32_t kiFrameHeight, const int32_t iNeedFeatureStorage,
SScreenBlockFeatureStorage* pScreenBlockFeatureStorage);
int32_t ReleaseScreenBlockFeatureStorage( CMemoryAlign *pMa, SScreenBlockFeatureStorage* pScreenBlockFeatureStorage );
//inline functions
inline void SetMvWithinIntegerMvRange( const int32_t kiMbWidth, const int32_t kiMbHeight, const int32_t kiMbX, const int32_t kiMbY,
const int32_t kiMaxMvRange,

View File

@ -138,14 +138,14 @@ typedef uint32_t (*PSampleSadHor8Func)( uint8_t*, int32_t, uint8_t*, int32_t, ui
typedef void (*PMotionSearchFunc) (SWelsFuncPtrList* pFuncList, void* pCurDqLayer, void* pMe,
void* pSlice);
typedef void (*PSearchMethodFunc) (SWelsFuncPtrList* pFuncList, void* pMe, void* pSlice, const int32_t kiEncStride, const int32_t kiRefStride);
typedef void (*PCalculateSatdFunc) ( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride);
typedef void (*PCalculateSatdFunc) ( PSampleSadSatdCostFunc pSatd, void * vpMe, const int32_t kiEncStride, const int32_t kiRefStride );
typedef bool (*PCheckDirectionalMv) (PSampleSadSatdCostFunc pSad, void * vpMe,
const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv, const int32_t kiEncStride, const int32_t kiRefStride,
int32_t& iBestSadCost);
typedef void (*PLineFullSearchFunc) ( void *pFunc, void *vpMe,
uint16_t* pMvdTable, const int32_t kiFixedMvd,
const int32_t kiEncStride, const int32_t kiRefStride,
const int32_t kiMinPos, const int32_t kiMaxPos,
typedef void (*PLineFullSearchFunc) ( void *pFunc, void *vpMe,
uint16_t* pMvdTable, const int32_t kiFixedMvd,
const int32_t kiEncStride, const int32_t kiRefStride,
const int32_t kiMinPos, const int32_t kiMaxPos,
const bool bVerticalSearch );
typedef void (*PCalculateBlockFeatureOfFrame)(uint8_t *pRef, const int32_t kiWidth, const int32_t kiHeight, const int32_t kiRefStride,
uint16_t* pFeatureOfBlock, uint32_t pTimesOfFeatureValue[]);

View File

@ -707,7 +707,12 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
pParam = (*ppCtx)->pSvcParam;
iDlayerCount = pParam->iSpatialLayerNum;
iNumRef = pParam->iNumRefFrame;
// highest_layers_in_temporal = 1 + WELS_MAX(pParam->iDecompStages, 1);
const int32_t kiFeatureStrategyIndex = 0;
const int32_t kiMe16x16 = ME_DIA_CROSS;
const int32_t kiMe8x8 = ME_DIA_CROSS_FME;
const int32_t kiNeedFeatureStorage = (pParam->iUsageType != SCREEN_CONTENT_REAL_TIME)?0:
((kiFeatureStrategyIndex<<16) + ((kiMe16x16 & 0x00FF)<<8) + (kiMe8x8 & 0x00FF));
iDlayerIndex = 0;
while (iDlayerIndex < iDlayerCount) {
@ -727,9 +732,8 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
// pRef list
pRefList = (SRefList*)pMa->WelsMallocz (sizeof (SRefList), "pRefList");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pRefList), FreeMemorySvc (ppCtx))
do {
pRefList->pRef[i] = AllocPicture (pMa, kiWidth, kiHeight, true); // to use actual size of current layer
pRefList->pRef[i] = AllocPicture (pMa, kiWidth, kiHeight, true, kiNeedFeatureStorage); // to use actual size of current layer
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pRefList->pRef[i]), FreeMemorySvc (ppCtx))
++ i;
} while (i < 1 + iNumRef);

View File

@ -37,6 +37,7 @@
*
*************************************************************************************/
#include "picture_handle.h"
#include "svc_motion_estimate.h"
namespace WelsSVCEnc {
/*!
@ -47,7 +48,8 @@ namespace WelsSVCEnc {
* \pram need_expand need borders expanding
* \return successful if effective picture pointer returned, otherwise failed with NULL
*/
SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth , const int32_t kiHeight, bool bNeedMbInfo) {
SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth , const int32_t kiHeight,
bool bNeedMbInfo, int32_t iNeedFeatureStorage) {
SPicture* pPic = NULL;
int32_t iPicWidth = 0;
int32_t iPicHeight = 0;
@ -107,6 +109,15 @@ SPicture* AllocPicture (CMemoryAlign* pMa, const int32_t kiWidth , const int32_t
WELS_VERIFY_RETURN_PROC_IF (NULL, NULL == pPic->pMbSkipSad, FreePicture (pMa, &pPic));
}
if (iNeedFeatureStorage) {
pPic->pScreenBlockFeatureStorage = static_cast<SScreenBlockFeatureStorage*> (pMa->WelsMallocz (sizeof (SScreenBlockFeatureStorage), "pScreenBlockFeatureStorage"));
int32_t iReturn = RequestScreenBlockFeatureStorage(pMa, kiWidth, kiHeight, iNeedFeatureStorage,
pPic->pScreenBlockFeatureStorage );
WELS_VERIFY_RETURN_PROC_IF (NULL, ENC_RETURN_SUCCESS != iReturn, FreePicture (pMa, &pPic));
} else {
pPic->pScreenBlockFeatureStorage = NULL;
}
return pPic;
}
@ -126,10 +137,10 @@ void FreePicture (CMemoryAlign* pMa, SPicture** ppPic) {
pPic->pBuffer = NULL;
pPic->pData[0] =
pPic->pData[1] =
pPic->pData[2] = NULL;
pPic->pData[2] = NULL;
pPic->iLineSize[0] =
pPic->iLineSize[1] =
pPic->iLineSize[2] = 0;
pPic->iLineSize[2] = 0;
pPic->iWidthInPixel = 0;
pPic->iHeightInPixel = 0;
@ -157,6 +168,13 @@ void FreePicture (CMemoryAlign* pMa, SPicture** ppPic) {
pMa->WelsFree (pPic->pMbSkipSad, "pPic->pMbSkipSad");
pPic->pMbSkipSad = NULL;
}
if (pPic->pScreenBlockFeatureStorage) {
ReleaseScreenBlockFeatureStorage(pMa, pPic->pScreenBlockFeatureStorage);
pMa->WelsFree (pPic->pScreenBlockFeatureStorage, "pPic->pScreenBlockFeatureStorage");
pPic->pScreenBlockFeatureStorage = NULL;
}
pMa->WelsFree (*ppPic, "pPic");
*ppPic = NULL;
}

View File

@ -96,9 +96,9 @@ void WelsInitMeFunc( SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag, bool bScre
*/
void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice) {
SDqLayer* pCurDqLayer = (SDqLayer*)pLplayer;
SWelsME* pMe = (SWelsME*)pLpme;
SSlice* pSlice = (SSlice*)pLpslice;
SDqLayer* pCurDqLayer = (SDqLayer*)pLplayer;
SWelsME* pMe = (SWelsME*)pLpme;
SSlice* pSlice = (SSlice*)pLpslice;
const int32_t kiStrideEnc = pCurDqLayer->iEncStride[0];
const int32_t kiStrideRef = pCurDqLayer->pRefPic->iLineSize[0];
@ -237,8 +237,8 @@ bool WelsMeSadCostSelect (int32_t* iSadCost, const uint16_t* kpMvdCost, int32_t*
void WelsDiamondSearch (SWelsFuncPtrList* pFuncList, void* pLpme, void* pLpslice,
const int32_t kiStrideEnc, const int32_t kiStrideRef) {
SWelsME* pMe = (SWelsME*)pLpme;
PSample4SadCostFunc pSad = pFuncList->sSampleDealingFuncs.pfSample4Sad[pMe->uiBlockSize];
SWelsME* pMe = (SWelsME*)pLpme;
PSample4SadCostFunc pSad = pFuncList->sSampleDealingFuncs.pfSample4Sad[pMe->uiBlockSize];
uint8_t* pFref = pMe->pRefMb;
uint8_t* const kpEncMb = pMe->pEncMb;
@ -542,18 +542,19 @@ int32_t ReleaseFeatureSearchPreparation( CMemoryAlign *pMa, uint16_t*& pFeatureO
}
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)) {
int32_t RequestScreenBlockFeatureStorage( CMemoryAlign *pMa, const int32_t kiFrameWidth, const int32_t kiFrameHeight, const int32_t iNeedFeatureStorage,
SScreenBlockFeatureStorage* pScreenBlockFeatureStorage) {
const int32_t kiFeatureStrategyIndex = iNeedFeatureStorage>>16;
const int32_t kiMe8x8FME = iNeedFeatureStorage & 0x0000FF & ME_FME;
const int32_t kiMe16x16FME = ((iNeedFeatureStorage & 0x00FF00)>>8) & ME_FME;
if ((kiMe8x8FME==ME_FME) && (kiMe16x16FME==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 bool bIsBlock8x8 = (kiMe8x8FME==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;
@ -749,6 +750,7 @@ void SaveFeatureSearchOut( const SMVUnitXY sBestMv, const uint32_t uiBestSadCost
pFeatureSearchOut->uiBestSadCost = uiBestSadCost;
pFeatureSearchOut->pBestRef = pRef;
}
bool FeatureSearchOne( SFeatureSearchIn &sFeatureSearchIn, const int32_t iFeatureDifference, const uint32_t kuiExpectedSearchTimes,
SFeatureSearchOut* pFeatureSearchOut) {
const int32_t iFeatureOfRef = (sFeatureSearchIn.iFeatureOfCurrent + iFeatureDifference);
@ -819,6 +821,7 @@ bool FeatureSearchOne( SFeatureSearchIn &sFeatureSearchIn, const int32_t iFeatur
return (i < iSearchTimesx2);
}
void MotionEstimateFeatureFullSearch( SFeatureSearchIn &sFeatureSearchIn,
const uint32_t kuiMaxSearchPoint,
SWelsME* pMe) {
@ -840,8 +843,8 @@ void MotionEstimateFeatureFullSearch( SFeatureSearchIn &sFeatureSearchIn,
// Search function options
/////////////////////////
void WelsDiamondCrossSearch(SWelsFuncPtrList *pFunc, void* vpMe, void* vpSlice, const int32_t kiEncStride, const int32_t kiRefStride) {
SWelsME* pMe = static_cast<SWelsME *>(vpMe);
SSlice* pSlice = static_cast<SSlice *>(vpSlice);
SWelsME* pMe = static_cast<SWelsME *>(vpMe);
SSlice* pSlice = static_cast<SSlice *>(vpSlice);
// Step 1: diamond search
WelsDiamondSearch(pFunc, vpMe, vpSlice, kiEncStride, kiRefStride);
@ -854,8 +857,8 @@ void WelsDiamondCrossSearch(SWelsFuncPtrList *pFunc, void* vpMe, void* vpSlice,
}
}
void WelsDiamondCrossFeatureSearch(SWelsFuncPtrList *pFunc, void* vpMe, void* vpSlice, const int32_t kiEncStride, const int32_t kiRefStride) {
SWelsME* pMe = static_cast<SWelsME *>(vpMe);
SSlice* pSlice = static_cast<SSlice *>(vpSlice);
SWelsME* pMe = static_cast<SWelsME *>(vpMe);
SSlice* pSlice = static_cast<SSlice *>(vpSlice);
// Step 1: diamond search + cross
WelsDiamondCrossSearch(pFunc, pMe, pSlice, kiEncStride, kiRefStride);
@ -875,5 +878,6 @@ void WelsDiamondCrossFeatureSearch(SWelsFuncPtrList *pFunc, void* vpMe, void* vp
pSlice->uiSliceFMECostDown -= pMe->uiSadCost;
}
}
} // namespace WelsSVCEnc

View File

@ -134,7 +134,7 @@ int32_t CWelsPreProcess::AllocSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCoding
uint8_t i = 0;
do {
SPicture* pPic = AllocPicture (pMa, kiPicWidth, kiPicHeight, false);
SPicture* pPic = AllocPicture (pMa, kiPicWidth, kiPicHeight, false, 0);
WELS_VERIFY_RETURN_IF (1, (NULL == pPic))
m_pSpatialPic[iDlayerIndex][i] = pPic;
++ i;
@ -435,7 +435,7 @@ int32_t WelsInitScaledPic (SWelsSvcCodingParam* pParam, Scaled_Picture* pScal
bool bInputPicNeedScaling = JudgeNeedOfScaling (pParam, pScaledPicture);
if (bInputPicNeedScaling) {
pScaledPicture->pScaledInputPicture = AllocPicture (pMemoryAlign, pParam->SUsedPicRect.iWidth,
pParam->SUsedPicRect.iHeight, false);
pParam->SUsedPicRect.iHeight, false, 0);
if (pScaledPicture->pScaledInputPicture == NULL)
return -1;
}