shithub: openh264

Download patch

ref: 75aa8e564ca011137f2331f2c0bfaf8691688374
parent: 2f8c539e60fafe2e3862d7bf13eb82577890bf00
parent: 6b707ffb14d63751712976ea3eba8a214b21bb5f
author: Licai Guo <[email protected]>
date: Thu Apr 17 14:31:26 EDT 2014

Merge pull request #708 from ruil2/enc_complexity_update

     add complexity calculation in workflow

--- a/codec/encoder/core/inc/rc.h
+++ b/codec/encoder/core/inc/rc.h
@@ -51,7 +51,7 @@
 namespace WelsSVCEnc {
 //trace
 #define GOM_TRACE_FLAG 1
-
+#define GOM_H_SCC               8
 #define    WELS_RC_DISABLE        0
 #define    WELS_RC_GOM            1
 
--- a/codec/encoder/core/inc/wels_preprocess.h
+++ b/codec/encoder/core/inc/wels_preprocess.h
@@ -127,6 +127,9 @@
   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 GetRefCandidateLtrIndex(int32_t iRefIdx);
+  void    AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture,
+                                    const int32_t kiDependencyId, const bool kbCalculateBGD);
+
  private:
   int32_t WelsPreprocessCreate();
   int32_t WelsPreprocessDestroy();
@@ -144,8 +147,6 @@
                           bool bCalculateVar, bool bCalculateBGD);
   void    BackgroundDetection (SVAAFrameInfo* pVaaInfo, SPicture* pCurPicture, SPicture* pRefPicture, bool bDetectFlag);
   void    AdaptiveQuantCalculation (SVAAFrameInfo* pVaaInfo, SPicture* pCurPicture, SPicture* pRefPicture);
-  void    AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture,
-                                    const int32_t kiDependencyId, const bool kbCalculateBGD);
   void    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);
   void    SetRefMbType (sWelsEncCtx* pCtx, uint32_t** pRefMbTypeArray, int32_t iRefPicType);
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -3002,6 +3002,10 @@
 #ifdef LONG_TERM_REF_DUMP
     dump_ref (pCtx);
 #endif
+    if((pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME)&&(pSvcParam->iRCMode != RC_OFF_MODE))
+      pCtx->pVpp->AnalyzePictureComplexity(pCtx,pCtx->pEncPic,((pCtx->eSliceType == P_SLICE)&&(pCtx->iNumRef0>0))?pCtx->pRefList0[0]:NULL,
+                                           iCurDid,pSvcParam->bEnableBackgroundDetection);
+
     WelsUpdateRefSyntax (pCtx,  pCtx->iPOC,
                          eFrameType);	//get reordering syntax used for writing slice header and transmit to encoder.
     PrefetchReferencePicture (pCtx, eFrameType);	// update reference picture for current pDq layer
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -140,7 +140,7 @@
       ++ i;
     } while (i < kuiRefNumInTemporal);
 
-    if(pParam->iUsageType == SCREEN_CONTENT_REAL_TIME)
+    if (pParam->iUsageType == SCREEN_CONTENT_REAL_TIME)
       m_uiSpatialLayersInTemporal[iDlayerIndex] = 1;
     else
       m_uiSpatialLayersInTemporal[iDlayerIndex] = kuiLayerInTemporal;
@@ -210,20 +210,20 @@
   SPicture* pCurPic = m_pSpatialPic[kiDidx][iCurTemporalIdx];
   bool bCalculateVar = (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE);
 
-  if(pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME){
-     SVAAFrameInfoExt* pVaaExt			= static_cast<SVAAFrameInfoExt*> (m_pEncCtx->pVaa);
-     SRefInfoParam* BestRefCandidateParam =&(pVaaExt->sVaaStrBestRefCandidate[0]);
-	   SPicture *pRefPic= m_pSpatialPic[0][BestRefCandidateParam->iSrcListIdx];
+  if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
+    SVAAFrameInfoExt* pVaaExt			= static_cast<SVAAFrameInfoExt*> (m_pEncCtx->pVaa);
+    SRefInfoParam* BestRefCandidateParam = & (pVaaExt->sVaaStrBestRefCandidate[0]);
+    SPicture* pRefPic = m_pSpatialPic[0][BestRefCandidateParam->iSrcListIdx];
 
-     VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, false, bCalculateVar, bCalculateBGD);
+    VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, false, bCalculateVar, bCalculateBGD);
 
-     if (pSvcParam->bEnableBackgroundDetection) {
-       BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE);
-     }
+    if (pSvcParam->bEnableBackgroundDetection) {
+      BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE);
+    }
 
-     if (bNeededMbAq) {
-     AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);
-     }
+    if (bNeededMbAq) {
+      AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);
+    }
   } else {
     SPicture* pRefPic = m_pSpatialPic[kiDidx][iRefTemporalIdx];
     SPicture* pLastPic = m_pLastSpatialPicture[kiDidx][0];
@@ -242,13 +242,8 @@
 
       AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);
     }
-
-    if(pSvcParam->iUsageType != SCREEN_CONTENT_REAL_TIME){
-      if (pSvcParam->iRCMode != RC_OFF_MODE) {
-        AnalyzePictureComplexity (pCtx, pCurPic, pRefPic, kiDidx, bCalculateBGD);
-      }
-      WelsExchangeSpatialPictures (&m_pLastSpatialPicture[kiDidx][1], &m_pLastSpatialPicture[kiDidx][0]);
-    }
+    AnalyzePictureComplexity (pCtx, pCurPic, pRefPic, kiDidx, bCalculateBGD);
+    WelsExchangeSpatialPictures (&m_pLastSpatialPicture[kiDidx][1], &m_pLastSpatialPicture[kiDidx][0]);
   }
   return 0;
 }
@@ -255,8 +250,8 @@
 
 int32_t CWelsPreProcess::UpdateSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam,
     const int8_t iCurTid, const int32_t d_idx) {
-  if(pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME)
-      return 0;
+  if (pCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME)
+    return 0;
   if (iCurTid < m_uiSpatialLayersInTemporal[d_idx] - 1 || pParam->iDecompStages == 0) {
     if ((iCurTid >= MAX_TEMPORAL_LEVEL) || (m_uiSpatialLayersInTemporal[d_idx] - 1 > MAX_TEMPORAL_LEVEL)) {
       InitLastSpatialPictures (pCtx);
@@ -723,39 +718,35 @@
 void CWelsPreProcess::AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture,
     const int32_t kiDependencyId, const bool bCalculateBGD) {
   SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;
-  SVAAFrameInfo* pVaaInfo	 = pCtx->pVaa;
-
-  SComplexityAnalysisParam* sComplexityAnalysisParam = & (pVaaInfo->sComplexityAnalysisParam);
-  SWelsSvcRc* SWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId];
   int32_t iComplexityAnalysisMode = 0;
 
-  if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) {
-    iComplexityAnalysisMode = FRAME_SAD;
-  } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) {
-    iComplexityAnalysisMode = GOM_SAD;
-  } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) {
-    iComplexityAnalysisMode = GOM_VAR;
-  } else {
+  if (pSvcParam->iRCMode == RC_OFF_MODE)
     return;
-  }
+  if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
+    SVAAFrameInfoExt* pVaaExt		= static_cast<SVAAFrameInfoExt*> (pCtx->pVaa);
+    SComplexityAnalysisScreenParam* sComplexityAnalysisParam	= &pVaaExt->sComplexityScreenParam;
+    SWelsSvcRc* pWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId];
 
-  sComplexityAnalysisParam->iComplexityAnalysisMode = iComplexityAnalysisMode;
-  sComplexityAnalysisParam->pCalcResult = & (pVaaInfo->sVaaCalcInfo);
-  sComplexityAnalysisParam->pBackgroundMbFlag = pVaaInfo->pVaaBackgroundMbFlag;
-  SetRefMbType (pCtx, & (sComplexityAnalysisParam->uiRefMbType), pRefPicture->iPictureType);
-  sComplexityAnalysisParam->iCalcBgd = bCalculateBGD;
-  sComplexityAnalysisParam->iFrameComplexity = 0;
+    if (pCtx->eSliceType == P_SLICE)
+      iComplexityAnalysisMode = GOM_SAD;
+    else if (pCtx->eSliceType == I_SLICE)
+      iComplexityAnalysisMode = GOM_VAR;
+    else
+      return;
 
-  memset (SWelsSvcRc->pGomForegroundBlockNum, 0, SWelsSvcRc->iGomSize * sizeof (int32_t));
-  if (iComplexityAnalysisMode != FRAME_SAD)
-    memset (SWelsSvcRc->pCurrentFrameGomSad, 0, SWelsSvcRc->iGomSize * sizeof (int32_t));
+    memset (pWelsSvcRc->pGomForegroundBlockNum, 0, pWelsSvcRc->iGomSize * sizeof (int32_t));
+    memset (pWelsSvcRc->pCurrentFrameGomSad, 0, pWelsSvcRc->iGomSize * sizeof (int32_t));
 
-  sComplexityAnalysisParam->pGomComplexity = SWelsSvcRc->pCurrentFrameGomSad;
-  sComplexityAnalysisParam->pGomForegroundBlockNum = SWelsSvcRc->pGomForegroundBlockNum;
-  sComplexityAnalysisParam->iMbNumInGom = SWelsSvcRc->iNumberMbGom;
+    sComplexityAnalysisParam->iFrameComplexity = 0;
+    sComplexityAnalysisParam->pGomComplexity = pWelsSvcRc->pCurrentFrameGomSad;
+    sComplexityAnalysisParam->iGomNumInFrame = pWelsSvcRc->iGomSize;
+    sComplexityAnalysisParam->iIdrFlag = (pCtx->eSliceType == I_SLICE);
+    sComplexityAnalysisParam->iMbRowInGom = GOM_H_SCC;
+    sComplexityAnalysisParam->sScrollResult.bScrollDetectFlag = false;
+    sComplexityAnalysisParam->sScrollResult.iScrollMvX = 0;
+    sComplexityAnalysisParam->sScrollResult.iScrollMvY = 0;
 
-  {
-    int32_t iMethodIdx = METHOD_COMPLEXITY_ANALYSIS;
+    const int32_t iMethodIdx = METHOD_COMPLEXITY_ANALYSIS_SCREEN;
     SPixMap sSrcPixMap;
     SPixMap sRefPixMap;
     memset (&sSrcPixMap, 0, sizeof (SPixMap));
@@ -769,17 +760,76 @@
     sSrcPixMap.sRect.iRectHeight = pCurPicture->iHeightInPixel;
     sSrcPixMap.eFormat = VIDEO_FORMAT_I420;
 
-    sRefPixMap.pPixel[0] = pRefPicture->pData[0];
-    sRefPixMap.iSizeInBits = g_kiPixMapSizeInBits;
-    sRefPixMap.iStride[0] = pRefPicture->iLineSize[0];
-    sRefPixMap.sRect.iRectWidth = pRefPicture->iWidthInPixel;
-    sRefPixMap.sRect.iRectHeight = pRefPicture->iHeightInPixel;
-    sRefPixMap.eFormat = VIDEO_FORMAT_I420;
+    if (pRefPicture != NULL) {
+      sRefPixMap.pPixel[0] = pRefPicture->pData[0];
+      sRefPixMap.iSizeInBits = g_kiPixMapSizeInBits;
+      sRefPixMap.iStride[0] = pRefPicture->iLineSize[0];
+      sRefPixMap.sRect.iRectWidth = pRefPicture->iWidthInPixel;
+      sRefPixMap.sRect.iRectHeight = pRefPicture->iHeightInPixel;
+      sRefPixMap.eFormat = VIDEO_FORMAT_I420;
+    }
 
     iRet = m_pInterfaceVp->Set (iMethodIdx, (void*)sComplexityAnalysisParam);
     iRet = m_pInterfaceVp->Process (iMethodIdx, &sSrcPixMap, &sRefPixMap);
     if (iRet == 0)
       m_pInterfaceVp->Get (iMethodIdx, (void*)sComplexityAnalysisParam);
+
+  } else {
+    SVAAFrameInfo* pVaaInfo	 = pCtx->pVaa;
+    SComplexityAnalysisParam* sComplexityAnalysisParam = & (pVaaInfo->sComplexityAnalysisParam);
+    SWelsSvcRc* SWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId];
+
+    if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) {
+      iComplexityAnalysisMode = FRAME_SAD;
+    } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) {
+      iComplexityAnalysisMode = GOM_SAD;
+    } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) {
+      iComplexityAnalysisMode = GOM_VAR;
+    } else {
+      return;
+    }
+    sComplexityAnalysisParam->iComplexityAnalysisMode = iComplexityAnalysisMode;
+    sComplexityAnalysisParam->pCalcResult = & (pVaaInfo->sVaaCalcInfo);
+    sComplexityAnalysisParam->pBackgroundMbFlag = pVaaInfo->pVaaBackgroundMbFlag;
+    SetRefMbType (pCtx, & (sComplexityAnalysisParam->uiRefMbType), pRefPicture->iPictureType);
+    sComplexityAnalysisParam->iCalcBgd = bCalculateBGD;
+    sComplexityAnalysisParam->iFrameComplexity = 0;
+
+    memset (SWelsSvcRc->pGomForegroundBlockNum, 0, SWelsSvcRc->iGomSize * sizeof (int32_t));
+    if (iComplexityAnalysisMode != FRAME_SAD)
+      memset (SWelsSvcRc->pCurrentFrameGomSad, 0, SWelsSvcRc->iGomSize * sizeof (int32_t));
+
+    sComplexityAnalysisParam->pGomComplexity = SWelsSvcRc->pCurrentFrameGomSad;
+    sComplexityAnalysisParam->pGomForegroundBlockNum = SWelsSvcRc->pGomForegroundBlockNum;
+    sComplexityAnalysisParam->iMbNumInGom = SWelsSvcRc->iNumberMbGom;
+
+    {
+      int32_t iMethodIdx = METHOD_COMPLEXITY_ANALYSIS;
+      SPixMap sSrcPixMap;
+      SPixMap sRefPixMap;
+      memset (&sSrcPixMap, 0, sizeof (SPixMap));
+      memset (&sRefPixMap, 0, sizeof (SPixMap));
+      int32_t iRet = 0;
+
+      sSrcPixMap.pPixel[0] = pCurPicture->pData[0];
+      sSrcPixMap.iSizeInBits = g_kiPixMapSizeInBits;
+      sSrcPixMap.iStride[0] = pCurPicture->iLineSize[0];
+      sSrcPixMap.sRect.iRectWidth = pCurPicture->iWidthInPixel;
+      sSrcPixMap.sRect.iRectHeight = pCurPicture->iHeightInPixel;
+      sSrcPixMap.eFormat = VIDEO_FORMAT_I420;
+
+      sRefPixMap.pPixel[0] = pRefPicture->pData[0];
+      sRefPixMap.iSizeInBits = g_kiPixMapSizeInBits;
+      sRefPixMap.iStride[0] = pRefPicture->iLineSize[0];
+      sRefPixMap.sRect.iRectWidth = pRefPicture->iWidthInPixel;
+      sRefPixMap.sRect.iRectHeight = pRefPicture->iHeightInPixel;
+      sRefPixMap.eFormat = VIDEO_FORMAT_I420;
+
+      iRet = m_pInterfaceVp->Set (iMethodIdx, (void*)sComplexityAnalysisParam);
+      iRet = m_pInterfaceVp->Process (iMethodIdx, &sSrcPixMap, &sRefPixMap);
+      if (iRet == 0)
+        m_pInterfaceVp->Get (iMethodIdx, (void*)sComplexityAnalysisParam);
+    }
   }
 }
 
@@ -1007,12 +1057,11 @@
   return static_cast<ESceneChangeIdc> (iVaaFrameSceneChangeIdc);
 }
 
-int32_t CWelsPreProcess::GetRefCandidateLtrIndex(int32_t iRefIdx)
-{
+int32_t CWelsPreProcess::GetRefCandidateLtrIndex (int32_t iRefIdx) {
   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;
+  SRefInfoParam* BestRefCandidateParam = & (pVaaExt->sVaaStrBestRefCandidate[iRefIdx]);
+  int32_t iLtrRefIdx = m_pSpatialPic[iTargetDid][BestRefCandidateParam->iSrcListIdx]->iLongTermPicNum;
   return iLtrRefIdx;
 }
 void  CWelsPreProcess::Padding (uint8_t* pSrcY, uint8_t* pSrcU, uint8_t* pSrcV, int32_t iStrideY, int32_t iStrideUV,