Merge pull request #728 from ruil2/enc_type2

add decide frame type for screen content
This commit is contained in:
Licai Guo 2014-04-22 10:15:25 +08:00
commit f5eb6d4fdc
3 changed files with 65 additions and 24 deletions

View File

@ -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;
}

View File

@ -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 {

View File

@ -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) {