shithub: openh264

Download patch

ref: 7a3b3fdbe7aa6c0119268205eaafd63a082299e4
parent: 25f53a2e3dd3cc978b9bf76fc14467e802c3ebf1
parent: f84f2315abba08e99875853ce12d9159c5e0d415
author: HaiboZhu <haibozhu@cisco.com>
date: Wed Mar 16 05:48:08 EDT 2016

Merge pull request #2403 from ruil2/downsampling1

change downsampling logic 

--- a/codec/encoder/core/inc/wels_preprocess.h
+++ b/codec/encoder/core/inc/wels_preprocess.h
@@ -140,7 +140,6 @@
                       const uint32_t kuiShortRefCount);
   void UpdateSrcListLosslessScreenRefSelectionWithLtr (SPicture* pCurPicture, const int32_t kiCurDid,
       const int32_t kuiMarkLongTermPicIdx, SPicture** pLongRefList);
-  bool BuildSpatialLayer(sWelsEncCtx* pCtx, const SSourcePicture* kpSrc,int32_t iSpatialLayer);
  private:
   int32_t WelsPreprocessCreate();
   int32_t WelsPreprocessDestroy();
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -3743,7 +3743,7 @@
   EWelsNalUnitType eNalType     = NAL_UNIT_UNSPEC_0;
   EWelsNalRefIdc eNalRefIdc     = NRI_PRI_LOWEST;
   int8_t iCurDid                = 0;
-  int8_t iCurTid                = 0;
+  int32_t iCurTid                = 0;
   bool bAvcBased                = false;
   SLogContext* pLogCtx = & (pCtx->sLogCtx);
   bool bFinishedWriteHeader = false;
@@ -3792,12 +3792,7 @@
   pCtx->pCurDqLayer             = pCtx->ppDqLayerList[pSpatialIndexMap->iDid];
   pCtx->pCurDqLayer->pRefLayer  = NULL;
 
-  while (iSpatialIdx < iSpatialNum) {
-    bool bEncoding = pCtx->pVpp->BuildSpatialLayer (pCtx, pSrcPic, iSpatialIdx);
-    if (!bEncoding) {
-      ++iSpatialIdx;
-      continue;
-    }
+  while (iSpatialIdx < pSvcParam->iSpatialLayerNum) {
     const int32_t iDidIdx  = (pSpatialIndexMap + iSpatialIdx)->iDid;
     SSpatialLayerConfig* pParam = &pSvcParam->sSpatialLayers[iDidIdx];
     SSpatialLayerInternal* pParamInternal = &pSvcParam->sDependencyLayers[iDidIdx];
@@ -3804,7 +3799,11 @@
     int32_t  iDecompositionStages = pSvcParam->sDependencyLayers[iDidIdx].iDecompositionStages;
     pCtx->pCurDqLayer           = pCtx->ppDqLayerList[iDidIdx];
     pCtx->uiDependencyId        = iCurDid = (int8_t)iDidIdx;
-
+    //skip this spatial layer
+    if(GetTemporalLevel (pParamInternal, pParamInternal->iCodingIndex,pSvcParam->uiGopSize) == INVALID_TEMPORAL_ID){
+      ++iSpatialIdx;
+      continue;
+    }
     eFrameType = DecideFrameType (pCtx, iSpatialNum, iDidIdx);
     if (eFrameType == videoFrameTypeSkip) {
       eFrameType = videoFrameTypeSkip;
@@ -3847,11 +3846,10 @@
       }
     }
     pCtx->iContinualSkipFrames = 0;
-
-    InitFrameCoding (pCtx, eFrameType, iDidIdx);
-    iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iSpatialIdx], pParamInternal->iCodingIndex,
-                                pSvcParam->uiGopSize);
+    iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[iDidIdx], pParamInternal->iCodingIndex,
+                                  pSvcParam->uiGopSize);
     pCtx->uiTemporalId = iCurTid;
+    InitFrameCoding (pCtx, eFrameType, iDidIdx);
 
     if (eFrameType == videoFrameTypeIDR) {
       // write parameter sets bitstream or SEI/SSEI (if any) here
@@ -4433,9 +4431,9 @@
            pFbi->iSubSeqId, iFrameSize);
   for (int32_t i = 0; i < iLayerNum; i++)
     WelsLog (pLogCtx, WELS_LOG_DEBUG,
-             "WelsEncoderEncodeExt() OutputInfo iLayerId = %d,iNalType = %d,iNalCount = %d, first Nal Length=%d,uiSpatialId = %d", i,
+             "WelsEncoderEncodeExt() OutputInfo iLayerId = %d,iNalType = %d,iNalCount = %d, first Nal Length=%d,uiSpatialId = %d,uiTemporalId = %d", i,
              pFbi->sLayerInfo[i].uiLayerType, pFbi->sLayerInfo[i].iNalCount, pFbi->sLayerInfo[i].pNalLengthInByte[0],
-             pFbi->sLayerInfo[i].uiSpatialId);
+             pFbi->sLayerInfo[i].uiSpatialId,pFbi->sLayerInfo[i].uiTemporalId);
   WelsEmms();
 
   pLayerBsInfo->eFrameType = eFrameType;
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -252,10 +252,6 @@
     if (bNeededMbAq) {
       SPicture* pCurPic = m_pLastSpatialPicture[kiDidx][1];
       SPicture* pRefPic = m_pLastSpatialPicture[kiDidx][0];
-      //printf("pCurPicDid = %d,pCurPicTid = %d,pRefPicDid = %d,pRefPicTid = %d,kiDidx = %d,pCurPic = %x,pRefPic = %x,bbCurPic = %x\n",
-      //         pCurPic->uiSpatialId,pCurPic->uiTemporalId,pCurPic->uiSpatialId,pCurPic->uiTemporalId,kiDidx,pCurPic,pRefPic,m_pSpatialPic[kiDidx][iCurTemporalIdx]);
-
-
       AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);
     }
   }
@@ -295,46 +291,9 @@
 
 
 /*
-*   SingleLayerPreprocess: down sampling if applicable
-*  @return: exact number of spatial layers need to encoder indeed
-*/
-bool CWelsPreProcess::BuildSpatialLayer (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc, int32_t iDependencyId) {
-  SWelsSvcCodingParam* pSvcParam    = pCtx->pSvcParam;
-  int32_t iMaxDid = pSvcParam->iSpatialLayerNum - 1;
-  SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];
-  SSpatialLayerConfig* pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];
-  SSpatialLayerInternal* pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];
-  int32_t iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &
-                        (pSvcParam->uiGopSize - 1)];
-
-
-  if (iTemporalId != INVALID_TEMPORAL_ID) {
-    if (iDependencyId == iMaxDid) {
-      return true;
-    } else {
-      int32_t iPicturePos               = m_uiSpatialLayersInTemporal[iDependencyId] - 1;
-      Scaled_Picture*  pScaledPicture = &m_sScaledPicture;
-
-      int32_t iTargetWidth              = pDlayerParam->iVideoWidth;
-      int32_t iTargetHeight             = pDlayerParam->iVideoHeight;
-
-      SPicture* pSrcPic                 = (pSpatialIndexMap + iMaxDid)->pSrc;; // large
-      SPicture* pDstPic                 = m_pSpatialPic[iDependencyId][iPicturePos]; // small
-
-      int32_t iSrcWidth                 = pSrcPic->iWidthInPixel;
-      int32_t iSrcHeight                = pSrcPic->iHeightInPixel;
-      int32_t iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];
-      int32_t iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];
-      DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,
-                         true);
-      WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);
-      m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
-      return true;
-    }
-  }
-  return false;
-}
-
+ *   SingleLayerPreprocess: down sampling if applicable
+ *  @return: exact number of spatial layers need to encoder indeed
+ */
 int32_t CWelsPreProcess::SingleLayerPreprocess (sWelsEncCtx* pCtx, const SSourcePicture* kpSrc,
     Scaled_Picture* pScaledPicture) {
   SWelsSvcCodingParam* pSvcParam    = pCtx->pSvcParam;
@@ -351,7 +310,8 @@
   int32_t iTargetWidth              = 0;
   int32_t iTargetHeight             = 0;
   int32_t iTemporalId = 0;
-
+  SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];
+  int32_t iClosestDid =  iDependencyId;
   pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];
   pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];
   iTargetWidth   = pDlayerParam->iVideoWidth;
@@ -360,13 +320,12 @@
                    (pSvcParam->uiGopSize - 1)];
   iSrcWidth   = pSvcParam->SUsedPicRect.iWidth;
   iSrcHeight  = pSvcParam->SUsedPicRect.iHeight;
-
   if (pSvcParam->uiIntraPeriod)
     pCtx->pVaa->bIdrPeriodFlag = (1 + pDlayerParamInternal->iFrameIndex >= (int32_t)pSvcParam->uiIntraPeriod) ? true :
-                                 false;
-
+        false;
   pSrcPic = pScaledPicture->pScaledInputPicture ? pScaledPicture->pScaledInputPicture :
             m_pSpatialPic[iDependencyId][iPicturePos];
+
   WelsMoveMemoryWrapper (pSvcParam, pSrcPic, kpSrc, iSrcWidth, iSrcHeight);
 
   if (pSvcParam->bEnableDenoise)
@@ -384,6 +343,7 @@
   }
   DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,
                      false);
+
   if (pSvcParam->bEnableSceneChangeDetect && !pCtx->pVaa->bIdrPeriodFlag) {
     if (pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
       pCtx->pVaa->eSceneChangeIdc = (pDlayerParamInternal->bEncCurFrmAsIdrFlag ? LARGE_CHANGED_SCENE :
@@ -401,29 +361,54 @@
       }
     }
   }
-
-  WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);
-  m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
-
   if (iTemporalId != INVALID_TEMPORAL_ID) {
     ++ iSpatialNum;
   }
+
+  WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);
+  m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
   -- iDependencyId;
+
+  // generate other spacial layer
+  // pSrc is
+  //    -- padded input pic, if downsample should be applied to generate highest layer, [if] block above
+  //    -- highest layer, if no downsampling, [else] block above
   if (pSvcParam->iSpatialLayerNum > 1) {
     while (iDependencyId >= 0) {
       pDlayerParamInternal = &pSvcParam->sDependencyLayers[iDependencyId];
+      pDlayerParam = &pSvcParam->sSpatialLayers[iDependencyId];
+      SPicture* pSrcPic  = (pSpatialIndexMap + iClosestDid)->pSrc;; // large
+      //SPicture* pSrcPic  = (pSpatialIndexMap + (pSvcParam->iSpatialLayerNum - 1))->pSrc;; // large
+      iTargetWidth  = pDlayerParam->iVideoWidth;
+      iTargetHeight = pDlayerParam->iVideoHeight;
       iTemporalId = pDlayerParamInternal->uiCodingIdx2TemporalId[pDlayerParamInternal->iCodingIndex &
                     (pSvcParam->uiGopSize - 1)];
+      iPicturePos = m_uiSpatialLayersInTemporal[iDependencyId] - 1;
 
-      if ((iTemporalId != INVALID_TEMPORAL_ID)) {
+      // down sampling performed
+      int32_t iSrcWidth                 = pScaledPicture->iScaledWidth[iClosestDid];
+      int32_t iSrcHeight                = pScaledPicture->iScaledHeight[iClosestDid];
+      pDstPic = m_pSpatialPic[iDependencyId][iPicturePos]; // small
+      iShrinkWidth = pScaledPicture->iScaledWidth[iDependencyId];
+      iShrinkHeight = pScaledPicture->iScaledHeight[iDependencyId];
+      DownsamplePadding (pSrcPic, pDstPic, iSrcWidth, iSrcHeight, iShrinkWidth, iShrinkHeight, iTargetWidth, iTargetHeight,
+                         true);
+
+      WelsUpdateSpatialIdxMap (pCtx, iDependencyId, pDstPic, iDependencyId);
+      if ((iTemporalId != INVALID_TEMPORAL_ID))
         ++ iSpatialNum;
-      }
+      m_pLastSpatialPicture[iDependencyId][1] = m_pSpatialPic[iDependencyId][iPicturePos];
+
+      iClosestDid = iDependencyId;
       -- iDependencyId;
+
     }
   }
   return iSpatialNum;
 
 }
+
+
 /*!
  * \brief   Whether input picture need be scaled?
  */
@@ -437,7 +422,6 @@
   int32_t iSpatialIdx = pParam->iSpatialLayerNum - 1;
 
   if (kiDstPicWidth >= kiInputPicWidth && kiDstPicHeight >= kiInputPicHeight) {
-    iSpatialIdx --;  // highest D layer do not need downsampling
     bNeedDownsampling = false;
   }
 
--- a/test/api/decode_api_test.cpp
+++ b/test/api/decode_api_test.cpp
@@ -759,7 +759,7 @@
 const uint32_t kiFrameRate = 12; //DO NOT CHANGE!
 const uint32_t kiFrameNum = 100; //DO NOT CHANGE!
 const char* pHashStr[] = { //DO NOT CHANGE!
-  "585663f78cadb70d9c9f179b9b53b90ffddf3178",
+  "9c4e6146b29bac5d5d4be3c5bbab9c072dcb3f3f",
   "f350001c333902029800bd291fbed915a4bdf19a",
   "eb9d853b7daec03052c4850027ac94adc84c3a7e"
 };
--- a/test/api/encoder_test.cpp
+++ b/test/api/encoder_test.cpp
@@ -131,7 +131,7 @@
   },
   {
     "res/Cisco_Absolute_Power_1280x720_30fps.yuv",
-    "b5f42875a550551d81e460017d2691d3c104cf2f", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_SINGLE_SLICE, false, 4, false, false, false
+    "3943145545a2bd27a642b2045d4e3dbae55c6870", CAMERA_VIDEO_REAL_TIME, 1280, 720, 30.0f, SM_SINGLE_SLICE, false, 4, false, false, false
   },
   // the following values may be adjusted for times since we start tuning the strategy
   {