add me function pointers for screen contents
This commit is contained in:
parent
cc7535ee52
commit
80ae4cb7d8
@ -90,6 +90,8 @@ typedef struct TagWelsME {
|
||||
SMVUnitXY sMvBase;
|
||||
SMVUnitXY sDirectionalMv;
|
||||
|
||||
SScreenBlockFeatureStorage* pRefFeatureStorage;
|
||||
|
||||
/* output */
|
||||
SMVUnitXY sMv;
|
||||
} SWelsME;
|
||||
@ -220,7 +222,10 @@ void HorizontalFullSearchUsingSSE41 (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
|
||||
const int32_t kiMinPos, const int32_t kiMaxPos,
|
||||
const bool bVerticalSearch);
|
||||
#endif
|
||||
void WelsMotionCrossSearch (SWelsFuncPtrList* pFuncList, SDqLayer* pCurLayer, SWelsME* pMe, const SSlice* pSlice);
|
||||
void WelsMotionCrossSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice,
|
||||
const int32_t kiEncStride, const int32_t kiRefStride);
|
||||
void WelsDiamondCrossSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice,
|
||||
const int32_t kiEncStride, const int32_t kiRefStride);
|
||||
|
||||
// Feature Search Basics
|
||||
#define LIST_SIZE_SUM_16x16 0x0FF01 //(256*255+1)
|
||||
@ -256,6 +261,9 @@ void PerformFMEPreprocess (SWelsFuncPtrList* pFunc, SPicture* pRef, uint16_t* pF
|
||||
void UpdateFMESwitch (SDqLayer* pCurLayer);
|
||||
void UpdateFMESwitchNull (SDqLayer* pCurLayer);
|
||||
|
||||
void WelsDiamondCrossFeatureSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice,
|
||||
const int32_t kiEncStride, const int32_t kiRefStride);
|
||||
|
||||
//inline functions
|
||||
inline void SetMvWithinIntegerMvRange (const int32_t kiMbWidth, const int32_t kiMbHeight, const int32_t kiMbX,
|
||||
const int32_t kiMbY,
|
||||
|
@ -2428,6 +2428,36 @@ static inline void SetNormalCodingFunc (SWelsFuncPtrList* pFuncList) {
|
||||
pFuncList->sSampleDealingFuncs.pfIntra4x4Combined3 =
|
||||
pFuncList->sSampleDealingFuncs.pfIntra4x4Combined3Satd;
|
||||
}
|
||||
bool SetMeMethod (const uint8_t uiMethod, PSearchMethodFunc& pSearchMethodFunc) {
|
||||
switch (uiMethod) {
|
||||
case ME_DIA:
|
||||
pSearchMethodFunc = WelsDiamondSearch;
|
||||
break;
|
||||
case ME_CROSS:
|
||||
pSearchMethodFunc = WelsMotionCrossSearch;
|
||||
break;
|
||||
case ME_DIA_CROSS:
|
||||
pSearchMethodFunc = WelsDiamondCrossSearch;
|
||||
break;
|
||||
case ME_DIA_CROSS_FME:
|
||||
pSearchMethodFunc = WelsDiamondCrossFeatureSearch;
|
||||
break;
|
||||
case ME_FULL:
|
||||
#ifdef HAVE_MMX
|
||||
// make sure your cpu can support x86 sse4.1 instruction set if try it
|
||||
//pSearchMethodFunc = WelsFullSearch;
|
||||
#else
|
||||
pSearchMethodFunc = WelsDiamondSearch;
|
||||
return false;
|
||||
#endif//HAVE_MMX
|
||||
break;
|
||||
default:
|
||||
pSearchMethodFunc = WelsDiamondSearch;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
||||
@ -2465,13 +2495,19 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
||||
return;
|
||||
//to init at each frame will be needed when dealing with hybrid content (camera+screen)
|
||||
if (pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||
SFeatureSearchPreparation* pFeatureSearchPreparation = pCurLayer->pFeatureSearchPreparation;
|
||||
if (pFeatureSearchPreparation) {
|
||||
pFeatureSearchPreparation->iHighFreMbCount = 0;
|
||||
if (P_SLICE == pCtx->eSliceType) {
|
||||
//MD related func pointers
|
||||
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaaOnScreen;
|
||||
|
||||
if (P_SLICE == pCtx->eSliceType) {
|
||||
//MD related func pointers
|
||||
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaaOnScreen;
|
||||
//ME related func pointers
|
||||
//ME16x16
|
||||
if (!SetMeMethod (ME_DIA_CROSS, pFuncList->pfSearchMethod[BLOCK_16x16])) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "SetMeMethod(BLOCK_16x16) ME_DIA_CROSS unsuccessful, switched to default search\n");
|
||||
}
|
||||
//ME8x8
|
||||
SFeatureSearchPreparation* pFeatureSearchPreparation = pCurLayer->pFeatureSearchPreparation;
|
||||
if (pFeatureSearchPreparation) {
|
||||
pFeatureSearchPreparation->iHighFreMbCount = 0;
|
||||
|
||||
//calculate bFMESwitchFlag
|
||||
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
||||
@ -2491,8 +2527,11 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
||||
}
|
||||
|
||||
//assign ME pointer
|
||||
if (pScreenBlockFeatureStorage->bRefBlockFeatureCalculated) {
|
||||
//TBC int32_t iIs16x16 = pScreenBlockFeatureStorage->iIs16x16;
|
||||
if (pFeatureSearchPreparation->bFMESwitchFlag && pScreenBlockFeatureStorage->bRefBlockFeatureCalculated
|
||||
&& (!pScreenBlockFeatureStorage->iIs16x16)) {
|
||||
if (!SetMeMethod (ME_DIA_CROSS_FME, pFuncList->pfSearchMethod[BLOCK_8x8])) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING, "SetMeMethod(BLOCK_8x8) ME_DIA_CROSS_FME unsuccessful, switched to default search\n");
|
||||
}
|
||||
}
|
||||
|
||||
//assign UpdateFMESwitch pointer
|
||||
@ -2501,11 +2540,11 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
||||
} else {
|
||||
pFuncList->pfUpdateFMESwitch = UpdateFMESwitchNull;
|
||||
}
|
||||
} else {
|
||||
//reset some status when at I_SLICE
|
||||
pFeatureSearchPreparation->bFMESwitchFlag = true;
|
||||
pFeatureSearchPreparation->uiFMEGoodFrameCount = FMESWITCH_DEFAULT_GOODFRAME_NUM;
|
||||
}
|
||||
}//if (pFeatureSearchPreparation)
|
||||
} else {
|
||||
//reset some status when at I_SLICE
|
||||
pCurLayer->pFeatureSearchPreparation->bFMESwitchFlag = true;
|
||||
pCurLayer->pFeatureSearchPreparation->uiFMEGoodFrameCount = FMESWITCH_DEFAULT_GOODFRAME_NUM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -971,6 +971,7 @@ void WelsMdIntraMb (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCach
|
||||
}
|
||||
|
||||
static inline void InitMe (const SWelsMD& sWelsMd, const int32_t iBlockSize, uint8_t* pEnc, uint8_t* pRef,
|
||||
SScreenBlockFeatureStorage* pRefFeatureStorage,
|
||||
SWelsME& sWelsMe) {
|
||||
sWelsMe.iCurMeBlockPixX = sWelsMd.iMbPixX;
|
||||
sWelsMe.iCurMeBlockPixY = sWelsMd.iMbPixY;
|
||||
@ -979,6 +980,8 @@ static inline void InitMe (const SWelsMD& sWelsMd, const int32_t iBlockSize, uin
|
||||
|
||||
sWelsMe.pEncMb = pEnc;
|
||||
sWelsMe.pRefMb = sWelsMe.pColoRefMb = pRef;
|
||||
|
||||
sWelsMe.pRefFeatureStorage = pRefFeatureStorage;
|
||||
}
|
||||
|
||||
int32_t WelsMdP16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWelsMd, SSlice* pSlice, SMB* pCurMb) {
|
||||
@ -988,6 +991,7 @@ int32_t WelsMdP16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWe
|
||||
const int32_t kiMbWidth = pCurLayer->iMbWidth; // for assign once
|
||||
const int32_t kiMbHeight = pCurLayer->iMbHeight;
|
||||
InitMe (*pWelsMd, BLOCK_16x16, pMbCache->SPicData.pEncMb[0], pMbCache->SPicData.pRefMb[0],
|
||||
pCurLayer->pRefPic->pScreenBlockFeatureStorage,
|
||||
*pMe16x16);
|
||||
//not putting the line below into InitMe to avoid judging mode in InitMe
|
||||
pMe16x16->uSadPredISatd.uiSadPred = pWelsMd->iSadPredMb;
|
||||
@ -1038,6 +1042,7 @@ int32_t WelsMdP16x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pW
|
||||
InitMe (*pWelsMd, BLOCK_16x8,
|
||||
pMbCache->SPicData.pEncMb[0] + (iPixelY * iStrideEnc),
|
||||
pMbCache->SPicData.pRefMb[0] + (iPixelY * iStrideRef),
|
||||
pCurDqLayer->pRefPic->pScreenBlockFeatureStorage,
|
||||
*sMe16x8);
|
||||
//not putting the lines below into InitMe to avoid judging mode in InitMe
|
||||
sMe16x8->iCurMeBlockPixY = pWelsMd->iMbPixY + iPixelY;
|
||||
@ -1065,6 +1070,7 @@ int32_t WelsMdP8x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWel
|
||||
InitMe (*pWelsMd, BLOCK_8x16,
|
||||
pMbCache->SPicData.pEncMb[0] + iPixelX,
|
||||
pMbCache->SPicData.pRefMb[0] + iPixelX,
|
||||
pCurLayer->pRefPic->pScreenBlockFeatureStorage,
|
||||
*sMe8x16);
|
||||
//not putting the lines below into InitMe to avoid judging mode in InitMe
|
||||
sMe8x16->iCurMeBlockPixX = pWelsMd->iMbPixX + iPixelX;
|
||||
@ -1100,6 +1106,7 @@ int32_t WelsMdP8x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWe
|
||||
InitMe (*pWelsMd, BLOCK_8x8,
|
||||
pMbCache->SPicData.pEncMb[0] + iStrideEnc,
|
||||
pMbCache->SPicData.pRefMb[0] + iStrideRef,
|
||||
pCurDqLayer->pRefPic->pScreenBlockFeatureStorage,
|
||||
*sMe8x8);
|
||||
//not putting these three lines below into InitMe to avoid judging mode in InitMe
|
||||
sMe8x8->iCurMeBlockPixX = pWelsMd->iMbPixX + iPixelX;
|
||||
|
@ -492,8 +492,8 @@ void LineFullSearch_c (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
|
||||
}
|
||||
}
|
||||
|
||||
void WelsMotionCrossSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
|
||||
const SSlice* pSlice, const int32_t kiEncStride, const int32_t kiRefStride) {
|
||||
void WelsMotionCrossSearch (SWelsFuncPtrList* pFuncList, SWelsME* pMe, SSlice* pSlice,
|
||||
const int32_t kiEncStride, const int32_t kiRefStride) {
|
||||
PLineFullSearchFunc pfVerticalFullSearchFunc = pFuncList->pfVerticalFullSearch;
|
||||
PLineFullSearchFunc pfHorizontalFullSearchFunc = pFuncList->pfHorizontalFullSearch;
|
||||
|
||||
@ -709,13 +709,18 @@ void FillQpelLocationByFeatureValue_c (uint16_t* pFeatureOfBlock, const int32_t
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateFeatureOfBlock (SWelsFuncPtrList* pFunc, SPicture* pRef,
|
||||
bool CalculateFeatureOfBlock (SWelsFuncPtrList* pFunc, SPicture* pRef,
|
||||
SScreenBlockFeatureStorage* pScreenBlockFeatureStorage) {
|
||||
uint16_t* pFeatureOfBlock = pScreenBlockFeatureStorage->pFeatureOfBlockPointer;
|
||||
uint32_t* pTimesOfFeatureValue = pScreenBlockFeatureStorage->pTimesOfFeatureValue;
|
||||
uint16_t** pLocationOfFeature = pScreenBlockFeatureStorage->pLocationOfFeature;
|
||||
uint16_t* pBuf = pScreenBlockFeatureStorage->pLocationPointer;
|
||||
|
||||
if (NULL == pFeatureOfBlock || NULL == pTimesOfFeatureValue || NULL == pLocationOfFeature || NULL == pBuf
|
||||
|| NULL == pRef->pData[0]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* pRefData = pRef->pData[0];
|
||||
const int32_t iRefStride = pRef->iLineSize[0];
|
||||
int32_t iIs16x16 = pScreenBlockFeatureStorage->iIs16x16;
|
||||
@ -735,25 +740,28 @@ void CalculateFeatureOfBlock (SWelsFuncPtrList* pFunc, SPicture* pRef,
|
||||
|
||||
//assign each pixel's pLocationOfFeature
|
||||
FillQpelLocationByFeatureValue_c (pFeatureOfBlock, iWidth, kiHeight, pFeatureValuePointerList);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PerformFMEPreprocess (SWelsFuncPtrList* pFunc, SPicture* pRef, uint16_t* pFeatureOfBlock,
|
||||
SScreenBlockFeatureStorage* pScreenBlockFeatureStorage) {
|
||||
pScreenBlockFeatureStorage->pFeatureOfBlockPointer = pFeatureOfBlock;
|
||||
CalculateFeatureOfBlock (pFunc, pRef, pScreenBlockFeatureStorage);
|
||||
pScreenBlockFeatureStorage->bRefBlockFeatureCalculated = true;
|
||||
pScreenBlockFeatureStorage->bRefBlockFeatureCalculated = CalculateFeatureOfBlock (pFunc, pRef,
|
||||
pScreenBlockFeatureStorage);
|
||||
|
||||
uint32_t uiRefPictureAvgQstepx16 = QStepx16ByQp[WelsMedian (0, pRef->iFrameAverageQp, 51)];
|
||||
uint32_t uiSadCostThreshold16x16 = ((30 * (uiRefPictureAvgQstepx16 + 160)) >> 3);
|
||||
pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_16x16] = uiSadCostThreshold16x16;
|
||||
pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_8x8] = (uiSadCostThreshold16x16 >> 2);
|
||||
pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_16x8]
|
||||
= pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_8x16]
|
||||
= pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_4x4] = UINT_MAX;
|
||||
if (pScreenBlockFeatureStorage->bRefBlockFeatureCalculated) {
|
||||
uint32_t uiRefPictureAvgQstepx16 = QStepx16ByQp[WelsMedian (0, pRef->iFrameAverageQp, 51)];
|
||||
uint32_t uiSadCostThreshold16x16 = ((30 * (uiRefPictureAvgQstepx16 + 160)) >> 3);
|
||||
pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_16x16] = uiSadCostThreshold16x16;
|
||||
pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_8x8] = (uiSadCostThreshold16x16 >> 2);
|
||||
pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_16x8]
|
||||
= pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_8x16]
|
||||
= pScreenBlockFeatureStorage->uiSadCostThreshold[BLOCK_4x4] = UINT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
//search related
|
||||
void SetFeatureSearchIn (SWelsFuncPtrList* pFunc, const SWelsME& sMe,
|
||||
bool SetFeatureSearchIn (SWelsFuncPtrList* pFunc, const SWelsME& sMe,
|
||||
const SSlice* pSlice, SScreenBlockFeatureStorage* pRefFeatureStorage,
|
||||
const int32_t kiEncStride, const int32_t kiRefStride,
|
||||
SFeatureSearchIn* pFeatureSearchIn) {
|
||||
@ -781,6 +789,12 @@ void SetFeatureSearchIn (SWelsFuncPtrList* pFunc, const SWelsME& sMe,
|
||||
pFeatureSearchIn->iMinQpelY = pFeatureSearchIn->iCurPixYQpel + ((pSlice->sMvStartMin.iMvY) << 2);
|
||||
pFeatureSearchIn->iMaxQpelX = pFeatureSearchIn->iCurPixXQpel + ((pSlice->sMvStartMax.iMvX) << 2);
|
||||
pFeatureSearchIn->iMaxQpelY = pFeatureSearchIn->iCurPixYQpel + ((pSlice->sMvStartMax.iMvY) << 2);
|
||||
|
||||
if (NULL == pFeatureSearchIn->pSad || NULL == pFeatureSearchIn->pTimesOfFeature
|
||||
|| NULL == pFeatureSearchIn->pQpelLocationOfFeature) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void SaveFeatureSearchOut (const SMVUnitXY sBestMv, const uint32_t uiBestSadCost, uint8_t* pRef,
|
||||
SFeatureSearchOut* pFeatureSearchOut) {
|
||||
@ -922,8 +936,7 @@ void WelsDiamondCrossSearch (SWelsFuncPtrList* pFunc, SWelsME* pMe, SSlice* pSli
|
||||
WelsDiamondSearch (pFunc, pMe, pSlice, kiEncStride, kiRefStride);
|
||||
|
||||
// Step 2: CROSS search
|
||||
SScreenBlockFeatureStorage pRefBlockFeature; //TODO: use this structure from Ref
|
||||
pMe->uiSadCostThreshold = pRefBlockFeature.uiSadCostThreshold[pMe->uiBlockSize];
|
||||
pMe->uiSadCostThreshold = pMe->pRefFeatureStorage->uiSadCostThreshold[pMe->uiBlockSize];
|
||||
if (pMe->uiSadCost >= pMe->uiSadCostThreshold) {
|
||||
WelsMotionCrossSearch (pFunc, pMe, pSlice, kiEncStride, kiRefStride);
|
||||
}
|
||||
@ -937,14 +950,13 @@ void WelsDiamondCrossFeatureSearch (SWelsFuncPtrList* pFunc, SWelsME* pMe, SSlic
|
||||
if (pMe->uiSadCost >= pMe->uiSadCostThreshold) {
|
||||
pSlice->uiSliceFMECostDown += pMe->uiSadCost;
|
||||
|
||||
SScreenBlockFeatureStorage tmpScreenBlockFeatureStorage; //TODO: use this structure from Ref
|
||||
uint32_t uiMaxSearchPoint = INT_MAX;//TODO: change it according to computational-complexity setting
|
||||
SFeatureSearchIn sFeatureSearchIn = {0};
|
||||
SetFeatureSearchIn (pFunc, *pMe, pSlice, &tmpScreenBlockFeatureStorage,
|
||||
kiEncStride, kiRefStride,
|
||||
&sFeatureSearchIn);
|
||||
MotionEstimateFeatureFullSearch (sFeatureSearchIn, uiMaxSearchPoint, pMe);
|
||||
|
||||
if (SetFeatureSearchIn (pFunc, *pMe, pSlice, pMe->pRefFeatureStorage,
|
||||
kiEncStride, kiRefStride,
|
||||
&sFeatureSearchIn)) {
|
||||
MotionEstimateFeatureFullSearch (sFeatureSearchIn, uiMaxSearchPoint, pMe);
|
||||
}
|
||||
pSlice->uiSliceFMECostDown -= pMe->uiSadCost;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user