Merge pull request #1774 from huili2/dec_flowchart_ec
modify decoder flowchart for non vcl AU check
This commit is contained in:
@@ -153,6 +153,7 @@ void WelsDqLayerDecodeStart (PWelsDecoderContext pCtx, PNalUnit pCurNal, PSps pS
|
|||||||
|
|
||||||
int32_t WelsDecodeAccessUnitStart (PWelsDecoderContext pCtx);
|
int32_t WelsDecodeAccessUnitStart (PWelsDecoderContext pCtx);
|
||||||
void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx);
|
void WelsDecodeAccessUnitEnd (PWelsDecoderContext pCtx);
|
||||||
|
void DecodeFinishUpdate (PWelsDecoderContext pCtx);
|
||||||
|
|
||||||
void ForceResetCurrentAccessUnit (PAccessUnit pAu);
|
void ForceResetCurrentAccessUnit (PAccessUnit pAu);
|
||||||
void ForceClearCurrentNal (PAccessUnit pAu);
|
void ForceClearCurrentNal (PAccessUnit pAu);
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
|||||||
|
|
||||||
|
|
||||||
switch (pNalUnitHeader->eNalUnitType) {
|
switch (pNalUnitHeader->eNalUnitType) {
|
||||||
|
case NAL_UNIT_AU_DELIMITER:
|
||||||
case NAL_UNIT_SEI:
|
case NAL_UNIT_SEI:
|
||||||
if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
|
if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
|
||||||
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
|
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
|
||||||
|
|||||||
@@ -661,14 +661,15 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
|||||||
0; // set 4 reserved bytes to zero
|
0; // set 4 reserved bytes to zero
|
||||||
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
|
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
|
||||||
if (pNalPayload) { //parse correct
|
if (pNalPayload) { //parse correct
|
||||||
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
|
|
||||||
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
|
|
||||||
}
|
|
||||||
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
|
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
|
||||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
|
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);
|
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DecodeFinishUpdate (pCtx);
|
||||||
|
|
||||||
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
||||||
#ifdef LONG_TERM_REF
|
#ifdef LONG_TERM_REF
|
||||||
@@ -680,8 +681,6 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
|||||||
return pCtx->iErrorCode;
|
return pCtx->iErrorCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (iRet) {
|
if (iRet) {
|
||||||
iRet = 0;
|
iRet = 0;
|
||||||
if (dsNoParamSets & pCtx->iErrorCode) {
|
if (dsNoParamSets & pCtx->iErrorCode) {
|
||||||
@@ -720,14 +719,15 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
|||||||
pRawData->pCurPos = pDstNal + iDstIdx + 4; //init, increase 4 reserved zero bytes, used to store the next NAL
|
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);
|
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
|
||||||
if (pNalPayload) { //parse correct
|
if (pNalPayload) { //parse correct
|
||||||
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) {
|
|
||||||
CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
|
|
||||||
}
|
|
||||||
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
|
if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
|
||||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
|
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);
|
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DecodeFinishUpdate (pCtx);
|
||||||
|
|
||||||
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
||||||
#ifdef LONG_TERM_REF
|
#ifdef LONG_TERM_REF
|
||||||
@@ -737,8 +737,6 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
|||||||
#endif
|
#endif
|
||||||
return pCtx->iErrorCode;
|
return pCtx->iErrorCode;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (iRet) {
|
if (iRet) {
|
||||||
iRet = 0;
|
iRet = 0;
|
||||||
if (dsNoParamSets & pCtx->iErrorCode) {
|
if (dsNoParamSets & pCtx->iErrorCode) {
|
||||||
@@ -760,6 +758,8 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
|||||||
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
|
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
|
||||||
|
|
||||||
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||||
|
}
|
||||||
|
DecodeFinishUpdate (pCtx);
|
||||||
|
|
||||||
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) {
|
||||||
#ifdef LONG_TERM_REF
|
#ifdef LONG_TERM_REF
|
||||||
@@ -770,7 +770,6 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
|||||||
return pCtx->iErrorCode;
|
return pCtx->iErrorCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return pCtx->iErrorCode;
|
return pCtx->iErrorCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -571,17 +571,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
|||||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_PPS_ID);
|
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];
|
pPps = &pCtx->sPpsBuffer[iPpsId];
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pPps = &pCtx->sPpsBuffer[iPpsId];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pPps->uiNumSliceGroups == 0) {
|
if (pPps->uiNumSliceGroups == 0) {
|
||||||
WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");
|
WelsLog (pLogCtx, WELS_LOG_WARNING, "Invalid PPS referenced");
|
||||||
@@ -590,19 +580,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kbExtensionFlag) {
|
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];
|
pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
|
||||||
ResetActiveSPSForEachLayer (pCtx);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pSubsetSps = &pCtx->sSubsetSpsBuffer[pPps->iSpsId];
|
|
||||||
}
|
|
||||||
pSps = &pSubsetSps->sSps;
|
pSps = &pSubsetSps->sSps;
|
||||||
if (pCtx->bSubspsAvailFlags[pPps->iSpsId] == false) {
|
if (pCtx->bSubspsAvailFlags[pPps->iSpsId] == false) {
|
||||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id is invalid!");
|
WelsLog (pLogCtx, WELS_LOG_ERROR, "SPS id is invalid!");
|
||||||
@@ -615,18 +593,7 @@ int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, co
|
|||||||
pCtx->iErrorCode |= dsNoParamSets;
|
pCtx->iErrorCode |= dsNoParamSets;
|
||||||
return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_INVALID_SPS_ID);
|
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];
|
pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
|
||||||
ResetActiveSPSForEachLayer (pCtx);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pSps = &pCtx->sSpsBuffer[pPps->iSpsId];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pSliceHead->iPpsId = iPpsId;
|
pSliceHead->iPpsId = iPpsId;
|
||||||
pSliceHead->iSpsId = pPps->iSpsId;
|
pSliceHead->iSpsId = pPps->iSpsId;
|
||||||
@@ -1722,6 +1689,22 @@ static void WriteBackActiveParameters (PWelsDecoderContext pCtx) {
|
|||||||
}
|
}
|
||||||
pCtx->iOverwriteFlags = OVERWRITE_NONE;
|
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
|
* ConstructAccessUnit
|
||||||
* construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
|
* construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
|
||||||
@@ -1824,12 +1807,6 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
|||||||
|
|
||||||
WelsDecodeAccessUnitEnd (pCtx);
|
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) {
|
if (ERR_NONE != iErr) {
|
||||||
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "returned error from decoding:[0x%x]", iErr);
|
WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "returned error from decoding:[0x%x]", iErr);
|
||||||
return iErr;
|
return iErr;
|
||||||
@@ -2195,14 +2172,31 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf
|
|||||||
|
|
||||||
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
|
||||||
PAccessUnit pAu = pCtx->pAccessUnitList;
|
PAccessUnit pAu = pCtx->pAccessUnitList;
|
||||||
if (pAu->uiAvailUnitsNum == 0)
|
bool bAuBoundaryFlag = false;
|
||||||
return true;
|
if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) { //VCL data, AU list should have data
|
||||||
PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
|
PNalUnit pCurNal = pAu->pNalUnitsList[pAu->uiEndPos];
|
||||||
if ((pCtx->iTotalNumMbRec != 0)
|
bAuBoundaryFlag = (pCtx->iTotalNumMbRec != 0)
|
||||||
&& (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
|
&& (CheckAccessUnitBoundaryExt (&pCtx->sLastNalHdrExt, &pCurNal->sNalHeaderExt, &pCtx->sLastSliceHeader,
|
||||||
&pCurNal->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader))) {
|
&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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Do Error Concealment here
|
//Do Error Concealment here
|
||||||
if (NeedErrorCon (pCtx)) { //should always be true!
|
if (bAuBoundaryFlag && (pCtx->iTotalNumMbRec != 0) && NeedErrorCon (pCtx)) { //AU ready but frame not completely reconed
|
||||||
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
|
||||||
ImplementErrorCon (pCtx);
|
ImplementErrorCon (pCtx);
|
||||||
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
|
pCtx->iTotalNumMbRec = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight;
|
||||||
@@ -2225,7 +2219,6 @@ bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferIn
|
|||||||
if (pCtx->bLastHasMmco5)
|
if (pCtx->bLastHasMmco5)
|
||||||
pCtx->iPrevFrameNum = 0;
|
pCtx->iPrevFrameNum = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user