shithub: openh264

Download patch

ref: 2eff808db7b90302ad66cc9dc6049bc850c42706
parent: 082248db1766ecd37fef543f9199280d17590084
author: ruil2 <[email protected]>
date: Tue Apr 22 05:59:38 EDT 2014

add decide frame type for screen content

--- a/codec/encoder/core/src/encoder.cpp
+++ b/codec/encoder/core/src/encoder.cpp
@@ -77,8 +77,8 @@
   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 @@
   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 @@
   WelsBlockFuncInit (&pFuncList->pfSetNZCZero, uiCpuFlag);
 
   InitFillNeighborCacheInterFunc (pFuncList, pParam->bEnableBackgroundDetection);
-  InitRefListMgrFunc(pFuncList,pParam->iUsageType);
+  InitRefListMgrFunc (pFuncList, pParam->iUsageType);
   return iReturn;
 }
 
@@ -285,28 +285,63 @@
   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;
+    //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;
+    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;
 }
 
--- a/codec/encoder/core/src/ref_list_mgr_svc.cpp
+++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp
@@ -599,6 +599,8 @@
         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 @@
                      "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 {
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -1047,6 +1047,8 @@
     iVaaFrameSceneChangeIdc = SIMILAR_SCENE;
   }
 
+  WelsLog(pCtx,WELS_LOG_INFO,"iVaaFrameSceneChangeIdc = %d,codingIdx = %d\n",iVaaFrameSceneChangeIdc,pCtx->iCodingIndex);
+
   SaveBestRefToVaa (sLtrSaved, & (pVaaExt->sVaaStrBestRefCandidate[0]));
 
   if (0 == iAvailableSceneRefNum) {