add interface and basic implementaion and UT for EncoderStatistics
This commit is contained in:
parent
d720122a37
commit
a765197b73
@ -103,6 +103,9 @@ typedef enum {
|
|||||||
ENCODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
|
ENCODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
|
||||||
ENCODER_OPTION_TRACE_CALLBACK_CONTEXT,
|
ENCODER_OPTION_TRACE_CALLBACK_CONTEXT,
|
||||||
|
|
||||||
|
ENCODER_OPTION_GET_STATISTICS, //read only
|
||||||
|
ENCODER_OPTION_STATISTICS_LOG_INTERVAL, // log interval in milliseconds
|
||||||
|
|
||||||
// advanced algorithmetic settings
|
// advanced algorithmetic settings
|
||||||
ENCODER_OPTION_IS_LOSSLESS_LINK
|
ENCODER_OPTION_IS_LOSSLESS_LINK
|
||||||
} ENCODER_OPTION;
|
} ENCODER_OPTION;
|
||||||
@ -120,7 +123,9 @@ typedef enum {
|
|||||||
DECODER_OPTION_ERROR_CON_IDC, //not finished yet, indicate decoder error concealment status, in progress
|
DECODER_OPTION_ERROR_CON_IDC, //not finished yet, indicate decoder error concealment status, in progress
|
||||||
DECODER_OPTION_TRACE_LEVEL,
|
DECODER_OPTION_TRACE_LEVEL,
|
||||||
DECODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
|
DECODER_OPTION_TRACE_CALLBACK, // a void (*)(void* context, int level, const char* message) function which receives log messages
|
||||||
DECODER_OPTION_TRACE_CALLBACK_CONTEXT
|
DECODER_OPTION_TRACE_CALLBACK_CONTEXT,
|
||||||
|
|
||||||
|
DECODER_OPTION_GET_STATISTICS
|
||||||
|
|
||||||
} DECODER_OPTION;
|
} DECODER_OPTION;
|
||||||
|
|
||||||
@ -455,4 +460,38 @@ typedef struct TagParserBsInfo {
|
|||||||
int iSpsHeightInPixel; //required SPS height info
|
int iSpsHeightInPixel; //required SPS height info
|
||||||
} SParserBsInfo, PParserBsInfo;
|
} SParserBsInfo, PParserBsInfo;
|
||||||
|
|
||||||
|
typedef struct TagVideoEncoderStatistics {
|
||||||
|
unsigned int uWidth; // the width of encoded frame
|
||||||
|
unsigned int uHeight; // the height of encoded frame
|
||||||
|
//following standard, will be 16x aligned, if there are multiple spatial, this is of the highest
|
||||||
|
float fAverageFrameSpeedInMs; // Average_Encoding_Time
|
||||||
|
|
||||||
|
// rate control related
|
||||||
|
float fAverageFrameRate; // the average frame rate in, calculate since encoding starts, supposed that the input timestamp is in unit of ms
|
||||||
|
float fLatestFrameRate; // the frame rate in, in the last second, supposed that the input timestamp is in unit of ms (? useful for checking BR, but is it easy to calculate?
|
||||||
|
unsigned int uiBitRate; // sendrate in Bits per second, calculated within the set time-window
|
||||||
|
|
||||||
|
unsigned int uiInputFrameCount; // number of frames
|
||||||
|
unsigned int uiSkippedFrameCount; // number of frames
|
||||||
|
|
||||||
|
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
|
||||||
|
unsigned int uIDRReqNum; // number of IDR requests
|
||||||
|
unsigned int uIDRSentNum; // number of actual IDRs sent
|
||||||
|
unsigned int uLTRSentNum; // number of LTR sent/marked
|
||||||
|
} SEncoderStatistics; // in building, coming soon
|
||||||
|
|
||||||
|
typedef struct TagVideoDecoderStatistics {
|
||||||
|
unsigned int uWidth; // the width of encode/decode frame
|
||||||
|
unsigned int uHeight; // the height of encode/decode frame
|
||||||
|
float fAverageFrameSpeedInMs; // Average_Decoding_Time
|
||||||
|
|
||||||
|
unsigned int uiDecodedFrameCount; // number of frames
|
||||||
|
unsigned int uiResolutionChangeTimes; // uiResolutionChangeTimes
|
||||||
|
unsigned int
|
||||||
|
uiAvgEcRatio; // when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
|
||||||
|
unsigned int uIDRReqNum; // number of actual IDR request
|
||||||
|
unsigned int uLTRReqNum; // number of actual LTR request
|
||||||
|
unsigned int uIDRRecvNum; // number of actual IDR received
|
||||||
|
} SDecoderStatistics; // in building, coming soon
|
||||||
|
|
||||||
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
|
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__
|
||||||
|
@ -216,6 +216,12 @@ typedef struct TagWelsEncCtx {
|
|||||||
SStatSliceInfo sPerInfo;
|
SStatSliceInfo sPerInfo;
|
||||||
#endif//STAT_OUTPUT
|
#endif//STAT_OUTPUT
|
||||||
|
|
||||||
|
//related to Statistics
|
||||||
|
int64_t uiStartTimestamp;
|
||||||
|
SEncoderStatistics sEncoderStatistics;
|
||||||
|
int32_t iStatisticsLogInterval;
|
||||||
|
int64_t iLastStatisticsLogTs;
|
||||||
|
|
||||||
int32_t iEncoderError;
|
int32_t iEncoderError;
|
||||||
WELS_MUTEX mutexEncoderError;
|
WELS_MUTEX mutexEncoderError;
|
||||||
bool bDeliveryFlag;
|
bool bDeliveryFlag;
|
||||||
|
@ -224,6 +224,10 @@ int64_t iAvgCost2Bits;
|
|||||||
int64_t iCost2BitsIntra;
|
int64_t iCost2BitsIntra;
|
||||||
int32_t iBaseQp;
|
int32_t iBaseQp;
|
||||||
long long uiLastTimeStamp;
|
long long uiLastTimeStamp;
|
||||||
|
|
||||||
|
//for statistics and online adjustments
|
||||||
|
int32_t iActualBitRate; // TODO: to complete later
|
||||||
|
float fLatestFrameRate; // TODO: to complete later
|
||||||
} SWelsSvcRc;
|
} SWelsSvcRc;
|
||||||
|
|
||||||
typedef void (*PWelsRCPictureInitFunc) (void* pCtx);
|
typedef void (*PWelsRCPictureInitFunc) (void* pCtx);
|
||||||
|
@ -55,6 +55,8 @@
|
|||||||
#define MAX_TRACE_LOG_SIZE (50 * (1<<20)) // max trace log size: 50 MB, overwrite occur if log file size exceeds this size
|
#define MAX_TRACE_LOG_SIZE (50 * (1<<20)) // max trace log size: 50 MB, overwrite occur if log file size exceeds this size
|
||||||
#endif//MAX_TRACE_LOG_SIZE
|
#endif//MAX_TRACE_LOG_SIZE
|
||||||
|
|
||||||
|
#define STATISTICS_LOG_INTERVAL_MS (5000) // output statistics log every 5s
|
||||||
|
|
||||||
/* MB width in pixels for specified colorspace I420 usually used in codec */
|
/* MB width in pixels for specified colorspace I420 usually used in codec */
|
||||||
#define MB_WIDTH_LUMA 16
|
#define MB_WIDTH_LUMA 16
|
||||||
#define MB_WIDTH_CHROMA (MB_WIDTH_LUMA>>1)
|
#define MB_WIDTH_CHROMA (MB_WIDTH_LUMA>>1)
|
||||||
|
@ -2085,6 +2085,8 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
|||||||
);
|
);
|
||||||
#endif//MEMORY_MONITOR
|
#endif//MEMORY_MONITOR
|
||||||
|
|
||||||
|
pCtx->iStatisticsLogInterval = STATISTICS_LOG_INTERVAL_MS;
|
||||||
|
|
||||||
*ppCtx = pCtx;
|
*ppCtx = pCtx;
|
||||||
|
|
||||||
WelsLog (pLogCtx, WELS_LOG_DEBUG, "WelsInitEncoderExt(), pCtx= 0x%p.", (void*)pCtx);
|
WelsLog (pLogCtx, WELS_LOG_DEBUG, "WelsInitEncoderExt(), pCtx= 0x%p.", (void*)pCtx);
|
||||||
@ -3736,6 +3738,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
|||||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||||
uiTmpIdrPicId = (*ppCtx)->sPSOVector.uiIdrPicId;
|
uiTmpIdrPicId = (*ppCtx)->sPSOVector.uiIdrPicId;
|
||||||
|
|
||||||
|
SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics;
|
||||||
|
|
||||||
WelsUninitEncoderExt (ppCtx);
|
WelsUninitEncoderExt (ppCtx);
|
||||||
|
|
||||||
/* Update new parameters */
|
/* Update new parameters */
|
||||||
@ -3746,10 +3750,13 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
|||||||
(*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
|
(*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
|
||||||
//if WelsInitEncoderExt succeed
|
//if WelsInitEncoderExt succeed
|
||||||
|
|
||||||
|
//load back the needed structure
|
||||||
//for FLEXIBLE_PARASET_ID
|
//for FLEXIBLE_PARASET_ID
|
||||||
memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
|
memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
|
||||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||||
(*ppCtx)->sPSOVector.uiIdrPicId = uiTmpIdrPicId;
|
(*ppCtx)->sPSOVector.uiIdrPicId = uiTmpIdrPicId;
|
||||||
|
//for sEncoderStatistics
|
||||||
|
(*ppCtx)->sEncoderStatistics = sTempEncoderStatistics;
|
||||||
} else {
|
} else {
|
||||||
/* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */
|
/* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */
|
||||||
pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT,
|
pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT,
|
||||||
|
@ -102,6 +102,8 @@ class CWelsH264SVCEncoder : public ISVCEncoder {
|
|||||||
void CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelIdc);
|
void CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelIdc);
|
||||||
void CheckReferenceNumSetting (int32_t iNumRef);
|
void CheckReferenceNumSetting (int32_t iNumRef);
|
||||||
void TraceParamInfo(SEncParamExt *pParam);
|
void TraceParamInfo(SEncParamExt *pParam);
|
||||||
|
void UpdateStatistics(const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType, const int64_t kiCurrentFrameMs);
|
||||||
|
|
||||||
sWelsEncCtx* m_pEncContext;
|
sWelsEncCtx* m_pEncContext;
|
||||||
|
|
||||||
welsCodecTrace* m_pWelsTrace;
|
welsCodecTrace* m_pWelsTrace;
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "ref_list_mgr_svc.h"
|
#include "ref_list_mgr_svc.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <measure_time.h>
|
||||||
#if defined(_WIN32) /*&& defined(_DEBUG)*/
|
#if defined(_WIN32) /*&& defined(_DEBUG)*/
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -416,8 +417,10 @@ int CWelsH264SVCEncoder::EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CWelsH264SVCEncoder::EncodeFrameInternal (const SSourcePicture* pSrcPic, SFrameBSInfo* pBsInfo) {
|
int CWelsH264SVCEncoder ::EncodeFrameInternal (const SSourcePicture* pSrcPic, SFrameBSInfo* pBsInfo) {
|
||||||
|
const int64_t kiBeforeFrameUs = WelsTime();
|
||||||
const int32_t kiEncoderReturn = WelsEncoderEncodeExt (m_pEncContext, pBsInfo, pSrcPic);
|
const int32_t kiEncoderReturn = WelsEncoderEncodeExt (m_pEncContext, pBsInfo, pSrcPic);
|
||||||
|
const int64_t kiCurrentFrameMs = (WelsTime() - kiBeforeFrameUs) / 1000;
|
||||||
|
|
||||||
if (kiEncoderReturn == ENC_RETURN_MEMALLOCERR) {
|
if (kiEncoderReturn == ENC_RETURN_MEMALLOCERR) {
|
||||||
WelsUninitEncoderExt (&m_pEncContext);
|
WelsUninitEncoderExt (&m_pEncContext);
|
||||||
@ -427,6 +430,9 @@ int CWelsH264SVCEncoder::EncodeFrameInternal (const SSourcePicture* pSrcPic, SF
|
|||||||
kiEncoderReturn);
|
kiEncoderReturn);
|
||||||
return cmUnkonwReason;
|
return cmUnkonwReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateStatistics (pSrcPic->uiTimeStamp, pBsInfo->eFrameType, kiCurrentFrameMs);
|
||||||
|
|
||||||
///////////////////for test
|
///////////////////for test
|
||||||
#ifdef OUTPUT_BIT_STREAM
|
#ifdef OUTPUT_BIT_STREAM
|
||||||
if (pBsInfo->eFrameType != videoFrameTypeInvalid && pBsInfo->eFrameType != videoFrameTypeSkip) {
|
if (pBsInfo->eFrameType != videoFrameTypeInvalid && pBsInfo->eFrameType != videoFrameTypeSkip) {
|
||||||
@ -586,6 +592,61 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
|
|||||||
++ i;
|
++ i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWelsH264SVCEncoder::UpdateStatistics (const int64_t kiCurrentFrameTs, EVideoFrameType eFrameType,
|
||||||
|
const int64_t kiCurrentFrameMs) {
|
||||||
|
SEncoderStatistics* pStatistics = & (m_pEncContext->sEncoderStatistics);
|
||||||
|
|
||||||
|
int32_t iMaxDid = m_pEncContext->pSvcParam->iSpatialLayerNum - 1;
|
||||||
|
if ((0 != pStatistics->uWidth && 0 != pStatistics->uHeight)
|
||||||
|
&& (pStatistics->uWidth != m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth
|
||||||
|
|| pStatistics->uHeight != m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight)) {
|
||||||
|
pStatistics->uiResolutionChangeTimes ++;
|
||||||
|
}
|
||||||
|
pStatistics->uWidth = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualWidth;
|
||||||
|
pStatistics->uHeight = m_pEncContext->pSvcParam->sDependencyLayers[iMaxDid].iActualHeight;
|
||||||
|
|
||||||
|
int32_t iProcessedFrameCount = pStatistics->uiInputFrameCount - pStatistics->uiSkippedFrameCount;
|
||||||
|
const bool kbCurrentFrameSkipped = (videoFrameTypeSkip == eFrameType);
|
||||||
|
if (!kbCurrentFrameSkipped && (iProcessedFrameCount + 1) != 0) {
|
||||||
|
pStatistics->fAverageFrameSpeedInMs = (iProcessedFrameCount * pStatistics->fAverageFrameSpeedInMs +
|
||||||
|
kiCurrentFrameMs) / (iProcessedFrameCount + 1);
|
||||||
|
}
|
||||||
|
pStatistics->uiInputFrameCount ++;
|
||||||
|
pStatistics->uiSkippedFrameCount += (kbCurrentFrameSkipped ? 1 : 0);
|
||||||
|
|
||||||
|
// rate control related
|
||||||
|
if (0 != m_pEncContext->uiStartTimestamp && kiCurrentFrameTs > m_pEncContext->uiStartTimestamp + 800) {
|
||||||
|
pStatistics->fAverageFrameRate = pStatistics->uiInputFrameCount * 1000 /
|
||||||
|
(kiCurrentFrameTs - m_pEncContext->uiStartTimestamp);
|
||||||
|
} else {
|
||||||
|
m_pEncContext->uiStartTimestamp = kiCurrentFrameTs;
|
||||||
|
}
|
||||||
|
pStatistics->fLatestFrameRate = m_pEncContext->pWelsSvcRc->fLatestFrameRate; //TODO: finish the calculation in RC
|
||||||
|
pStatistics->uiBitRate = m_pEncContext->pWelsSvcRc->iActualBitRate; //TODO: finish the calculation in RC
|
||||||
|
|
||||||
|
if (videoFrameTypeIDR == eFrameType || videoFrameTypeI == eFrameType) {
|
||||||
|
pStatistics->uIDRSentNum ++;
|
||||||
|
}
|
||||||
|
if (m_pEncContext->pLtr->bLTRMarkingFlag) {
|
||||||
|
pStatistics->uLTRSentNum ++;
|
||||||
|
}
|
||||||
|
//TODO: update uIDRSentNum in forceIDR
|
||||||
|
|
||||||
|
if (m_pEncContext->iStatisticsLogInterval > 0) {
|
||||||
|
if (WELS_ABS (kiCurrentFrameTs - m_pEncContext->iLastStatisticsLogTs) > m_pEncContext->iStatisticsLogInterval) {
|
||||||
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||||
|
"EncoderStatistics: %dx%d, SpeedInMs: %f, AverFrameRate=%f, LastFrameRate=%f, LatestBitRate=%d, uiInputFrameCount=%d, uiSkippedFrameCount=%d, uiResolutionChangeTimes=%d, uIDRReqNum=%d, uIDRSentNum=%d, uLTRSentNum=%d",
|
||||||
|
pStatistics->uWidth, pStatistics->uHeight, pStatistics->fAverageFrameSpeedInMs,
|
||||||
|
pStatistics->fAverageFrameRate, pStatistics->fLatestFrameRate, pStatistics->uiBitRate,
|
||||||
|
pStatistics->uiInputFrameCount, pStatistics->uiSkippedFrameCount,
|
||||||
|
pStatistics->uiResolutionChangeTimes, pStatistics->uIDRReqNum, pStatistics->uIDRSentNum, pStatistics->uLTRSentNum);
|
||||||
|
m_pEncContext->iLastStatisticsLogTs = kiCurrentFrameTs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,..
|
* InDataFormat, IDRInterval, SVC Encode Param, Frame Rate, Bitrate,..
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
@ -919,6 +980,16 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
|||||||
m_pEncContext->pSvcParam->iComplexityMode = (ECOMPLEXITY_MODE)iValue;
|
m_pEncContext->pSvcParam->iComplexityMode = (ECOMPLEXITY_MODE)iValue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ENCODER_OPTION_GET_STATISTICS: {
|
||||||
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
|
||||||
|
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_GET_STATISTICS: this option is get-only!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: {
|
||||||
|
int32_t iValue = * (static_cast<int32_t*> (pOption));
|
||||||
|
m_pEncContext->iStatisticsLogInterval = iValue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ENCODER_OPTION_IS_LOSSLESS_LINK: {
|
case ENCODER_OPTION_IS_LOSSLESS_LINK: {
|
||||||
bool bValue = * (static_cast<bool*> (pOption));
|
bool bValue = * (static_cast<bool*> (pOption));
|
||||||
m_pEncContext->pSvcParam->bIsLosslessLink = bValue;
|
m_pEncContext->pSvcParam->bIsLosslessLink = bValue;
|
||||||
@ -1026,6 +1097,30 @@ int CWelsH264SVCEncoder::GetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ENCODER_OPTION_GET_STATISTICS: {
|
||||||
|
SEncoderStatistics* pStatistics = (static_cast<SEncoderStatistics*> (pOption));
|
||||||
|
pStatistics->uWidth = m_pEncContext->sEncoderStatistics.uWidth;
|
||||||
|
pStatistics->uHeight = m_pEncContext->sEncoderStatistics.uHeight;
|
||||||
|
pStatistics->fAverageFrameSpeedInMs = m_pEncContext->sEncoderStatistics.fAverageFrameSpeedInMs;
|
||||||
|
|
||||||
|
// rate control related
|
||||||
|
pStatistics->fAverageFrameRate = m_pEncContext->sEncoderStatistics.fAverageFrameRate;
|
||||||
|
pStatistics->fLatestFrameRate = m_pEncContext->sEncoderStatistics.fLatestFrameRate;
|
||||||
|
pStatistics->uiBitRate = m_pEncContext->sEncoderStatistics.uiBitRate;
|
||||||
|
|
||||||
|
pStatistics->uiInputFrameCount = m_pEncContext->sEncoderStatistics.uiInputFrameCount;
|
||||||
|
pStatistics->uiSkippedFrameCount = m_pEncContext->sEncoderStatistics.uiSkippedFrameCount;
|
||||||
|
|
||||||
|
pStatistics->uiResolutionChangeTimes = m_pEncContext->sEncoderStatistics.uiResolutionChangeTimes;
|
||||||
|
pStatistics->uIDRReqNum = m_pEncContext->sEncoderStatistics.uIDRReqNum;
|
||||||
|
pStatistics->uIDRSentNum = m_pEncContext->sEncoderStatistics.uIDRSentNum;
|
||||||
|
pStatistics->uLTRSentNum = m_pEncContext->sEncoderStatistics.uLTRSentNum;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ENCODER_OPTION_STATISTICS_LOG_INTERVAL: {
|
||||||
|
* ((int32_t*)pOption) = m_pEncContext->iStatisticsLogInterval;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ENCODER_OPTION_COMPLEXITY: {
|
case ENCODER_OPTION_COMPLEXITY: {
|
||||||
* ((int32_t*)pOption) = m_pEncContext->pSvcParam->iComplexityMode;
|
* ((int32_t*)pOption) = m_pEncContext->pSvcParam->iComplexityMode;
|
||||||
}
|
}
|
||||||
|
@ -661,3 +661,83 @@ TEST_F (EncoderInterfaceTest, EncodeParameterSets) {
|
|||||||
TEST_F (EncoderInterfaceTest, BasicReturnTypeTest) {
|
TEST_F (EncoderInterfaceTest, BasicReturnTypeTest) {
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F (EncoderInterfaceTest, GetStatistics) {
|
||||||
|
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();
|
||||||
|
EncodeOneIDRandP (pPtrEnc);
|
||||||
|
|
||||||
|
SEncoderStatistics sEncoderStatistics;
|
||||||
|
iResult = pPtrEnc->GetOption (ENCODER_OPTION_GET_STATISTICS, &sEncoderStatistics);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uiInputFrameCount, 2);
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uIDRSentNum, 1);
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uiResolutionChangeTimes, 0);
|
||||||
|
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uWidth, sEncParamBase.iPicWidth);
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uHeight, sEncParamBase.iPicHeight);
|
||||||
|
|
||||||
|
// try param change
|
||||||
|
// 1, get the existing
|
||||||
|
pPtrEnc->GetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, pParamExt);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
|
||||||
|
// 2, change the reoslution
|
||||||
|
GetValidEncParamBase (&sEncParamBase);
|
||||||
|
int32_t knownResolutionChangeTimes = 0;
|
||||||
|
if (pParamExt->iPicWidth != sEncParamBase.iPicWidth || pParamExt->iPicHeight != sEncParamBase.iPicHeight) {
|
||||||
|
knownResolutionChangeTimes = 1;
|
||||||
|
}
|
||||||
|
pParamExt->iPicWidth = pParamExt->sSpatialLayers[0].iVideoWidth = sEncParamBase.iPicWidth;
|
||||||
|
pParamExt->iPicHeight = pParamExt->sSpatialLayers[0].iVideoHeight = sEncParamBase.iPicHeight;
|
||||||
|
pPtrEnc->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, pParamExt);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
|
||||||
|
// 3, code one frame
|
||||||
|
PrepareOneSrcFrame();
|
||||||
|
iResult = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
iResult = pPtrEnc->GetOption (ENCODER_OPTION_GET_STATISTICS, &sEncoderStatistics);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uiInputFrameCount, 3);
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uIDRSentNum, 2);
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uiResolutionChangeTimes, knownResolutionChangeTimes);
|
||||||
|
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uWidth, sEncParamBase.iPicWidth);
|
||||||
|
EXPECT_EQ (sEncoderStatistics.uHeight, sEncParamBase.iPicHeight);
|
||||||
|
|
||||||
|
// 4, change log interval
|
||||||
|
int32_t iInterval = 0;
|
||||||
|
iResult = pPtrEnc->GetOption (ENCODER_OPTION_STATISTICS_LOG_INTERVAL, &iInterval);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
EXPECT_EQ (iInterval, 5000);
|
||||||
|
|
||||||
|
int32_t iInterval2 = 2000;
|
||||||
|
iResult = pPtrEnc->SetOption (ENCODER_OPTION_STATISTICS_LOG_INTERVAL, &iInterval2);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
iResult = pPtrEnc->GetOption (ENCODER_OPTION_STATISTICS_LOG_INTERVAL, &iInterval);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
EXPECT_EQ (iInterval, iInterval2);
|
||||||
|
|
||||||
|
iInterval2 = 0;
|
||||||
|
iResult = pPtrEnc->SetOption (ENCODER_OPTION_STATISTICS_LOG_INTERVAL, &iInterval2);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
iResult = pPtrEnc->GetOption (ENCODER_OPTION_STATISTICS_LOG_INTERVAL, &iInterval);
|
||||||
|
EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
|
||||||
|
EXPECT_EQ (iInterval, iInterval2);
|
||||||
|
|
||||||
|
// finish
|
||||||
|
pPtrEnc->Uninitialize();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user