shithub: openh264

Download patch

ref: 4484df4bbb4561128a3320a1ab329cff20843431
parent: e8b1802b88e35178663ef56baa0bdca0241649b7
parent: 5cd3c5d7cfb59587941454279952f4572e90a7d4
author: guangwei <[email protected]>
date: Mon Apr 17 10:23:27 EDT 2017

Merge pull request #2723 from huili2/parseonly_statistics_add

add parseonly statistics

--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -1022,11 +1022,15 @@
   uint32_t uiHeight = pDecStat->uiHeight;
   int32_t iAvgLumaQp = pDecStat->iAvgLumaQp;
   uint32_t iLogInterval = pDecStat->iStatisticsLogInterval;
+  uint32_t uiProfile = pDecStat->uiProfile;
+  uint32_t uiLevel = pDecStat->uiLevel;
   memset (pDecStat, 0, sizeof (SDecoderStatistics));
   pDecStat->uiWidth = uiWidth;
   pDecStat->uiHeight = uiHeight;
   pDecStat->iAvgLumaQp = iAvgLumaQp;
   pDecStat->iStatisticsLogInterval = iLogInterval;
+  pDecStat->uiProfile = uiProfile;
+  pDecStat->uiLevel = uiLevel;
 }
 
 //update information when freezing occurs, including IDR/non-IDR number
@@ -1049,15 +1053,22 @@
   //update QP info
   int32_t iTotalQp = 0;
   const int32_t kiMbNum = pCurDq->iMbWidth * pCurDq->iMbHeight;
-  int32_t iCorrectMbNum = 0;
-  for (int32_t iMb = 0; iMb < kiMbNum; ++iMb) {
-    iCorrectMbNum += (int32_t) pCurDq->pMbCorrectlyDecodedFlag[iMb];
-    iTotalQp += pCurDq->pLumaQp[iMb] * pCurDq->pMbCorrectlyDecodedFlag[iMb];
+  if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) { //all correct
+    for (int32_t iMb = 0; iMb < kiMbNum; ++iMb) {
+      iTotalQp += pCurDq->pLumaQp[iMb];
+    }
+    iTotalQp /= kiMbNum;
+  } else {
+    int32_t iCorrectMbNum = 0;
+    for (int32_t iMb = 0; iMb < kiMbNum; ++iMb) {
+      iCorrectMbNum += (int32_t) pCurDq->pMbCorrectlyDecodedFlag[iMb];
+      iTotalQp += pCurDq->pLumaQp[iMb] * pCurDq->pMbCorrectlyDecodedFlag[iMb];
+    }
+    if (iCorrectMbNum == 0) //non MB is correct, should remain QP statistic info
+      iTotalQp = pDecStat->iAvgLumaQp;
+    else
+      iTotalQp /= iCorrectMbNum;
   }
-  if (iCorrectMbNum == 0) //non MB is correct, should remain QP statistic info
-    iTotalQp = pDecStat->iAvgLumaQp;
-  else
-    iTotalQp /= iCorrectMbNum;
   if (pDecStat->uiDecodedFrameCount + 1 == 0) { //maximum uint32_t reached
     ResetDecStatNums (pDecStat);
     pDecStat->iAvgLumaQp = iTotalQp;
@@ -1068,7 +1079,8 @@
   //update IDR number
   if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag) {
     pDecStat->uiIDRCorrectNum += (pPic->bIsComplete);
-    pDecStat->uiEcIDRNum += (!pPic->bIsComplete);
+    if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE)
+      pDecStat->uiEcIDRNum += (!pPic->bIsComplete);
   }
 }
 
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -72,6 +72,19 @@
     }
   }
 
+  const int32_t kiActualWidth = kiWidth - (pCtx->sFrameCrop.iLeftOffset + pCtx->sFrameCrop.iRightOffset) * 2;
+  const int32_t kiActualHeight = kiHeight - (pCtx->sFrameCrop.iTopOffset + pCtx->sFrameCrop.iBottomOffset) * 2;
+
+
+  if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) {
+    if ((pCtx->sDecoderStatistics.uiWidth != (unsigned int) kiActualWidth) || (pCtx->sDecoderStatistics.uiHeight != (unsigned int) kiActualHeight)) {
+      pCtx->sDecoderStatistics.uiResolutionChangeTimes++;
+      pCtx->sDecoderStatistics.uiWidth = kiActualWidth;
+      pCtx->sDecoderStatistics.uiHeight = kiActualHeight;
+    }
+    UpdateDecStatNoFreezingInfo (pCtx);
+  }
+
   if (pCtx->pParam->bParseOnly) { //should exit for parse only to prevent access NULL pDstInfo
     PAccessUnit pCurAu = pCtx->pAccessUnitList;
     if (dsErrorFree == pCtx->iErrorCode) { //correct decoding, add to data buffer
@@ -198,8 +211,8 @@
 
   pDstInfo->UsrData.sSystemBuffer.iFormat = videoFormatI420;
 
-  pDstInfo->UsrData.sSystemBuffer.iWidth = kiWidth - (pCtx->sFrameCrop.iLeftOffset + pCtx->sFrameCrop.iRightOffset) * 2;
-  pDstInfo->UsrData.sSystemBuffer.iHeight = kiHeight - (pCtx->sFrameCrop.iTopOffset + pCtx->sFrameCrop.iBottomOffset) * 2;
+  pDstInfo->UsrData.sSystemBuffer.iWidth = kiActualWidth;
+  pDstInfo->UsrData.sSystemBuffer.iHeight = kiActualHeight;
   pDstInfo->UsrData.sSystemBuffer.iStride[0] = pPic->iLinesize[0];
   pDstInfo->UsrData.sSystemBuffer.iStride[1] = pPic->iLinesize[1];
   ppDst[0] = ppDst[0] + pCtx->sFrameCrop.iTopOffset * 2 * pPic->iLinesize[0] + pCtx->sFrameCrop.iLeftOffset * 2;
@@ -235,8 +248,15 @@
   pCtx->iMbEcedNum = pPic->iMbEcedNum;
   pCtx->iMbNum = pPic->iMbNum;
   pCtx->iMbEcedPropNum = pPic->iMbEcedPropNum;
-  UpdateDecStat (pCtx, pDstInfo->iBufferStatus != 0);
-
+  if (pCtx->pParam->eEcActiveIdc != ERROR_CON_DISABLE) {
+    if (pDstInfo->iBufferStatus && ((pCtx->sDecoderStatistics.uiWidth != (unsigned int) kiActualWidth)
+                                    || (pCtx->sDecoderStatistics.uiHeight != (unsigned int) kiActualHeight))) {
+      pCtx->sDecoderStatistics.uiResolutionChangeTimes++;
+      pCtx->sDecoderStatistics.uiWidth = kiActualWidth;
+      pCtx->sDecoderStatistics.uiHeight = kiActualHeight;
+    }
+    UpdateDecStat (pCtx, pDstInfo->iBufferStatus != 0);
+  }
   return ERR_NONE;
 }
 
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -585,14 +585,6 @@
       //TODO after dec status updated
       m_pDecContext->iErrorCode |= dsDataErrorConcealed;
 
-      //
-      if ((m_pDecContext->sDecoderStatistics.uiWidth != (unsigned int) pDstInfo->UsrData.sSystemBuffer.iWidth)
-          || (m_pDecContext->sDecoderStatistics.uiHeight != (unsigned int) pDstInfo->UsrData.sSystemBuffer.iHeight)) {
-        m_pDecContext->sDecoderStatistics.uiResolutionChangeTimes++;
-        m_pDecContext->sDecoderStatistics.uiWidth = pDstInfo->UsrData.sSystemBuffer.iWidth;
-        m_pDecContext->sDecoderStatistics.uiHeight = pDstInfo->UsrData.sSystemBuffer.iHeight;
-
-      }
       m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
       if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
         ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
@@ -626,24 +618,18 @@
       ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
       m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
     }
-
-    if ((m_pDecContext->sDecoderStatistics.uiWidth != (unsigned int) pDstInfo->UsrData.sSystemBuffer.iWidth)
-        || (m_pDecContext->sDecoderStatistics.uiHeight != (unsigned int) pDstInfo->UsrData.sSystemBuffer.iHeight)) {
-      m_pDecContext->sDecoderStatistics.uiResolutionChangeTimes++;
-      m_pDecContext->sDecoderStatistics.uiWidth = pDstInfo->UsrData.sSystemBuffer.iWidth;
-      m_pDecContext->sDecoderStatistics.uiHeight = pDstInfo->UsrData.sSystemBuffer.iHeight;
-    }
   }
   iEnd = WelsTime();
   m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
 
-  OutputStatisticsLog(m_pDecContext->sDecoderStatistics);
+  OutputStatisticsLog (m_pDecContext->sDecoderStatistics);
 
   return dsErrorFree;
 }
 
-void CWelsDecoder::OutputStatisticsLog(SDecoderStatistics& sDecoderStatistics) {
-  if ((sDecoderStatistics.uiDecodedFrameCount > 0) && (sDecoderStatistics.iStatisticsLogInterval > 0) && ((sDecoderStatistics.uiDecodedFrameCount % sDecoderStatistics.iStatisticsLogInterval) == 0)) {
+void CWelsDecoder::OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics) {
+  if ((sDecoderStatistics.uiDecodedFrameCount > 0) && (sDecoderStatistics.iStatisticsLogInterval > 0)
+      && ((sDecoderStatistics.uiDecodedFrameCount % sDecoderStatistics.iStatisticsLogInterval) == 0)) {
     WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
              "uiWidth=%d, uiHeight=%d, fAverageFrameSpeedInMs=%.1f, fActualAverageFrameSpeedInMs=%.1f, \
               uiDecodedFrameCount=%d, uiResolutionChangeTimes=%d, uiIDRCorrectNum=%d, \
@@ -652,37 +638,37 @@
               iSpsReportErrorNum=%d, iSubSpsReportErrorNum=%d, iPpsReportErrorNum=%d, iSpsNoExistNalNum=%d, iSubSpsNoExistNalNum=%d, iPpsNoExistNalNum=%d, \
               uiProfile=%d, uiLevel=%d, \
               iCurrentActiveSpsId=%d, iCurrentActivePpsId=%d,",
-              sDecoderStatistics.uiWidth,
-              sDecoderStatistics.uiHeight,
-              sDecoderStatistics.fAverageFrameSpeedInMs,
-              sDecoderStatistics.fActualAverageFrameSpeedInMs,
+             sDecoderStatistics.uiWidth,
+             sDecoderStatistics.uiHeight,
+             sDecoderStatistics.fAverageFrameSpeedInMs,
+             sDecoderStatistics.fActualAverageFrameSpeedInMs,
 
-              sDecoderStatistics.uiDecodedFrameCount,
-              sDecoderStatistics.uiResolutionChangeTimes,
-              sDecoderStatistics.uiIDRCorrectNum,
+             sDecoderStatistics.uiDecodedFrameCount,
+             sDecoderStatistics.uiResolutionChangeTimes,
+             sDecoderStatistics.uiIDRCorrectNum,
 
-              sDecoderStatistics.uiAvgEcRatio,
-              sDecoderStatistics.uiAvgEcPropRatio,
-              sDecoderStatistics.uiEcIDRNum,
-              sDecoderStatistics.uiEcFrameNum,
+             sDecoderStatistics.uiAvgEcRatio,
+             sDecoderStatistics.uiAvgEcPropRatio,
+             sDecoderStatistics.uiEcIDRNum,
+             sDecoderStatistics.uiEcFrameNum,
 
-              sDecoderStatistics.uiIDRLostNum,
-              sDecoderStatistics.uiFreezingIDRNum,
-              sDecoderStatistics.uiFreezingNonIDRNum,
-              sDecoderStatistics.iAvgLumaQp,
+             sDecoderStatistics.uiIDRLostNum,
+             sDecoderStatistics.uiFreezingIDRNum,
+             sDecoderStatistics.uiFreezingNonIDRNum,
+             sDecoderStatistics.iAvgLumaQp,
 
-              sDecoderStatistics.iSpsReportErrorNum,
-              sDecoderStatistics.iSubSpsReportErrorNum,
-              sDecoderStatistics.iPpsReportErrorNum,
-              sDecoderStatistics.iSpsNoExistNalNum,
-              sDecoderStatistics.iSubSpsNoExistNalNum,
-              sDecoderStatistics.iPpsNoExistNalNum,
+             sDecoderStatistics.iSpsReportErrorNum,
+             sDecoderStatistics.iSubSpsReportErrorNum,
+             sDecoderStatistics.iPpsReportErrorNum,
+             sDecoderStatistics.iSpsNoExistNalNum,
+             sDecoderStatistics.iSubSpsNoExistNalNum,
+             sDecoderStatistics.iPpsNoExistNalNum,
 
-              sDecoderStatistics.uiProfile,
-              sDecoderStatistics.uiLevel,
+             sDecoderStatistics.uiProfile,
+             sDecoderStatistics.uiLevel,
 
-              sDecoderStatistics.iCurrentActiveSpsId,
-              sDecoderStatistics.iCurrentActivePpsId);
+             sDecoderStatistics.iCurrentActiveSpsId,
+             sDecoderStatistics.iCurrentActivePpsId);
   }
 }
 
@@ -701,6 +687,7 @@
     m_pDecContext->iErrorCode |= dsInvalidArgument;
     return dsInvalidArgument;
   }
+  int64_t iEnd, iStart = WelsTime();
   if (CheckBsBuffer (m_pDecContext, kiSrcLen)) {
     if (ResetDecoder())
       return dsOutOfMemory;
@@ -745,6 +732,14 @@
 
   if (!m_pDecContext->bFramePending && m_pDecContext->pParserBsInfo->iNalNum) {
     memcpy (pDstInfo, m_pDecContext->pParserBsInfo, sizeof (SParserBsInfo));
+
+    if (m_pDecContext->iErrorCode == ERR_NONE) { //update statistics: decoding frame count
+      m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
+      if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
+        ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
+        m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
+      }
+    }
   }
 
   m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
@@ -753,6 +748,8 @@
     WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode);
     m_pDecContext->bPrintFrameErrorTraceFlag = false;
   }
+  iEnd = WelsTime();
+  m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
 
   return (DECODING_STATE) m_pDecContext->iErrorCode;
 }
--- a/test/api/decode_api_test.cpp
+++ b/test/api/decode_api_test.cpp
@@ -970,6 +970,79 @@
   } //while
 }
 
+TEST_F (DecodeParseAPI, ParseOnly_SpecStatistics) {
+  //set params
+  int32_t iLayerNum = 1;
+  int32_t iSliceNum = 1;
+  EncodeDecodeFileParamBase p;
+  const int iLoopNum = 10;
+  p.frameRate = kiFrameRate;
+  p.numframes = 2;  //encode 2 frames in each test
+  p.width = iWidth_ = 16;
+  p.height = iHeight_ = 16; //default start width/height = 16, will be modified each time
+  int iTotalFrmCnt = 0;
+  for (int i = 0; i < iLoopNum; ++i) {
+    prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate, &param_);
+    param_.iSpatialLayerNum = iLayerNum;
+    param_.sSpatialLayers[0].iDLayerQp = 40; //to revent size too limited to encoding fail
+    encoder_->Uninitialize();
+    int rv = encoder_->InitializeExt (&param_);
+    ASSERT_TRUE (rv == 0);
+    int32_t iTraceLevel = WELS_LOG_QUIET;
+    rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
+    ASSERT_TRUE (rv == 0);
+    rv = decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
+    ASSERT_TRUE (rv == 0);
+    //Start for enc
+    int iLen = 0;
+    ASSERT_TRUE (prepareEncDecParam (p));
+    int iFrame = 0;
+    while (iFrame < p.numframes) {
+      EncodeOneFrame (0);
+      encToDecData (info, iLen);
+      iFrame++;
+      iTotalFrmCnt++;
+      rv = decoder_->DecodeParser (info.sLayerInfo[0].pBsBuf, iLen, &BsInfo_);
+      ASSERT_TRUE (rv == 0);
+      ASSERT_TRUE (BsInfo_.iNalNum == 0);
+      rv = decoder_->DecodeParser (NULL, 0, &BsInfo_);
+      ASSERT_TRUE (rv == 0);
+      ASSERT_TRUE (BsInfo_.iNalNum != 0);
+      SDecoderStatistics sDecStat;
+      rv = decoder_->GetOption (DECODER_OPTION_GET_STATISTICS, &sDecStat);
+      ASSERT_TRUE (rv == 0);
+      uint32_t uiProfile, uiLevel;
+      rv = decoder_->GetOption (DECODER_OPTION_PROFILE, &uiProfile);
+      ASSERT_TRUE (rv == 0);
+      rv = decoder_->GetOption (DECODER_OPTION_LEVEL, &uiLevel);
+      ASSERT_TRUE (rv == 0);
+
+      ASSERT_EQ (sDecStat.uiWidth, p.width);
+      ASSERT_EQ (sDecStat.uiHeight, p.height);
+      ASSERT_EQ (sDecStat.uiResolutionChangeTimes, (i + 1));
+      EXPECT_EQ (sDecStat.iCurrentActiveSpsId, 0);
+      EXPECT_EQ (sDecStat.iCurrentActivePpsId, 0);
+      ASSERT_EQ (sDecStat.uiDecodedFrameCount, iTotalFrmCnt);
+      ASSERT_EQ (sDecStat.uiProfile, uiProfile);
+      ASSERT_EQ (sDecStat.uiLevel, uiLevel);
+      EXPECT_TRUE (sDecStat.fActualAverageFrameSpeedInMs != 0.);
+      EXPECT_TRUE (sDecStat.fAverageFrameSpeedInMs != 0.);
+      EXPECT_TRUE (sDecStat.iAvgLumaQp != 0);
+      EXPECT_EQ (sDecStat.uiIDRCorrectNum, (i + 1));
+    }
+    //set next width & height
+    p.width += 16;
+    p.height += 16;
+    if ((unsigned int) p.width > kiWidth) //exceeds max frame size
+      p.width = 16;
+    if ((unsigned int) p.height > kiHeight)
+      p.height = 16;
+    iWidth_ = p.width;
+    iHeight_ = p.height;
+  }
+}
+
+
 //Test parseonly crash cases
 class DecodeParseCrashAPI : public DecodeParseAPI {
  public:
@@ -1162,5 +1235,4 @@
 #endif
 
 }
-