ref: 79ed7449234d5f076bf3fd950a203cae2944294a
parent: f141bd6170ffa57665e793ae95376b0460e6a768
author: Licai Guo <guolicai@gmail.com>
date: Wed Apr 16 14:27:08 EDT 2014
overwriteactivesps
--- a/codec/decoder/core/inc/decoder_context.h
+++ b/codec/decoder/core/inc/decoder_context.h
@@ -156,6 +156,13 @@
PExpandPictureFunc pExpandChromaPicture[2];
} SExpandPicFunc;
+enum {
+ OVERWRITE_NONE = 0,
+ OVERWRITE_PPS = 1,
+ OVERWRITE_SPS = 1 << 1,
+ OVERWRITE_SUBSETSPS = 1 << 2
+};
+
/*
* SWelsDecoderContext: to maintail all modules data over decoder@framework
*/
@@ -230,14 +237,14 @@
SPosOffset sFrameCrop;
- SSps sSpsBuffer[MAX_SPS_COUNT];
- SPps sPpsBuffer[MAX_PPS_COUNT];
+ SSps sSpsBuffer[MAX_SPS_COUNT + 1];
+ SPps sPpsBuffer[MAX_PPS_COUNT + 1];
PSliceHeader pSliceHeader;
PPicBuff pPicBuff[LIST_A]; // Initially allocated memory for pictures which are used in decoding.
int32_t iPicQueueNumber;
- SSubsetSps sSubsetSpsBuffer[MAX_SPS_COUNT];
+ SSubsetSps sSubsetSpsBuffer[MAX_SPS_COUNT + 1];
SNalUnit sPrefixNal;
PAccessUnit pAccessUnitList; // current access unit list to be performed
@@ -278,6 +285,7 @@
uint16_t uiCurIdrPicId;
#endif
bool bNewSeqBegin;
+ int iOverwriteFlags;
int32_t iErrorConMethod; //
PGetIntraPredFunc pGetI16x16LumaPredFunc[7]; //h264_predict_copy_16x16;
PGetIntraPredFunc pGetI4x4LumaPredFunc[14]; // h264_predict_4x4_t
--- a/codec/decoder/core/src/au_parser.cpp
+++ b/codec/decoder/core/src/au_parser.cpp
@@ -174,8 +174,6 @@
switch (pNalUnitHeader->eNalUnitType) {
case NAL_UNIT_SEI:
- case NAL_UNIT_SPS:
- case NAL_UNIT_PPS:
if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
pCtx->bAuReadyFlag = true;
@@ -730,6 +728,14 @@
return NULL;
}
+bool CheckSpsActive (PWelsDecoderContext pCtx, PSps pSps) {
+ for (int i = 0; i < MAX_LAYER_NUM; i++) {
+ if (pCtx->pActiveLayerSps[i] == pSps)
+ return true;
+ }
+ return false;
+}
+
#define SPS_LOG2_MAX_FRAME_NUM_MINUS4_MAX 12
#define SPS_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4_MAX 12
#define SPS_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE_MAX 255
@@ -792,15 +798,9 @@
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_SPS_ID_OVERFLOW);
}
iSpsId = uiCode;
-
- if (kbUseSubsetFlag) {
- pCtx->bSubspsAvailFlags[iSpsId] = false;
- } else {
- pCtx->bSpsAvailFlags[iSpsId] = false;
- }
pSubsetSps = &sTempSubsetSps;
pSps = &sTempSubsetSps.sSps;
- memset (pSubsetSps, 0, sizeof(SSubsetSps));
+ memset (pSubsetSps, 0, sizeof (SSubsetSps));
const SLevelLimits* pSLevelLimits = GetLevelLimits (uiLevelIdc, bConstraintSetFlags[3]);
if (NULL == pSLevelLimits) {
WelsLog (pCtx, WELS_LOG_WARNING, "ParseSps(): level_idx (%d).\n", uiLevelIdc);
@@ -897,7 +897,7 @@
WelsLog (pCtx, WELS_LOG_ERROR, "pic_width_in_mbs(%d) exceeds the maximum allowed!\n", pSps->iMbWidth);
return GENERATE_ERROR_NO (ERR_LEVEL_PARAM_SETS, ERR_INFO_INVALID_MAX_MB_SIZE);
}
- if (((uint64_t)pSps->iMbWidth * (uint64_t)pSps->iMbWidth) > (uint64_t)(8 * pSLevelLimits->iMaxFS)) {
+ if (((uint64_t)pSps->iMbWidth * (uint64_t)pSps->iMbWidth) > (uint64_t) (8 * pSLevelLimits->iMaxFS)) {
WelsLog (pCtx, WELS_LOG_WARNING, " the pic_width_in_mbs exceeds the level limits!\n");
}
WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //pic_height_in_map_units_minus1
@@ -978,12 +978,45 @@
*pPicWidth = pSps->iMbWidth << 4;
*pPicHeight = pSps->iMbHeight << 4;
+ PSps pTmpSps = NULL;
if (kbUseSubsetFlag) {
- memcpy (&pCtx->sSubsetSpsBuffer[iSpsId], pSubsetSps, sizeof(SSubsetSps));
+ pTmpSps = &pCtx->sSubsetSpsBuffer[iSpsId].sSps;
+ } else {
+ pTmpSps = &pCtx->sSpsBuffer[iSpsId];
+ }
+ if (CheckSpsActive (pCtx, pTmpSps)) {
+ // we are overwriting the active sps, copy a temp buffer
+ if (kbUseSubsetFlag) {
+ if (memcmp (&pCtx->sSubsetSpsBuffer[iSpsId], pSubsetSps, sizeof (SSubsetSps)) != 0) {
+ if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
+ memcpy (&pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT], pSubsetSps, sizeof (SSubsetSps));
+ pCtx->bAuReadyFlag = true;
+ pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
+ pCtx->iOverwriteFlags |= OVERWRITE_SUBSETSPS;
+ } else {
+ memcpy (&pCtx->sSubsetSpsBuffer[iSpsId], pSubsetSps, sizeof (SSubsetSps));
+ }
+ }
+ } else {
+ if (memcmp (&pCtx->sSpsBuffer[iSpsId], pSps, sizeof (SSps)) != 0) {
+ if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
+ memcpy (&pCtx->sSpsBuffer[MAX_SPS_COUNT], pSps, sizeof (SSps));
+ pCtx->iOverwriteFlags |= OVERWRITE_SPS;
+ pCtx->bAuReadyFlag = true;
+ pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
+ } else {
+ memcpy (&pCtx->sSpsBuffer[iSpsId], pSps, sizeof (SSps));
+ }
+ }
+ }
+ }
+ // Not overwrite active sps, just copy to final place
+ else if (kbUseSubsetFlag) {
+ memcpy (&pCtx->sSubsetSpsBuffer[iSpsId], pSubsetSps, sizeof (SSubsetSps));
pCtx->bSubspsAvailFlags[iSpsId] = true;
pCtx->bSubspsExistAheadFlag = true;
} else {
- memcpy (&pCtx->sSpsBuffer[iSpsId], pSps, sizeof(SSps));
+ memcpy (&pCtx->sSpsBuffer[iSpsId], pSps, sizeof (SSps));
pCtx->bSpsAvailFlags[iSpsId] = true;
pCtx->bSpsExistAheadFlag = true;
}
@@ -1018,10 +1051,8 @@
if (uiPpsId >= MAX_PPS_COUNT) {
return ERR_INFO_PPS_ID_OVERFLOW;
}
-
- pCtx->bPpsAvailFlags[uiPpsId] = false;
pPps = &sTempPps;
- memset (pPps, 0, sizeof(SPps));
+ memset (pPps, 0, sizeof (SPps));
pPps->iPpsId = uiPpsId;
WELS_READ_VERIFY (BsGetUe (pBsAux, &uiCode)); //seq_parameter_set_id
@@ -1102,10 +1133,23 @@
pPps->bConstainedIntraPredFlag = !!uiCode;
WELS_READ_VERIFY (BsGetOneBit (pBsAux, &uiCode)); //redundant_pic_cnt_present_flag
pPps->bRedundantPicCntPresentFlag = !!uiCode;
-
- memcpy (&pCtx->sPpsBuffer[uiPpsId], pPps, sizeof(SPps));
- pCtx->bPpsAvailFlags[uiPpsId] = true;
-
+ if (pCtx->pAccessUnitList->uiAvailUnitsNum > 0) {
+ PNalUnit pLastNalUnit = pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum - 1];
+ PPps pLastPps = pLastNalUnit->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps;
+ // the active pps is overwrite, write to a temp place
+ if (pLastPps == &pCtx->sPpsBuffer[uiPpsId] && memcmp (&pCtx->sPpsBuffer[uiPpsId], pPps, sizeof (*pPps)) != 0) {
+ memcpy (&pCtx->sPpsBuffer[MAX_PPS_COUNT], pPps, sizeof (SPps));
+ pCtx->iOverwriteFlags |= OVERWRITE_PPS;
+ pCtx->bAuReadyFlag = true;
+ pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1;
+ } else {
+ memcpy (&pCtx->sPpsBuffer[uiPpsId], pPps, sizeof (SPps));
+ pCtx->bPpsAvailFlags[uiPpsId] = true;
+ }
+ } else {
+ memcpy (&pCtx->sPpsBuffer[uiPpsId], pPps, sizeof (SPps));
+ pCtx->bPpsAvailFlags[uiPpsId] = true;
+ }
return ERR_NONE;
}
--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -61,7 +61,7 @@
extern void FreePicture (PPicture pPic);
inline void GetValueOf4Bytes (uint8_t* pDstNal, int32_t iDdstIdx) {
- ST32(pDstNal, iDdstIdx);
+ ST32 (pDstNal, iDdstIdx);
}
static int32_t CreatePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, const int32_t kiSize,
@@ -421,7 +421,7 @@
int32_t iSrcConsumed = 0; // consumed bit count of source bs
int32_t iDstIdx = 0; //the size of current NAL after 0x03 removal and 00 00 01 removal
int32_t iSrcLength = 0; //the total size of current AU or NAL
-
+ int32_t iRet = 0;
int32_t iConsumedBytes = 0;
int32_t iOffset = 0;
@@ -461,7 +461,9 @@
iConsumedBytes = 0;
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
-
+ if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
+ iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
+ }
if (pCtx->bAuReadyFlag) {
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
@@ -480,20 +482,17 @@
//Do error concealment here
ImplementErrorCon (pCtx);
}
-
- if ((IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) || IS_SEI_NAL (pCtx->sCurNalHead.eNalUnitType)) &&
- pNalPayload) {
- if (ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes)) {
- if (dsNoParamSets & pCtx->iErrorCode) {
+ if (iRet) {
+ iRet = 0;
+ if (dsNoParamSets & pCtx->iErrorCode) {
#ifdef LONG_TERM_REF
- pCtx->bParamSetsLostFlag = true;
+ pCtx->bParamSetsLostFlag = true;
#else
- pCtx->bReferenceLostAtT0Flag = true;
+ pCtx->bReferenceLostAtT0Flag = true;
#endif
- ResetParameterSetsState (pCtx);
- }
- return pCtx->iErrorCode;
+ ResetParameterSetsState (pCtx);
}
+ return pCtx->iErrorCode;
}
pDstNal += iDstIdx; //update current position
@@ -520,7 +519,9 @@
iConsumedBytes = 0;
pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes);
-
+ if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
+ iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
+ }
if (pCtx->bAuReadyFlag) {
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
@@ -536,22 +537,18 @@
//Do error concealment here
ImplementErrorCon (pCtx);
}
-
- if ((IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) || IS_SEI_NAL (pCtx->sCurNalHead.eNalUnitType))
- && pNalPayload) {
- if (ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes)) {
- if (dsNoParamSets & pCtx->iErrorCode) {
+ if (iRet) {
+ iRet = 0;
+ if (dsNoParamSets & pCtx->iErrorCode) {
#ifdef LONG_TERM_REF
- pCtx->bParamSetsLostFlag = true;
+ pCtx->bParamSetsLostFlag = true;
#else
- pCtx->bReferenceLostAtT0Flag = true;
+ pCtx->bReferenceLostAtT0Flag = true;
#endif
- ResetParameterSetsState (pCtx);
- }
- return pCtx->iErrorCode;
+ ResetParameterSetsState (pCtx);
}
+ return pCtx->iErrorCode;
}
-
pDstNal += iDstIdx;
pRawData->pCurPos = pDstNal; //init the pCurPos for next NAL(s) storage
} else { /* no supplementary picture payload input, but stored a picture */
@@ -574,7 +571,6 @@
ResetParameterSetsState (pCtx);
return pCtx->iErrorCode;
}
- //Do error concealment here
ImplementErrorCon (pCtx);
}
}
@@ -662,7 +658,7 @@
pCtx->pIdctResAddPredFunc = IdctResAddPred_c;
#if defined(HAVE_NEON)
- if ( pCtx->uiCpuFlag & WELS_CPU_NEON ) {
+ if (pCtx->uiCpuFlag & WELS_CPU_NEON) {
pCtx->pIdctResAddPredFunc = IdctResAddPred_neon;
pCtx->pGetI16x16LumaPredFunc[I16_PRED_DC] = WelsDecoderI16x16LumaPredDc_neon;
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -1505,6 +1505,20 @@
return bNewSeq;
}
+static void WriteBackActiveParameters(PWelsDecoderContext pCtx) {
+ if (pCtx->iOverwriteFlags & OVERWRITE_PPS) {
+ memcpy(&pCtx->sPpsBuffer[pCtx->sPpsBuffer[MAX_PPS_COUNT].iPpsId], &pCtx->sPpsBuffer[MAX_PPS_COUNT], sizeof(SPps));
+ pCtx->bNewSeqBegin = true;
+ }
+ if (pCtx->iOverwriteFlags & OVERWRITE_SPS) {
+ memcpy(&pCtx->sSpsBuffer[pCtx->sSpsBuffer[MAX_SPS_COUNT].iSpsId], &pCtx->sSpsBuffer[MAX_SPS_COUNT], sizeof(SSps));
+ pCtx->bNewSeqBegin = true;
+ }
+ if (pCtx->iOverwriteFlags & OVERWRITE_SUBSETSPS) {
+ memcpy(&pCtx->sSubsetSpsBuffer[pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT].sSps.iSpsId], &pCtx->sSubsetSpsBuffer[MAX_SPS_COUNT], sizeof(SSubsetSps));
+ }
+ pCtx->iOverwriteFlags = OVERWRITE_NONE;
+}
/*
* ConstructAccessUnit
* construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
@@ -1522,12 +1536,12 @@
int32_t iWidth;
int32_t iHeight;
int32_t iStride[2] = { 0 };
-
PAccessUnit pCurAu = pCtx->pAccessUnitList;
pCtx->bAuReadyFlag = false;
pCtx->bLastHasMmco5 = false;
- pCtx->bNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps(pCtx);
+ bool bTmpNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps(pCtx);
+ pCtx->bNewSeqBegin = pCtx->bNewSeqBegin && bTmpNewSeqBegin;
iErr = WelsDecodeAccessUnitStart (pCtx);
GetVclNalTemporalId (pCtx);
@@ -1558,6 +1572,7 @@
WelsDecodeAccessUnitEnd (pCtx);
pCtx->bNewSeqBegin = false;
+ WriteBackActiveParameters(pCtx);
if (ERR_NONE != iErr) {
WelsLog (pCtx, WELS_LOG_INFO, "returned error from decoding:[0x%x]\n", iErr);