From 2eff808db7b90302ad66cc9dc6049bc850c42706 Mon Sep 17 00:00:00 2001 From: ruil2 <ruil2@cisco.com> Date: Tue, 22 Apr 2014 09:59:38 +0800 Subject: [PATCH] add decide frame type for screen content --- codec/encoder/core/src/encoder.cpp | 83 +++++++++++++++------ codec/encoder/core/src/ref_list_mgr_svc.cpp | 4 + codec/encoder/core/src/wels_preprocess.cpp | 2 + 3 files changed, 65 insertions(+), 24 deletions(-) diff --git a/codec/encoder/core/src/encoder.cpp b/codec/encoder/core/src/encoder.cpp index 48a72515..8a10f53a 100644 --- a/codec/encoder/core/src/encoder.cpp +++ b/codec/encoder/core/src/encoder.cpp @@ -77,8 +77,8 @@ int32_t InitPic (const void* kpSrc, const int32_t kiColorspace, const int32_t ki pSrcPic->iPicHeight = kiHeight; //currently encoder only supports videoFormatI420. - if((kiColorspace & (~videoFormatVFlip))!= videoFormatI420) - return 2; + if ((kiColorspace & (~videoFormatVFlip)) != videoFormatI420) + return 2; switch (kiColorspace & (~videoFormatVFlip)) { case videoFormatI420: case videoFormatYV12: @@ -184,7 +184,7 @@ int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam* WelsInitIntraPredFuncs (pFuncList, uiCpuFlag); /* ME func */ - WelsInitMeFunc(pFuncList, uiCpuFlag, SCREEN_CONTENT_REAL_TIME==pParam->iUsageType); + WelsInitMeFunc (pFuncList, uiCpuFlag, SCREEN_CONTENT_REAL_TIME == pParam->iUsageType); /* sad, satd, average */ WelsInitSampleSadFunc (pFuncList, uiCpuFlag); @@ -207,7 +207,7 @@ int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam* WelsBlockFuncInit (&pFuncList->pfSetNZCZero, uiCpuFlag); InitFillNeighborCacheInterFunc (pFuncList, pParam->bEnableBackgroundDetection); - InitRefListMgrFunc(pFuncList,pParam->iUsageType); + InitRefListMgrFunc (pFuncList, pParam->iUsageType); return iReturn; } @@ -285,28 +285,63 @@ EVideoFrameType DecideFrameType (sWelsEncCtx* pEncCtx, const int8_t kiSpatialNum EVideoFrameType iFrameType = videoFrameTypeInvalid; bool bSceneChangeFlag = false; - // perform scene change detection - if ((!pSvcParam->bEnableSceneChangeDetect) || pEncCtx->pVaa->bIdrPeriodFlag || - (kiSpatialNum < pSvcParam->iSpatialLayerNum) - || (pEncCtx->iFrameIndex < (VGOP_SIZE << 1))) { // avoid too frequent I frame coding, rc control - bSceneChangeFlag = false; + if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) { + if ((!pSvcParam->bEnableSceneChangeDetect) || pEncCtx->pVaa->bIdrPeriodFlag || + (kiSpatialNum < pSvcParam->iSpatialLayerNum)) { + bSceneChangeFlag = false; + } else { + bSceneChangeFlag = pEncCtx->pVaa->bSceneChangeFlag; + } + pEncCtx->bCurFrameMarkedAsSceneLtr = false; + if (pEncCtx->pVaa->bIdrPeriodFlag || pEncCtx->bEncCurFrmAsIdrFlag || (!pSvcParam->bEnableLongTermReference + && bSceneChangeFlag)) { + iFrameType = videoFrameTypeIDR; + } else if (pSvcParam->bEnableLongTermReference && (bSceneChangeFlag + || pEncCtx->pVaa->eSceneChangeIdc == LARGE_CHANGED_SCENE)) { + int iActualLtrcount = 0; + SPicture** pLongTermRefList = pEncCtx->ppRefPicListExt[0]->pLongRefList; + for (int i = 0; i < pSvcParam->iLTRRefNum; ++i) { + if (NULL != pLongTermRefList[i] && pLongTermRefList[i]->bUsedAsRef && pLongTermRefList[i]->bIsLongRef + && pLongTermRefList[i]->bIsSceneLTR) { + ++iActualLtrcount; + } + } + if (iActualLtrcount == pSvcParam->iLTRRefNum && bSceneChangeFlag) { + iFrameType = videoFrameTypeIDR; + } else { + iFrameType = videoFrameTypeP; + pEncCtx->bCurFrameMarkedAsSceneLtr = true; + } + } else { + iFrameType = videoFrameTypeP; + } + if (videoFrameTypeIDR == iFrameType) { + pEncCtx->iCodingIndex = 0; + pEncCtx->bCurFrameMarkedAsSceneLtr = true; + } } else { - bSceneChangeFlag = pEncCtx->pVaa->bSceneChangeFlag; + // perform scene change detection + if ((!pSvcParam->bEnableSceneChangeDetect) || pEncCtx->pVaa->bIdrPeriodFlag || + (kiSpatialNum < pSvcParam->iSpatialLayerNum) + || (pEncCtx->iFrameIndex < (VGOP_SIZE << 1))) { // avoid too frequent I frame coding, rc control + bSceneChangeFlag = false; + } else { + bSceneChangeFlag = pEncCtx->pVaa->bSceneChangeFlag; + } + + //scene_changed_flag: RC enable && iSpatialNum == pSvcParam->iSpatialLayerNum + //bIdrPeriodFlag: RC disable || iSpatialNum != pSvcParam->iSpatialLayerNum + //pEncCtx->bEncCurFrmAsIdrFlag: 1. first frame should be IDR; 2. idr pause; 3. idr request + iFrameType = (pEncCtx->pVaa->bIdrPeriodFlag || bSceneChangeFlag + || pEncCtx->bEncCurFrmAsIdrFlag) ? videoFrameTypeIDR : videoFrameTypeP; + + if (videoFrameTypeP == iFrameType && pEncCtx->iSkipFrameFlag > 0) { // for frame skip, 1/5/2010 + -- pEncCtx->iSkipFrameFlag; + iFrameType = videoFrameTypeSkip; + } else if (videoFrameTypeIDR == iFrameType) { + pEncCtx->iCodingIndex = 0; + } } - - //scene_changed_flag: RC enable && iSpatialNum == pSvcParam->iSpatialLayerNum - //bIdrPeriodFlag: RC disable || iSpatialNum != pSvcParam->iSpatialLayerNum - //pEncCtx->bEncCurFrmAsIdrFlag: 1. first frame should be IDR; 2. idr pause; 3. idr request - iFrameType = (pEncCtx->pVaa->bIdrPeriodFlag || bSceneChangeFlag - || pEncCtx->bEncCurFrmAsIdrFlag) ? videoFrameTypeIDR : videoFrameTypeP; - - if (videoFrameTypeP == iFrameType && pEncCtx->iSkipFrameFlag > 0) { // for frame skip, 1/5/2010 - -- pEncCtx->iSkipFrameFlag; - iFrameType = videoFrameTypeSkip; - } else if (videoFrameTypeIDR == iFrameType) { - pEncCtx->iCodingIndex = 0; - } - return iFrameType; } diff --git a/codec/encoder/core/src/ref_list_mgr_svc.cpp b/codec/encoder/core/src/ref_list_mgr_svc.cpp index 5c69fe3e..240ebf6c 100644 --- a/codec/encoder/core/src/ref_list_mgr_svc.cpp +++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp @@ -599,6 +599,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, WELS_LOG_INFO, "WelsBuildRefList pCtx->uiTemporalId = %d,pRef->iFrameNum = %d,pRef->uiTemporalId = %d\n", + pCtx->uiTemporalId,pRef->iFrameNum,pRef->uiTemporalId); break; } } @@ -770,6 +772,8 @@ bool WelsBuildRefListScreen (void* pEncCtx, const int32_t iPOC, int32_t iBestLtr "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, WELS_LOG_INFO, "WelsBuildRefListScreen pCtx->uiTemporalId = %d,pRef->iFrameNum = %d,pRef->uiTemporalId = %d\n", + pCtx->uiTemporalId,pRefPic->iFrameNum,pRefPic->uiTemporalId); } } } else { diff --git a/codec/encoder/core/src/wels_preprocess.cpp b/codec/encoder/core/src/wels_preprocess.cpp index 28b4c8b7..3b43acae 100644 --- a/codec/encoder/core/src/wels_preprocess.cpp +++ b/codec/encoder/core/src/wels_preprocess.cpp @@ -1047,6 +1047,8 @@ ESceneChangeIdc CWelsPreProcess::DetectSceneChangeScreen (sWelsEncCtx* pCtx, SPi iVaaFrameSceneChangeIdc = SIMILAR_SCENE; } + WelsLog(pCtx,WELS_LOG_INFO,"iVaaFrameSceneChangeIdc = %d,codingIdx = %d\n",iVaaFrameSceneChangeIdc,pCtx->iCodingIndex); + SaveBestRefToVaa (sLtrSaved, & (pVaaExt->sVaaStrBestRefCandidate[0])); if (0 == iAvailableSceneRefNum) {