ref: 2294b786cf028234c1ebae956be0287af1e0152f
parent: 9ea4d5bd73f1ade5a2a41f4fb72422687e5ee5cb
parent: b6e28495dde19724b6c4854d5013ce72cd6b5b66
author: sijchen <sijchen@cisco.com>
date: Fri Feb 27 12:44:03 EST 2015
Merge pull request #1774 from huili2/dec_flowchart_ec modify decoder flowchart for non vcl AU check
--- a/codec/decoder/core/inc/decoder_core.h
+++ b/codec/decoder/core/inc/decoder_core.h
@@ -153,6 +153,7 @@
int32_t WelsDecodeAccessUnitStart (PWelsDecoderContext pCtx);
void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx);
+void DecodeFinishUpdate (PWelsDecoderContext pCtx);
void ForceResetCurrentAccessUnit (PAccessUnit pAu);
void ForceClearCurrentNal (PAccessUnit pAu);
--- a/codec/decoder/core/src/au_parser.cpp
+++ b/codec/decoder/core/src/au_parser.cpp
@@ -178,6 +178,7 @@
switch (pNalUnitHeader->eNalUnitType) {
+ case NAL_UNIT_AU_DELIMITER:
case NAL_UNIT_SEI:
if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -661,25 +661,24 @@
0; // set 4 reserved bytes to zero
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
if (pNalPayload) { //parse correct
- if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
- CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
- }
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
}
- if (pCtx->bAuReadyFlag) {
+ CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
+ if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
+ }
+ }
+ DecodeFinishUpdate (pCtx);
- if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
+ if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
#ifdef LONG_TERM_REF
- pCtx->bParamSetsLostFlag = true;
+ pCtx->bParamSetsLostFlag = true;
#else
- pCtx->bReferenceLostAtT0Flag = true;
+ pCtx->bReferenceLostAtT0Flag = true;
#endif
- if (dsOutOfMemory & pCtx->iErrorCode) {
- return pCtx->iErrorCode;
- }
- }
+ if (dsOutOfMemory & pCtx->iErrorCode) {
+ return pCtx->iErrorCode;
}
}
if (iRet) {
@@ -720,24 +719,23 @@
pRawData->pCurPos = pDstNal + iDstIdx + 4; //init, increase 4 reserved zero bytes, used to store the next NAL
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
if (pNalPayload) { //parse correct
- if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
- CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
- }
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
}
- if (pCtx->bAuReadyFlag) {
+ CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
+ if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
+ }
+ }
+ DecodeFinishUpdate (pCtx);
- if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
+ if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
#ifdef LONG_TERM_REF
- pCtx->bParamSetsLostFlag = true;
+ pCtx->bParamSetsLostFlag = true;
#else
- pCtx->bReferenceLostAtT0Flag = true;
+ pCtx->bReferenceLostAtT0Flag = true;
#endif
- return pCtx->iErrorCode;
- }
- }
+ return pCtx->iErrorCode;
}
if (iRet) {
iRet = 0;
@@ -760,15 +758,16 @@
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
+ }
+ DecodeFinishUpdate (pCtx);
- if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
+ if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
#ifdef LONG_TERM_REF
- pCtx->bParamSetsLostFlag = true;
+ pCtx->bParamSetsLostFlag = true;
#else
- pCtx->bReferenceLostAtT0Flag = true;
+ pCtx->bReferenceLostAtT0Flag = true;
#endif
- return pCtx->iErrorCode;
- }
+ return pCtx->iErrorCode;
}
}
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -571,17 +571,7 @@
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_PPS_ID);
}
- if (pCtx->iOverwriteFlags & OVERWRITE_PPS) {
- if (pCtx->pAccessUnitList->uiAvailUnitsNum > 1 || pCtx->iTotalNumMbRec > 0) {
- pPps = &pCtx->sPpsBuffer[MAX_PPS_COUNT];
- } else {
- memcpy (&pCtx->sPpsBuffer[pCtx->sPpsBuffer[MAX_PPS_COUNT].iPpsId], &pCtx->sPpsBuffer[MAX_PPS_COUNT], sizeof (SPps));
- pCtx->iOverwriteFlags ^= OVERWRITE_PPS;
- pPps = &pCtx->sPpsBuffer[iPpsId];
- }
- } else {
- pPps = &pCtx->sPpsBuffer[iPpsId];
- }
+ pPps = &pCtx->sPpsBuffer[iPpsId];
if (pPps->uiNumSliceGroups == 0) {
WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");
@@ -590,19 +580,7 @@
}
if (kbExtensionFlag) {
- if (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS) {
- if (pCtx->pAccessUnitList->uiAvailUnitsNum > 1 || pCtx->iTotalNumMbRec > 0) {
- pSubsetSps = &pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT];
- } else {
- memcpy (&pCtx->sSubsetSpsBuffer[pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT].sSps.iSpsId],
- &pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT], sizeof (SSubsetSps));
- pCtx->iOverwriteFlags ^= OVERWRITE_SUBSETSPS;
- pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
- ResetActiveSPSForEachLayer (pCtx);
- }
- } else {
- pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
- }
+ pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
pSps = &pSubsetSps->sSps;
if (pCtx->bSubspsAvailFlags[pPps->iSpsId] == false) {
WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id is invalid!");
@@ -615,18 +593,7 @@
pCtx->iErrorCode |= dsNoParamSets;
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
}
- if (pCtx->iOverwriteFlags & OVERWRITE_SPS) {
- if (pCtx->pAccessUnitList->uiAvailUnitsNum > 1 || pCtx->iTotalNumMbRec > 0) {
- pSps = &pCtx->sSpsBuffer[MAX_SPS_COUNT];
- } else {
- memcpy (&pCtx->sSpsBuffer[pCtx->sSpsBuffer[MAX_SPS_COUNT].iSpsId], &pCtx->sSpsBuffer[MAX_SPS_COUNT], sizeof (SSps));
- pCtx->iOverwriteFlags ^= OVERWRITE_SPS;
- pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
- ResetActiveSPSForEachLayer (pCtx);
- }
- } else {
- pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
- }
+ pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
}
pSliceHead->iPpsId = iPpsId;
pSliceHead->iSpsId = pPps->iSpsId;
@@ -1722,7 +1689,23 @@
}
pCtx->iOverwriteFlags = OVERWRITE_NONE;
}
+
/*
+ * DecodeFinishUpdate
+ * decoder finish decoding, update active parameter sets and new seq status
+ *
+ */
+
+void DecodeFinishUpdate (PWelsDecoderContext pCtx) {
+ pCtx->bNewSeqBegin = false;
+ WriteBackActiveParameters (pCtx);
+ pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
+ pCtx->bNextNewSeqBegin = false; // reset it
+ if (pCtx->bNewSeqBegin)
+ ResetActiveSPSForEachLayer (pCtx);
+}
+
+/*
* ConstructAccessUnit
* construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
* joint a collective access unit.
@@ -1824,12 +1807,6 @@
WelsDecodeAccessUnitEnd (pCtx);
- pCtx->bNewSeqBegin = false;
- WriteBackActiveParameters (pCtx);
- pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin;
- pCtx->bNextNewSeqBegin = false; // reset it
- if (pCtx->bNewSeqBegin)
- ResetActiveSPSForEachLayer (pCtx);
if (ERR_NONE != iErr) {
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "returned error from decoding:[0x%x]", iErr);
return iErr;
@@ -2195,36 +2172,52 @@
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
PAccessUnit pAu = pCtx->pAccessUnitList;
- if (pAu->uiAvailUnitsNum == 0)
- return true;
- PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
- if ((pCtx->iTotalNumMbRec != 0)
- && (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
- &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader))) {
- //Do Error Concealment here
- if (NeedErrorCon (pCtx)) { //should always be true!
- if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
- ImplementErrorCon (pCtx);
- pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
- pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
- pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
+ bool bAuBoundaryFlag = false;
+ if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) { //VCL data, AU list should have data
+ PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
+ bAuBoundaryFlag = (pCtx->iTotalNumMbRec != 0)
+ && (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
+ &pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader));
+ } else { //non VCL
+ if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_AU_DELIMITER) {
+ bAuBoundaryFlag = true;
+ } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SEI) {
+ bAuBoundaryFlag = true;
+ } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SPS) {
+ bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_SPS);
+ } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_SUBSET_SPS) {
+ bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS);
+ } else if (pCtx->sCurNalHead.eNalUnitType == NAL_UNIT_PPS) {
+ bAuBoundaryFlag = !! (pCtx->iOverwriteFlags & OVERWRITE_PPS);
+ }
+ if (bAuBoundaryFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) { //Construct remaining data first
+ ConstructAccessUnit (pCtx, ppDst, pDstInfo);
+ }
+ }
- DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
- pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
- if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
- MarkECFrameAsRef (pCtx);
- }
- } else {
- if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) {
- pCtx->pDec = NULL;
- return false;
- }
+ //Do Error Concealment here
+ if (bAuBoundaryFlag && (pCtx->iTotalNumMbRec != 0) && NeedErrorCon (pCtx)) { //AU ready but frame not completely reconed
+ if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
+ ImplementErrorCon (pCtx);
+ pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
+ pCtx->pDec->iSpsId = pCtx->pSps->iSpsId;
+ pCtx->pDec->iPpsId = pCtx->pPps->iPpsId;
+
+ DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
+ pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
+ if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
+ MarkECFrameAsRef (pCtx);
}
- pCtx->pDec = NULL;
- pCtx->iPrevFrameNum = pCtx->sLastSliceHeader.iFrameNum; //save frame_num
- if (pCtx->bLastHasMmco5)
- pCtx->iPrevFrameNum = 0;
+ } else {
+ if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) {
+ pCtx->pDec = NULL;
+ return false;
+ }
}
+ pCtx->pDec = NULL;
+ pCtx->iPrevFrameNum = pCtx->sLastSliceHeader.iFrameNum; //save frame_num
+ if (pCtx->bLastHasMmco5)
+ pCtx->iPrevFrameNum = 0;
}
return ERR_NONE;
}