ref: 4484df4bbb4561128a3320a1ab329cff20843431
parent: e8b1802b88e35178663ef56baa0bdca0241649b7
parent: 5cd3c5d7cfb59587941454279952f4572e90a7d4
author: guangwei <GuangweiWang@users.noreply.github.com>
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, ¶m_);
+ param_.iSpatialLayerNum = iLayerNum;
+ param_.sSpatialLayers[0].iDLayerQp = 40; //to revent size too limited to encoding fail
+ encoder_->Uninitialize();
+ int rv = encoder_->InitializeExt (¶m_);
+ 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
}
-