Merge pull request #1530 from sijchen/after_review
[Encoder] add total length in encoder output and complete statistics
This commit is contained in:
commit
703bbef128
@ -404,6 +404,7 @@ typedef struct {
|
||||
SLayerBSInfo sLayerInfo[MAX_LAYER_NUM_OF_FRAME];
|
||||
|
||||
EVideoFrameType eFrameType;
|
||||
int iFrameSizeInBytes;
|
||||
long long uiTimeStamp;
|
||||
} SFrameBSInfo, *PFrameBSInfo;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user