Merge pull request #713 from licaiguo/overwriteactivesps

overwriteactivesps
This commit is contained in:
huili2 2014-04-18 13:16:18 +08:00
commit 7d99aa4e22
4 changed files with 114 additions and 51 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;