add timestamp in decoder
This commit is contained in:
@@ -577,6 +577,8 @@ typedef struct TagParserBsInfo {
|
|||||||
unsigned char* pDstBuff; ///< outputted dst buffer for parsed bitstream
|
unsigned char* pDstBuff; ///< outputted dst buffer for parsed bitstream
|
||||||
int iSpsWidthInPixel; ///< required SPS width info
|
int iSpsWidthInPixel; ///< required SPS width info
|
||||||
int iSpsHeightInPixel; ///< required SPS height info
|
int iSpsHeightInPixel; ///< required SPS height info
|
||||||
|
unsigned long long uiInBsTimeStamp; ///< input BS timestamp
|
||||||
|
unsigned long long uiOutBsTimeStamp; ///< output BS timestamp
|
||||||
} SParserBsInfo, *PParserBsInfo;
|
} SParserBsInfo, *PParserBsInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -196,7 +196,8 @@ typedef struct TagSysMemBuffer {
|
|||||||
*/
|
*/
|
||||||
typedef struct TagBufferInfo {
|
typedef struct TagBufferInfo {
|
||||||
int iBufferStatus; ///< 0: one frame data is not ready; 1: one frame data is ready
|
int iBufferStatus; ///< 0: one frame data is not ready; 1: one frame data is ready
|
||||||
|
unsigned long long uiInBsTimeStamp; ///< input BS timestamp
|
||||||
|
unsigned long long uiOutYuvTimeStamp; ///< output YUV timestamp, when bufferstatus is 1
|
||||||
union {
|
union {
|
||||||
SSysMEMBuffer sSystemBuffer; ///< memory info for one picture
|
SSysMEMBuffer sSystemBuffer; ///< memory info for one picture
|
||||||
} UsrData; ///< output buffer info
|
} UsrData; ///< output buffer info
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
|||||||
FILE* fpTrack = fopen ("3.len", "rb");
|
FILE* fpTrack = fopen ("3.len", "rb");
|
||||||
unsigned long pInfo[4];
|
unsigned long pInfo[4];
|
||||||
#endif// STICK_STREAM_SIZE
|
#endif// STICK_STREAM_SIZE
|
||||||
|
unsigned long long uiTimeStamp = 0;
|
||||||
int64_t iStart = 0, iEnd = 0, iTotal = 0;
|
int64_t iStart = 0, iEnd = 0, iTotal = 0;
|
||||||
int32_t iSliceSize;
|
int32_t iSliceSize;
|
||||||
int32_t iSliceIndex = 0;
|
int32_t iSliceIndex = 0;
|
||||||
@@ -208,8 +208,9 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
|||||||
pData[0] = NULL;
|
pData[0] = NULL;
|
||||||
pData[1] = NULL;
|
pData[1] = NULL;
|
||||||
pData[2] = NULL;
|
pData[2] = NULL;
|
||||||
|
uiTimeStamp ++;
|
||||||
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
|
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
|
||||||
|
sDstBufInfo.uiInBsTimeStamp = uiTimeStamp;
|
||||||
pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo);
|
pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo);
|
||||||
|
|
||||||
if (sDstBufInfo.iBufferStatus == 1) {
|
if (sDstBufInfo.iBufferStatus == 1) {
|
||||||
@@ -242,6 +243,7 @@ void H264DecodeInstance (ISVCDecoder* pDecoder, const char* kpH264FileName, cons
|
|||||||
pData[1] = NULL;
|
pData[1] = NULL;
|
||||||
pData[2] = NULL;
|
pData[2] = NULL;
|
||||||
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
|
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
|
||||||
|
sDstBufInfo.uiInBsTimeStamp = uiTimeStamp;
|
||||||
pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo);
|
pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo);
|
||||||
if (sDstBufInfo.iBufferStatus == 1) {
|
if (sDstBufInfo.iBufferStatus == 1) {
|
||||||
pDst[0] = pData[0];
|
pDst[0] = pData[0];
|
||||||
|
|||||||
@@ -402,6 +402,7 @@ double dDecTime;
|
|||||||
SDecoderStatistics sDecoderStatistics;// For real time debugging
|
SDecoderStatistics sDecoderStatistics;// For real time debugging
|
||||||
int32_t iECMVs[16][2];
|
int32_t iECMVs[16][2];
|
||||||
PPicture pECRefPic[16];
|
PPicture pECRefPic[16];
|
||||||
|
unsigned long long uiTimeStamp;
|
||||||
} SWelsDecoderContext, *PWelsDecoderContext;
|
} SWelsDecoderContext, *PWelsDecoderContext;
|
||||||
|
|
||||||
static inline void ResetActiveSPSForEachLayer (PWelsDecoderContext pCtx) {
|
static inline void ResetActiveSPSForEachLayer (PWelsDecoderContext pCtx) {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ union {
|
|||||||
} sVclNal;
|
} sVclNal;
|
||||||
SPrefixNalUnit sPrefixNal;
|
SPrefixNalUnit sPrefixNal;
|
||||||
} sNalData;
|
} sNalData;
|
||||||
|
unsigned long long uiTimeStamp;
|
||||||
} SNalUnit, *PNalUnit;
|
} SNalUnit, *PNalUnit;
|
||||||
|
|
||||||
///////////////////////////////////ACCESS Unit level///////////////////////////////////
|
///////////////////////////////////ACCESS Unit level///////////////////////////////////
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ int32_t iLongTermFrameIdx; //id for long term ref pic
|
|||||||
|
|
||||||
int32_t iSpsId; //against mosaic caused by cross-IDR interval reference.
|
int32_t iSpsId; //against mosaic caused by cross-IDR interval reference.
|
||||||
int32_t iPpsId;
|
int32_t iPpsId;
|
||||||
|
unsigned long long uiTimeStamp;
|
||||||
} SPicture, *PPicture; // "Picture" declaration is comflict with Mac system
|
} SPicture, *PPicture; // "Picture" declaration is comflict with Mac system
|
||||||
|
|
||||||
} // namespace WelsDec
|
} // namespace WelsDec
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
|||||||
|
|
||||||
case NAL_UNIT_PREFIX:
|
case NAL_UNIT_PREFIX:
|
||||||
pCurNal = &pCtx->sPrefixNal;
|
pCurNal = &pCtx->sPrefixNal;
|
||||||
|
pCurNal->uiTimeStamp = pCtx->uiTimeStamp;
|
||||||
|
|
||||||
if (iNalSize < NAL_UNIT_HEADER_EXT_SIZE) {
|
if (iNalSize < NAL_UNIT_HEADER_EXT_SIZE) {
|
||||||
PAccessUnit pCurAu = pCtx->pAccessUnitList;
|
PAccessUnit pCurAu = pCtx->pAccessUnitList;
|
||||||
@@ -256,7 +257,7 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
|||||||
pCtx->iErrorCode |= dsOutOfMemory;
|
pCtx->iErrorCode |= dsOutOfMemory;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
pCurNal->uiTimeStamp = pCtx->uiTimeStamp;
|
||||||
pCurNal->sNalHeaderExt.sNalUnitHeader.uiForbiddenZeroBit = pNalUnitHeader->uiForbiddenZeroBit;
|
pCurNal->sNalHeaderExt.sNalUnitHeader.uiForbiddenZeroBit = pNalUnitHeader->uiForbiddenZeroBit;
|
||||||
pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc = pNalUnitHeader->uiNalRefIdc;
|
pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc = pNalUnitHeader->uiNalRefIdc;
|
||||||
pCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType = pNalUnitHeader->eNalUnitType;
|
pCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType = pNalUnitHeader->eNalUnitType;
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
|||||||
|
|
||||||
if (!pCtx->bParseOnly) {
|
if (!pCtx->bParseOnly) {
|
||||||
//////output:::normal path
|
//////output:::normal path
|
||||||
|
pDstInfo->uiOutYuvTimeStamp = pPic->uiTimeStamp;
|
||||||
ppDst[0] = pPic->pData[0];
|
ppDst[0] = pPic->pData[0];
|
||||||
ppDst[1] = pPic->pData[1];
|
ppDst[1] = pPic->pData[1];
|
||||||
ppDst[2] = pPic->pData[2];
|
ppDst[2] = pPic->pData[2];
|
||||||
@@ -1742,7 +1743,7 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
|||||||
int32_t iIdx = pCurAu->uiStartPos;
|
int32_t iIdx = pCurAu->uiStartPos;
|
||||||
int32_t iEndIdx = pCurAu->uiEndPos;
|
int32_t iEndIdx = pCurAu->uiEndPos;
|
||||||
uint8_t* pNalBs = NULL;
|
uint8_t* pNalBs = NULL;
|
||||||
|
pParser->uiOutBsTimeStamp = (pCurAu->pNalUnitsList [iIdx]) ? pCurAu->pNalUnitsList [iIdx]->uiTimeStamp : 0;
|
||||||
pParser->iNalNum = 0;
|
pParser->iNalNum = 0;
|
||||||
pParser->iSpsWidthInPixel = (pCtx->pSps->iMbWidth << 4);
|
pParser->iSpsWidthInPixel = (pCtx->pSps->iMbWidth << 4);
|
||||||
pParser->iSpsHeightInPixel = (pCtx->pSps->iMbHeight << 4);
|
pParser->iSpsHeightInPixel = (pCtx->pSps->iMbHeight << 4);
|
||||||
@@ -1774,6 +1775,7 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
|||||||
pDstBuf += iNalLen;
|
pDstBuf += iNalLen;
|
||||||
}
|
}
|
||||||
} else { //error
|
} else { //error
|
||||||
|
pCtx->pParserBsInfo->uiOutBsTimeStamp = 0;
|
||||||
pCtx->pParserBsInfo->iNalNum = 0;
|
pCtx->pParserBsInfo->iNalNum = 0;
|
||||||
pCtx->pParserBsInfo->iSpsWidthInPixel = 0;
|
pCtx->pParserBsInfo->iSpsWidthInPixel = 0;
|
||||||
pCtx->pParserBsInfo->iSpsHeightInPixel = 0;
|
pCtx->pParserBsInfo->iSpsHeightInPixel = 0;
|
||||||
@@ -1935,6 +1937,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
|||||||
return ERR_INFO_REF_COUNT_OVERFLOW;
|
return ERR_INFO_REF_COUNT_OVERFLOW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pCtx->pDec->uiTimeStamp = pNalCur->uiTimeStamp;
|
||||||
|
|
||||||
if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode
|
if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode
|
||||||
for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
|
for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
|
||||||
|
|||||||
@@ -412,8 +412,9 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
|||||||
ppDst[0] = ppDst[1] = ppDst[2] = NULL;
|
ppDst[0] = ppDst[1] = ppDst[2] = NULL;
|
||||||
m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
|
m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
|
||||||
m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
|
m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
|
||||||
|
unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
|
||||||
memset (pDstInfo, 0, sizeof (SBufferInfo));
|
memset (pDstInfo, 0, sizeof (SBufferInfo));
|
||||||
|
pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
|
||||||
#ifdef LONG_TERM_REF
|
#ifdef LONG_TERM_REF
|
||||||
m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
|
m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
|
||||||
m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
|
m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
|
||||||
@@ -422,7 +423,12 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_pDecContext->iFeedbackTidInAu = -1; //initialize
|
m_pDecContext->iFeedbackTidInAu = -1; //initialize
|
||||||
|
if (pDstInfo) {
|
||||||
|
pDstInfo->uiOutYuvTimeStamp = 0;
|
||||||
|
m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
|
||||||
|
} else {
|
||||||
|
m_pDecContext->uiTimeStamp = 0;
|
||||||
|
}
|
||||||
WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
|
WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
|
||||||
pDstInfo, NULL); //iErrorCode has been modified in this function
|
pDstInfo, NULL); //iErrorCode has been modified in this function
|
||||||
m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
|
m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
|
||||||
@@ -524,6 +530,12 @@ DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc,
|
|||||||
m_pDecContext->pParserBsInfo = pDstInfo;
|
m_pDecContext->pParserBsInfo = pDstInfo;
|
||||||
pDstInfo->iNalNum = 0;
|
pDstInfo->iNalNum = 0;
|
||||||
pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
|
pDstInfo->iSpsWidthInPixel = pDstInfo->iSpsHeightInPixel = 0;
|
||||||
|
if(pDstInfo) {
|
||||||
|
m_pDecContext->uiTimeStamp = pDstInfo->uiInBsTimeStamp;
|
||||||
|
pDstInfo->uiOutBsTimeStamp = 0;
|
||||||
|
} else {
|
||||||
|
m_pDecContext->uiTimeStamp = 0;
|
||||||
|
}
|
||||||
WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
|
WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, NULL, NULL, pDstInfo);
|
||||||
|
|
||||||
return (DECODING_STATE) m_pDecContext->iErrorCode;
|
return (DECODING_STATE) m_pDecContext->iErrorCode;
|
||||||
|
|||||||
@@ -1032,6 +1032,53 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) {
|
|||||||
(void) iSkipedBytes;
|
(void) iSkipedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) {
|
||||||
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
||||||
|
encoder_->Uninitialize();
|
||||||
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
|
|
||||||
|
InitialEncDec (p.width, p.height);
|
||||||
|
int32_t iTraceLevel = WELS_LOG_QUIET;
|
||||||
|
encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
|
||||||
|
decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
|
||||||
|
int32_t iSpsPpsIdAddition = 1;
|
||||||
|
encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition);
|
||||||
|
int32_t iIDRPeriod = 60;
|
||||||
|
encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
|
||||||
|
SLTRConfig sLtrConfigVal;
|
||||||
|
sLtrConfigVal.bEnableLongTermReference = 1;
|
||||||
|
sLtrConfigVal.iLTRRefNum = 1;
|
||||||
|
encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
|
||||||
|
int32_t iLtrPeriod = 2;
|
||||||
|
encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
|
||||||
|
int iIdx = 0;
|
||||||
|
int iSkipedBytes;
|
||||||
|
unsigned long long uiEncTimeStamp = 100;
|
||||||
|
while (iIdx <= p.numframes) {
|
||||||
|
EncodeOneFrame (1);
|
||||||
|
//decoding after each encoding frame
|
||||||
|
int len = 0;
|
||||||
|
encToDecData (info, len);
|
||||||
|
unsigned char* pData[3] = { NULL };
|
||||||
|
memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
|
||||||
|
uint32_t uiEcIdc = ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE;
|
||||||
|
decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
|
||||||
|
dstBufInfo_.uiInBsTimeStamp = uiEncTimeStamp;
|
||||||
|
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
|
||||||
|
memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
|
||||||
|
dstBufInfo_.uiInBsTimeStamp = uiEncTimeStamp;
|
||||||
|
rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
|
||||||
|
if(dstBufInfo_.iBufferStatus == 1) {
|
||||||
|
EXPECT_EQ (uiEncTimeStamp, dstBufInfo_.uiOutYuvTimeStamp);
|
||||||
|
}
|
||||||
|
iIdx++;
|
||||||
|
uiEncTimeStamp++;
|
||||||
|
}
|
||||||
|
(void) iSkipedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_NOPREFIX) {
|
TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_NOPREFIX) {
|
||||||
SLTRMarkingFeedback m_LTR_Marking_Feedback;
|
SLTRMarkingFeedback m_LTR_Marking_Feedback;
|
||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
|
|||||||
Reference in New Issue
Block a user