Merge pull request #954 from huili2/instant_dec
enable no-delay decoding for MSlice
This commit is contained in:
commit
53f77ee7b5
@ -260,6 +260,7 @@ typedef struct TagWelsDecoderContext {
|
||||
uint8_t uiTargetDqId; // maximal DQ ID in current access unit, meaning target layer ID
|
||||
bool bAvcBasedFlag; // For decoding bitstream:
|
||||
bool bEndOfStreamFlag; // Flag on end of stream requested by external application layer
|
||||
bool bInstantDecFlag; // Flag for no-delay decoding
|
||||
bool bInitialDqLayersMem; // dq layers related memory is available?
|
||||
|
||||
bool bOnlyOneLayerInCurAuFlag; //only one layer in current AU: 1
|
||||
|
@ -139,8 +139,12 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
||||
* DecodeCurrentAccessUnit
|
||||
* Decode current access unit when current AU is completed.
|
||||
*/
|
||||
int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int32_t* iDstLen, int32_t* pWidth,
|
||||
int32_t* pHeight, SBufferInfo* pDstInfo);
|
||||
int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo);
|
||||
|
||||
/*
|
||||
* Check if frame is completed and EC is required
|
||||
*/
|
||||
bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** pDst, SBufferInfo* pDstInfo);
|
||||
|
||||
/*
|
||||
* Prepare current dq layer context initialization.
|
||||
|
@ -509,6 +509,9 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
|
||||
iConsumedBytes = 0;
|
||||
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
|
||||
if ((pCtx->iErrorConMethod != ERROR_CON_DISABLE) && (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1))) {
|
||||
CheckAndDoEC (pCtx, ppDst, pDstBufInfo);
|
||||
}
|
||||
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
|
||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
|
||||
}
|
||||
|
@ -45,8 +45,7 @@
|
||||
|
||||
namespace WelsDec {
|
||||
|
||||
static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t** ppDst, int32_t* pDstLen,
|
||||
int32_t* pWidth, int32_t* pHeight, SBufferInfo* pDstInfo) {
|
||||
static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
PDqLayer pCurDq = pCtx->pCurDqLayer;
|
||||
PPicture pPic = pCtx->pDec;
|
||||
|
||||
@ -56,15 +55,6 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight;
|
||||
bool bFrameCompleteFlag = true;
|
||||
|
||||
if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING,
|
||||
"DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d \n",
|
||||
pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight);
|
||||
bFrameCompleteFlag = false; //return later after output buffer is done
|
||||
}
|
||||
|
||||
pCtx->iTotalNumMbRec = 0;
|
||||
|
||||
if (pCtx->bNewSeqBegin) {
|
||||
memcpy (& (pCtx->sFrameCrop), & (pCurDq->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.pSps->sFrameCrop),
|
||||
sizeof (SPosOffset)); //confirmed_safe_unsafe_usage
|
||||
@ -79,14 +69,21 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t
|
||||
pCtx->sFrameCrop.iBottomOffset);
|
||||
}
|
||||
|
||||
if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) {
|
||||
WelsLog (pCtx, WELS_LOG_WARNING,
|
||||
"DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d \n",
|
||||
pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight);
|
||||
bFrameCompleteFlag = false; //return later after output buffer is done
|
||||
if (pCtx->bInstantDecFlag) //no-delay decoding, wait for new slice
|
||||
return -1;
|
||||
}
|
||||
|
||||
pCtx->iTotalNumMbRec = 0;
|
||||
|
||||
//////output:::normal path
|
||||
ppDst[0] = pPic->pData[0];
|
||||
ppDst[1] = pPic->pData[1];
|
||||
ppDst[2] = pPic->pData[2];
|
||||
*pDstLen = pPic->iLinesize[0];
|
||||
* (pDstLen + 1) = pPic->iLinesize[1];
|
||||
*pWidth = kiWidth;
|
||||
*pHeight = kiHeight;
|
||||
|
||||
pDstInfo->UsrData.sSystemBuffer.iFormat = videoFormatI420;
|
||||
|
||||
@ -1520,6 +1517,12 @@ int32_t WelsDecodeAccessUnitStart (PWelsDecoderContext pCtx) {
|
||||
}
|
||||
|
||||
void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx) {
|
||||
//save previous header info
|
||||
PAccessUnit pCurAu = pCtx->pAccessUnitList;
|
||||
PNalUnit pCurNal = pCurAu->pNalUnitsList[pCurAu->uiEndPos];
|
||||
memcpy (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, sizeof (SNalUnitHeaderExt));
|
||||
memcpy (&pCtx->sLastSliceHeader,
|
||||
&pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader, sizeof (SSliceHeader));
|
||||
// uninitialize context of current access unit and rbsp buffer clean
|
||||
ResetCurrentAccessUnit (pCtx);
|
||||
}
|
||||
@ -1603,9 +1606,6 @@ static void WriteBackActiveParameters (PWelsDecoderContext pCtx) {
|
||||
*/
|
||||
int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
int32_t iErr;
|
||||
int32_t iWidth;
|
||||
int32_t iHeight;
|
||||
int32_t iStride[2] = { 0 };
|
||||
PAccessUnit pCurAu = pCtx->pAccessUnitList;
|
||||
|
||||
pCtx->bAuReadyFlag = false;
|
||||
@ -1637,11 +1637,14 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
||||
}
|
||||
|
||||
|
||||
iErr = DecodeCurrentAccessUnit (pCtx, ppDst, iStride, &iWidth, &iHeight, pDstInfo);
|
||||
iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo);
|
||||
|
||||
WelsDecodeAccessUnitEnd (pCtx);
|
||||
//Do error concealment here
|
||||
ImplementErrorCon (pCtx);
|
||||
|
||||
if (!pCtx->bInstantDecFlag) {
|
||||
//Do error concealment here
|
||||
ImplementErrorCon (pCtx);
|
||||
}
|
||||
|
||||
pCtx->bNewSeqBegin = false;
|
||||
WriteBackActiveParameters (pCtx);
|
||||
@ -1749,8 +1752,7 @@ void ResetParameterSetsState (PWelsDecoderContext pCtx) {
|
||||
* DecodeCurrentAccessUnit
|
||||
* Decode current access unit when current AU is completed.
|
||||
*/
|
||||
int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int32_t* pDstLen, int32_t* pWidth,
|
||||
int32_t* pHeight, SBufferInfo* pDstInfo) {
|
||||
int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
int32_t iRefCount[LIST_A];
|
||||
PNalUnit pNalCur = NULL;
|
||||
PAccessUnit pCurAu = pCtx->pAccessUnitList;
|
||||
@ -1794,13 +1796,6 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3
|
||||
}
|
||||
}
|
||||
|
||||
//For fixing the nal lossing issue
|
||||
if ((pCtx->iTotalNumMbRec != 0) &&
|
||||
(CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pNalCur->sNalHeaderExt, &pCtx->sLastSliceHeader,
|
||||
&pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader))) {
|
||||
pCtx->iTotalNumMbRec = 0;
|
||||
}
|
||||
|
||||
if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode
|
||||
for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i)
|
||||
memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t)));
|
||||
@ -1948,10 +1943,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3
|
||||
#endif//#if !CODEC_FOR_TESTBED
|
||||
|
||||
if (dq_cur->uiLayerDqId == kuiTargetLayerDqId) {
|
||||
if (DecodeFrameConstruction (pCtx, ppDst, pDstLen, pWidth, pHeight, pDstInfo)) {
|
||||
memcpy (&pCtx->sLastNalHdrExt, &pCurAu->pNalUnitsList[iIdx - 1]->sNalHeaderExt, sizeof (SNalUnitHeaderExt));
|
||||
memcpy (&pCtx->sLastSliceHeader, &pCurAu->pNalUnitsList[iIdx - 1]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader,
|
||||
sizeof (SSliceHeader));
|
||||
if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) {
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
@ -1981,4 +1973,23 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
bool CheckAndDoEC (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||
PAccessUnit pAu = pCtx->pAccessUnitList;
|
||||
PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
|
||||
if ((pCtx->iTotalNumMbRec != 0)
|
||||
&& (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
|
||||
&pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader))) {
|
||||
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
|
||||
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
|
||||
PPicture pCurPic = pCtx->pDec; //temporally store current picture
|
||||
//Do Error Concealment here
|
||||
ImplementErrorCon (pCtx);
|
||||
pCtx->pPreviousDecodedPictureInDpb = pCurPic; //save ECed pic for future use
|
||||
pCtx->iPrevFrameNum = pCtx->sLastSliceHeader.iFrameNum; //save frame_num
|
||||
if (pCtx->bLastHasMmco5)
|
||||
pCtx->iPrevFrameNum = 0;
|
||||
}
|
||||
return ERR_NONE;
|
||||
}
|
||||
|
||||
} // namespace WelsDec
|
||||
|
@ -372,6 +372,7 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
||||
//For application MODE, the error detection should be added for safe.
|
||||
//But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL.
|
||||
m_pDecContext->bEndOfStreamFlag = true;
|
||||
m_pDecContext->bInstantDecFlag = true;
|
||||
}
|
||||
|
||||
ppDst[0] = ppDst[1] = ppDst[2] = NULL;
|
||||
@ -390,7 +391,7 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc,
|
||||
|
||||
WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, ppDst,
|
||||
pDstInfo); //iErrorCode has been modified in this function
|
||||
|
||||
m_pDecContext->bInstantDecFlag = false; //reset no-delay flag
|
||||
if (m_pDecContext->iErrorCode) {
|
||||
ENalUnitType eNalType =
|
||||
NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently
|
||||
|
Loading…
x
Reference in New Issue
Block a user