completing and bug-fixing the screen content MD/ME process
This commit is contained in:
@@ -119,7 +119,9 @@ SWelsSliceBs* pSliceBs; // bitstream buffering for various slices, [uiSliceI
|
|||||||
int32_t* pSadCostMb;
|
int32_t* pSadCostMb;
|
||||||
/* MVD cost tables for Inter MB */
|
/* MVD cost tables for Inter MB */
|
||||||
int32_t iMvRange;
|
int32_t iMvRange;
|
||||||
uint16_t* pMvdCostTableInter; //[52]; // adaptive to spatial layers
|
uint16_t* pMvdCostTable; //[52]; // adaptive to spatial layers
|
||||||
|
int32_t iMvdCostTableSize; //the size of above table
|
||||||
|
int32_t iMvdCostTableStride; //the stride of above table
|
||||||
SMVUnitXY*
|
SMVUnitXY*
|
||||||
pMvUnitBlock4x4; // (*pMvUnitBlock4x4[2])[MB_BLOCK4x4_NUM]; // for store each 4x4 blocks' mv unit, the two swap after different d layer
|
pMvUnitBlock4x4; // (*pMvUnitBlock4x4[2])[MB_BLOCK4x4_NUM]; // for store each 4x4 blocks' mv unit, the two swap after different d layer
|
||||||
int8_t*
|
int8_t*
|
||||||
|
|||||||
@@ -76,15 +76,7 @@ void WelsMdInterMb (void* pEncCtx, void* pWelsMd, SSlice* pSlice, SMB* pCurMb, S
|
|||||||
//both used in BL and EL
|
//both used in BL and EL
|
||||||
//void wels_md_inter_init ( SWelsMD* pMd, const uint8_t ref_idx, const bool is_highest_dlayer_flag );
|
//void wels_md_inter_init ( SWelsMD* pMd, const uint8_t ref_idx, const bool is_highest_dlayer_flag );
|
||||||
|
|
||||||
bool WelsMdInterJudgeBGDPskip (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
|
||||||
bool* bKeepSkip);
|
|
||||||
bool WelsMdInterJudgeBGDPskipFalse (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
|
||||||
bool* bKeepSkip);
|
|
||||||
|
|
||||||
void WelsMdInterUpdateBGDInfo (SDqLayer* pCurLayer, SMB* pCurMb, const bool kbCollocatedPredFlag,
|
|
||||||
const int32_t kiRefPictureType);
|
|
||||||
void WelsMdInterUpdateBGDInfoNULL (SDqLayer* pCurLayer, SMB* pCurMb, const bool kbCollocatedPredFlag,
|
|
||||||
const int32_t kiRefPictureType);
|
|
||||||
|
|
||||||
bool WelsMdInterJudgePskip (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
bool WelsMdInterJudgePskip (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||||
bool bTrySkip);
|
bool bTrySkip);
|
||||||
@@ -102,9 +94,6 @@ void WelsMdInterSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlic
|
|||||||
void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
|
||||||
//end of: both used in BL and EL
|
//end of: both used in BL and EL
|
||||||
|
|
||||||
//typedef void (*MD_INTRA_MB_BASE) (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb);
|
|
||||||
|
|
||||||
void WelsInitSCDPskipFunc (SWelsFuncPtrList* pFuncList, const bool bScrollingDetection);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif//WELS_MACROBLOCK_MODE_DECISION_H__
|
#endif//WELS_MACROBLOCK_MODE_DECISION_H__
|
||||||
|
|||||||
@@ -64,11 +64,31 @@ void WelsMdSpatialelInterMbIlfmdNoilp (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, S
|
|||||||
void WelsMdInterMbEnhancelayer (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache);
|
void WelsMdInterMbEnhancelayer (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache);
|
||||||
SMB* GetRefMb (SDqLayer* pCurLayer, SMB* pCurMb);
|
SMB* GetRefMb (SDqLayer* pCurLayer, SMB* pCurMb);
|
||||||
void SetMvBaseEnhancelayer (SWelsMD* pMd, SMB* pCurMb, const SMB* kpRefMb);
|
void SetMvBaseEnhancelayer (SWelsMD* pMd, SMB* pCurMb, const SMB* kpRefMb);
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// MD from background detection
|
||||||
|
//////////////
|
||||||
|
bool WelsMdInterJudgeBGDPskip (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||||
|
bool* bKeepSkip);
|
||||||
|
bool WelsMdInterJudgeBGDPskipFalse (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||||
|
bool* bKeepSkip);
|
||||||
|
|
||||||
|
void WelsMdInterUpdateBGDInfo (SDqLayer* pCurLayer, SMB* pCurMb, const bool kbCollocatedPredFlag,
|
||||||
|
const int32_t kiRefPictureType);
|
||||||
|
void WelsMdInterUpdateBGDInfoNULL (SDqLayer* pCurLayer, SMB* pCurMb, const bool kbCollocatedPredFlag,
|
||||||
|
const int32_t kiRefPictureType);
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// MD for screen contents
|
||||||
|
//////////////
|
||||||
bool MdInterSCDPskipProcess (sWelsEncCtx* pEncCtx, SWelsMD* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
bool MdInterSCDPskipProcess (sWelsEncCtx* pEncCtx, SWelsMD* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||||
ESkipModes eSkipMode);
|
ESkipModes eSkipMode);
|
||||||
|
|
||||||
typedef bool (*pJudgeSkipFun) (sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache* pMbCache, SWelsMD* pWelsMd);
|
typedef bool (*pJudgeSkipFun) (sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache* pMbCache, SWelsMD* pWelsMd);
|
||||||
void SetBlockStaticIdcToMd (void* pVaa, void* pMd, SMB* pCurMb, void* pDqLay);
|
void SetBlockStaticIdcToMd (void* pVaa, void* pMd, SMB* pCurMb, void* pDqLay);
|
||||||
|
void WelsInitSCDPskipFunc (SWelsFuncPtrList* pFuncList, const bool bScrollingDetection);
|
||||||
|
|
||||||
|
void SetScrollingMvToMd (void* pVaa, void* pWelsMd);
|
||||||
|
void SetScrollingMvToMdNull (void* pVaa, void* pWelsMd);
|
||||||
}
|
}
|
||||||
#endif //SVC_MODE_DECISION_H
|
#endif //SVC_MODE_DECISION_H
|
||||||
|
|
||||||
|
|||||||
@@ -145,8 +145,8 @@ void WelsInitMeFunc (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag, bool bScre
|
|||||||
* \return NONE
|
* \return NONE
|
||||||
*/
|
*/
|
||||||
void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
|
void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
|
||||||
|
void WelsMotionEstimateSearchStatic (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
|
||||||
|
void WelsMotionEstimateSearchScrolled (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* pLpslice);
|
||||||
/*!
|
/*!
|
||||||
* \brief BL mb motion estimate initial point testing
|
* \brief BL mb motion estimate initial point testing
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ typedef void (*PInterMdBackgroundInfoUpdateFunc) (SDqLayer* pCurLayer, SMB* pCu
|
|||||||
|
|
||||||
typedef bool (*PInterMdScrollingPSkipDecisionFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb,
|
typedef bool (*PInterMdScrollingPSkipDecisionFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb,
|
||||||
SMbCache* pMbCache);
|
SMbCache* pMbCache);
|
||||||
|
typedef void (*PSetScrollingMv) (void* pVaa, void* pMd);
|
||||||
|
|
||||||
typedef void (*PInterMdFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb, SMbCache* pMbCache);
|
typedef void (*PInterMdFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb, SMbCache* pMbCache);
|
||||||
|
|
||||||
@@ -208,6 +209,7 @@ struct TagWelsFuncPointerList {
|
|||||||
PInterMdBackgroundInfoUpdateFunc pfInterMdBackgroundInfoUpdate;
|
PInterMdBackgroundInfoUpdateFunc pfInterMdBackgroundInfoUpdate;
|
||||||
|
|
||||||
PInterMdScrollingPSkipDecisionFunc pfSCDPSkipDecision;
|
PInterMdScrollingPSkipDecisionFunc pfSCDPSkipDecision;
|
||||||
|
PSetScrollingMv pfSetScrollingMv;
|
||||||
|
|
||||||
SMcFunc sMcFuncs;
|
SMcFunc sMcFuncs;
|
||||||
SSampleDealingFunc sSampleDealingFuncs;
|
SSampleDealingFunc sSampleDealingFuncs;
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
#include "sample.h"
|
#include "sample.h"
|
||||||
|
|
||||||
#include "svc_base_layer_md.h"
|
#include "svc_base_layer_md.h"
|
||||||
|
#include "svc_mode_decision.h"
|
||||||
#include "set_mb_syn_cavlc.h"
|
#include "set_mb_syn_cavlc.h"
|
||||||
#include "crt_util_safe_x.h" // Safe CRT routines like utils for cross_platforms
|
#include "crt_util_safe_x.h" // Safe CRT routines like utils for cross_platforms
|
||||||
#include "slice_multi_threading.h"
|
#include "slice_multi_threading.h"
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "picture_handle.h"
|
#include "picture_handle.h"
|
||||||
#include "svc_base_layer_md.h"
|
#include "svc_base_layer_md.h"
|
||||||
#include "svc_encode_slice.h"
|
#include "svc_encode_slice.h"
|
||||||
|
#include "svc_mode_decision.h"
|
||||||
#include "decode_mb_aux.h"
|
#include "decode_mb_aux.h"
|
||||||
#include "deblocking.h"
|
#include "deblocking.h"
|
||||||
#include "ref_list_mgr_svc.h"
|
#include "ref_list_mgr_svc.h"
|
||||||
@@ -1278,8 +1279,9 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
|||||||
(*ppCtx)->iMvRange = pParam->iUsageType ? EXPANDED_MV_RANGE : CAMERA_STARTMV_RANGE;
|
(*ppCtx)->iMvRange = pParam->iUsageType ? EXPANDED_MV_RANGE : CAMERA_STARTMV_RANGE;
|
||||||
const int32_t kiMvdRange = (pParam->iUsageType ? EXPANDED_MVD_RANGE : ((kiNumDependencyLayers == 1) ? CAMERA_MVD_RANGE :
|
const int32_t kiMvdRange = (pParam->iUsageType ? EXPANDED_MVD_RANGE : ((kiNumDependencyLayers == 1) ? CAMERA_MVD_RANGE :
|
||||||
CAMERA_HIGHLAYER_MVD_RANGE));
|
CAMERA_HIGHLAYER_MVD_RANGE));
|
||||||
const uint32_t kuiMvdInterTableSize = 1 + (kiMvdRange << 3);//intepel*4=qpel; qpel_mv_range*2=(+/-);
|
const uint32_t kuiMvdInterTableSize = (kiMvdRange << 2); //intepel*4=qpel
|
||||||
const uint32_t kuiMvdCacheAlignedSize = kuiMvdInterTableSize * sizeof (uint16_t);
|
const uint32_t kuiMvdInterTableStride = 1 + (kuiMvdInterTableSize << 1);//qpel_mv_range*2=(+/-);
|
||||||
|
const uint32_t kuiMvdCacheAlignedSize = kuiMvdInterTableStride * sizeof (uint16_t);
|
||||||
int32_t iVclLayersBsSizeCount = 0;
|
int32_t iVclLayersBsSizeCount = 0;
|
||||||
int32_t iNonVclLayersBsSizeCount = 0;
|
int32_t iNonVclLayersBsSizeCount = 0;
|
||||||
int32_t iTargetSpatialBsSize = 0;
|
int32_t iTargetSpatialBsSize = 0;
|
||||||
@@ -1482,9 +1484,11 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*ppCtx)->pMvdCostTableInter = (uint16_t*)pMa->WelsMallocz (52 * kuiMvdCacheAlignedSize, "pMvdCostTableInter");
|
(*ppCtx)->iMvdCostTableSize = kuiMvdInterTableSize;
|
||||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pMvdCostTableInter), FreeMemorySvc (ppCtx))
|
(*ppCtx)->iMvdCostTableStride = kuiMvdInterTableStride;
|
||||||
MvdCostInit ((*ppCtx)->pMvdCostTableInter, kuiMvdInterTableSize); //should put to a better place?
|
(*ppCtx)->pMvdCostTable = (uint16_t*)pMa->WelsMallocz (52 * kuiMvdCacheAlignedSize, "pMvdCostTable");
|
||||||
|
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pMvdCostTable), FreeMemorySvc (ppCtx))
|
||||||
|
MvdCostInit ((*ppCtx)->pMvdCostTable, kuiMvdInterTableStride); //should put to a better place?
|
||||||
|
|
||||||
if ((*ppCtx)->ppRefPicListExt[0] != NULL && (*ppCtx)->ppRefPicListExt[0]->pRef[0] != NULL)
|
if ((*ppCtx)->ppRefPicListExt[0] != NULL && (*ppCtx)->ppRefPicListExt[0]->pRef[0] != NULL)
|
||||||
(*ppCtx)->pDecPic = (*ppCtx)->ppRefPicListExt[0]->pRef[0];
|
(*ppCtx)->pDecPic = (*ppCtx)->ppRefPicListExt[0]->pRef[0];
|
||||||
@@ -1741,9 +1745,9 @@ void FreeMemorySvc (sWelsEncCtx** ppCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* MVD cost tables for Inter */
|
/* MVD cost tables for Inter */
|
||||||
if (NULL != pCtx->pMvdCostTableInter) {
|
if (NULL != pCtx->pMvdCostTable) {
|
||||||
pMa->WelsFree (pCtx->pMvdCostTableInter, "pMvdCostTableInter");
|
pMa->WelsFree (pCtx->pMvdCostTable, "pMvdCostTable");
|
||||||
pCtx->pMvdCostTableInter = NULL;
|
pCtx->pMvdCostTable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeCodingParam (&pCtx->pSvcParam, pMa);
|
FreeCodingParam (&pCtx->pSvcParam, pMa);
|
||||||
@@ -2150,7 +2154,8 @@ void WelsUninitEncoderExt (sWelsEncCtx** ppCtx) {
|
|||||||
if (NULL == ppCtx || NULL == *ppCtx)
|
if (NULL == ppCtx || NULL == *ppCtx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_INFO, "WelsUninitEncoderExt(), pCtx= %p, iThreadCount= %d, iMultipleThreadIdc= %d.\n",
|
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_INFO,
|
||||||
|
"WelsUninitEncoderExt(), pCtx= %p, iThreadCount= %d, iMultipleThreadIdc= %d.\n",
|
||||||
(void*) (*ppCtx), (*ppCtx)->pSvcParam->iCountThreadsNum, (*ppCtx)->pSvcParam->iMultipleThreadIdc);
|
(void*) (*ppCtx), (*ppCtx)->pSvcParam->iCountThreadsNum, (*ppCtx)->pSvcParam->iMultipleThreadIdc);
|
||||||
|
|
||||||
#if defined(STAT_OUTPUT)
|
#if defined(STAT_OUTPUT)
|
||||||
@@ -2168,7 +2173,8 @@ void WelsUninitEncoderExt (sWelsEncCtx** ppCtx) {
|
|||||||
WelsEventSignal (& (*ppCtx)->pSliceThreading->pExitEncodeEvent[iThreadIdx]);
|
WelsEventSignal (& (*ppCtx)->pSliceThreading->pExitEncodeEvent[iThreadIdx]);
|
||||||
WelsEventSignal (& (*ppCtx)->pSliceThreading->pThreadMasterEvent[iThreadIdx]);
|
WelsEventSignal (& (*ppCtx)->pSliceThreading->pThreadMasterEvent[iThreadIdx]);
|
||||||
res = WelsThreadJoin ((*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx]); // waiting thread exit
|
res = WelsThreadJoin ((*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx]); // waiting thread exit
|
||||||
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_INFO, "WelsUninitEncoderExt(), pthread_join(pThreadHandles%d) return %d..\n", iThreadIdx,
|
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_INFO, "WelsUninitEncoderExt(), pthread_join(pThreadHandles%d) return %d..\n",
|
||||||
|
iThreadIdx,
|
||||||
res);
|
res);
|
||||||
(*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx] = 0;
|
(*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx] = 0;
|
||||||
}
|
}
|
||||||
@@ -2494,14 +2500,19 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
|||||||
SWelsFuncPtrList* pFuncList = pCtx->pFuncList;
|
SWelsFuncPtrList* pFuncList = pCtx->pFuncList;
|
||||||
SLogContext* pLogCtx = & (pCtx->sLogCtx);
|
SLogContext* pLogCtx = & (pCtx->sLogCtx);
|
||||||
/* function pointers conditional assignment under sWelsEncCtx, layer_mb_enc_rec (in stack) is exclusive */
|
/* function pointers conditional assignment under sWelsEncCtx, layer_mb_enc_rec (in stack) is exclusive */
|
||||||
if (kbHighestSpatialLayer && pCtx->pSvcParam->iUsageType == CAMERA_VIDEO_REAL_TIME) {
|
if ((pCtx->pSvcParam->iUsageType == CAMERA_VIDEO_REAL_TIME && kbHighestSpatialLayer) ||
|
||||||
|
(pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME && P_SLICE == pCtx->eSliceType
|
||||||
|
&& kbHighestSpatialLayer) //TODO: here is for sync with the origin code, consider the design again with more tests
|
||||||
|
) {
|
||||||
SetFastCodingFunc (pFuncList);
|
SetFastCodingFunc (pFuncList);
|
||||||
} else {
|
} else {
|
||||||
SetNormalCodingFunc (pFuncList);
|
SetNormalCodingFunc (pFuncList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_SLICE == pCtx->eSliceType) {
|
if (P_SLICE == pCtx->eSliceType) {
|
||||||
pFuncList->pfMotionSearch[0] = WelsMotionEstimateSearch;
|
for (int i = 0; i < BLOCK_STATIC_IDC_ALL; i++) {
|
||||||
|
pFuncList->pfMotionSearch[i] = WelsMotionEstimateSearch;
|
||||||
|
}
|
||||||
pFuncList->pfSearchMethod[BLOCK_16x16] =
|
pFuncList->pfSearchMethod[BLOCK_16x16] =
|
||||||
pFuncList->pfSearchMethod[BLOCK_16x8] =
|
pFuncList->pfSearchMethod[BLOCK_16x8] =
|
||||||
pFuncList->pfSearchMethod[BLOCK_8x16] =
|
pFuncList->pfSearchMethod[BLOCK_8x16] =
|
||||||
@@ -2509,6 +2520,8 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
|||||||
pFuncList->pfSearchMethod[BLOCK_4x4] = WelsDiamondSearch;
|
pFuncList->pfSearchMethod[BLOCK_4x4] = WelsDiamondSearch;
|
||||||
pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
|
pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
|
||||||
pFuncList->sSampleDealingFuncs.pfMeCost = pCtx->pFuncList->sSampleDealingFuncs.pfSampleSatd;
|
pFuncList->sSampleDealingFuncs.pfMeCost = pCtx->pFuncList->sSampleDealingFuncs.pfSampleSatd;
|
||||||
|
pFuncList->pfSetScrollingMv = SetScrollingMvToMdNull;
|
||||||
|
|
||||||
if (kbHighestSpatialLayer) {
|
if (kbHighestSpatialLayer) {
|
||||||
pFuncList->pfCalculateSatd = NotCalculateSatdCost;
|
pFuncList->pfCalculateSatd = NotCalculateSatdCost;
|
||||||
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaa;
|
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaa;
|
||||||
@@ -2518,7 +2531,6 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
//to init at each frame will be needed when dealing with hybrid content (camera+screen)
|
//to init at each frame will be needed when dealing with hybrid content (camera+screen)
|
||||||
if (pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
if (pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
|
||||||
if (P_SLICE == pCtx->eSliceType) {
|
if (P_SLICE == pCtx->eSliceType) {
|
||||||
@@ -2526,6 +2538,17 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
|||||||
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaaOnScreen;
|
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaaOnScreen;
|
||||||
|
|
||||||
//ME related func pointers
|
//ME related func pointers
|
||||||
|
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
|
||||||
|
if (pVaaExt->sScrollDetectInfo.bScrollDetectFlag
|
||||||
|
&& (pVaaExt->sScrollDetectInfo.iScrollMvX | pVaaExt->sScrollDetectInfo.iScrollMvY)) {
|
||||||
|
pFuncList->pfSetScrollingMv = SetScrollingMvToMd;
|
||||||
|
} else {
|
||||||
|
pFuncList->pfSetScrollingMv = SetScrollingMvToMdNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFuncList->pfMotionSearch[NO_STATIC] = WelsMotionEstimateSearch;
|
||||||
|
pFuncList->pfMotionSearch[COLLOCATED_STATIC] = WelsMotionEstimateSearchStatic;
|
||||||
|
pFuncList->pfMotionSearch[SCROLLED_STATIC] = WelsMotionEstimateSearchScrolled;
|
||||||
//ME16x16
|
//ME16x16
|
||||||
if (!SetMeMethod (ME_DIA_CROSS, pFuncList->pfSearchMethod[BLOCK_16x16])) {
|
if (!SetMeMethod (ME_DIA_CROSS, pFuncList->pfSearchMethod[BLOCK_16x16])) {
|
||||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "SetMeMethod(BLOCK_16x16) ME_DIA_CROSS unsuccessful, switched to default search\n");
|
WelsLog (pLogCtx, WELS_LOG_WARNING, "SetMeMethod(BLOCK_16x16) ME_DIA_CROSS unsuccessful, switched to default search\n");
|
||||||
@@ -2547,8 +2570,7 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
|||||||
pFeatureSearchPreparation->pRefBlockFeature = pScreenBlockFeatureStorage;
|
pFeatureSearchPreparation->pRefBlockFeature = pScreenBlockFeatureStorage;
|
||||||
if (pFeatureSearchPreparation->bFMESwitchFlag
|
if (pFeatureSearchPreparation->bFMESwitchFlag
|
||||||
&& !pScreenBlockFeatureStorage->bRefBlockFeatureCalculated) {
|
&& !pScreenBlockFeatureStorage->bRefBlockFeatureCalculated) {
|
||||||
//TODO: use ORIGIN of reference when preprocessing is ready
|
PerformFMEPreprocess (pFuncList, pCurLayer->pRefOri[0], pFeatureSearchPreparation->pFeatureOfBlock,
|
||||||
PerformFMEPreprocess (pFuncList, pCurLayer->pRefPic, pFeatureSearchPreparation->pFeatureOfBlock,
|
|
||||||
pScreenBlockFeatureStorage);
|
pScreenBlockFeatureStorage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2556,7 +2578,8 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
|
|||||||
if (pFeatureSearchPreparation->bFMESwitchFlag && pScreenBlockFeatureStorage->bRefBlockFeatureCalculated
|
if (pFeatureSearchPreparation->bFMESwitchFlag && pScreenBlockFeatureStorage->bRefBlockFeatureCalculated
|
||||||
&& (!pScreenBlockFeatureStorage->iIs16x16)) {
|
&& (!pScreenBlockFeatureStorage->iIs16x16)) {
|
||||||
if (!SetMeMethod (ME_DIA_CROSS_FME, pFuncList->pfSearchMethod[BLOCK_8x8])) {
|
if (!SetMeMethod (ME_DIA_CROSS_FME, pFuncList->pfSearchMethod[BLOCK_8x8])) {
|
||||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "SetMeMethod(BLOCK_8x8) ME_DIA_CROSS_FME unsuccessful, switched to default search\n");
|
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||||
|
"SetMeMethod(BLOCK_8x8) ME_DIA_CROSS_FME unsuccessful, switched to default search\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3366,6 +3389,12 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
|||||||
PerformDeblockingFilter (pCtx);
|
PerformDeblockingFilter (pCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pCtx->pFuncList->pfRc.pfWelsRcPictureInfoUpdate (pCtx, iLayerSize);
|
||||||
|
pCtx->pDecPic->iFrameAverageQp = pCtx->pWelsSvcRc->iAverageFrameQp;
|
||||||
|
|
||||||
|
//update scc related
|
||||||
|
pCtx->pFuncList->pfUpdateFMESwitch (pCtx->pCurDqLayer);
|
||||||
|
|
||||||
// reference picture list update
|
// reference picture list update
|
||||||
if (eNalRefIdc != NRI_PRI_LOWEST) {
|
if (eNalRefIdc != NRI_PRI_LOWEST) {
|
||||||
if (!pCtx->pFuncList->pUpdateRefList (pCtx)) {
|
if (!pCtx->pFuncList->pUpdateRefList (pCtx)) {
|
||||||
@@ -3380,8 +3409,6 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
|||||||
|
|
||||||
iFrameSize += iLayerSize;
|
iFrameSize += iLayerSize;
|
||||||
|
|
||||||
pCtx->pFuncList->pfRc.pfWelsRcPictureInfoUpdate (pCtx, iLayerSize);
|
|
||||||
|
|
||||||
#ifdef ENABLE_FRAME_DUMP
|
#ifdef ENABLE_FRAME_DUMP
|
||||||
// Dump reconstruction picture for each sQualityStat layer
|
// Dump reconstruction picture for each sQualityStat layer
|
||||||
if (iCurDid + 1 < pSvcParam->iSpatialLayerNum)
|
if (iCurDid + 1 < pSvcParam->iSpatialLayerNum)
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ void SetUnref (SPicture* pRef) {
|
|||||||
pRef->uiRecieveConfirmed = RECIEVE_FAILED;
|
pRef->uiRecieveConfirmed = RECIEVE_FAILED;
|
||||||
pRef->iMarkFrameNum = -1;
|
pRef->iMarkFrameNum = -1;
|
||||||
pRef->bUsedAsRef = false;
|
pRef->bUsedAsRef = false;
|
||||||
|
|
||||||
|
if (NULL != pRef->pScreenBlockFeatureStorage)
|
||||||
|
pRef->pScreenBlockFeatureStorage->bRefBlockFeatureCalculated = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +589,8 @@ bool WelsBuildRefList (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx
|
|||||||
if (pRefList->pLongRefList[i]->uiRecieveConfirmed == RECIEVE_SUCCESS) {
|
if (pRefList->pLongRefList[i]->uiRecieveConfirmed == RECIEVE_SUCCESS) {
|
||||||
pCtx->pRefList0[pCtx->iNumRef0++] = pRefList->pLongRefList[i];
|
pCtx->pRefList0[pCtx->iNumRef0++] = pRefList->pLongRefList[i];
|
||||||
pLtr->iLastRecoverFrameNum = pCtx->iFrameNum;
|
pLtr->iLastRecoverFrameNum = pCtx->iFrameNum;
|
||||||
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO, "pRef is int32_t !iLastRecoverFrameNum = %d, pRef iFrameNum = %d,LTR number = %d,",
|
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
|
||||||
|
"pRef is int32_t !iLastRecoverFrameNum = %d, pRef iFrameNum = %d,LTR number = %d,",
|
||||||
pLtr->iLastRecoverFrameNum, pCtx->pRefList0[0]->iFrameNum, pRefList->uiLongRefCount);
|
pLtr->iLastRecoverFrameNum, pCtx->pRefList0[0]->iFrameNum, pRefList->uiLongRefCount);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -596,7 +600,8 @@ bool WelsBuildRefList (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx
|
|||||||
SPicture* pRef = pRefList->pShortRefList[i];
|
SPicture* pRef = pRefList->pShortRefList[i];
|
||||||
if (pRef != NULL && pRef->bUsedAsRef && pRef->iFramePoc >= 0 && pRef->uiTemporalId <= kuiTid) {
|
if (pRef != NULL && pRef->bUsedAsRef && pRef->iFramePoc >= 0 && pRef->uiTemporalId <= kuiTid) {
|
||||||
pCtx->pRefList0[pCtx->iNumRef0++] = pRef;
|
pCtx->pRefList0[pCtx->iNumRef0++] = pRef;
|
||||||
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsBuildRefList pCtx->uiTemporalId = %d,pRef->iFrameNum = %d,pRef->uiTemporalId = %d\n",
|
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
|
||||||
|
"WelsBuildRefList pCtx->uiTemporalId = %d,pRef->iFrameNum = %d,pRef->uiTemporalId = %d\n",
|
||||||
pCtx->uiTemporalId, pRef->iFrameNum, pRef->uiTemporalId);
|
pCtx->uiTemporalId, pRef->iFrameNum, pRef->uiTemporalId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -641,7 +646,8 @@ void WelsUpdateRefSyntax (sWelsEncCtx* pCtx, const int32_t iPOC, const int32_t u
|
|||||||
if (iAbsDiffPicNumMinus1 < 0) {
|
if (iAbsDiffPicNumMinus1 < 0) {
|
||||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1:%d\n", iAbsDiffPicNumMinus1);
|
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1:%d\n", iAbsDiffPicNumMinus1);
|
||||||
iAbsDiffPicNumMinus1 += (1 << (pCtx->pSps->uiLog2MaxFrameNum));
|
iAbsDiffPicNumMinus1 += (1 << (pCtx->pSps->uiLog2MaxFrameNum));
|
||||||
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1< 0, update as:%d\n", iAbsDiffPicNumMinus1);
|
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "WelsUpdateRefSyntax():::uiAbsDiffPicNumMinus1< 0, update as:%d\n",
|
||||||
|
iAbsDiffPicNumMinus1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pRefReorder->SReorderingSyntax[0].uiReorderingOfPicNumsIdc = 0;
|
pRefReorder->SReorderingSyntax[0].uiReorderingOfPicNumsIdc = 0;
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ void WelsMdInterInit (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb, const i
|
|||||||
ST32 (&pCurMb->sP16x16Mv, 0);
|
ST32 (&pCurMb->sP16x16Mv, 0);
|
||||||
ST32 (&pCurLayer->pDecPic->sMvList[kiMbXY], 0);
|
ST32 (&pCurLayer->pDecPic->sMvList[kiMbXY], 0);
|
||||||
|
|
||||||
SetMvWithinIntegerMvRange (kiMbWidth, kiMbHeight, kiMbX, kiMbY, CAMERA_STARTMV_RANGE, & (pSlice->sMvStartMin),
|
SetMvWithinIntegerMvRange (kiMbWidth, kiMbHeight, kiMbX, kiMbY, pEncCtx->iMvRange, & (pSlice->sMvStartMin),
|
||||||
& (pSlice->sMvStartMax));
|
& (pSlice->sMvStartMax));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1118,7 +1118,7 @@ int32_t WelsMdP8x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWe
|
|||||||
pSlice->uiMvcNum = 1;
|
pSlice->uiMvcNum = 1;
|
||||||
|
|
||||||
PredMv (&pMbCache->sMvComponents, i << 2, 2, pWelsMd->uiRef, & (sMe8x8->sMvp));
|
PredMv (&pMbCache->sMvComponents, i << 2, 2, pWelsMd->uiRef, & (sMe8x8->sMvp));
|
||||||
pFunc->pfMotionSearch[0] (pFunc, pCurDqLayer, sMe8x8, pSlice);
|
pFunc->pfMotionSearch[pWelsMd->iBlock8x8StaticIdc[i]] (pFunc, pCurDqLayer, sMe8x8, pSlice);
|
||||||
UpdateP8x8Motion2Cache (pMbCache, i << 2, pWelsMd->uiRef, & (sMe8x8->sMv));
|
UpdateP8x8Motion2Cache (pMbCache, i << 2, pWelsMd->uiRef, & (sMe8x8->sMv));
|
||||||
iCostP8x8 += sMe8x8->uiSatdCost;
|
iCostP8x8 += sMe8x8->uiSatdCost;
|
||||||
// sMe8x8++;
|
// sMe8x8++;
|
||||||
@@ -1753,73 +1753,6 @@ void WelsMdInterEncode (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb, SMbCa
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////
|
|
||||||
// try the BGD Pskip
|
|
||||||
//////
|
|
||||||
bool WelsMdInterJudgeBGDPskip (void* pCtx, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
|
||||||
bool* bKeepSkip) {
|
|
||||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
|
||||||
SWelsMD* pWelsMd = (SWelsMD*)pMd;
|
|
||||||
|
|
||||||
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
|
||||||
|
|
||||||
const int32_t kiRefMbQp = pCurDqLayer->pRefPic->pRefMbQp[pCurMb->iMbXY];
|
|
||||||
const int32_t kiCurMbQp = pCurMb->uiLumaQp;// unsigned -> signed
|
|
||||||
int8_t* pVaaBgMbFlag = pEncCtx->pVaa->pVaaBackgroundMbFlag + pCurMb->iMbXY;
|
|
||||||
|
|
||||||
const int32_t kiMbWidth = pCurDqLayer->iMbWidth;
|
|
||||||
|
|
||||||
*bKeepSkip = (*bKeepSkip) &&
|
|
||||||
((!pVaaBgMbFlag[-1]) &&
|
|
||||||
(!pVaaBgMbFlag[-kiMbWidth]) &&
|
|
||||||
(!pVaaBgMbFlag[-kiMbWidth + 1]));
|
|
||||||
|
|
||||||
if (
|
|
||||||
*pVaaBgMbFlag
|
|
||||||
&& !IS_INTRA (pMbCache->uiRefMbType)
|
|
||||||
&& (kiRefMbQp - kiCurMbQp <= DELTA_QP_BGD_THD || kiRefMbQp <= 26)
|
|
||||||
) {
|
|
||||||
SMVUnitXY sVaaPredSkipMv = { 0 };
|
|
||||||
PredSkipMv (pMbCache, &sVaaPredSkipMv);
|
|
||||||
WelsMdBackgroundMbEnc (pEncCtx, pWelsMd, pCurMb, pMbCache, pSlice, (LD32 (&sVaaPredSkipMv) == 0));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WelsMdInterJudgeBGDPskipFalse (void* pCtx, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
|
||||||
bool* bKeepSkip) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//////
|
|
||||||
// update BGD related info
|
|
||||||
//////
|
|
||||||
void WelsMdInterUpdateBGDInfo (SDqLayer* pCurLayer, SMB* pCurMb, const bool bCollocatedPredFlag,
|
|
||||||
const int32_t iRefPictureType) {
|
|
||||||
uint8_t* pTargetRefMbQpList = (pCurLayer->pDecPic->pRefMbQp);
|
|
||||||
const int32_t kiMbXY = pCurMb->iMbXY;
|
|
||||||
|
|
||||||
if (pCurMb->uiCbp || I_SLICE == iRefPictureType || 0 == bCollocatedPredFlag) {
|
|
||||||
pTargetRefMbQpList[kiMbXY] = pCurMb->uiLumaQp;
|
|
||||||
} else { //unchange, do not need to evaluation?
|
|
||||||
uint8_t* pRefPicRefMbQpList = (pCurLayer->pRefPic->pRefMbQp);
|
|
||||||
pTargetRefMbQpList[kiMbXY] = pRefPicRefMbQpList[kiMbXY];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pCurMb->uiMbType == MB_TYPE_BACKGROUND) {
|
|
||||||
pCurMb->uiMbType = MB_TYPE_SKIP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WelsMdInterUpdateBGDInfoNULL (SDqLayer* pCurLayer, SMB* pCurMb, const bool bCollocatedPredFlag,
|
|
||||||
const int32_t iRefPictureType) {
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -1843,7 +1776,8 @@ void WelsMdInterSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlic
|
|||||||
if (bSkip) {
|
if (bSkip) {
|
||||||
WelsMdInterDecidedPskip (pEncCtx, pSlice, pCurMb, pMbCache);
|
WelsMdInterDecidedPskip (pEncCtx, pSlice, pCurMb, pMbCache);
|
||||||
} else {
|
} else {
|
||||||
//Step 2: ILFMD in P
|
//Step 3: SubP16 MD
|
||||||
|
pEncCtx->pFuncList->pfSetScrollingMv (pEncCtx->pVaa, pWelsMd); //SCC
|
||||||
pEncCtx->pFuncList->pfInterFineMd (pEncCtx, pWelsMd, pSlice, pCurMb, pWelsMd->iCostLuma);
|
pEncCtx->pFuncList->pfInterFineMd (pEncCtx, pWelsMd, pSlice, pCurMb, pWelsMd->iCostLuma);
|
||||||
|
|
||||||
//refinement for inter type
|
//refinement for inter type
|
||||||
@@ -1875,83 +1809,4 @@ void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB*
|
|||||||
pCurMb->pSadCost[0] = 0;
|
pCurMb->pSadCost[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
//func pointer of inter MD for sub16x16 INTER MD for screen content coding
|
|
||||||
//
|
|
||||||
static inline void MergeSub16Me (const SWelsME& sSrcMe0, const SWelsME& sSrcMe1, SWelsME* pTarMe) {
|
|
||||||
memcpy (pTarMe, &sSrcMe0, sizeof (sSrcMe0)); // confirmed_safe_unsafe_usage
|
|
||||||
|
|
||||||
pTarMe->uiSadCost = sSrcMe0.uiSadCost + sSrcMe1.uiSadCost;//not precise cost since MVD cost is not the same
|
|
||||||
pTarMe->uiSatdCost = sSrcMe0.uiSatdCost + sSrcMe1.uiSatdCost;//not precise cost since MVD cost is not the same
|
|
||||||
}
|
|
||||||
static inline bool IsSameMv (const SMVUnitXY& sMv0, const SMVUnitXY& sMv1) {
|
|
||||||
return ((sMv0.iMvX == sMv1.iMvX) && (sMv0.iMvY == sMv1.iMvY));
|
|
||||||
}
|
|
||||||
bool TryModeMerge (SMbCache* pMbCache, SWelsMD* pWelsMd, SMB* pCurMb) {
|
|
||||||
SWelsME* pMe8x8 = & (pWelsMd->sMe.sMe8x8[0]);
|
|
||||||
const bool bSameMv16x8_0 = IsSameMv (pMe8x8[0].sMv, pMe8x8[1].sMv);
|
|
||||||
const bool bSameMv16x8_1 = IsSameMv (pMe8x8[2].sMv, pMe8x8[3].sMv);
|
|
||||||
|
|
||||||
const bool bSameMv8x16_0 = IsSameMv (pMe8x8[0].sMv, pMe8x8[2].sMv);
|
|
||||||
const bool bSameMv8x16_1 = IsSameMv (pMe8x8[1].sMv, pMe8x8[3].sMv);
|
|
||||||
//need to consider iRefIdx when multi ref is available
|
|
||||||
const bool bSameRefIdx16x8_0 = true; //pMe8x8[0].iRefIdx == pMe8x8[1].iRefIdx;
|
|
||||||
const bool bSameRefIdx16x8_1 = true; //pMe8x8[2].iRefIdx == pMe8x8[3].iRefIdx;
|
|
||||||
const bool bSameRefIdx8x16_0 = true; //pMe8x8[0].iRefIdx == pMe8x8[2].iRefIdx;
|
|
||||||
const bool bSameRefIdx8x16_1 = true; //pMe8x8[1].iRefIdx == pMe8x8[3].iRefIdx;
|
|
||||||
const int32_t iSameMv = (bSameMv16x8_0 << 7) | (bSameRefIdx16x8_0 << 6) | (bSameMv16x8_1 << 5) |
|
|
||||||
(bSameRefIdx16x8_1 << 4) |
|
|
||||||
(bSameMv8x16_0 << 3) | (bSameRefIdx8x16_0 << 2) | (bSameMv8x16_1 << 1) | (bSameRefIdx8x16_1);
|
|
||||||
|
|
||||||
switch (iSameMv) {
|
|
||||||
case 0xF0:
|
|
||||||
pCurMb->uiMbType = MB_TYPE_16x8;
|
|
||||||
MergeSub16Me (pMe8x8[0], pMe8x8[1], & (pWelsMd->sMe.sMe16x8[0]));
|
|
||||||
MergeSub16Me (pMe8x8[2], pMe8x8[3], & (pWelsMd->sMe.sMe16x8[1]));
|
|
||||||
PredInter16x8Mv (pMbCache, 0, 0, & (pWelsMd->sMe.sMe16x8[0].sMvp));
|
|
||||||
PredInter16x8Mv (pMbCache, 8, 0, & (pWelsMd->sMe.sMe16x8[1].sMvp));
|
|
||||||
break;
|
|
||||||
case 0x0F:
|
|
||||||
pCurMb->uiMbType = MB_TYPE_8x16;
|
|
||||||
MergeSub16Me (pMe8x8[0], pMe8x8[2], & (pWelsMd->sMe.sMe8x16[0]));
|
|
||||||
MergeSub16Me (pMe8x8[1], pMe8x8[3], & (pWelsMd->sMe.sMe8x16[1]));
|
|
||||||
PredInter8x16Mv (pMbCache, 0, 0, & (pWelsMd->sMe.sMe8x16[0].sMvp));
|
|
||||||
PredInter8x16Mv (pMbCache, 4, 0, & (pWelsMd->sMe.sMe8x16[1].sMvp));
|
|
||||||
break;
|
|
||||||
case 0xFF:
|
|
||||||
//MERGE_16x16
|
|
||||||
//from test results of multiple sequences show that using the following 0x0F to merge 16x16
|
|
||||||
//for some seq there is BR saving some loss
|
|
||||||
//on the whole the BR will increase little bit
|
|
||||||
//to save complexity we decided not to merge 16x16 at present (10/12/2012)
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return (MB_TYPE_8x8 != pCurMb->uiMbType);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WelsMdInterFinePartitionVaaOnScreen (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t iBestCost) {
|
|
||||||
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pEnc;
|
|
||||||
SWelsMD* pWelsMd = (SWelsMD*)pMd;
|
|
||||||
SMbCache* pMbCache = &pSlice->sMbCacheInfo;
|
|
||||||
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
|
||||||
int32_t iCostP8x8;
|
|
||||||
uint8_t uiMbSign = pEncCtx->pFuncList->pfGetMbSignFromInterVaa (&pEncCtx->pVaa->sVaaCalcInfo.pSad8x8[pCurMb->iMbXY][0]);
|
|
||||||
|
|
||||||
if (MBVAASIGN_FLAT == uiMbSign) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
iCostP8x8 = WelsMdP8x8 (pEncCtx->pFuncList, pCurDqLayer, pWelsMd, pSlice);
|
|
||||||
if (iCostP8x8 < iBestCost) {
|
|
||||||
iBestCost = iCostP8x8;
|
|
||||||
pCurMb->uiMbType = MB_TYPE_8x8;
|
|
||||||
|
|
||||||
TryModeMerge (pMbCache, pWelsMd, pCurMb);
|
|
||||||
}
|
|
||||||
pWelsMd->iCostLuma = iBestCost;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace WelsSVCEnc
|
} // namespace WelsSVCEnc
|
||||||
|
|||||||
@@ -921,10 +921,10 @@ bool DynSlcJudgeSliceBoundaryStepBack (void* pCtx, void* pSlice, SSliceCtx* pSli
|
|||||||
///////////////
|
///////////////
|
||||||
// pMb loop
|
// pMb loop
|
||||||
///////////////
|
///////////////
|
||||||
inline void WelsInitInterMDStruc (const SMB* pCurMb, uint16_t* pMvdCostTableInter, const int32_t kiMvdInterTableStride,
|
inline void WelsInitInterMDStruc (const SMB* pCurMb, uint16_t* pMvdCostTable, const int32_t kiMvdInterTableStride,
|
||||||
SWelsMD* pMd) {
|
SWelsMD* pMd) {
|
||||||
pMd->iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];
|
pMd->iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];
|
||||||
pMd->pMvdCost = &pMvdCostTableInter[pCurMb->uiLumaQp * kiMvdInterTableStride];
|
pMd->pMvdCost = &pMvdCostTable[pCurMb->uiLumaQp * kiMvdInterTableStride];
|
||||||
pMd-> iMbPixX = (pCurMb->iMbX << 4);
|
pMd-> iMbPixX = (pCurMb->iMbX << 4);
|
||||||
pMd-> iMbPixY = (pCurMb->iMbY << 4);
|
pMd-> iMbPixY = (pCurMb->iMbY << 4);
|
||||||
memset (&pMd->iBlock8x8StaticIdc[0], 0, sizeof (pMd->iBlock8x8StaticIdc));
|
memset (&pMd->iBlock8x8StaticIdc[0], 0, sizeof (pMd->iBlock8x8StaticIdc));
|
||||||
@@ -943,9 +943,8 @@ int32_t WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd,
|
|||||||
int32_t iCurMbIdx = -1;
|
int32_t iCurMbIdx = -1;
|
||||||
int32_t iMbSkipRun = 0;
|
int32_t iMbSkipRun = 0;
|
||||||
const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;
|
const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;
|
||||||
const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iSpatialLayerNum == 1 ? 648 : 972);
|
const int32_t kiMvdInterTableStride = pEncCtx->iMvdCostTableStride;
|
||||||
const int32_t kiMvdInterTableStride = 1 + (kiMvdInterTableSize << 1);
|
uint16_t* pMvdCostTable = &pEncCtx->pMvdCostTable[pEncCtx->iMvdCostTableSize];
|
||||||
uint16_t* pMvdCostTableInter = &pEncCtx->pMvdCostTableInter[kiMvdInterTableSize];
|
|
||||||
const int32_t kiSliceIdx = pSlice->uiSliceIdx;
|
const int32_t kiSliceIdx = pSlice->uiSliceIdx;
|
||||||
const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
|
const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
|
||||||
int32_t iEncReturn = ENC_RETURN_SUCCESS;
|
int32_t iEncReturn = ENC_RETURN_SUCCESS;
|
||||||
@@ -965,7 +964,7 @@ int32_t WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd,
|
|||||||
WelsMdInterInit (pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);
|
WelsMdInterInit (pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);
|
||||||
|
|
||||||
TRY_REENCODING:
|
TRY_REENCODING:
|
||||||
WelsInitInterMDStruc (pCurMb, pMvdCostTableInter, kiMvdInterTableStride, pMd);
|
WelsInitInterMDStruc (pCurMb, pMvdCostTable, kiMvdInterTableStride, pMd);
|
||||||
pEncCtx->pFuncList->pfInterMd (pEncCtx, pMd, pSlice, pCurMb, pMbCache);
|
pEncCtx->pFuncList->pfInterMd (pEncCtx, pMd, pSlice, pCurMb, pMbCache);
|
||||||
//mb_qp
|
//mb_qp
|
||||||
|
|
||||||
@@ -1041,7 +1040,7 @@ int32_t WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice,
|
|||||||
int32_t iMbSkipRun = 0;
|
int32_t iMbSkipRun = 0;
|
||||||
const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iSpatialLayerNum == 1 ? 648 : 972);
|
const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iSpatialLayerNum == 1 ? 648 : 972);
|
||||||
const int32_t kiMvdInterTableStride = 1 + (kiMvdInterTableSize << 1);
|
const int32_t kiMvdInterTableStride = 1 + (kiMvdInterTableSize << 1);
|
||||||
uint16_t* pMvdCostTableInter = &pEncCtx->pMvdCostTableInter[kiMvdInterTableSize];
|
uint16_t* pMvdCostTable = &pEncCtx->pMvdCostTable[kiMvdInterTableSize];
|
||||||
const int32_t kiSliceIdx = pSlice->uiSliceIdx;
|
const int32_t kiSliceIdx = pSlice->uiSliceIdx;
|
||||||
const int32_t kiPartitionId = (kiSliceIdx % pEncCtx->iActiveThreadsNum);
|
const int32_t kiPartitionId = (kiSliceIdx % pEncCtx->iActiveThreadsNum);
|
||||||
const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
|
const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
|
||||||
@@ -1074,7 +1073,7 @@ int32_t WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice,
|
|||||||
WelsMdInterInit (pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);
|
WelsMdInterInit (pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);
|
||||||
|
|
||||||
TRY_REENCODING:
|
TRY_REENCODING:
|
||||||
WelsInitInterMDStruc (pCurMb, pMvdCostTableInter, kiMvdInterTableStride, pMd);
|
WelsInitInterMDStruc (pCurMb, pMvdCostTable, kiMvdInterTableStride, pMd);
|
||||||
pEncCtx->pFuncList->pfInterMd (pEncCtx, pMd, pSlice, pCurMb, pMbCache);
|
pEncCtx->pFuncList->pfInterMd (pEncCtx, pMd, pSlice, pCurMb, pMbCache);
|
||||||
//mb_qp
|
//mb_qp
|
||||||
|
|
||||||
|
|||||||
@@ -47,39 +47,9 @@
|
|||||||
|
|
||||||
namespace WelsSVCEnc {
|
namespace WelsSVCEnc {
|
||||||
|
|
||||||
//
|
//////////////
|
||||||
// md in enhancement layer
|
// MD for enhancement layers
|
||||||
///
|
//////////////
|
||||||
|
|
||||||
inline bool IsMbStatic (int32_t* pBlockType, EStaticBlockIdc eType) {
|
|
||||||
return (pBlockType != NULL &&
|
|
||||||
eType == pBlockType[0] &&
|
|
||||||
eType == pBlockType[1] &&
|
|
||||||
eType == pBlockType[2] &&
|
|
||||||
eType == pBlockType[3]);
|
|
||||||
}
|
|
||||||
inline bool IsMbCollocatedStatic (int32_t* pBlockType) {
|
|
||||||
return IsMbStatic (pBlockType, COLLOCATED_STATIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsMbScrolledStatic (int32_t* pBlockType) {
|
|
||||||
return IsMbStatic (pBlockType, SCROLLED_STATIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int32_t CalUVSadCost (SWelsFuncPtrList* pFunc, uint8_t* pEncOri, int32_t iStrideUV, uint8_t* pRefOri,
|
|
||||||
int32_t iRefLineSize) {
|
|
||||||
return pFunc->sSampleDealingFuncs.pfSampleSad[BLOCK_8x8] (pEncOri, iStrideUV, pRefOri, iRefLineSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool CheckBorder (int32_t iMbX, int32_t iMbY, int32_t iScrollMvX, int32_t iScrollMvY, int32_t iMbWidth,
|
|
||||||
int32_t iMbHeight) {
|
|
||||||
return ((iMbX << 4) + iScrollMvX < 0 ||
|
|
||||||
(iMbX << 4) + iScrollMvX > (iMbWidth - 1) << 4 ||
|
|
||||||
(iMbY << 4) + iScrollMvY < 0 ||
|
|
||||||
(iMbY << 4) + iScrollMvY > (iMbHeight - 1) << 4
|
|
||||||
); //border check for safety
|
|
||||||
}
|
|
||||||
|
|
||||||
void WelsMdSpatialelInterMbIlfmdNoilp (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* pSlice,
|
void WelsMdSpatialelInterMbIlfmdNoilp (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* pSlice,
|
||||||
SMB* pCurMb, const Mb_Type kuiRefMbType) {
|
SMB* pCurMb, const Mb_Type kuiRefMbType) {
|
||||||
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
||||||
@@ -149,10 +119,8 @@ void WelsMdInterMbEnhancelayer (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCur
|
|||||||
WelsMdSpatialelInterMbIlfmdNoilp (pEncCtx, pWelsMd, pSlice, pCurMb, kuiInterLayerRefMbType); //MD process
|
WelsMdSpatialelInterMbIlfmdNoilp (pEncCtx, pWelsMd, pSlice, pCurMb, kuiInterLayerRefMbType); //MD process
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////
|
|
||||||
// do initiation for noILP (needed by ILFMD)
|
|
||||||
////////////////////////
|
|
||||||
|
|
||||||
|
// do initiation for noILP (needed by ILFMD)
|
||||||
SMB* GetRefMb (SDqLayer* pCurLayer, SMB* pCurMb) {
|
SMB* GetRefMb (SDqLayer* pCurLayer, SMB* pCurMb) {
|
||||||
const SDqLayer* kpRefLayer = pCurLayer->pRefLayer;
|
const SDqLayer* kpRefLayer = pCurLayer->pRefLayer;
|
||||||
const int32_t kiRefMbIdx = (pCurMb->iMbY >> 1) * kpRefLayer->iMbWidth + (pCurMb->iMbX >>
|
const int32_t kiRefMbIdx = (pCurMb->iMbY >> 1) * kpRefLayer->iMbWidth + (pCurMb->iMbX >>
|
||||||
@@ -184,6 +152,111 @@ void SetMvBaseEnhancelayer (SWelsMD* pMd, SMB* pCurMb, const SMB* kpRefMb) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// MD for Background decision
|
||||||
|
//////////////
|
||||||
|
//////
|
||||||
|
// try the BGD Pskip
|
||||||
|
//////
|
||||||
|
bool WelsMdInterJudgeBGDPskip (void* pCtx, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||||
|
bool* bKeepSkip) {
|
||||||
|
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
|
||||||
|
SWelsMD* pWelsMd = (SWelsMD*)pMd;
|
||||||
|
|
||||||
|
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
||||||
|
|
||||||
|
const int32_t kiRefMbQp = pCurDqLayer->pRefPic->pRefMbQp[pCurMb->iMbXY];
|
||||||
|
const int32_t kiCurMbQp = pCurMb->uiLumaQp;// unsigned -> signed
|
||||||
|
int8_t* pVaaBgMbFlag = pEncCtx->pVaa->pVaaBackgroundMbFlag + pCurMb->iMbXY;
|
||||||
|
|
||||||
|
const int32_t kiMbWidth = pCurDqLayer->iMbWidth;
|
||||||
|
|
||||||
|
*bKeepSkip = (*bKeepSkip) &&
|
||||||
|
((!pVaaBgMbFlag[-1]) &&
|
||||||
|
(!pVaaBgMbFlag[-kiMbWidth]) &&
|
||||||
|
(!pVaaBgMbFlag[-kiMbWidth + 1]));
|
||||||
|
|
||||||
|
if (
|
||||||
|
*pVaaBgMbFlag
|
||||||
|
&& !IS_INTRA (pMbCache->uiRefMbType)
|
||||||
|
&& (kiRefMbQp - kiCurMbQp <= DELTA_QP_BGD_THD || kiRefMbQp <= 26)
|
||||||
|
) {
|
||||||
|
SMVUnitXY sVaaPredSkipMv = { 0 };
|
||||||
|
PredSkipMv (pMbCache, &sVaaPredSkipMv);
|
||||||
|
WelsMdBackgroundMbEnc (pEncCtx, pWelsMd, pCurMb, pMbCache, pSlice, (LD32 (&sVaaPredSkipMv) == 0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WelsMdInterJudgeBGDPskipFalse (void* pCtx, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache,
|
||||||
|
bool* bKeepSkip) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////
|
||||||
|
// update BGD related info
|
||||||
|
//////
|
||||||
|
void WelsMdInterUpdateBGDInfo (SDqLayer* pCurLayer, SMB* pCurMb, const bool bCollocatedPredFlag,
|
||||||
|
const int32_t iRefPictureType) {
|
||||||
|
uint8_t* pTargetRefMbQpList = (pCurLayer->pDecPic->pRefMbQp);
|
||||||
|
const int32_t kiMbXY = pCurMb->iMbXY;
|
||||||
|
|
||||||
|
if (pCurMb->uiCbp || I_SLICE == iRefPictureType || 0 == bCollocatedPredFlag) {
|
||||||
|
pTargetRefMbQpList[kiMbXY] = pCurMb->uiLumaQp;
|
||||||
|
} else { //unchange, do not need to evaluation?
|
||||||
|
uint8_t* pRefPicRefMbQpList = (pCurLayer->pRefPic->pRefMbQp);
|
||||||
|
pTargetRefMbQpList[kiMbXY] = pRefPicRefMbQpList[kiMbXY];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCurMb->uiMbType == MB_TYPE_BACKGROUND) {
|
||||||
|
pCurMb->uiMbType = MB_TYPE_SKIP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WelsMdInterUpdateBGDInfoNULL (SDqLayer* pCurLayer, SMB* pCurMb, const bool bCollocatedPredFlag,
|
||||||
|
const int32_t iRefPictureType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// MD for screen contents
|
||||||
|
//////////////
|
||||||
|
inline bool IsMbStatic (int32_t* pBlockType, EStaticBlockIdc eType) {
|
||||||
|
return (pBlockType != NULL &&
|
||||||
|
eType == pBlockType[0] &&
|
||||||
|
eType == pBlockType[1] &&
|
||||||
|
eType == pBlockType[2] &&
|
||||||
|
eType == pBlockType[3]);
|
||||||
|
}
|
||||||
|
inline bool IsMbCollocatedStatic (int32_t* pBlockType) {
|
||||||
|
return IsMbStatic (pBlockType, COLLOCATED_STATIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsMbScrolledStatic (int32_t* pBlockType) {
|
||||||
|
return IsMbStatic (pBlockType, SCROLLED_STATIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t CalUVSadCost (SWelsFuncPtrList* pFunc, uint8_t* pEncOri, int32_t iStrideUV, uint8_t* pRefOri,
|
||||||
|
int32_t iRefLineSize) {
|
||||||
|
return pFunc->sSampleDealingFuncs.pfSampleSad[BLOCK_8x8] (pEncOri, iStrideUV, pRefOri, iRefLineSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool CheckBorder (int32_t iMbX, int32_t iMbY, int32_t iScrollMvX, int32_t iScrollMvY, int32_t iMbWidth,
|
||||||
|
int32_t iMbHeight) {
|
||||||
|
return ((iMbX << 4) + iScrollMvX < 0 ||
|
||||||
|
(iMbX << 4) + iScrollMvX > (iMbWidth - 1) << 4 ||
|
||||||
|
(iMbY << 4) + iScrollMvY < 0 ||
|
||||||
|
(iMbY << 4) + iScrollMvY > (iMbHeight - 1) << 4
|
||||||
|
); //border check for safety
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool JudgeStaticSkip (sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache* pMbCache, SWelsMD* pWelsMd) {
|
bool JudgeStaticSkip (sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache* pMbCache, SWelsMD* pWelsMd) {
|
||||||
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
||||||
const int32_t kiMbX = pCurMb->iMbX;
|
const int32_t kiMbX = pCurMb->iMbX;
|
||||||
@@ -414,5 +487,112 @@ void WelsInitSCDPskipFunc (SWelsFuncPtrList* pFuncList, const bool bScrollingDet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// SubP16x16 Mode Decision for screen content
|
||||||
|
////////////////////////
|
||||||
|
//
|
||||||
|
//func pointer of inter MD for sub16x16 INTER MD for screen content coding
|
||||||
|
//
|
||||||
|
static inline void MergeSub16Me (const SWelsME& sSrcMe0, const SWelsME& sSrcMe1, SWelsME* pTarMe) {
|
||||||
|
memcpy (pTarMe, &sSrcMe0, sizeof (sSrcMe0)); // confirmed_safe_unsafe_usage
|
||||||
|
|
||||||
|
pTarMe->uiSadCost = sSrcMe0.uiSadCost + sSrcMe1.uiSadCost;//not precise cost since MVD cost is not the same
|
||||||
|
pTarMe->uiSatdCost = sSrcMe0.uiSatdCost + sSrcMe1.uiSatdCost;//not precise cost since MVD cost is not the same
|
||||||
|
}
|
||||||
|
static inline bool IsSameMv (const SMVUnitXY& sMv0, const SMVUnitXY& sMv1) {
|
||||||
|
return ((sMv0.iMvX == sMv1.iMvX) && (sMv0.iMvY == sMv1.iMvY));
|
||||||
|
}
|
||||||
|
bool TryModeMerge (SMbCache* pMbCache, SWelsMD* pWelsMd, SMB* pCurMb) {
|
||||||
|
SWelsME* pMe8x8 = & (pWelsMd->sMe.sMe8x8[0]);
|
||||||
|
const bool bSameMv16x8_0 = IsSameMv (pMe8x8[0].sMv, pMe8x8[1].sMv);
|
||||||
|
const bool bSameMv16x8_1 = IsSameMv (pMe8x8[2].sMv, pMe8x8[3].sMv);
|
||||||
|
|
||||||
|
const bool bSameMv8x16_0 = IsSameMv (pMe8x8[0].sMv, pMe8x8[2].sMv);
|
||||||
|
const bool bSameMv8x16_1 = IsSameMv (pMe8x8[1].sMv, pMe8x8[3].sMv);
|
||||||
|
//need to consider iRefIdx when multi ref is available
|
||||||
|
const bool bSameRefIdx16x8_0 = true; //pMe8x8[0].iRefIdx == pMe8x8[1].iRefIdx;
|
||||||
|
const bool bSameRefIdx16x8_1 = true; //pMe8x8[2].iRefIdx == pMe8x8[3].iRefIdx;
|
||||||
|
const bool bSameRefIdx8x16_0 = true; //pMe8x8[0].iRefIdx == pMe8x8[2].iRefIdx;
|
||||||
|
const bool bSameRefIdx8x16_1 = true; //pMe8x8[1].iRefIdx == pMe8x8[3].iRefIdx;
|
||||||
|
const int32_t iSameMv = ((bSameMv16x8_0 && bSameRefIdx16x8_0 && bSameMv16x8_1 && bSameRefIdx16x8_1) << 1) |
|
||||||
|
(bSameMv8x16_0 && bSameRefIdx8x16_0 && bSameMv8x16_1 && bSameRefIdx8x16_1);
|
||||||
|
|
||||||
|
//TODO: did not consider the MVD cost here, may consider later
|
||||||
|
switch (iSameMv) {
|
||||||
|
case 3:
|
||||||
|
//MERGE_16x16
|
||||||
|
//from test results of multiple sequences show that using the following 0x0F to merge 16x16
|
||||||
|
//for some seq there is BR saving some loss
|
||||||
|
//on the whole the BR will increase little bit
|
||||||
|
//to save complexity we decided not to merge 16x16 at present (10/12/2012)
|
||||||
|
//TODO: agjusted order, consider re-test later
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pCurMb->uiMbType = MB_TYPE_16x8;
|
||||||
|
MergeSub16Me (pMe8x8[0], pMe8x8[1], & (pWelsMd->sMe.sMe16x8[0]));
|
||||||
|
MergeSub16Me (pMe8x8[2], pMe8x8[3], & (pWelsMd->sMe.sMe16x8[1]));
|
||||||
|
PredInter16x8Mv (pMbCache, 0, 0, & (pWelsMd->sMe.sMe16x8[0].sMvp));
|
||||||
|
PredInter16x8Mv (pMbCache, 8, 0, & (pWelsMd->sMe.sMe16x8[1].sMvp));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
pCurMb->uiMbType = MB_TYPE_8x16;
|
||||||
|
MergeSub16Me (pMe8x8[0], pMe8x8[2], & (pWelsMd->sMe.sMe8x16[0]));
|
||||||
|
MergeSub16Me (pMe8x8[1], pMe8x8[3], & (pWelsMd->sMe.sMe8x16[1]));
|
||||||
|
PredInter8x16Mv (pMbCache, 0, 0, & (pWelsMd->sMe.sMe8x16[0].sMvp));
|
||||||
|
PredInter8x16Mv (pMbCache, 4, 0, & (pWelsMd->sMe.sMe8x16[1].sMvp));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (MB_TYPE_8x8 != pCurMb->uiMbType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WelsMdInterFinePartitionVaaOnScreen (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, int32_t iBestCost) {
|
||||||
|
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pEnc;
|
||||||
|
SWelsMD* pWelsMd = (SWelsMD*)pMd;
|
||||||
|
SMbCache* pMbCache = &pSlice->sMbCacheInfo;
|
||||||
|
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
|
||||||
|
int32_t iCostP8x8;
|
||||||
|
uint8_t uiMbSign = pEncCtx->pFuncList->pfGetMbSignFromInterVaa (&pEncCtx->pVaa->sVaaCalcInfo.pSad8x8[pCurMb->iMbXY][0]);
|
||||||
|
|
||||||
|
if (MBVAASIGN_FLAT == uiMbSign) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iCostP8x8 = WelsMdP8x8 (pEncCtx->pFuncList, pCurDqLayer, pWelsMd, pSlice);
|
||||||
|
if (iCostP8x8 < iBestCost) {
|
||||||
|
iBestCost = iCostP8x8;
|
||||||
|
pCurMb->uiMbType = MB_TYPE_8x8;
|
||||||
|
|
||||||
|
TryModeMerge (pMbCache, pWelsMd, pCurMb);
|
||||||
|
}
|
||||||
|
pWelsMd->iCostLuma = iBestCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// SetScrollingMvToMd
|
||||||
|
//
|
||||||
|
void SetScrollingMvToMd (void* pVaa, void* pMd) {
|
||||||
|
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (pVaa);
|
||||||
|
SWelsMD* pWelsMd = static_cast<SWelsMD*> (pMd);
|
||||||
|
|
||||||
|
SMVUnitXY sTempMv;
|
||||||
|
sTempMv.iMvX = pVaaExt->sScrollDetectInfo.iScrollMvX;
|
||||||
|
sTempMv.iMvY = pVaaExt->sScrollDetectInfo.iScrollMvY;
|
||||||
|
|
||||||
|
(pWelsMd->sMe.sMe16x16).sDirectionalMv =
|
||||||
|
(pWelsMd->sMe.sMe8x8[0]).sDirectionalMv =
|
||||||
|
(pWelsMd->sMe.sMe8x8[1]).sDirectionalMv =
|
||||||
|
(pWelsMd->sMe.sMe8x8[2]).sDirectionalMv =
|
||||||
|
(pWelsMd->sMe.sMe8x8[3]).sDirectionalMv = sTempMv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetScrollingMvToMdNull (void* pVaa, void* pWelsMd) {
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace WelsSVCEnc
|
} // namespace WelsSVCEnc
|
||||||
|
|||||||
@@ -71,19 +71,22 @@ static inline void MeEndIntepelSearch (SWelsME* pMe) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WelsInitMeFunc (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag, bool bScreenContent) {
|
void WelsInitMeFunc (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag, bool bScreenContent) {
|
||||||
|
pFuncList->pfUpdateFMESwitch = UpdateFMESwitchNull;
|
||||||
|
|
||||||
if (!bScreenContent) {
|
if (!bScreenContent) {
|
||||||
pFuncList->pfCheckDirectionalMv = CheckDirectionalMvFalse;
|
pFuncList->pfCheckDirectionalMv = CheckDirectionalMvFalse;
|
||||||
pFuncList->pfCalculateBlockFeatureOfFrame[0] =
|
pFuncList->pfCalculateBlockFeatureOfFrame[0] =
|
||||||
pFuncList->pfCalculateBlockFeatureOfFrame[1] = NULL;
|
pFuncList->pfCalculateBlockFeatureOfFrame[1] = NULL;
|
||||||
pFuncList->pfCalculateSingleBlockFeature[0] =
|
pFuncList->pfCalculateSingleBlockFeature[0] =
|
||||||
pFuncList->pfCalculateSingleBlockFeature[1] = NULL;
|
pFuncList->pfCalculateSingleBlockFeature[1] = NULL;
|
||||||
pFuncList->pfUpdateFMESwitch = UpdateFMESwitchNull;
|
|
||||||
} else {
|
} else {
|
||||||
pFuncList->pfCheckDirectionalMv = CheckDirectionalMv;
|
pFuncList->pfCheckDirectionalMv = CheckDirectionalMv;
|
||||||
|
|
||||||
//for cross serarch
|
//for cross serarch
|
||||||
pFuncList->pfVerticalFullSearch = LineFullSearch_c;
|
pFuncList->pfVerticalFullSearch = LineFullSearch_c;
|
||||||
pFuncList->pfHorizontalFullSearch = LineFullSearch_c;
|
pFuncList->pfHorizontalFullSearch = LineFullSearch_c;
|
||||||
|
|
||||||
#if defined (X86_ASM)
|
#if defined (X86_ASM)
|
||||||
if (uiCpuFlag & WELS_CPU_SSE41) {
|
if (uiCpuFlag & WELS_CPU_SSE41) {
|
||||||
pFuncList->pfSampleSadHor8[0] = SampleSad8x8Hor8_sse41;
|
pFuncList->pfSampleSadHor8[0] = SampleSad8x8Hor8_sse41;
|
||||||
@@ -99,7 +102,6 @@ void WelsInitMeFunc (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag, bool bScre
|
|||||||
//TODO: it is possible to differentiate width that is times of 8, so as to accelerate the speed when width is times of 8?
|
//TODO: it is possible to differentiate width that is times of 8, so as to accelerate the speed when width is times of 8?
|
||||||
pFuncList->pfCalculateSingleBlockFeature[0] = SumOf8x8SingleBlock_c;
|
pFuncList->pfCalculateSingleBlockFeature[0] = SumOf8x8SingleBlock_c;
|
||||||
pFuncList->pfCalculateSingleBlockFeature[1] = SumOf16x16SingleBlock_c;
|
pFuncList->pfCalculateSingleBlockFeature[1] = SumOf16x16SingleBlock_c;
|
||||||
pFuncList->pfUpdateFMESwitch = UpdateFMESwitchNull;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +131,38 @@ void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void
|
|||||||
kiStrideRef);
|
kiStrideRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WelsMotionEstimateSearchStatic (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* 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];
|
||||||
|
|
||||||
|
pMe->sMv.iMvX = pMe->sMv.iMvY = 0;
|
||||||
|
pMe->uiSadCost =
|
||||||
|
pFuncList->sSampleDealingFuncs.pfSampleSad[pMe->uiBlockSize] (pMe->pEncMb, kiStrideEnc, pMe->pRefMb, kiStrideRef) ;
|
||||||
|
pMe->uiSadCost += COST_MVD (pMe->pMvdCost, - pMe->sMvp.iMvX, - pMe->sMvp.iMvY);
|
||||||
|
MeEndIntepelSearch (pMe);
|
||||||
|
pFuncList->pfCalculateSatd (pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiBlockSize], pMe, kiStrideEnc,
|
||||||
|
kiStrideRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WelsMotionEstimateSearchScrolled (SWelsFuncPtrList* pFuncList, void* pLplayer, void* pLpme, void* 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];
|
||||||
|
|
||||||
|
pMe->sMv = pMe->sDirectionalMv;
|
||||||
|
pMe->pRefMb = pMe->pColoRefMb + pMe->sMv.iMvY * kiStrideRef + pMe->sMv.iMvX;
|
||||||
|
pMe->uiSadCost =
|
||||||
|
pFuncList->sSampleDealingFuncs.pfSampleSad[pMe->uiBlockSize] (pMe->pEncMb, kiStrideEnc, pMe->pRefMb, kiStrideRef)
|
||||||
|
+ COST_MVD (pMe->pMvdCost, (pMe->sMv.iMvX << 2) - pMe->sMvp.iMvX, (pMe->sMv.iMvY << 2) - pMe->sMvp.iMvY);
|
||||||
|
MeEndIntepelSearch (pMe);
|
||||||
|
pFuncList->pfCalculateSatd (pFuncList->sSampleDealingFuncs.pfSampleSatd[pMe->uiBlockSize], pMe, kiStrideEnc,
|
||||||
|
kiStrideRef);
|
||||||
|
}
|
||||||
/*!
|
/*!
|
||||||
* \brief EL mb motion estimate initial point testing
|
* \brief EL mb motion estimate initial point testing
|
||||||
*
|
*
|
||||||
@@ -456,7 +490,7 @@ void HorizontalFullSearchUsingSSE41 (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
|
|||||||
SMVUnitXY sBestMv;
|
SMVUnitXY sBestMv;
|
||||||
sBestMv.iMvX = iBestPos - kiCurMeBlockPix;
|
sBestMv.iMvX = iBestPos - kiCurMeBlockPix;
|
||||||
sBestMv.iMvY = 0;
|
sBestMv.iMvY = 0;
|
||||||
UpdateMeResults (sBestMv, uiBestCost, &pMe->pColoRefMb[sBestMv.iMvY], pMe);
|
UpdateMeResults (sBestMv, uiBestCost, &pMe->pColoRefMb[sBestMv.iMvX], pMe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -488,7 +522,7 @@ void LineFullSearch_c (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
|
|||||||
SMVUnitXY sBestMv;
|
SMVUnitXY sBestMv;
|
||||||
sBestMv.iMvX = bVerticalSearch ? 0 : (iBestPos - kiCurMeBlockPix);
|
sBestMv.iMvX = bVerticalSearch ? 0 : (iBestPos - kiCurMeBlockPix);
|
||||||
sBestMv.iMvY = bVerticalSearch ? (iBestPos - kiCurMeBlockPix) : 0;
|
sBestMv.iMvY = bVerticalSearch ? (iBestPos - kiCurMeBlockPix) : 0;
|
||||||
UpdateMeResults (sBestMv, uiBestCost, &pMe->pColoRefMb[sBestMv.iMvY * kiStride], pMe);
|
UpdateMeResults (sBestMv, uiBestCost, &pMe->pColoRefMb[sBestMv.iMvY * kiRefStride + sBestMv.iMvX], pMe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user