add dec status for freezing

This commit is contained in:
huili2 2014-11-27 01:46:55 -08:00
parent 82b70b34fe
commit 504cabf106
8 changed files with 116 additions and 43 deletions

View File

@ -613,13 +613,17 @@ typedef struct TagVideoDecoderStatistics {
float fAverageFrameSpeedInMs; ///< average_Decoding_Time
unsigned int uiDecodedFrameCount; ///< number of frames
unsigned int uiResolutionChangeTimes; ///< uiResolutionChangeTimes
unsigned int uiIDRRecvNum; ///< number of actual IDR received
unsigned int uiIDRCorrectNum; ///< number of correct IDR received
//EC on related
unsigned int
uiAvgEcRatio; ///< when EC is on, the average ratio of correct or EC areas, can be an indicator of reconstruction quality
unsigned int uiEcIDRNum; ///< number of actual unintegrity IDR or not received but eced
unsigned int uiEcFrameNum; ///<
unsigned int uiIDRLostNum; ///< decoder detect the number of lost IDR
unsigned int uiIDRLostNum; ///< number of lost IDR
unsigned int uiFreezingIDRNum; ///< number of freezing IDR with error
unsigned int uiFreezingNonIDRNum; ///< number of freezing non-IDR with error
int iAvgLumaQp; ///< average luma QP. default: -1, no correct frame outputted
} SDecoderStatistics; // in building, coming soon
#endif//WELS_VIDEO_CODEC_APPLICATION_DEFINITION_H__

View File

@ -135,6 +135,14 @@ void AssignFuncPointerForRec (PWelsDecoderContext pCtx);
void GetVclNalTemporalId (PWelsDecoderContext pCtx); //get the info that whether or not have VCL NAL in current AU,
//and if YES, get the temporal ID
//reset decoder number related statistics info
void ResetDecStatNums (SDecoderStatistics* pDecStat);
//update information when freezing occurs, including IDR/non-IDR number
void UpdateDecStatFreezingInfo (const bool kbIdrFlag, SDecoderStatistics* pDecStat);
//update information when no freezing occurs, including QP, correct IDR number, ECed IDR number
void UpdateDecStatNoFreezingInfo (PWelsDecoderContext pCtx);
//update decoder statistics information
void UpdateDecStat (PWelsDecoderContext pCtx, const bool kbOutput);
#ifdef __cplusplus
}
#endif//__cplusplus

View File

@ -237,7 +237,7 @@ int32_t iImgWidthInPixel; // width of image in pixel reconstruction picture t
int32_t iImgHeightInPixel;// height of image in pixel reconstruction picture to be output
int32_t iLastImgWidthInPixel; // width of image in last successful pixel reconstruction picture to be output
int32_t iLastImgHeightInPixel;// height of image in last successful pixel reconstruction picture to be output
bool bFreezeOutput;
bool bFreezeOutput; // indicating current frame freezing. Default: true
// Derived common elements

View File

@ -147,7 +147,7 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
pCtx->iImgHeightInPixel = 0; // alloc picture data when picture size is available
pCtx->iLastImgWidthInPixel = 0;
pCtx->iLastImgHeightInPixel = 0;
pCtx->bFreezeOutput = false;
pCtx->bFreezeOutput = true;
pCtx->iFrameNum = -1;
pCtx->iPrevFrameNum = -1;
@ -165,6 +165,7 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx, SLogContext* pLogCtx) {
pCtx->bAvcBasedFlag = true;
pCtx->eErrorConMethod = ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE;
pCtx->pPreviousDecodedPictureInDpb = NULL;
pCtx->sDecoderStatistics.iAvgLumaQp = -1;
}
@ -275,7 +276,7 @@ void WelsFreeMem (PWelsDecoderContext pCtx) {
pCtx->iImgHeightInPixel = 0;
pCtx->iLastImgWidthInPixel = 0;
pCtx->iLastImgHeightInPixel = 0;
pCtx->bFreezeOutput = false;
pCtx->bFreezeOutput = true;
pCtx->bHaveGotMemory = false;
WelsFree (pCtx->pCabacDecEngine, "pCtx->pCabacDecEngine");
}
@ -777,4 +778,62 @@ void AssignFuncPointerForRec (PWelsDecoderContext pCtx) {
WelsBlockFuncInit (&pCtx->sBlockFunc, pCtx->uiCpuFlag);
}
//reset decoder number related statistics info
void ResetDecStatNums (SDecoderStatistics* pDecStat) {
uint32_t uiWidth = pDecStat->uiWidth;
uint32_t uiHeight = pDecStat->uiHeight;
int32_t iAvgLumaQp = pDecStat->iAvgLumaQp;
memset (pDecStat, 0, sizeof (SDecoderStatistics));
pDecStat->uiWidth = uiWidth;
pDecStat->uiHeight = uiHeight;
pDecStat->iAvgLumaQp = iAvgLumaQp;
}
//update information when freezing occurs, including IDR/non-IDR number
void UpdateDecStatFreezingInfo (const bool kbIdrFlag, SDecoderStatistics* pDecStat) {
if (kbIdrFlag)
pDecStat->uiFreezingIDRNum++;
else
pDecStat->uiFreezingNonIDRNum++;
}
//update information when no freezing occurs, including QP, correct IDR number, ECed IDR number
void UpdateDecStatNoFreezingInfo (PWelsDecoderContext pCtx) {
PDqLayer pCurDq = pCtx->pCurDqLayer;
PPicture pPic = pCtx->pDec;
SDecoderStatistics* pDecStat = &pCtx->sDecoderStatistics;
if (pDecStat->iAvgLumaQp == -1) //first correct frame received
pDecStat->iAvgLumaQp = 0;
//update QP info
int32_t iTotalQp = 0;
const int32_t kiMbNum = pCurDq->iMbWidth * pCurDq->iMbHeight;
for (int32_t iMb = 0; iMb < kiMbNum; ++iMb) {
iTotalQp += pCurDq->pLumaQp[iMb] * pCurDq->pMbCorrectlyDecodedFlag[iMb];
}
iTotalQp /= kiMbNum;
if (pDecStat->uiDecodedFrameCount + 1 == 0) { //maximum uint32_t reached
ResetDecStatNums (pDecStat);
pDecStat->iAvgLumaQp = iTotalQp;
} else
pDecStat->iAvgLumaQp = (uint64_t) (pDecStat->iAvgLumaQp * pDecStat->uiDecodedFrameCount + iTotalQp) /
(pDecStat->uiDecodedFrameCount + 1);
//update IDR number
if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag) {
pDecStat->uiIDRCorrectNum += (pPic->bIsComplete);
pDecStat->uiEcIDRNum += (!pPic->bIsComplete);
}
}
//update decoder statistics information
void UpdateDecStat (PWelsDecoderContext pCtx, const bool kbOutput) {
if (pCtx->bFreezeOutput)
UpdateDecStatFreezingInfo (pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.bIdrFlag, &pCtx->sDecoderStatistics);
else if (kbOutput)
UpdateDecStatNoFreezingInfo (pCtx);
}
} // namespace WelsDec

View File

@ -44,7 +44,6 @@
#include "error_concealment.h"
namespace WelsDec {
static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
PDqLayer pCurDq = pCtx->pCurDqLayer;
PPicture pPic = pCtx->pDec;
@ -88,24 +87,22 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
pCtx->iTotalNumMbRec = 0;
if (!pCtx->bParseOnly) {
//////output:::normal path
pDstInfo->uiOutYuvTimeStamp = pPic->uiTimeStamp;
ppDst[0] = pPic->pData[0];
ppDst[1] = pPic->pData[1];
ppDst[2] = pPic->pData[2];
//////output:::normal path
pDstInfo->uiOutYuvTimeStamp = pPic->uiTimeStamp;
ppDst[0] = pPic->pData[0];
ppDst[1] = pPic->pData[1];
ppDst[2] = pPic->pData[2];
pDstInfo->UsrData.sSystemBuffer.iFormat = videoFormatI420;
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.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;
ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
pDstInfo->iBufferStatus = 1;
}
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.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;
ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset;
pDstInfo->iBufferStatus = 1;
bool bOutResChange = (pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth)
|| (pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight);
@ -119,13 +116,6 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
&& pCtx->iErrorCode && bOutResChange)
pCtx->bFreezeOutput = true;
if ((pDstInfo->iBufferStatus == 1) && (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag)) {
if (pPic->bIsComplete)
pCtx->sDecoderStatistics.uiIDRRecvNum++;
else
pCtx->sDecoderStatistics.uiEcIDRNum++;
}
if (pDstInfo->iBufferStatus == 0) {
if (!bFrameCompleteFlag)
pCtx->iErrorCode |= dsBitstreamError;
@ -137,6 +127,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "DecodeFrameConstruction():New sequence detected, but freezed.");
}
}
UpdateDecStat (pCtx, pDstInfo->iBufferStatus);
return 0;
}

View File

@ -157,8 +157,9 @@ void DoErrorConSliceCopy (PWelsDecoderContext pCtx) {
} //iMbX
} //iMbY
pCtx->sDecoderStatistics.uiAvgEcRatio = (pCtx->sDecoderStatistics.uiAvgEcRatio * pCtx->sDecoderStatistics.uiEcFrameNum)
+ ((iMbEcedNum * 100) / iMbNum) ;
if (!pCtx->bFreezeOutput)
pCtx->sDecoderStatistics.uiAvgEcRatio = (pCtx->sDecoderStatistics.uiAvgEcRatio * pCtx->sDecoderStatistics.uiEcFrameNum)
+ ((iMbEcedNum * 100) / iMbNum) ;
}
//Do error concealment using slice MV copy method
@ -415,8 +416,9 @@ void DoErrorConSliceMVCopy (PWelsDecoderContext pCtx) {
} //iMbX
} //iMbY
pCtx->sDecoderStatistics.uiAvgEcRatio = (pCtx->sDecoderStatistics.uiAvgEcRatio * pCtx->sDecoderStatistics.uiEcFrameNum)
+ ((iMbEcedNum * 100) / iMbNum) ;
if (!pCtx->bFreezeOutput)
pCtx->sDecoderStatistics.uiAvgEcRatio = (pCtx->sDecoderStatistics.uiAvgEcRatio * pCtx->sDecoderStatistics.uiEcFrameNum)
+ ((iMbEcedNum * 100) / iMbNum) ;
}
//Mark erroneous frame as Ref Pic into DPB

View File

@ -373,8 +373,9 @@ long CWelsDecoder::GetOption (DECODER_OPTION eOptID, void* pOption) {
pDecoderStatistics->fAverageFrameSpeedInMs = (float) (m_pDecContext->dDecTime) /
(m_pDecContext->sDecoderStatistics.uiDecodedFrameCount);
memset (&m_pDecContext->sDecoderStatistics, 0, sizeof (SDecoderStatistics));
ResetDecStatNums (&m_pDecContext->sDecoderStatistics);
m_pDecContext->dDecTime = 0;
return cmResultSuccess;
}
@ -478,6 +479,10 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
}
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->sDecoderStatistics.uiEcFrameNum++;
m_pDecContext->sDecoderStatistics.uiAvgEcRatio = m_pDecContext->sDecoderStatistics.uiAvgEcRatio /
m_pDecContext->sDecoderStatistics.uiEcFrameNum;
@ -490,14 +495,18 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
if (pDstInfo->iBufferStatus == 1) {
m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
if (m_pDecContext->sDecoderStatistics.uiDecodedFrameCount == 0) { //exceed max value of uint32_t
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;
}
m_pDecContext->sDecoderStatistics.uiDecodedFrameCount++;
}
iEnd = WelsTime();
m_pDecContext->dDecTime += (iEnd - iStart) / 1e3;
@ -529,7 +538,7 @@ DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
m_pDecContext->pParserBsInfo = pDstInfo;
pDstInfo->iNalNum = 0;
pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
if(pDstInfo) {
if (pDstInfo) {
m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
pDstInfo->uiOutBsTimeStamp = 0;
} else {

View File

@ -122,7 +122,7 @@ void DecoderInterfaceTest::DecoderBs (const char* sFileName) {
#if defined(ANDROID_NDK)
std::string filename = std::string ("/sdcard/") + sFileName;
ASSERT_TRUE (pH264File = fopen (filename.c_str(),"rb"));
ASSERT_TRUE (pH264File = fopen (filename.c_str(), "rb"));
#else
ASSERT_TRUE (pH264File = fopen (sFileName, "rb"));
#endif
@ -130,7 +130,7 @@ void DecoderInterfaceTest::DecoderBs (const char* sFileName) {
iFileSize = (int32_t) ftell (pH264File);
fseek (pH264File, 0L, SEEK_SET);
pBuf = new uint8_t[iFileSize + 4];
ASSERT_EQ(fread (pBuf, 1, iFileSize, pH264File), (unsigned int) iFileSize);
ASSERT_EQ (fread (pBuf, 1, iFileSize, pH264File), (unsigned int) iFileSize);
memcpy (pBuf + iFileSize, &uiStartCode[0], 4); //confirmed_safe_unsafe_usage
while (true) {
if (iBufPos >= iFileSize) {
@ -416,7 +416,7 @@ void DecoderInterfaceTest::TestGetDecStatistics() {
EXPECT_EQ (57u, sDecStatic.uiAvgEcRatio);
EXPECT_EQ (5u, sDecStatic.uiDecodedFrameCount);
EXPECT_EQ (288u, sDecStatic.uiHeight);
EXPECT_EQ (1u, sDecStatic.uiIDRRecvNum);
EXPECT_EQ (1u, sDecStatic.uiIDRCorrectNum);
EXPECT_EQ (3u, sDecStatic.uiResolutionChangeTimes);
EXPECT_EQ (352u, sDecStatic.uiWidth);
EXPECT_EQ (4u, sDecStatic.uiEcFrameNum);
@ -433,7 +433,7 @@ void DecoderInterfaceTest::TestGetDecStatistics() {
EXPECT_EQ (0u, sDecStatic.uiAvgEcRatio);
EXPECT_EQ (97u, sDecStatic.uiDecodedFrameCount);
EXPECT_EQ (144u, sDecStatic.uiHeight);
EXPECT_EQ (3u, sDecStatic.uiIDRRecvNum);
EXPECT_EQ (3u, sDecStatic.uiIDRCorrectNum);
EXPECT_EQ (0u, sDecStatic.uiEcIDRNum);
EXPECT_EQ (1u, sDecStatic.uiResolutionChangeTimes);
EXPECT_EQ (176u, sDecStatic.uiWidth);
@ -452,7 +452,7 @@ void DecoderInterfaceTest::TestGetDecStatistics() {
EXPECT_EQ (0u, sDecStatic.uiAvgEcRatio);
EXPECT_EQ (99u, sDecStatic.uiDecodedFrameCount);
EXPECT_EQ (144u, sDecStatic.uiHeight);
EXPECT_EQ (4u, sDecStatic.uiIDRRecvNum);
EXPECT_EQ (4u, sDecStatic.uiIDRCorrectNum);
EXPECT_EQ (0u, sDecStatic.uiEcIDRNum);
EXPECT_EQ (1u, sDecStatic.uiResolutionChangeTimes);
EXPECT_EQ (176u, sDecStatic.uiWidth);
@ -472,7 +472,7 @@ void DecoderInterfaceTest::TestGetDecStatistics() {
EXPECT_EQ (0u, sDecStatic.uiAvgEcRatio);
EXPECT_EQ (9u, sDecStatic.uiDecodedFrameCount);
EXPECT_EQ (192u, sDecStatic.uiHeight);
EXPECT_EQ (1u, sDecStatic.uiIDRRecvNum);
EXPECT_EQ (1u, sDecStatic.uiIDRCorrectNum);
EXPECT_EQ (1u, sDecStatic.uiResolutionChangeTimes);
EXPECT_EQ (320u, sDecStatic.uiWidth);
EXPECT_EQ (0u, sDecStatic.uiEcFrameNum);