ref: 2e5243e5fcc89f7301f69af4ac03dd889390523d
parent: f48b2e55ba2fba3e6c88d0fc75b645832a0d5c21
author: dong zhang <dongzha@cisco.com>
date: Tue Nov 25 09:25:08 EST 2014
add timestamp in decoder
--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -577,6 +577,8 @@
unsigned char* pDstBuff; ///< outputted dst buffer for parsed bitstream
int iSpsWidthInPixel; ///< required SPS width info
int iSpsHeightInPixel; ///< required SPS height info
+ unsigned long long uiInBsTimeStamp; ///< input BS timestamp
+ unsigned long long uiOutBsTimeStamp; ///< output BS timestamp
} SParserBsInfo, *PParserBsInfo;
/**
--- a/codec/api/svc/codec_def.h
+++ b/codec/api/svc/codec_def.h
@@ -196,7 +196,8 @@
*/
typedef struct TagBufferInfo {
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 {
SSysMEMBuffer sSystemBuffer; ///< memory info for one picture
} UsrData; ///< output buffer info
--- a/codec/console/dec/src/h264dec.cpp
+++ b/codec/console/dec/src/h264dec.cpp
@@ -74,7 +74,7 @@
FILE* fpTrack = fopen ("3.len", "rb");
unsigned long pInfo[4];
#endif// STICK_STREAM_SIZE
-
+ unsigned long long uiTimeStamp = 0;
int64_t iStart = 0, iEnd = 0, iTotal = 0;
int32_t iSliceSize;
int32_t iSliceIndex = 0;
@@ -208,8 +208,9 @@
pData[0] = NULL;
pData[1] = NULL;
pData[2] = NULL;
+ uiTimeStamp ++;
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
-
+ sDstBufInfo.uiInBsTimeStamp = uiTimeStamp;
pDecoder->DecodeFrame2 (pBuf + iBufPos, iSliceSize, pData, &sDstBufInfo);
if (sDstBufInfo.iBufferStatus == 1) {
@@ -242,6 +243,7 @@
pData[1] = NULL;
pData[2] = NULL;
memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
+ sDstBufInfo.uiInBsTimeStamp = uiTimeStamp;
pDecoder->DecodeFrame2 (NULL, 0, pData, &sDstBufInfo);
if (sDstBufInfo.iBufferStatus == 1) {
pDst[0] = pData[0];
--- a/codec/decoder/core/inc/decoder_context.h
+++ b/codec/decoder/core/inc/decoder_context.h
@@ -402,6 +402,7 @@
SDecoderStatistics sDecoderStatistics;// For real time debugging
int32_t iECMVs[16][2];
PPicture pECRefPic[16];
+unsigned long long uiTimeStamp;
} SWelsDecoderContext, *PWelsDecoderContext;
static inline void ResetActiveSPSForEachLayer (PWelsDecoderContext pCtx) {
--- a/codec/decoder/core/inc/nalu.h
+++ b/codec/decoder/core/inc/nalu.h
@@ -57,7 +57,7 @@
} sVclNal;
SPrefixNalUnit sPrefixNal;
} sNalData;
-
+unsigned long long uiTimeStamp;
} SNalUnit, *PNalUnit;
///////////////////////////////////ACCESS Unit level///////////////////////////////////
--- a/codec/decoder/core/inc/picture.h
+++ b/codec/decoder/core/inc/picture.h
@@ -77,6 +77,7 @@
int32_t iSpsId; //against mosaic caused by cross-IDR interval reference.
int32_t iPpsId;
+unsigned long long uiTimeStamp;
} SPicture, *PPicture; // "Picture" declaration is comflict with Mac system
} // namespace WelsDec
--- a/codec/decoder/core/src/au_parser.cpp
+++ b/codec/decoder/core/src/au_parser.cpp
@@ -187,6 +187,7 @@
case NAL_UNIT_PREFIX:
pCurNal = &pCtx->sPrefixNal;
+ pCurNal->uiTimeStamp = pCtx->uiTimeStamp;
if (iNalSize < NAL_UNIT_HEADER_EXT_SIZE) {
PAccessUnit pCurAu = pCtx->pAccessUnitList;
@@ -256,7 +257,7 @@
pCtx->iErrorCode |= dsOutOfMemory;
return NULL;
}
-
+ pCurNal->uiTimeStamp = pCtx->uiTimeStamp;
pCurNal->sNalHeaderExt.sNalUnitHeader.uiForbiddenZeroBit = pNalUnitHeader->uiForbiddenZeroBit;
pCurNal->sNalHeaderExt.sNalUnitHeader.uiNalRefIdc = pNalUnitHeader->uiNalRefIdc;
pCurNal->sNalHeaderExt.sNalUnitHeader.eNalUnitType = pNalUnitHeader->eNalUnitType;
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -90,6 +90,7 @@
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];
@@ -1742,7 +1743,7 @@
int32_t iIdx = pCurAu->uiStartPos;
int32_t iEndIdx = pCurAu->uiEndPos;
uint8_t* pNalBs = NULL;
-
+ pParser->uiOutBsTimeStamp = (pCurAu->pNalUnitsList [iIdx]) ? pCurAu->pNalUnitsList [iIdx]->uiTimeStamp : 0;
pParser->iNalNum = 0;
pParser->iSpsWidthInPixel = (pCtx->pSps->iMbWidth << 4);
pParser->iSpsHeightInPixel = (pCtx->pSps->iMbHeight << 4);
@@ -1774,6 +1775,7 @@
pDstBuf += iNalLen;
}
} else { //error
+ pCtx->pParserBsInfo->uiOutBsTimeStamp = 0;
pCtx->pParserBsInfo->iNalNum = 0;
pCtx->pParserBsInfo->iSpsWidthInPixel = 0;
pCtx->pParserBsInfo->iSpsHeightInPixel = 0;
@@ -1935,6 +1937,7 @@
return ERR_INFO_REF_COUNT_OVERFLOW;
}
}
+ pCtx->pDec->uiTimeStamp = pNalCur->uiTimeStamp;
if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode
for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -412,8 +412,9 @@
ppDst[0] = ppDst[1] = ppDst[2] = NULL;
m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding.
m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize
+ unsigned long long uiInBsTimeStamp = pDstInfo->uiInBsTimeStamp;
memset (pDstInfo, 0, sizeof (SBufferInfo));
-
+ pDstInfo->uiInBsTimeStamp = uiInBsTimeStamp;
#ifdef LONG_TERM_REF
m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR
m_pDecContext->bCurAuContainLtrMarkSeFlag = false;
@@ -422,7 +423,12 @@
#endif
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,
pDstInfo, NULL); //iErrorCode has been modified in this function
m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
@@ -524,6 +530,12 @@
m_pDecContext->pParserBsInfo = pDstInfo;
pDstInfo->iNalNum = 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);
return (DECODING_STATE) m_pDecContext->iErrorCode;
--- a/test/api/encode_decode_api_test.cpp
+++ b/test/api/encode_decode_api_test.cpp
@@ -1032,6 +1032,53 @@
(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) {
SLTRMarkingFeedback m_LTR_Marking_Feedback;
SLTRRecoverRequest m_LTR_Recover_Request;