ref: 4fab8c2ee72b10615b0e45832a1c5c60a4654d96
parent: 292d2511e2f91ffc00a1b9addf0876a0bcad271e
author: Sijia Chen <sijchen@cisco.com>
date: Tue Oct 28 12:58:59 EDT 2014
for reference selection under screen: 1, ref_list_mgr_svc.cpp, Ln314: fix a wrong DeleteLTRFromLongList which should not be used under screen strategy 2, ref_list_mgr_svc.cpp, Ln910: remove the frame which is furthest in distance to the current frame in ref list 3, wels_preprocess.cpp: use scene LTR ref list when the current frame is scene LTR -, ref_list_mgr_svc.cpp, Ln811: add DEBUG trace reviewed at: https://rbcommons.com/s/OpenH264/r/870/
--- a/codec/common/inc/macros.h
+++ b/codec/common/inc/macros.h
@@ -272,6 +272,9 @@
#define WELS_GCC_UNUSED
#endif
+inline bool CheckInRangeCloseOpen (const int16_t kiCurrent, const int16_t kiMin, const int16_t kiMax) {
+return ((kiCurrent >= kiMin) && (kiCurrent < kiMax));
+}
#endif//WELS_MACRO_UTILIZATIONS_H__
--- a/codec/encoder/core/inc/svc_motion_estimate.h
+++ b/codec/encoder/core/inc/svc_motion_estimate.h
@@ -342,12 +342,9 @@
pMvMax->iMvY = WELS_MIN (((kiMbHeight - kiMbY) << 4) - INTPEL_NEEDED_MARGIN, kiMaxMvRange);
}
-inline bool CheckMvInRange (const int16_t kiCurrentMv, const int16_t kiMinMv, const int16_t kiMaxMv) {
-return ((kiCurrentMv >= kiMinMv) && (kiCurrentMv < kiMaxMv));
-}
inline bool CheckMvInRange (const SMVUnitXY ksCurrentMv, const SMVUnitXY ksMinMv, const SMVUnitXY ksMaxMv) {
-return (CheckMvInRange (ksCurrentMv.iMvX, ksMinMv.iMvX, ksMaxMv.iMvX)
- && CheckMvInRange (ksCurrentMv.iMvY, ksMinMv.iMvY, ksMaxMv.iMvY));
+return (CheckInRangeCloseOpen (ksCurrentMv.iMvX, ksMinMv.iMvX, ksMaxMv.iMvX)
+ && CheckInRangeCloseOpen (ksCurrentMv.iMvY, ksMinMv.iMvY, ksMaxMv.iMvY));
}
//FME switch related
inline bool CalcFMESwitchFlag (const uint8_t uiFMEGoodFrameCount, const int32_t iHighFreMbPrecentage,
--- a/codec/encoder/core/inc/wels_preprocess.h
+++ b/codec/encoder/core/inc/wels_preprocess.h
@@ -106,7 +106,8 @@
typedef struct SVAAFrameInfoExt_t: public SVAAFrameInfo {
SComplexityAnalysisScreenParam sComplexityScreenParam;
SScrollDetectionParam sScrollDetectInfo;
- SRefInfoParam sVaaStrBestRefCandidate[MAX_REF_PIC_COUNT]; //TOP3_BEST_REF_NO_TID
+ SRefInfoParam sVaaStrBestRefCandidate[MAX_REF_PIC_COUNT];
+ SRefInfoParam sVaaLtrBestRefCandidate[MAX_REF_PIC_COUNT];
int32_t iNumOfAvailableRef;
int32_t iVaaBestRefFrameNum;
@@ -127,7 +128,7 @@
int32_t AnalyzeSpatialPic (sWelsEncCtx* pEncCtx, const int32_t kiDIdx);
int32_t UpdateSpatialPictures (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam, const int8_t iCurTid,
const int32_t d_idx);
- int32_t GetRefFrameInfo (int32_t iRefIdx, SPicture*& pRefOri);
+ int32_t GetRefFrameInfo (int32_t iRefIdx, bool bCurrentFrameIsSceneLtr, SPicture*& pRefOri);
void AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture,
const int32_t kiDependencyId, const bool kbCalculateBGD);
int32_t UpdateBlockIdcForScreen (uint8_t* pCurBlockStaticPointer, const SPicture* kpRefPic, const SPicture* kpSrcPic);
--- a/codec/encoder/core/src/ref_list_mgr_svc.cpp
+++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp
@@ -106,6 +106,7 @@
SPicture* pRef = pRefList->pLongRefList[i];
if (pRef != NULL && pRef->bUsedAsRef && pRef->bIsLongRef && (!pRef->bIsSceneLTR) &&
(pCtx->uiTemporalId < pRef->uiTemporalId || pCtx->bCurFrameMarkedAsSceneLtr)) {
+ //this is our strategy to Unref all non-sceneLTR when the the current frame is sceneLTR
pRef->SetUnref();
DeleteLTRFromLongList (pCtx, i);
i--;
@@ -310,12 +311,13 @@
int32_t iLtrIdx = pCtx->pDecPic->iLongTermPicNum;
pCtx->pVaa->uiMarkLongTermPicIdx = pCtx->pDecPic->iLongTermPicNum;
+ assert (CheckInRangeCloseOpen (iLtrIdx, 0, MAX_REF_PIC_COUNT));
if (pLongRefList[iLtrIdx] != NULL) {
pLongRefList[iLtrIdx]->SetUnref();
- DeleteLTRFromLongList (pCtx, iLtrIdx);
+ } else {
+ pRefList->uiLongRefCount++;
}
pLongRefList[iLtrIdx] = pCtx->pDecPic;
- pRefList->uiLongRefCount++;
}
static void PrefetchNextBuffer (void* pEncCtx) {
@@ -773,7 +775,7 @@
int iLtrRefIdx = 0;
SPicture* pRefOri = NULL;
for (int idx = 0; idx < pVaaExt->iNumOfAvailableRef; idx++) {
- iLtrRefIdx = pCtx->pVpp->GetRefFrameInfo (idx, pRefOri);
+ iLtrRefIdx = pCtx->pVpp->GetRefFrameInfo (idx, pCtx->bCurFrameMarkedAsSceneLtr, pRefOri);
if (iLtrRefIdx >= 0 && iLtrRefIdx <= pParam->iLTRRefNum) {
SPicture* pRefPic = pRefList->pLongRefList[iLtrRefIdx];
if (pRefPic != NULL && pRefPic->bUsedAsRef && pRefPic->bIsLongRef) {
@@ -805,6 +807,29 @@
}
}
} // end of (int idx = 0; idx < pVaaExt->iNumOfAvailableRef; idx++)
+
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
+ "WelsBuildRefListScreen(), CurrentFramePoc=%d, isLTR=%d", iPOC, pCtx->bCurFrameMarkedAsSceneLtr);
+ for (int j = 0; j < iNumRef; j++) {
+ SPicture* pARefPicture = pRefList->pLongRefList[j];
+ if (pARefPicture != NULL) {
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
+ "WelsBuildRefListScreen()\tRefLot[%d]: iPoc=%d, iPictureType=%d, bUsedAsRef=%d, bIsLongRef=%d, bIsSceneLTR=%d, uiTemporalId=%d, iFrameNum=%d, iMarkFrameNum=%d, iLongTermPicNum=%d, uiRecieveConfirmed=%d",
+ j,
+ pARefPicture->iFramePoc,
+ pARefPicture->iPictureType,
+ pARefPicture->bUsedAsRef,
+ pARefPicture->bIsLongRef,
+ pARefPicture->bIsSceneLTR,
+ pARefPicture->uiTemporalId,
+ pARefPicture->iFrameNum,
+ pARefPicture->iMarkFrameNum,
+ pARefPicture->iLongTermPicNum,
+ pARefPicture->uiRecieveConfirmed);
+ } else {
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "WelsBuildRefListScreen()\tRefLot[%d]: NULL", j);
+ }
+ }
} else {
// dealing with IDR
WelsResetRefList (pCtx); //for IDR, SHOULD reset pRef list.
@@ -817,6 +842,11 @@
return (pCtx->iNumRef0 > 0 || pCtx->eSliceType == I_SLICE) ? (true) : (false);
}
+
+static inline bool IsValidFrameNum (const int32_t kiFrameNum) {
+ return (kiFrameNum < (1 << 30)); // TODO: use the original judge first, may be improved
+}
+
void WelsMarkPicScreen (void* pEncCtx) {
#define STR_ROOM 1
sWelsEncCtx* pCtx = (sWelsEncCtx*)pEncCtx;
@@ -853,7 +883,6 @@
}
}
} else {
- int32_t iMinSTRframe_num = 1 << 30; // is big enough
int32_t iRefNum_t[MAX_TEMPORAL_LAYER_NUM] = {0};
for (i = 0 ; i < pRefList->uiLongRefCount ; ++i) {
if (ppLongRefList[i]->bUsedAsRef && ppLongRefList[i]->bIsLongRef && (!ppLongRefList[i]->bIsSceneLTR)) {
@@ -867,11 +896,20 @@
iMaxMultiRefTid = i;
}
}
+ int32_t iLongestDeltaFrameNum = -1;
+ int32_t iMaxFrameNum = (1 << pCtx->pSps->uiLog2MaxFrameNum);
+
for (i = 0 ; i < pRefList->uiLongRefCount ; ++i) {
if (ppLongRefList[i]->bUsedAsRef && ppLongRefList[i]->bIsLongRef && (!ppLongRefList[i]->bIsSceneLTR)
&& iMaxMultiRefTid == ppLongRefList[i]->uiTemporalId) {
- if (ppLongRefList[i]->iFrameNum < iMinSTRframe_num) {
+ assert (IsValidFrameNum (ppLongRefList[i]->iFrameNum)); // pLtr->iCurLtrIdx must have a value
+ int32_t iDeltaFrameNum = (pCtx->iFrameNum >= ppLongRefList[i]->iFrameNum)
+ ? (pCtx->iFrameNum - ppLongRefList[i]->iFrameNum)
+ : (pCtx->iFrameNum + iMaxFrameNum - ppLongRefList[i]->iFrameNum);
+
+ if (iDeltaFrameNum > iLongestDeltaFrameNum) {
pLtr->iCurLtrIdx = ppLongRefList[i]->iLongTermPicNum;
+ iLongestDeltaFrameNum = iDeltaFrameNum;
}
}
}
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -219,7 +219,8 @@
if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (m_pEncCtx->pVaa);
- SRefInfoParam* BestRefCandidateParam = & (pVaaExt->sVaaStrBestRefCandidate[0]);
+ SRefInfoParam* BestRefCandidateParam = (pCtx->bCurFrameMarkedAsSceneLtr) ? (& (pVaaExt->sVaaLtrBestRefCandidate[0])) :
+ (& (pVaaExt->sVaaStrBestRefCandidate[0]));
SPicture* pRefPic = m_pSpatialPic[0][BestRefCandidateParam->iSrcListIdx];
VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, false, bCalculateVar, bCalculateBGD);
@@ -1116,8 +1117,8 @@
pVaaExt->iVaaBestRefFrameNum = sLtrSaved.pRefPicture->iFrameNum;
pVaaExt->pVaaBestBlockStaticIdc = sLtrSaved.pBestBlockStaticIdc;
- if (0 == iAvailableSceneRefNum) {
- SaveBestRefToVaa (sSceneLtrSaved, & (pVaaExt->sVaaStrBestRefCandidate[1]));
+ if (0 < iAvailableSceneRefNum) {
+ SaveBestRefToVaa (sSceneLtrSaved, & (pVaaExt->sVaaLtrBestRefCandidate[0]));
}
pVaaExt->iNumOfAvailableRef = 1;
@@ -1124,13 +1125,13 @@
return static_cast<ESceneChangeIdc> (iVaaFrameSceneChangeIdc);
}
-int32_t CWelsPreProcess::GetRefFrameInfo (int32_t iRefIdx, SPicture*& pRefOri) {
+int32_t CWelsPreProcess::GetRefFrameInfo (int32_t iRefIdx, bool bCurrentFrameIsSceneLtr, SPicture*& pRefOri) {
const int32_t iTargetDid = m_pEncCtx->pSvcParam->iSpatialLayerNum - 1;
SVAAFrameInfoExt* pVaaExt = static_cast<SVAAFrameInfoExt*> (m_pEncCtx->pVaa);
- SRefInfoParam* BestRefCandidateParam = & (pVaaExt->sVaaStrBestRefCandidate[iRefIdx]);
- int32_t iLtrRefIdx = m_pSpatialPic[iTargetDid][BestRefCandidateParam->iSrcListIdx]->iLongTermPicNum;
- pRefOri = m_pSpatialPic[iTargetDid][BestRefCandidateParam->iSrcListIdx];
- return iLtrRefIdx;
+ SRefInfoParam* pBestRefCandidateParam = (bCurrentFrameIsSceneLtr) ? (& (pVaaExt->sVaaLtrBestRefCandidate[iRefIdx])) :
+ (& (pVaaExt->sVaaStrBestRefCandidate[iRefIdx]));
+ pRefOri = m_pSpatialPic[iTargetDid][pBestRefCandidateParam->iSrcListIdx];
+ return (m_pSpatialPic[iTargetDid][pBestRefCandidateParam->iSrcListIdx]->iLongTermPicNum);
}
void CWelsPreProcess::Padding (uint8_t* pSrcY, uint8_t* pSrcU, uint8_t* pSrcV, int32_t iStrideY, int32_t iStrideUV,
int32_t iActualWidth, int32_t iPaddingWidth, int32_t iActualHeight, int32_t iPaddingHeight) {
--- a/test/api/encoder_test.cpp
+++ b/test/api/encoder_test.cpp
@@ -129,7 +129,7 @@
//for different strategy
{
"res/Cisco_Absolute_Power_1280x720_30fps.yuv",
- "868f327765dc8e705ad6a9a942bfc7e32c03c791", SCREEN_CONTENT_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, true, true, false
+ "6a7fc060a4d9dc0ec397987f02df0cf4d96181e6", SCREEN_CONTENT_REAL_TIME, 1280, 720, 30.0f, SM_DYN_SLICE, false, 1, true, true, false
},
{
"res/CiscoVT2people_320x192_12fps.yuv",