shithub: openh264

Download patch

ref: dd93aa90b2b719aa2413cb5d7a7af2fc79cb591a
parent: e79769fb881f399e171a7d0121a8868576b02d77
parent: bb58c5c720cd9737078ed6aeae93c2c5c532e787
author: ruil2 <ruil2@cisco.com>
date: Wed Feb 19 05:18:56 EST 2014

Merge pull request #290 from volvet/develop_b

Refactor CWelsPreProcess

--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -190,14 +190,8 @@
   int32_t						iFrameBsSize;	// count size of frame bs in bytes allocated
   int32_t						iPosBsBuffer;	// current writing position of frame bs pBuffer
 
-  /* For Downsampling & VAA I420 based source pictures */
-  SPicture*					pSpatialPic[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1 +
-      LONG_TERM_REF_NUM];	// need memory requirement with total number of (log2(uiGopSize)+1+1+long_term_ref_num)
-
   SSpatialPicIndex			sSpatialIndexMap[MAX_DEPENDENCY_LAYER];
-  uint8_t						uiSpatialLayersInTemporal[MAX_DEPENDENCY_LAYER];
 
-  uint8_t                     uiSpatialPicNum[MAX_DEPENDENCY_LAYER];
   bool						bLongTermRefFlag[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1/*+LONG_TERM_REF_NUM*/];
 
   int16_t						iMaxSliceCount;// maximal count number of slices for all layers observation
--- a/codec/encoder/core/inc/wels_preprocess.h
+++ b/codec/encoder/core/inc/wels_preprocess.h
@@ -108,8 +108,11 @@
 
  public:
   int32_t WelsPreprocessReset (sWelsEncCtx* pEncCtx);
+  int32_t AllocSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam);
+  void    FreeSpatialPictures (sWelsEncCtx* pCtx);
   int32_t BuildSpatialPicList (sWelsEncCtx* pEncCtx, const SSourcePicture** kppSrcPicList, const int32_t kiConfiguredLayerNum);
   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);
 
  private:
   int32_t WelsPreprocessCreate();
@@ -148,6 +151,11 @@
   sWelsEncCtx*     m_pEncCtx;
   bool             m_bInitDone;
   bool             m_bOfficialBranch;
+  /* For Downsampling & VAA I420 based source pictures */
+  SPicture*        m_pSpatialPic[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1 +
+      LONG_TERM_REF_NUM];	// need memory requirement with total number of (log2(uiGopSize)+1+1+long_term_ref_num)
+  uint8_t          m_uiSpatialLayersInTemporal[MAX_DEPENDENCY_LAYER];
+  uint8_t          m_uiSpatialPicNum[MAX_DEPENDENCY_LAYER];
 };
 
 }
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -564,63 +564,12 @@
 #endif//!MT_ENABLED
 
   if (NULL != pCountLayers)
-    *pCountLayers	= iCountNumLayers;
+    *pCountLayers = iCountNumLayers;
   if (NULL != pCountNals)
-    *pCountNals 	= iCountNumNals;
+    *pCountNals	= iCountNumNals;
   return 0;
 }
 
-/*!
- * \brief	alloc spatial layers pictures (I420 based source pictures)
- */
-int32_t AllocSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam) {
-  CMemoryAlign* pMa						= pCtx->pMemAlign;
-  const int32_t kiDlayerCount					= pParam->iSpatialLayerNum;
-  int32_t iDlayerIndex							= 0;
-
-  // spatial pictures
-  iDlayerIndex = 0;
-  do {
-    const int32_t kiPicWidth = pParam->sDependencyLayers[iDlayerIndex].iFrameWidth;
-    const int32_t kiPicHeight   = pParam->sDependencyLayers[iDlayerIndex].iFrameHeight;
-    const uint8_t kuiLayerInTemporal = 2 + WELS_MAX (pParam->sDependencyLayers[iDlayerIndex].iHighestTemporalId, 1);
-    const uint8_t kuiRefNumInTemporal = kuiLayerInTemporal + pParam->iLTRRefNum;
-    uint8_t i = 0;
-
-    do {
-      SPicture* pPic = AllocPicture (pMa, kiPicWidth, kiPicHeight, false);
-      WELS_VERIFY_RETURN_IF(1, (NULL == pPic))
-      pCtx->pSpatialPic[iDlayerIndex][i] = pPic;
-      ++ i;
-    } while (i < kuiRefNumInTemporal);
-
-    pCtx->uiSpatialLayersInTemporal[iDlayerIndex] = kuiLayerInTemporal;
-    pCtx->uiSpatialPicNum[iDlayerIndex] = kuiRefNumInTemporal;
-    ++ iDlayerIndex;
-  } while (iDlayerIndex < kiDlayerCount);
-
-  return 0;
-}
-
-void FreeSpatialPictures (sWelsEncCtx* pCtx) {
-  CMemoryAlign* pMa	= pCtx->pMemAlign;
-  int32_t j = 0;
-  while (j < pCtx->pSvcParam->iSpatialLayerNum) {
-    uint8_t i = 0;
-    uint8_t uiRefNumInTemporal = pCtx->uiSpatialPicNum[j];
-
-    while (i < uiRefNumInTemporal) {
-      if (NULL != pCtx->pSpatialPic[j][i]) {
-        FreePicture (pMa, &pCtx->pSpatialPic[j][i]);
-      }
-      ++ i;
-    }
-    pCtx->uiSpatialLayersInTemporal[j]	= 0;
-    ++ j;
-  }
-
-}
-
 static  void  InitMbInfo (sWelsEncCtx* pEnc, SMB*   pList, SDqLayer* pLayer, const int32_t kiDlayerId,
                           const int32_t kiMaxMbNum) {
   int32_t  iMbWidth		= pLayer->iMbWidth;
@@ -846,12 +795,6 @@
     ++ iDlayerIndex;
   }
 
-  // for I420 based source spatial pictures
-  if (AllocSpatialPictures (*ppCtx, pParam)) {
-    FreeMemorySvc (ppCtx);
-    return 1;
-  }
-
   iDlayerIndex	= 0;
   while (iDlayerIndex < iDlayerCount) {
     SDqLayer* pDqLayer		= NULL;
@@ -1703,8 +1646,6 @@
       pMa->WelsFree (pCtx->ppDqLayerList, "ppDqLayerList");
       pCtx->ppDqLayerList = NULL;
     }
-    FreeSpatialPictures (pCtx);
-
     // reference picture list extension
     if (NULL != pCtx->ppRefPicListExt && pParam != NULL) {
       ilayer = 0;
@@ -2126,10 +2067,16 @@
 
   pCtx->pVpp = new CWelsPreProcess (pCtx);
   if (pCtx->pVpp == NULL) {
+    iRet = 1;
     WelsLog (pCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), pOut of memory in case new CWelsPreProcess().\n");
     FreeMemorySvc (&pCtx);
     return iRet;
   }
+  if( (iRet = pCtx->pVpp->AllocSpatialPictures(pCtx, pCtx->pSvcParam)) != 0 ){
+    WelsLog( pCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), pVPP alloc spatial pictures failed\n");
+    FreeMemorySvc(&pCtx);
+    return iRet;
+  }
 
 #if defined(MEMORY_MONITOR)
   WelsLog (pCtx, WELS_LOG_INFO, "WelsInitEncoderExt() exit, overall memory usage: %llu bytes\n",
@@ -2286,6 +2233,7 @@
 #endif//MT_ENABLED
 
   if ((*ppCtx)->pVpp) {
+    (*ppCtx)->pVpp->FreeSpatialPictures(*ppCtx);
     delete (*ppCtx)->pVpp;
     (*ppCtx)->pVpp = NULL;
   }
@@ -3747,23 +3695,9 @@
       pCtx->bLongTermRefFlag[d_idx][0] = true;
     }
 
-    if (iCurTid < pCtx->uiSpatialLayersInTemporal[d_idx] - 1 || pSvcParam->iDecompStages == 0) {
-      if ((iCurTid >= MAX_TEMPORAL_LEVEL) || (pCtx->uiSpatialLayersInTemporal[d_idx] - 1 > MAX_TEMPORAL_LEVEL)) {
-        ForceCodingIDR (pCtx);	// some logic error
-        return -1;
-      }
-
-      if (pSvcParam->bEnableLongTermReference && pCtx->bLongTermRefFlag[d_idx][iCurTid]) {
-        SPicture* tmp	= pCtx->pSpatialPic[d_idx][pCtx->uiSpatialLayersInTemporal[d_idx] + pCtx->pVaa->uiMarkLongTermPicIdx];
-        pCtx->pSpatialPic[d_idx][pCtx->uiSpatialLayersInTemporal[d_idx] + pCtx->pVaa->uiMarkLongTermPicIdx] =
-          pCtx->pSpatialPic[d_idx][iCurTid];
-        pCtx->pSpatialPic[d_idx][iCurTid] = pCtx->pSpatialPic[d_idx][pCtx->uiSpatialLayersInTemporal[d_idx] - 1];
-        pCtx->pSpatialPic[d_idx][pCtx->uiSpatialLayersInTemporal[d_idx] - 1] = tmp;
-        pCtx->bLongTermRefFlag[d_idx][iCurTid] = false;
-      } else {
-        WelsExchangeSpatialPictures (&pCtx->pSpatialPic[d_idx][pCtx->uiSpatialLayersInTemporal[d_idx] - 1],
-                                     &pCtx->pSpatialPic[d_idx][iCurTid]);
-      }
+    if( pCtx->pVpp->UpdateSpatialPictures(pCtx, pSvcParam, iCurTid, d_idx) != 0 ){
+      ForceCodingIDR(pCtx);
+      return -1;
     }
 
     if (pSvcParam->bEnableLongTermReference && ((pCtx->pLtr[pCtx->uiDependencyId].bLTRMarkingFlag
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -212,6 +212,9 @@
   m_bOfficialBranch  = false;
   m_pEncCtx = pEncCtx;
   memset (&m_sScaledPicture, 0, sizeof (m_sScaledPicture));
+  memset (m_pSpatialPic, 0, sizeof(m_pSpatialPic));
+  memset (m_uiSpatialLayersInTemporal, 0, sizeof(m_uiSpatialLayersInTemporal));
+  memset (m_uiSpatialPicNum, 0, sizeof(m_uiSpatialPicNum));
 }
 
 CWelsPreProcess::~CWelsPreProcess() {
@@ -260,6 +263,53 @@
   return iRet;
 }
 
+int32_t CWelsPreProcess::AllocSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam) {
+  CMemoryAlign* pMa						= pCtx->pMemAlign;
+  const int32_t kiDlayerCount					= pParam->iSpatialLayerNum;
+  int32_t iDlayerIndex							= 0;
+
+  // spatial pictures
+  iDlayerIndex = 0;
+  do {
+    const int32_t kiPicWidth = pParam->sDependencyLayers[iDlayerIndex].iFrameWidth;
+    const int32_t kiPicHeight   = pParam->sDependencyLayers[iDlayerIndex].iFrameHeight;
+    const uint8_t kuiLayerInTemporal = 2 + WELS_MAX (pParam->sDependencyLayers[iDlayerIndex].iHighestTemporalId, 1);
+    const uint8_t kuiRefNumInTemporal = kuiLayerInTemporal + pParam->iLTRRefNum;
+    uint8_t i = 0;
+
+    do {
+      SPicture* pPic = AllocPicture (pMa, kiPicWidth, kiPicHeight, false);
+      WELS_VERIFY_RETURN_IF(1, (NULL == pPic))
+      m_pSpatialPic[iDlayerIndex][i] = pPic;
+      ++ i;
+    } while (i < kuiRefNumInTemporal);
+
+    m_uiSpatialLayersInTemporal[iDlayerIndex] = kuiLayerInTemporal;
+    m_uiSpatialPicNum[iDlayerIndex] = kuiRefNumInTemporal;
+    ++ iDlayerIndex;
+  } while (iDlayerIndex < kiDlayerCount);
+
+  return 0;
+}
+
+void CWelsPreProcess::FreeSpatialPictures (sWelsEncCtx* pCtx) {
+  CMemoryAlign* pMa	= pCtx->pMemAlign;
+  int32_t j = 0;
+  while (j < pCtx->pSvcParam->iSpatialLayerNum) {
+    uint8_t i = 0;
+    uint8_t uiRefNumInTemporal = m_uiSpatialPicNum[j];
+
+    while (i < uiRefNumInTemporal) {
+      if (NULL != m_pSpatialPic[j][i]) {
+        FreePicture (pMa, &m_pSpatialPic[j][i]);
+      }
+      ++ i;
+    }
+    m_uiSpatialLayersInTemporal[j] = 0;
+    ++ j;
+  }
+}
+
 int32_t CWelsPreProcess::BuildSpatialPicList (sWelsEncCtx* pCtx, const SSourcePicture** kppSrcPicList,
     const int32_t kiConfiguredLayerNum) {
   SWelsSvcCodingParam* pSvcParam = pCtx->pSvcParam;
@@ -314,15 +364,15 @@
   bool bNeededMbAq = (pSvcParam->bEnableAdaptiveQuant && (pCtx->eSliceType == P_SLICE));
   bool bCalculateBGD = (pCtx->eSliceType == P_SLICE && pSvcParam->bEnableBackgroundDetection);
 
-  int32_t iCurTemporalIdx  = pCtx->uiSpatialLayersInTemporal[kiDidx] - 1;
+  int32_t iCurTemporalIdx  = m_uiSpatialLayersInTemporal[kiDidx] - 1;
 
   int32_t iRefTemporalIdx = (int32_t)g_kuiRefTemporalIdx[pSvcParam->iDecompStages][pCtx->iCodingIndex &
                             (pSvcParam->uiGopSize - 1)];
   if (pCtx->uiTemporalId == 0 && pCtx->pLtr[pCtx->uiDependencyId].bReceivedT0LostFlag)
-    iRefTemporalIdx = pCtx->uiSpatialLayersInTemporal[kiDidx] + pCtx->pVaa->uiValidLongTermPicIdx;
+    iRefTemporalIdx = m_uiSpatialLayersInTemporal[kiDidx] + pCtx->pVaa->uiValidLongTermPicIdx;
 
-  SPicture* pCurPic = pCtx->pSpatialPic[kiDidx][iCurTemporalIdx];
-  SPicture* pRefPic = pCtx->pSpatialPic[kiDidx][iRefTemporalIdx];
+  SPicture* pCurPic = m_pSpatialPic[kiDidx][iCurTemporalIdx];
+  SPicture* pRefPic = m_pSpatialPic[kiDidx][iRefTemporalIdx];
   {
     SPicture* pLastPic = m_pLastSpatialPicture[kiDidx][0];
     bool bCalculateSQDiff = ((pLastPic->pData[0] == pRefPic->pData[0]) && bNeededMbAq);
@@ -351,7 +401,28 @@
   return 0;
 }
 
+int32_t CWelsPreProcess::UpdateSpatialPictures(sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam,
+    const int8_t iCurTid, const int32_t d_idx) {
+  if (iCurTid < m_uiSpatialLayersInTemporal[d_idx] - 1 || pParam->iDecompStages == 0){
+    if ((iCurTid >= MAX_TEMPORAL_LEVEL) || (m_uiSpatialLayersInTemporal[d_idx] - 1 > MAX_TEMPORAL_LEVEL)) {
+      return 1;
+    }
+    if (pParam->bEnableLongTermReference && pCtx->bLongTermRefFlag[d_idx][iCurTid]) {
+      SPicture* tmp	= m_pSpatialPic[d_idx][m_uiSpatialLayersInTemporal[d_idx] + pCtx->pVaa->uiMarkLongTermPicIdx];
+      m_pSpatialPic[d_idx][m_uiSpatialLayersInTemporal[d_idx] + pCtx->pVaa->uiMarkLongTermPicIdx] =
+      m_pSpatialPic[d_idx][iCurTid];
+      m_pSpatialPic[d_idx][iCurTid] = m_pSpatialPic[d_idx][m_uiSpatialLayersInTemporal[d_idx] - 1];
+      m_pSpatialPic[d_idx][m_uiSpatialLayersInTemporal[d_idx] - 1] = tmp;
+      pCtx->bLongTermRefFlag[d_idx][iCurTid] = false;
+    } else {
+      WelsExchangeSpatialPictures (&m_pSpatialPic[d_idx][m_uiSpatialLayersInTemporal[d_idx] - 1],
+                                   &m_pSpatialPic[d_idx][iCurTid]);
+    }
+  }
+  return 0;
+}
 
+
 /*
 *	SingleLayerPreprocess: down sampling if applicable
 *  @return:	exact number of spatial layers need to encoder indeed
@@ -359,8 +430,8 @@
 int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc,
     Scaled_Picture* pScaledPicture) {
   SWelsSvcCodingParam* pSvcParam    = pCtx->pSvcParam;
-  int8_t	iDependencyId			= pSvcParam->iSpatialLayerNum - 1;
-  int32_t iPicturePos	                    = pCtx->uiSpatialLayersInTemporal[iDependencyId] - 1;
+  int8_t  iDependencyId             = pSvcParam->iSpatialLayerNum - 1;
+  int32_t iPicturePos               = m_uiSpatialLayersInTemporal[iDependencyId] - 1;
 
   SPicture* pSrcPic					= NULL;	// large
   SPicture* pDstPic					= NULL;	// small
@@ -381,7 +452,7 @@
   iSrcHeight  = pSvcParam->SUsedPicRect.iHeight;
 
   pSrcPic = pScaledPicture->pScaledInputPicture ? pScaledPicture->pScaledInputPicture :
-            pCtx->pSpatialPic[iDependencyId][iPicturePos];
+            m_pSpatialPic[iDependencyId][iPicturePos];
 
   WelsMoveMemoryWrapper (pSvcParam, pSrcPic, kpSrc, iSrcWidth, iSrcHeight);
 
@@ -394,7 +465,7 @@
   pDstPic = pSrcPic;
   if (pScaledPicture->pScaledInputPicture) {
     // for highest downsampling
-    pDstPic		= pCtx->pSpatialPic[iDependencyId][iPicturePos];
+    pDstPic		= m_pSpatialPic[iDependencyId][iPicturePos];
     iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];
     iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];
   }
@@ -404,7 +475,7 @@
       && !pCtx->bEncCurFrmAsIdrFlag
       && ! (pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1))) {
     SPicture* pRefPic = pCtx->pLtr[iDependencyId].bReceivedT0LostFlag ?
-                        pCtx->pSpatialPic[iDependencyId][pCtx->uiSpatialLayersInTemporal[iDependencyId] +
+                        m_pSpatialPic[iDependencyId][m_uiSpatialLayersInTemporal[iDependencyId] +
                             pCtx->pVaa->uiValidLongTermPicIdx] : m_pLastSpatialPicture[iDependencyId][0];
 
     pCtx->pVaa->bSceneChangeFlag = DetectSceneChange (pDstPic, pRefPic);
@@ -423,7 +494,7 @@
     -- iActualSpatialLayerNum;
   }
 
-  m_pLastSpatialPicture[iDependencyId][1]	= pCtx->pSpatialPic[iDependencyId][iPicturePos];
+  m_pLastSpatialPicture[iDependencyId][1]	= m_pSpatialPic[iDependencyId][iPicturePos];
   -- iDependencyId;
 
   // generate other spacial layer
@@ -436,7 +507,7 @@
       iTargetWidth	= pDlayerParam->iFrameWidth;
       iTargetHeight	= pDlayerParam->iFrameHeight;
       iTemporalId = pDlayerParam->uiCodingIdx2TemporalId[pCtx->iCodingIndex & (pSvcParam->uiGopSize - 1)];
-      iPicturePos		= pCtx->uiSpatialLayersInTemporal[iDependencyId] - 1;
+      iPicturePos		= m_uiSpatialLayersInTemporal[iDependencyId] - 1;
 
       // NOT work for CGS, FIXME
       // spatial layer is able to encode indeed
@@ -443,7 +514,7 @@
       if ((iTemporalId != INVALID_TEMPORAL_ID)) {
         // down sampling performed
 
-        pDstPic	= pCtx->pSpatialPic[iDependencyId][iPicturePos];	// small
+        pDstPic	= m_pSpatialPic[iDependencyId][iPicturePos];	// small
         iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];
         iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];
         DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight);
@@ -453,7 +524,7 @@
         -- iActualSpatialLayerNum;
         ++ iSpatialNum;
 
-        m_pLastSpatialPicture[iDependencyId][1]	= pCtx->pSpatialPic[iDependencyId][iPicturePos];
+        m_pLastSpatialPicture[iDependencyId][1]	= m_pSpatialPic[iDependencyId][iPicturePos];
       }
       -- iDependencyId;
     }
@@ -485,7 +556,7 @@
     } while (j < iSpatialLayersCfgCount);
 
     assert (j < iSpatialLayersCfgCount);
-    pDstPic = pCtx->pSpatialPic[j][pCtx->uiSpatialLayersInTemporal[j] - 1];
+    pDstPic = m_pSpatialPic[j][m_uiSpatialLayersInTemporal[j] - 1];
 
     WelsUpdateSpatialIdxMap (pCtx, i, pDstPic, j);
 
@@ -501,7 +572,7 @@
   if (pSvcParam->bEnableSceneChangeDetect && (kiSpatialNum == pSvcParam->iSpatialLayerNum)
       && !pCtx->pVaa->bIdrPeriodFlag && !pCtx->bEncCurFrmAsIdrFlag) {
     SPicture* pRef = pCtx->pLtr[0].bReceivedT0LostFlag ?
-                     pCtx->pSpatialPic[0][pCtx->uiSpatialLayersInTemporal[0] + pCtx->pVaa->uiValidLongTermPicIdx] :
+                     m_pSpatialPic[0][m_uiSpatialLayersInTemporal[0] + pCtx->pVaa->uiValidLongTermPicIdx] :
                      m_pLastSpatialPicture[0][0];
 
     pCtx->pVaa->bSceneChangeFlag = DetectSceneChange (pDstPic, pRef);
@@ -570,8 +641,8 @@
   int32_t iDlayerIndex					= 0;
 
   for (; iDlayerIndex < kiDlayerCount; iDlayerIndex++) {
-    const int32_t kiLayerInTemporal = pCtx->uiSpatialLayersInTemporal[iDlayerIndex];
-    m_pLastSpatialPicture[iDlayerIndex][0]	= pCtx->pSpatialPic[iDlayerIndex][kiLayerInTemporal - 2];
+    const int32_t kiLayerInTemporal = m_uiSpatialLayersInTemporal[iDlayerIndex];
+    m_pLastSpatialPicture[iDlayerIndex][0]	= m_pSpatialPic[iDlayerIndex][kiLayerInTemporal - 2];
     m_pLastSpatialPicture[iDlayerIndex][1]	= NULL;
   }
   for (; iDlayerIndex < MAX_DEPENDENCY_LAYER; iDlayerIndex++) {