Merge pull request #1530 from sijchen/after_review

[Encoder] add total length in encoder output and complete statistics
This commit is contained in:
ruil2 2014-11-14 11:20:45 +08:00
commit 703bbef128
6 changed files with 69 additions and 13 deletions

View File

@ -404,6 +404,7 @@ typedef struct {
SLayerBSInfo sLayerInfo[MAX_LAYER_NUM_OF_FRAME];
EVideoFrameType eFrameType;
int iFrameSizeInBytes;
long long uiTimeStamp;
} SFrameBSInfo, *PFrameBSInfo;

View File

@ -221,6 +221,9 @@ typedef struct TagWelsEncCtx {
SEncoderStatistics sEncoderStatistics;
int32_t iStatisticsLogInterval;
int64_t iLastStatisticsLogTs;
int64_t iTotalEncodedBits;
int64_t iLastStatisticsBits;
int64_t iLastStatisticsFrameCount;
int32_t iEncoderError;
WELS_MUTEX mutexEncoderError;

View File

@ -2736,7 +2736,7 @@ void ParasetIdAdditionIdAdjust (SParaSetOffsetVariable* sParaSetOffsetVariable,
* \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 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
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 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
}
*pNumNal = iCountNal;
*pTotalLength = iSize;
return ENC_RETURN_SUCCESS;
}
@ -2944,13 +2946,14 @@ int32_t WelsEncoderEncodeParameterSets (sWelsEncCtx* pCtx, void* pDst) {
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;
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
//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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
WelsEmms();
pFbi->eFrameType = eFrameType;
pFbi->iFrameSizeInBytes = iFrameSize;
return ENC_RETURN_SUCCESS;
}

View File

@ -102,7 +102,7 @@ class CWelsH264SVCEncoder : public ISVCEncoder {
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;

View File

@ -431,7 +431,7 @@ int CWelsH264SVCEncoder ::EncodeFrameInternal (const SSourcePicture* pSrcPic, S
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 @@ int CWelsH264SVCEncoder::ForceIntraFrame (bool bIDR) {
ForceCodingIDR (m_pEncContext);
m_pEncContext->sEncoderStatistics.uiIDRReqNum++;
return 0;
}
void CWelsH264SVCEncoder::CheckProfileSetting (int32_t iLayer, EProfileIdc uiProfileIdc) {
@ -594,7 +596,7 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
}
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 @@ void CWelsH264SVCEncoder::UpdateStatistics (const int64_t kiCurrentFrameTs, EVid
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
}
}

View File

@ -770,3 +770,31 @@ TEST_F (EncoderInterfaceTest, GetStatistics) {
// 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();
}