ref: 703bbef12849115b79b730b320fa7cfb2dbe3fa1
parent: aed7b2316c03d17904ba13374b62209df2953f72
parent: b56b8725fc0928f5295d2a38776766c7e60c0fad
author: ruil2 <ruil2@cisco.com>
date: Fri Nov 14 06:20:45 EST 2014
Merge pull request #1530 from sijchen/after_review [Encoder] add total length in encoder output and complete statistics
--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -404,6 +404,7 @@
SLayerBSInfo sLayerInfo[MAX_LAYER_NUM_OF_FRAME];
EVideoFrameType eFrameType;
+ int iFrameSizeInBytes;
long long uiTimeStamp;
} SFrameBSInfo, *PFrameBSInfo;
--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -221,6 +221,9 @@
SEncoderStatistics sEncoderStatistics;
int32_t iStatisticsLogInterval;
int64_t iLastStatisticsLogTs;
+ int64_t iTotalEncodedBits;
+ int64_t iLastStatisticsBits;
+ int64_t iLastStatisticsFrameCount;
int32_t iEncoderError;
WELS_MUTEX mutexEncoderError;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -2736,7 +2736,7 @@
* \brief write all parameter sets introduced in SVC extension
* \return writing results, success or error
*/
-int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pNumNal) {
+int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pNumNal, int32_t* pTotalLength) {
int32_t iSize = 0;
int32_t iNal = 0;
int32_t iIdx = 0;
@@ -2748,6 +2748,7 @@
if (NULL == pCtx || NULL == pNalLen || NULL == pNumNal)
return ENC_RETURN_UNEXPECTED;
+ *pTotalLength = 0;
/* write all SPS */
iIdx = 0;
while (iIdx < pCtx->iSpsNum) {
@@ -2834,6 +2835,7 @@
}
*pNumNal = iCountNal;
+ *pTotalLength = iSize;
return ENC_RETURN_SUCCESS;
}
@@ -2944,6 +2946,7 @@
SFrameBSInfo* pFbi = (SFrameBSInfo*)pDst;
SLayerBSInfo* pLayerBsInfo = &pFbi->sLayerInfo[0];
int32_t iCountNal = 0;
+ int32_t iTotalLength = 0;
pLayerBsInfo->pBsBuf = pCtx->pFrameBs;
pLayerBsInfo->pNalLengthInByte = pCtx->pOut->pNalLen;
@@ -2950,7 +2953,7 @@
InitBits (&pCtx->pOut->sBsWrite, pCtx->pOut->pBsBuffer, pCtx->pOut->uiSize);
pCtx->iPosBsBuffer = 0;
- int32_t iReturn = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal);
+ int32_t iReturn = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal, &iTotalLength);
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
pLayerBsInfo->uiSpatialId = 0;
@@ -3094,7 +3097,8 @@
//if ( pSvcParam->bEnableSSEI )
// write parameter sets bitstream here
- pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal);
+ int32_t iNonVclSize = 0;
+ pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &pLayerBsInfo->pNalLengthInByte[0], &iCountNal, &iNonVclSize);
WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
pLayerBsInfo->uiSpatialId = 0;
@@ -3107,6 +3111,8 @@
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
++ iLayerNum;
+
+ iFrameSize += iNonVclSize;
}
pCtx->pCurDqLayer = pCtx->ppDqLayerList[pSpatialIndexMap->iDid];
@@ -3605,6 +3611,8 @@
pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + 1;
++ iLayerNum;
+
+ iFrameSize += iPaddingNalSize;
}
if ((pParam->sSliceCfg.uiSliceMode == SM_FIXEDSLCNUM_SLICE || pParam->sSliceCfg.uiSliceMode == SM_AUTO_SLICE)
@@ -3677,6 +3685,7 @@
WelsEmms();
pFbi->eFrameType = eFrameType;
+ pFbi->iFrameSizeInBytes = iFrameSize;
return ENC_RETURN_SUCCESS;
}
--- a/codec/encoder/plus/inc/welsEncoderExt.h
+++ b/codec/encoder/plus/inc/welsEncoderExt.h
@@ -102,7 +102,7 @@
void CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelIdc);
void CheckReferenceNumSetting (int32_t iNumRef);
void TraceParamInfo(SEncParamExt *pParam);
- void UpdateStatistics(const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType, const int64_t kiCurrentFrameMs);
+ void UpdateStatistics(const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType, const int32_t kiCurrentFrameSize, const int64_t kiCurrentFrameMs);
sWelsEncCtx* m_pEncContext;
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -431,7 +431,7 @@
return cmUnkonwReason;
}
- UpdateStatistics (pSrcPic->uiTimeStamp, pBsInfo->eFrameType, kiCurrentFrameMs);
+ UpdateStatistics (pSrcPic->uiTimeStamp, pBsInfo->eFrameType, pBsInfo->iFrameSizeInBytes, kiCurrentFrameMs);
///////////////////for test
#ifdef OUTPUT_BIT_STREAM
@@ -504,6 +504,8 @@
ForceCodingIDR (m_pEncContext);
+ m_pEncContext->sEncoderStatistics.uiIDRReqNum++;
+
return 0;
}
void CWelsH264SVCEncoder::CheckProfileSetting (int32_t iLayer, EProfileIdc uiProfileIdc) {
@@ -594,7 +596,7 @@
}
void CWelsH264SVCEncoder::UpdateStatistics (const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType,
- const int64_t kiCurrentFrameMs) {
+ const int32_t kiCurrentFrameSize, const int64_t kiCurrentFrameMs) {
SEncoderStatistics* pStatistics = & (m_pEncContext->sEncoderStatistics);
int32_t iMaxDid = m_pEncContext->pSvcParam->iSpatialLayerNum - 1;
@@ -633,20 +635,33 @@
if (m_pEncContext->pLtr->bLTRMarkingFlag) {
pStatistics->uiLTRSentNum ++;
}
- //TODO: update uiIDRReqNum in forceIDR
+ m_pEncContext->iTotalEncodedBits += kiCurrentFrameSize;
+
if (m_pEncContext->iStatisticsLogInterval > 0) {
- if (WELS_ABS (kiCurrentFrameTs - m_pEncContext->iLastStatisticsLogTs) > m_pEncContext->iStatisticsLogInterval) {
+ int64_t iTimeDiff = kiCurrentFrameTs - m_pEncContext->iLastStatisticsLogTs;
+ if (iTimeDiff > m_pEncContext->iStatisticsLogInterval) {
+ pStatistics->fLatestFrameRate = (pStatistics->uiInputFrameCount - m_pEncContext->iLastStatisticsFrameCount) * 1000 /
+ iTimeDiff;
+ pStatistics->uiBitRate = static_cast<unsigned int> ((m_pEncContext->iTotalEncodedBits -
+ m_pEncContext->iLastStatisticsBits) * 1000 / iTimeDiff);
+
+ // update variables
+ m_pEncContext->iLastStatisticsLogTs = kiCurrentFrameTs;
+ m_pEncContext->iLastStatisticsBits = m_pEncContext->iTotalEncodedBits;
+ m_pEncContext->iLastStatisticsFrameCount = pStatistics->uiInputFrameCount;
+
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
- "EncoderStatistics: %dx%d, SpeedInMs: %f, AverFrameRate=%f, LastFrameRate=NA, LatestBitRate=NA, uiInputFrameCount=%d, uiSkippedFrameCount=%d, uiResolutionChangeTimes=%d, uIDRReqNum=%d, uIDRSentNum=%d, uLTRSentNum=NA",
+ "EncoderStatistics: %dx%d, SpeedInMs: %f, fAverageFrameRate=%f, \
+ LastFrameRate=%f, LatestBitRate=%d, uiInputFrameCount=%d, uiSkippedFrameCount=%d, \
+ uiResolutionChangeTimes=%d, uIDRReqNum=%d, uIDRSentNum=%d, uLTRSentNum=NA",
pStatistics->uiWidth, pStatistics->uiHeight,
pStatistics->fAverageFrameSpeedInMs, pStatistics->fAverageFrameRate,
+ pStatistics->fLatestFrameRate, pStatistics->uiBitRate,
pStatistics->uiInputFrameCount, pStatistics->uiSkippedFrameCount,
- pStatistics->uiResolutionChangeTimes, pStatistics->uiIDRSentNum, pStatistics->uiLTRSentNum);
+ pStatistics->uiResolutionChangeTimes, pStatistics->uiIDRReqNum, pStatistics->uiIDRSentNum);
//TODO: the following statistics will be calculated and added later
- //pStatistics->fLatestFrameRate, pStatistics->uiBitRate,
- //pStatistics->uiIDRReqNum,
- m_pEncContext->iLastStatisticsLogTs = kiCurrentFrameTs;
+ //pStatistics->uiLTRSentNum
}
}
--- a/test/encoder/EncUT_EncoderExt.cpp
+++ b/test/encoder/EncUT_EncoderExt.cpp
@@ -770,3 +770,31 @@
// finish
pPtrEnc->Uninitialize();
}
+
+TEST_F (EncoderInterfaceTest, FrameSizeCheck) {
+ SEncParamBase sEncParamBase;
+ GetValidEncParamBase (&sEncParamBase);
+
+ int iResult = pPtrEnc->Initialize (&sEncParamBase);
+ EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
+ if (iResult != cmResultSuccess) {
+ fprintf (stderr, "Unexpected ParamBase? \
+ iUsageType=%d, Pic=%dx%d, TargetBitrate=%d, iRCMode=%d, fMaxFrameRate=%.1f\n",
+ sEncParamBase.iUsageType, sEncParamBase.iPicWidth, sEncParamBase.iPicHeight,
+ sEncParamBase.iTargetBitrate, sEncParamBase.iRCMode, sEncParamBase.fMaxFrameRate);
+ }
+
+ PrepareOneSrcFrame();
+ iResult = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
+
+ uint32_t length = 0;
+ for (int i = 0; i < sFbi.iLayerNum; ++i) {
+ for (int j = 0; j < sFbi.sLayerInfo[i].iNalCount; ++j) {
+ length += sFbi.sLayerInfo[i].pNalLengthInByte[j];
+ }
+ }
+ EXPECT_EQ (length, sFbi.iFrameSizeInBytes);
+
+ // finish
+ pPtrEnc->Uninitialize();
+}