add dec status for freezing
This commit is contained in:
parent
82b70b34fe
commit
504cabf106
@ -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__
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user