Merge pull request #713 from licaiguo/overwriteactivesps
overwriteactivesps
This commit is contained in:
commit
7d99aa4e22
@ -156,6 +156,13 @@ typedef struct TagExpandPicFunc {
|
||||
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
|
||||
*/
|
||||
@ -231,14 +238,14 @@ typedef struct TagWelsDecoderContext {
|
||||
|
||||
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
|
||||
@ -279,6 +286,7 @@ typedef struct TagWelsDecoderContext {
|
||||
uint16_t uiCurIdrPicId;
|
||||
#endif
|
||||
bool bNewSeqBegin;
|
||||
int iOverwriteFlags;
|
||||
int32_t iErrorConMethod; //
|
||||
PPicture pPreviousDecodedPictureInDpb; //pointer to previously decoded picture in DPB for error concealment
|
||||
PGetIntraPredFunc pGetI16x16LumaPredFunc[7]; //h264_predict_copy_16x16;
|
||||
|
@ -174,8 +174,6 @@ uint8_t* ParseNalHeader (PWelsDecoderContext pCtx, SNalUnitHeader* pNalUnitHeade
|
||||
|
||||
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 @@ const SLevelLimits* GetLevelLimits (int32_t iLevelIdx, bool bConstraint3) {
|
||||
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 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
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 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
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 @@ int32_t ParseSps (PWelsDecoderContext pCtx, PBitStringAux pBsAux, int32_t* pPicW
|
||||
|
||||
*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 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
|
||||
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 @@ int32_t ParsePps (PWelsDecoderContext pCtx, PPps pPpsList, PBitStringAux pBsAux)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ extern PPicture AllocPicture (PWelsDecoderContext pCtx, const int32_t kiPicWidth
|
||||
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,
|
||||
@ -422,7 +422,7 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
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;
|
||||
|
||||
@ -462,7 +462,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 (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
|
||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
|
||||
}
|
||||
if (pCtx->bAuReadyFlag) {
|
||||
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||
|
||||
@ -481,20 +483,17 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
//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
|
||||
@ -521,7 +520,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 (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) && pNalPayload) {
|
||||
iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes);
|
||||
}
|
||||
if (pCtx->bAuReadyFlag) {
|
||||
ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
|
||||
|
||||
@ -537,22 +538,18 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
//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 */
|
||||
@ -575,7 +572,6 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in
|
||||
ResetParameterSetsState (pCtx);
|
||||
return pCtx->iErrorCode;
|
||||
}
|
||||
//Do error concealment here
|
||||
ImplementErrorCon (pCtx);
|
||||
}
|
||||
}
|
||||
@ -663,7 +659,7 @@ void AssignFuncPointerForRec (PWelsDecoderContext pCtx) {
|
||||
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;
|
||||
|
@ -1531,6 +1531,20 @@ static bool CheckNewSeqBeginAndUpdateActiveLayerSps(PWelsDecoderContext pCtx) {
|
||||
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
|
||||
@ -1548,12 +1562,12 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
||||
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);
|
||||
|
||||
@ -1584,6 +1598,7 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI
|
||||
|
||||
WelsDecodeAccessUnitEnd (pCtx);
|
||||
pCtx->bNewSeqBegin = false;
|
||||
WriteBackActiveParameters(pCtx);
|
||||
if (ERR_NONE != iErr) {
|
||||
WelsLog (pCtx, WELS_LOG_INFO, "returned error from decoding:[0x%x]\n", iErr);
|
||||
return iErr;
|
||||
|
Loading…
Reference in New Issue
Block a user