completing and bug-fixing the screen content MD/ME process

This commit is contained in:
Sijia Chen 2014-07-02 10:33:47 +08:00
parent 2eb65d7d72
commit a964ae8cfa
17 changed files with 404 additions and 289 deletions

View File

@ -43,11 +43,11 @@ namespace WelsSVCEnc {
* auxiliary struct for bit-stream reading / writing
*/
typedef struct TagBitStringAux {
uint8_t* pBuf; // pBuffer to start position
uint8_t* pBufEnd; // pBuffer + length
uint8_t* pBufPtr; // current writing position
uint32_t uiCurBits;
int32_t iLeftBits; // count number of available bits left ([1, 8]),
uint8_t* pBuf; // pBuffer to start position
uint8_t* pBufEnd; // pBuffer + length
uint8_t* pBufPtr; // current writing position
uint32_t uiCurBits;
int32_t iLeftBits; // count number of available bits left ([1, 8]),
// need pointer to next byte start position in case 0 bit left then 8 instead
} SBitStringAux;
@ -61,15 +61,15 @@ int32_t iLeftBits; // count number of available bits left ([1, 8]),
* \return iSize of pBuffer pData in byte; failed in -1 return
*/
static inline int32_t InitBits (SBitStringAux* pBs, const uint8_t* kpBuf, const int32_t kiSize) {
uint8_t* ptr = (uint8_t*)kpBuf;
uint8_t* ptr = (uint8_t*)kpBuf;
pBs->pBuf = ptr;
pBs->pBufPtr = ptr;
pBs->pBufEnd = ptr + kiSize;
pBs->iLeftBits = 32;
pBs->uiCurBits = 0;
pBs->pBuf = ptr;
pBs->pBufPtr = ptr;
pBs->pBufEnd = ptr + kiSize;
pBs->iLeftBits = 32;
pBs->uiCurBits = 0;
return kiSize;
return kiSize;
}
}

View File

@ -50,15 +50,15 @@ namespace WelsSVCEnc {
//struct tagDeblockingFunc;
typedef struct TagDeblockingFilter {
uint8_t* pCsData[3]; // pointer to reconstructed picture pData
int32_t iCsStride[3]; // Cs iStride
int16_t iMbStride;
int8_t iSliceAlphaC0Offset;
int8_t iSliceBetaOffset;
uint8_t uiLumaQP;
uint8_t uiChromaQP;
uint8_t uiFilterIdc;
uint8_t uiReserved;
uint8_t* pCsData[3]; // pointer to reconstructed picture pData
int32_t iCsStride[3]; // Cs iStride
int16_t iMbStride;
int8_t iSliceAlphaC0Offset;
int8_t iSliceBetaOffset;
uint8_t uiLumaQP;
uint8_t uiChromaQP;
uint8_t uiFilterIdc;
uint8_t uiReserved;
} SDeblockingFilter;
#if defined(__cplusplus)

View File

@ -119,7 +119,9 @@ SWelsSliceBs* pSliceBs; // bitstream buffering for various slices, [uiSliceI
int32_t* pSadCostMb;
/* MVD cost tables for Inter MB */
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*
pMvUnitBlock4x4; // (*pMvUnitBlock4x4[2])[MB_BLOCK4x4_NUM]; // for store each 4x4 blocks' mv unit, the two swap after different d layer
int8_t*

View File

@ -76,15 +76,7 @@ void WelsMdInterMb (void* pEncCtx, void* pWelsMd, SSlice* pSlice, SMB* pCurMb, S
//both used in BL and EL
//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 bTrySkip);
@ -102,9 +94,6 @@ void WelsMdInterSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlic
void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB* pCurMb, SMbCache* pMbCache);
//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__

View File

@ -64,11 +64,31 @@ void WelsMdSpatialelInterMbIlfmdNoilp (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, S
void WelsMdInterMbEnhancelayer (void* pEnc, void* pMd, SSlice* pSlice, SMB* pCurMb, SMbCache* pMbCache);
SMB* GetRefMb (SDqLayer* pCurLayer, SMB* pCurMb);
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,
ESkipModes eSkipMode);
typedef bool (*pJudgeSkipFun) (sWelsEncCtx* pEncCtx, SMB* pCurMb, SMbCache* pMbCache, SWelsMD* pWelsMd);
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

View File

@ -145,8 +145,8 @@ void WelsInitMeFunc (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag, bool bScre
* \return NONE
*/
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
*

View File

@ -132,6 +132,7 @@ typedef void (*PInterMdBackgroundInfoUpdateFunc) (SDqLayer* pCurLayer, SMB* pCu
typedef bool (*PInterMdScrollingPSkipDecisionFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb,
SMbCache* pMbCache);
typedef void (*PSetScrollingMv) (void* pVaa, void* pMd);
typedef void (*PInterMdFunc) (void* pEncCtx, void* pWelsMd, SSlice* slice, SMB* pCurMb, SMbCache* pMbCache);
@ -208,6 +209,7 @@ struct TagWelsFuncPointerList {
PInterMdBackgroundInfoUpdateFunc pfInterMdBackgroundInfoUpdate;
PInterMdScrollingPSkipDecisionFunc pfSCDPSkipDecision;
PSetScrollingMv pfSetScrollingMv;
SMcFunc sMcFuncs;
SSampleDealingFunc sSampleDealingFuncs;

View File

@ -49,6 +49,7 @@
#include "sample.h"
#include "svc_base_layer_md.h"
#include "svc_mode_decision.h"
#include "set_mb_syn_cavlc.h"
#include "crt_util_safe_x.h" // Safe CRT routines like utils for cross_platforms
#include "slice_multi_threading.h"

View File

@ -46,6 +46,7 @@
#include "picture_handle.h"
#include "svc_base_layer_md.h"
#include "svc_encode_slice.h"
#include "svc_mode_decision.h"
#include "decode_mb_aux.h"
#include "deblocking.h"
#include "ref_list_mgr_svc.h"
@ -527,7 +528,7 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara
iCountNumNals += kiNumOfSlice;
assert (iCountNumNals - iOrgNumNals <= MAX_NAL_UNITS_IN_LAYER);
if (kiNumOfSlice > MAX_SLICES_NUM) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_ERROR,
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
"AcquireLayersNals(), num_of_slice(%d) > MAX_SLICES_NUM(%d) per (iDid= %d, qid= %d) settings!\n",
kiNumOfSlice, MAX_SLICES_NUM, iDIndex, 0);
return 1;
@ -535,7 +536,7 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara
}
if (iCountNumNals - iOrgNumNals > MAX_NAL_UNITS_IN_LAYER) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_ERROR,
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
"AcquireLayersNals(), num_of_nals(%d) > MAX_NAL_UNITS_IN_LAYER(%d) per (iDid= %d, qid= %d) settings!\n",
(iCountNumNals - iOrgNumNals), MAX_NAL_UNITS_IN_LAYER, iDIndex, 0);
return 1;
@ -551,7 +552,7 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara
// to check number of layers / nals / slices dependencies, 12/8/2010
if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_ERROR, "AcquireLayersNals(), iCountNumLayers(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!",
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR, "AcquireLayersNals(), iCountNumLayers(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!",
iCountNumLayers, MAX_LAYER_NUM_OF_FRAME);
return 1;
}
@ -955,7 +956,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
& (pDlayerParam->sSliceCfg),
pPps);
if (iResult) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult);
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult);
FreeMemorySvc (ppCtx);
return 1;
}
@ -1278,21 +1279,22 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
(*ppCtx)->iMvRange = pParam->iUsageType ? EXPANDED_MV_RANGE : CAMERA_STARTMV_RANGE;
const int32_t kiMvdRange = (pParam->iUsageType ? EXPANDED_MVD_RANGE : ((kiNumDependencyLayers == 1) ? CAMERA_MVD_RANGE :
CAMERA_HIGHLAYER_MVD_RANGE));
const uint32_t kuiMvdInterTableSize = 1 + (kiMvdRange << 3);//intepel*4=qpel; qpel_mv_range*2=(+/-);
const uint32_t kuiMvdCacheAlignedSize = kuiMvdInterTableSize * sizeof (uint16_t);
const uint32_t kuiMvdInterTableSize = (kiMvdRange << 2); //intepel*4=qpel
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 iNonVclLayersBsSizeCount = 0;
int32_t iTargetSpatialBsSize = 0;
if (kiNumDependencyLayers < 1 || kiNumDependencyLayers > MAX_DEPENDENCY_LAYER) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc() failed due to invalid iNumDependencyLayers(%d)!\n",
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc() failed due to invalid iNumDependencyLayers(%d)!\n",
kiNumDependencyLayers);
FreeMemorySvc (ppCtx);
return 1;
}
if (pParam->uiGopSize == 0 || (pParam->uiIntraPeriod && ((pParam->uiIntraPeriod % pParam->uiGopSize) != 0))) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING,
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING,
"RequestMemorySvc() failed due to invalid uiIntraPeriod(%d) (=multipler of uiGopSize(%d)!",
pParam->uiIntraPeriod, pParam->uiGopSize);
FreeMemorySvc (ppCtx);
@ -1306,7 +1308,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
iResult = AcquireLayersNals (ppCtx, pParam, &iCountLayers, &iCountNals);
if (iResult) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), AcquireLayersNals failed(%d)!", iResult);
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), AcquireLayersNals failed(%d)!", iResult);
FreeMemorySvc (ppCtx);
return 1;
}
@ -1359,7 +1361,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
// for pSlice bs buffers
if (pParam->iMultipleThreadIdc > 1 && RequestMtResource (ppCtx, pParam, iCountBsLen, iTargetSpatialBsSize)) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), RequestMtResource failed!");
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), RequestMtResource failed!");
FreeMemorySvc (ppCtx);
return 1;
}
@ -1406,7 +1408,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
// stride tables
if (AllocStrideTables (ppCtx, kiNumDependencyLayers)) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), AllocStrideTables failed!");
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), AllocStrideTables failed!");
FreeMemorySvc (ppCtx);
return 1;
}
@ -1422,7 +1424,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
(*ppCtx)->pVaa = (SVAAFrameInfoExt*)pMa->WelsMallocz (sizeof (SVAAFrameInfoExt), "pVaa");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pVaa), FreeMemorySvc (ppCtx))
if (RequestMemoryVaaScreen ((*ppCtx)->pVaa, pMa, (*ppCtx)->pSvcParam->iMaxNumRefFrame, iCountMaxMbNum << 2)) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), RequestMemoryVaaScreen failed!");
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), RequestMemoryVaaScreen failed!");
FreeMemorySvc (ppCtx);
return 1;
}
@ -1471,20 +1473,22 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
iResult = InitDqLayers (ppCtx);
if (iResult) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult);
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult);
FreeMemorySvc (ppCtx);
return iResult;
}
if (InitMbListD (ppCtx)) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitMbListD failed!");
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitMbListD failed!");
FreeMemorySvc (ppCtx);
return 1;
}
(*ppCtx)->pMvdCostTableInter = (uint16_t*)pMa->WelsMallocz (52 * kuiMvdCacheAlignedSize, "pMvdCostTableInter");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pMvdCostTableInter), FreeMemorySvc (ppCtx))
MvdCostInit ((*ppCtx)->pMvdCostTableInter, kuiMvdInterTableSize); //should put to a better place?
(*ppCtx)->iMvdCostTableSize = kuiMvdInterTableSize;
(*ppCtx)->iMvdCostTableStride = kuiMvdInterTableStride;
(*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)
(*ppCtx)->pDecPic = (*ppCtx)->ppRefPicListExt[0]->pRef[0];
@ -1741,9 +1745,9 @@ void FreeMemorySvc (sWelsEncCtx** ppCtx) {
}
/* MVD cost tables for Inter */
if (NULL != pCtx->pMvdCostTableInter) {
pMa->WelsFree (pCtx->pMvdCostTableInter, "pMvdCostTableInter");
pCtx->pMvdCostTableInter = NULL;
if (NULL != pCtx->pMvdCostTable) {
pMa->WelsFree (pCtx->pMvdCostTable, "pMvdCostTable");
pCtx->pMvdCostTable = NULL;
}
FreeCodingParam (&pCtx->pSvcParam, pMa);
@ -1757,7 +1761,7 @@ void FreeMemorySvc (sWelsEncCtx** ppCtx) {
#endif//MEMORY_MONITOR
if ((*ppCtx)->pMemAlign != NULL) {
WelsLog (&(*ppCtx)->sLogCtx, WELS_LOG_INFO, "FreeMemorySvc(), verify memory usage (%d bytes) after free..\n",
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_INFO, "FreeMemorySvc(), verify memory usage (%d bytes) after free..\n",
(*ppCtx)->pMemAlign->WelsGetMemoryUsage());
delete (*ppCtx)->pMemAlign;
(*ppCtx)->pMemAlign = NULL;
@ -2150,7 +2154,8 @@ void WelsUninitEncoderExt (sWelsEncCtx** ppCtx) {
if (NULL == ppCtx || NULL == *ppCtx)
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);
#if defined(STAT_OUTPUT)
@ -2168,7 +2173,8 @@ void WelsUninitEncoderExt (sWelsEncCtx** ppCtx) {
WelsEventSignal (& (*ppCtx)->pSliceThreading->pExitEncodeEvent[iThreadIdx]);
WelsEventSignal (& (*ppCtx)->pSliceThreading->pThreadMasterEvent[iThreadIdx]);
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);
(*ppCtx)->pSliceThreading->pThreadHandles[iThreadIdx] = 0;
}
@ -2333,7 +2339,7 @@ void WelsInitCurrentDlayerMltslc (sWelsEncCtx* pCtx, int32_t iPartitionNum) {
/ (pSliceCtx->iMaxSliceNumConstraint))
) {
WelsLog (&(pCtx->sLogCtx),
WelsLog (& (pCtx->sLogCtx),
WELS_LOG_WARNING,
"Set-SliceConstraint(%d) too small for current resolution (MB# %d) under QP/BR!\n",
pSliceCtx->uiSliceSizeConstraint,
@ -2492,16 +2498,21 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
const bool kbHighestSpatialLayer =
(pCtx->pSvcParam->iSpatialLayerNum == (pCurLayer->sLayerInfo.sNalHeaderExt.uiDependencyId + 1));
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 */
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);
} else {
SetNormalCodingFunc (pFuncList);
}
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_16x8] =
pFuncList->pfSearchMethod[BLOCK_8x16] =
@ -2509,6 +2520,8 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
pFuncList->pfSearchMethod[BLOCK_4x4] = WelsDiamondSearch;
pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
pFuncList->sSampleDealingFuncs.pfMeCost = pCtx->pFuncList->sSampleDealingFuncs.pfSampleSatd;
pFuncList->pfSetScrollingMv = SetScrollingMvToMdNull;
if (kbHighestSpatialLayer) {
pFuncList->pfCalculateSatd = NotCalculateSatdCost;
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)
if (pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
if (P_SLICE == pCtx->eSliceType) {
@ -2526,6 +2538,17 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
pFuncList->pfInterFineMd = WelsMdInterFinePartitionVaaOnScreen;
//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
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");
@ -2547,8 +2570,7 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
pFeatureSearchPreparation->pRefBlockFeature = pScreenBlockFeatureStorage;
if (pFeatureSearchPreparation->bFMESwitchFlag
&& !pScreenBlockFeatureStorage->bRefBlockFeatureCalculated) {
//TODO: use ORIGIN of reference when preprocessing is ready
PerformFMEPreprocess (pFuncList, pCurLayer->pRefPic, pFeatureSearchPreparation->pFeatureOfBlock,
PerformFMEPreprocess (pFuncList, pCurLayer->pRefOri[0], pFeatureSearchPreparation->pFeatureOfBlock,
pScreenBlockFeatureStorage);
}
@ -2556,7 +2578,8 @@ void PreprocessSliceCoding (sWelsEncCtx* pCtx) {
if (pFeatureSearchPreparation->bFMESwitchFlag && pScreenBlockFeatureStorage->bRefBlockFeatureCalculated
&& (!pScreenBlockFeatureStorage->iIs16x16)) {
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");
}
}
@ -2833,7 +2856,7 @@ int32_t WritePadding (sWelsEncCtx* pCtx, int32_t iLen, int32_t& iSize) {
if ((pBs->pBufEnd - pBs->pBufPtr) < iLen || iNal >= pCtx->pOut->iCountNals) {
#if GOM_TRACE_FLAG
WelsLog (&(pCtx->sLogCtx), WELS_LOG_ERROR,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
"[RC] paddingcal pBuffer overflow, bufferlen=%lld, paddinglen=%d, iNalIdx= %d, iCountNals= %d\n",
static_cast<long long int> (pBs->pBufEnd - pBs->pBufPtr), iLen, iNal, pCtx->pOut->iCountNals);
#endif
@ -2947,7 +2970,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
int8_t iCurDid = 0;
int8_t iCurTid = 0;
bool bAvcBased = false;
SLogContext* pLogCtx = &(pCtx->sLogCtx);
SLogContext* pLogCtx = & (pCtx->sLogCtx);
#if defined(ENABLE_PSNR_CALC)
float fSnrY = .0f, fSnrU = .0f, fSnrV = .0f;
#endif//ENABLE_PSNR_CALC
@ -3366,6 +3389,12 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
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
if (eNalRefIdc != NRI_PRI_LOWEST) {
if (!pCtx->pFuncList->pUpdateRefList (pCtx)) {
@ -3380,8 +3409,6 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
iFrameSize += iLayerSize;
pCtx->pFuncList->pfRc.pfWelsRcPictureInfoUpdate (pCtx, iLayerSize);
#ifdef ENABLE_FRAME_DUMP
// Dump reconstruction picture for each sQualityStat layer
if (iCurDid + 1 < pSvcParam->iSpatialLayerNum)

View File

@ -348,11 +348,11 @@ void RcTraceVGopBitrate (sWelsEncCtx* pEncCtx) {
#ifdef _TEST_TEMP_Rc_
fprintf (fp_vgop, "%d\n", WELS_ROUND ((double)iTotalBits / iFrameInVGop));
#endif
WelsLog (&(pEncCtx->sLogCtx), WELS_LOG_INFO, "[Rc] VGOPbitrate%d: %d \n", kiDid, iVGopBitrate);
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "[Rc] VGOPbitrate%d: %d \n", kiDid, iVGopBitrate);
if (iTotalBits > 0) {
iTid = 0;
while (iTid <= kiHighestTid) {
WelsLog (&(pEncCtx->sLogCtx), WELS_LOG_INFO, "T%d=%8.3f \n", iTid, (double) (pTOverRc[iTid].iGopBitsDq / iTotalBits));
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "T%d=%8.3f \n", iTid, (double) (pTOverRc[iTid].iGopBitsDq / iTotalBits));
++ iTid;
}
}
@ -756,7 +756,7 @@ void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
void RcTraceFrameBits (sWelsEncCtx* pEncCtx) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
WelsLog (&(pEncCtx->sLogCtx), WELS_LOG_INFO,
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO,
"[Rc] encoding_qp%d, qp = %3d, index = %8d, iTid = %1d, used = %8d, target = %8d, remaingbits = %8d\n",
pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp, pEncCtx->iFrameIndex, pEncCtx->uiTemporalId,
pWelsSvcRc->iFrameDqBits,

View File

@ -49,6 +49,9 @@ void SetUnref (SPicture* pRef) {
pRef->uiRecieveConfirmed = RECIEVE_FAILED;
pRef->iMarkFrameNum = -1;
pRef->bUsedAsRef = false;
if (NULL != pRef->pScreenBlockFeatureStorage)
pRef->pScreenBlockFeatureStorage->bRefBlockFeatureCalculated = false;
}
}
@ -168,7 +171,7 @@ static inline void DeleteInvalidLTR (sWelsEncCtx* pCtx) {
SLTRState* pLtr = &pCtx->pLtr[pCtx->uiDependencyId];
int32_t iMaxFrameNumPlus1 = (1 << pCtx->pSps->uiLog2MaxFrameNum);
int32_t i;
SLogContext* pLogCtx = &(pCtx->sLogCtx);
SLogContext* pLogCtx = & (pCtx->sLogCtx);
for (i = 0; i < LONG_TERM_REF_NUM; i++) {
if (pLongRefList[i] != NULL) {
@ -211,7 +214,7 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
int32_t i, j;
if (pLtr->uiLtrMarkState == LTR_MARKING_SUCCESS) {
WelsLog (&(pCtx->sLogCtx), WELS_LOG_WARNING,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
"pLtr->uiLtrMarkState = %d, pLtr.iCurLtrIdx = %d , pLtr->iLtrMarkFbFrameNum = %d ,pCtx->iFrameNum = %d ",
pLtr->uiLtrMarkState, pLtr->iCurLtrIdx, pLtr->iLtrMarkFbFrameNum, pCtx->iFrameNum);
for (i = 0; i < pRefList->uiLongRefCount; i++) {
@ -234,7 +237,7 @@ static inline void HandleLTRMarkFeedback (sWelsEncCtx* pCtx) {
pLtr->iLTRMarkSuccessNum++;
pLtr->iCurLtrIdx = (pLtr->iCurLtrIdx + 1) % LONG_TERM_REF_NUM;
pLtr->iLTRMarkMode = (pLtr->iLTRMarkSuccessNum >= (LONG_TERM_REF_NUM)) ? (LTR_DELAY_MARK) : (LTR_DIRECT_MARK);
WelsLog (&(pCtx->sLogCtx), WELS_LOG_WARNING, "LTR mark mode =%d", pLtr->iLTRMarkMode);
WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "LTR mark mode =%d", pLtr->iLTRMarkMode);
pLtr->bLTRMarkEnable = true;
break;
}
@ -523,12 +526,12 @@ int32_t FilterLTRRecoveryRequest (sWelsEncCtx* pCtx, SLTRRecoverRequest* pLTRRec
pLtr->bReceivedT0LostFlag = true;
pLtr->iLastCorFrameNumDec = pRequest->iLastCorrectFrameNum;
pLtr->iCurFrameNumInDec = pRequest->iCurrentFrameNum;
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"Receive valid LTR recovery pRequest,feedback_type = %d ,uiIdrPicId = %d , current_frame_num = %d , last correct frame num = %d"
, pRequest->uiFeedbackType, pRequest->uiIDRPicId, pRequest->iCurrentFrameNum, pRequest->iLastCorrectFrameNum);
}
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"Receive LTR recovery pRequest,feedback_type = %d ,uiIdrPicId = %d , current_frame_num = %d , last correct frame num = %d"
, pRequest->uiFeedbackType, pRequest->uiIDRPicId, pRequest->iCurrentFrameNum, pRequest->iLastCorrectFrameNum);
}
@ -546,13 +549,13 @@ void FilterLTRMarkingFeedback (sWelsEncCtx* pCtx, SLTRMarkingFeedback* pLTRMarki
|| pLTRMarkingFeedback->uiFeedbackType == LTR_MARKING_FAILED)) { // avoid error pData
pLtr->uiLtrMarkState = pLTRMarkingFeedback->uiFeedbackType;
pLtr->iLtrMarkFbFrameNum = pLTRMarkingFeedback->iLTRFrameNum ;
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"Receive valid LTR marking feedback, feedback_type = %d , uiIdrPicId = %d , LTR_frame_num = %d , cur_idr_pic_id = %d",
pLTRMarkingFeedback->uiFeedbackType, pLTRMarkingFeedback->uiIDRPicId, pLTRMarkingFeedback->iLTRFrameNum ,
pCtx->sPSOVector.uiIdrPicId);
} else {
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"Receive LTR marking feedback, feedback_type = %d , uiIdrPicId = %d , LTR_frame_num = %d , cur_idr_pic_id = %d",
pLTRMarkingFeedback->uiFeedbackType, pLTRMarkingFeedback->uiIDRPicId, pLTRMarkingFeedback->iLTRFrameNum ,
pCtx->sPSOVector.uiIdrPicId);
@ -586,7 +589,8 @@ bool WelsBuildRefList (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx
if (pRefList->pLongRefList[i]->uiRecieveConfirmed == RECIEVE_SUCCESS) {
pCtx->pRefList0[pCtx->iNumRef0++] = pRefList->pLongRefList[i];
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);
break;
}
@ -596,7 +600,8 @@ bool WelsBuildRefList (void* pEncCtx, const int32_t iPOC, int32_t iBestLtrRefIdx
SPicture* pRef = pRefList->pShortRefList[i];
if (pRef != NULL && pRef->bUsedAsRef && pRef->iFramePoc >= 0 && pRef->uiTemporalId <= kuiTid) {
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);
break;
}
@ -639,9 +644,10 @@ void WelsUpdateRefSyntax (sWelsEncCtx* pCtx, const int32_t iPOC, const int32_t u
if (pCtx->iNumRef0 > 0) {
if ((!pCtx->pRefList0[0]->bIsLongRef) || (!pCtx->pSvcParam->bEnableLongTermReference)) {
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));
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;
@ -770,11 +776,11 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
if (pRefPic->uiTemporalId <= pCtx->uiTemporalId && (!pCtx->bCurFrameMarkedAsSceneLtr || pRefPic->bIsSceneLTR)) {
pCtx->pCurDqLayer->pRefOri[pCtx->iNumRef0] = pRefOri;
pCtx->pRefList0[pCtx->iNumRef0++] = pRefPic;
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"WelsBuildRefListScreen(), ref !current iFrameNum = %d, ref iFrameNum = %d,LTR number = %d,iNumRef = %d ref is Scene LTR = %d\n",
pCtx->iFrameNum, pCtx->pRefList0[pCtx->iNumRef0 - 1]->iFrameNum, pRefList->uiLongRefCount, iNumRef,
pRefPic->bIsSceneLTR);
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"WelsBuildRefListScreen pCtx->uiTemporalId = %d,pRef->iFrameNum = %d,pRef->uiTemporalId = %d\n",
pCtx->uiTemporalId, pRefPic->iFrameNum, pRefPic->uiTemporalId);
}
@ -787,7 +793,7 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr
|| pRefList->pLongRefList[i]->uiTemporalId < pCtx->uiTemporalId) {
pCtx->pCurDqLayer->pRefOri[pCtx->iNumRef0] = pRefOri;
pCtx->pRefList0[pCtx->iNumRef0++] = pRefList->pLongRefList[i];
WelsLog (&(pCtx->sLogCtx), WELS_LOG_INFO,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
"WelsBuildRefListScreen(), ref !current iFrameNum = %d, ref iFrameNum = %d,LTR number = %d\n",
pCtx->iFrameNum, pCtx->pRefList0[pCtx->iNumRef0 - 1]->iFrameNum, pRefList->uiLongRefCount);
break;

View File

@ -211,7 +211,7 @@ void DynamicAdjustSlicing (sWelsEncCtx* pCtx,
iNumMbInEachGom = pWelsSvcRc->iNumberMbGom;
if (iNumMbInEachGom <= 0) {
WelsLog (&(pCtx->sLogCtx), WELS_LOG_ERROR,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
"[MT] DynamicAdjustSlicing(), invalid iNumMbInEachGom= %d from RC, iDid= %d, iCountNumMb= %d\n", iNumMbInEachGom,
iCurDid, kiCountNumMb);
return;
@ -940,7 +940,7 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
WelsEventSignal (
&pEncPEncCtx->pSliceThreading->pFinUpdateMbListEvent[iEventIdx]); // mean finished update pMb list for this pSlice
} else { // WELS_THREAD_ERROR_WAIT_TIMEOUT, or WELS_THREAD_ERROR_WAIT_FAILED
WelsLog (&(pEncPEncCtx->sLogCtx), WELS_LOG_WARNING,
WelsLog (& (pEncPEncCtx->sLogCtx), WELS_LOG_WARNING,
"[MT] CodingSliceThreadProc(), waiting pReadySliceCodingEvent[%d] failed(%d) and thread%d terminated!\n", iEventIdx,
iWaitRet, iThreadIdx);
uiThrdRet = 1;
@ -978,7 +978,7 @@ int32_t FiredSliceThreads (sWelsEncCtx* pCtx, SSliceThreadPrivateData* pPriData,
const int32_t kiEventCnt = uiNumThreads;
if (pPriData == NULL || pLbi == NULL || kiEventCnt <= 0 || pEventsList == NULL) {
WelsLog (&(pCtx->sLogCtx), WELS_LOG_ERROR,
WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
"FiredSliceThreads(), fail due pPriData == %p || pLbi == %p || iEventCnt(%d) <= 0 || pEventsList == %p!!\n",
(void*)pPriData, (void*)pLbi, uiNumThreads, (void*)pEventsList);
return 1;

View File

@ -358,7 +358,7 @@ void WelsMdInterInit (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb, const i
ST32 (&pCurMb->sP16x16Mv, 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));
}
@ -1118,7 +1118,7 @@ int32_t WelsMdP8x8 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SWelsMD* pWe
pSlice->uiMvcNum = 1;
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));
iCostP8x8 += sMe8x8->uiSatdCost;
// 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) {
WelsMdInterDecidedPskip (pEncCtx, pSlice, pCurMb, pMbCache);
} 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);
//refinement for inter type
@ -1875,83 +1809,4 @@ void WelsMdIntraSecondaryModesEnc (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SMB*
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

View File

@ -921,10 +921,10 @@ bool DynSlcJudgeSliceBoundaryStepBack (void* pCtx, void* pSlice, SSliceCtx* pSli
///////////////
// 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) {
pMd->iLambda = g_kiQpCostTable[pCurMb->uiLumaQp];
pMd->pMvdCost = &pMvdCostTableInter[pCurMb->uiLumaQp * kiMvdInterTableStride];
pMd->pMvdCost = &pMvdCostTable[pCurMb->uiLumaQp * kiMvdInterTableStride];
pMd-> iMbPixX = (pCurMb->iMbX << 4);
pMd-> iMbPixY = (pCurMb->iMbY << 4);
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 iMbSkipRun = 0;
const int32_t kiTotalNumMb = pCurLayer->iMbWidth * pCurLayer->iMbHeight;
const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iSpatialLayerNum == 1 ? 648 : 972);
const int32_t kiMvdInterTableStride = 1 + (kiMvdInterTableSize << 1);
uint16_t* pMvdCostTableInter = &pEncCtx->pMvdCostTableInter[kiMvdInterTableSize];
const int32_t kiMvdInterTableStride = pEncCtx->iMvdCostTableStride;
uint16_t* pMvdCostTable = &pEncCtx->pMvdCostTable[pEncCtx->iMvdCostTableSize];
const int32_t kiSliceIdx = pSlice->uiSliceIdx;
const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
int32_t iEncReturn = ENC_RETURN_SUCCESS;
@ -965,7 +964,7 @@ int32_t WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd,
WelsMdInterInit (pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);
TRY_REENCODING:
WelsInitInterMDStruc (pCurMb, pMvdCostTableInter, kiMvdInterTableStride, pMd);
WelsInitInterMDStruc (pCurMb, pMvdCostTable, kiMvdInterTableStride, pMd);
pEncCtx->pFuncList->pfInterMd (pEncCtx, pMd, pSlice, pCurMb, pMbCache);
//mb_qp
@ -1041,7 +1040,7 @@ int32_t WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice,
int32_t iMbSkipRun = 0;
const int32_t kiMvdInterTableSize = (pEncCtx->pSvcParam->iSpatialLayerNum == 1 ? 648 : 972);
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 kiPartitionId = (kiSliceIdx % pEncCtx->iActiveThreadsNum);
const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
@ -1074,7 +1073,7 @@ int32_t WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice,
WelsMdInterInit (pEncCtx, pSlice, pCurMb, kiSliceFirstMbXY);
TRY_REENCODING:
WelsInitInterMDStruc (pCurMb, pMvdCostTableInter, kiMvdInterTableStride, pMd);
WelsInitInterMDStruc (pCurMb, pMvdCostTable, kiMvdInterTableStride, pMd);
pEncCtx->pFuncList->pfInterMd (pEncCtx, pMd, pSlice, pCurMb, pMbCache);
//mb_qp

View File

@ -47,39 +47,9 @@
namespace WelsSVCEnc {
//
// md in enhancement layer
///
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
}
//////////////
// MD for enhancement layers
//////////////
void WelsMdSpatialelInterMbIlfmdNoilp (sWelsEncCtx* pEncCtx, SWelsMD* pWelsMd, SSlice* pSlice,
SMB* pCurMb, const Mb_Type kuiRefMbType) {
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
}
///////////////////////
// do initiation for noILP (needed by ILFMD)
////////////////////////
// do initiation for noILP (needed by ILFMD)
SMB* GetRefMb (SDqLayer* pCurLayer, SMB* pCurMb) {
const SDqLayer* kpRefLayer = pCurLayer->pRefLayer;
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) {
SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer;
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

View File

@ -71,19 +71,22 @@ static inline void MeEndIntepelSearch (SWelsME* pMe) {
}
void WelsInitMeFunc (SWelsFuncPtrList* pFuncList, uint32_t uiCpuFlag, bool bScreenContent) {
pFuncList->pfUpdateFMESwitch = UpdateFMESwitchNull;
if (!bScreenContent) {
pFuncList->pfCheckDirectionalMv = CheckDirectionalMvFalse;
pFuncList->pfCalculateBlockFeatureOfFrame[0] =
pFuncList->pfCalculateBlockFeatureOfFrame[1] = NULL;
pFuncList->pfCalculateSingleBlockFeature[0] =
pFuncList->pfCalculateSingleBlockFeature[1] = NULL;
pFuncList->pfUpdateFMESwitch = UpdateFMESwitchNull;
} else {
pFuncList->pfCheckDirectionalMv = CheckDirectionalMv;
//for cross serarch
pFuncList->pfVerticalFullSearch = LineFullSearch_c;
pFuncList->pfHorizontalFullSearch = LineFullSearch_c;
#if defined (X86_ASM)
if (uiCpuFlag & WELS_CPU_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?
pFuncList->pfCalculateSingleBlockFeature[0] = SumOf8x8SingleBlock_c;
pFuncList->pfCalculateSingleBlockFeature[1] = SumOf16x16SingleBlock_c;
pFuncList->pfUpdateFMESwitch = UpdateFMESwitchNull;
}
}
@ -129,6 +131,38 @@ void WelsMotionEstimateSearch (SWelsFuncPtrList* pFuncList, void* pLplayer, void
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
*
@ -456,7 +490,7 @@ void HorizontalFullSearchUsingSSE41 (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
SMVUnitXY sBestMv;
sBestMv.iMvX = iBestPos - kiCurMeBlockPix;
sBestMv.iMvY = 0;
UpdateMeResults (sBestMv, uiBestCost, &pMe->pColoRefMb[sBestMv.iMvY], pMe);
UpdateMeResults (sBestMv, uiBestCost, &pMe->pColoRefMb[sBestMv.iMvX], pMe);
}
}
#endif
@ -488,7 +522,7 @@ void LineFullSearch_c (SWelsFuncPtrList* pFuncList, SWelsME* pMe,
SMVUnitXY sBestMv;
sBestMv.iMvX = bVerticalSearch ? 0 : (iBestPos - kiCurMeBlockPix);
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);
}
}

View File

@ -982,7 +982,7 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi
SPicture* pRefPic = NULL;
SRefInfoParam* pRefPicInfo = NULL;
uint8_t* pCurBlockStaticPointer = NULL;
SLogContext* pLogCtx = &(pCtx->sLogCtx);
SLogContext* pLogCtx = & (pCtx->sLogCtx);
const int32_t iNegligibleMotionBlocks = (static_cast<int32_t> ((pCurPicture->iWidthInPixel >> 3) *
(pCurPicture->iHeightInPixel >> 3) * STATIC_SCENE_MOTION_RATIO));
const uint8_t iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[m_pEncCtx->sSpatialIndexMap[0].iDid],