ref: 2e5f1b213478bfe830ad846088d6ad14c1400dd5
parent: 3efc32a15e9773b6023805033d7b74f75862b8a6
parent: 0fc550221585d252f2beb3b6720469875673910b
author: huili2 <huili2@cisco.com>
date: Wed Feb 27 09:04:37 EST 2019
Merge pull request #3100 from xiaotiansf/NewBugzilla2 Fix Issues 13030 and 13039 in oss-fuzz.
--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -78,13 +78,14 @@
/**
* Errors derived from bitstream parsing
*/
- dsErrorFree = 0x00, ///< bit stream error-free
- dsFramePending = 0x01, ///< need more throughput to generate a frame output,
- dsRefLost = 0x02, ///< layer lost at reference frame with temporal id 0
- dsBitstreamError = 0x04, ///< error bitstreams(maybe broken internal frame) the decoder cared
- dsDepLayerLost = 0x08, ///< dependented layer is ever lost
- dsNoParamSets = 0x10, ///< no parameter set NALs involved
- dsDataErrorConcealed = 0x20, ///< current data error concealed specified
+ dsErrorFree = 0x00, ///< bit stream error-free
+ dsFramePending = 0x01, ///< need more throughput to generate a frame output,
+ dsRefLost = 0x02, ///< layer lost at reference frame with temporal id 0
+ dsBitstreamError = 0x04, ///< error bitstreams(maybe broken internal frame) the decoder cared
+ dsDepLayerLost = 0x08, ///< dependented layer is ever lost
+ dsNoParamSets = 0x10, ///< no parameter set NALs involved
+ dsDataErrorConcealed = 0x20, ///< current data error concealed specified
+ dsRefListNullPtrs = 0x40, ///<ref picure list contains null ptrs within uiRefCount range
/**
* Errors derived from logic level
--- a/codec/decoder/core/src/decode_slice.cpp
+++ b/codec/decoder/core/src/decode_slice.cpp
@@ -56,6 +56,28 @@
extern PPicture AllocPicture (PWelsDecoderContext pCtx, const int32_t kiPicWidth, const int32_t kiPicHeight);
+static bool CheckRefPics (const PWelsDecoderContext& pCtx) {
+ int32_t listCount = 1;
+ if (pCtx->eSliceType == B_SLICE) {
+ ++listCount;
+ }
+ for (int32_t list = LIST_0; list < listCount; ++list) {
+ int32_t shortRefCount = pCtx->sRefPic.uiShortRefCount[list];
+ for (int32_t refIdx = 0; refIdx < shortRefCount; ++refIdx) {
+ if (!pCtx->sRefPic.pShortRefList[list][refIdx]) {
+ return false;
+ }
+ }
+ int32_t longRefCount = pCtx->sRefPic.uiLongRefCount[list];
+ for (int32_t refIdx = 0; refIdx < longRefCount; ++refIdx) {
+ if (!pCtx->sRefPic.pLongRefList[list][refIdx]) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
int32_t WelsTargetSliceConstruction (PWelsDecoderContext pCtx) {
PDqLayer pCurLayer = pCtx->pCurDqLayer;
PSlice pCurSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
@@ -318,7 +340,10 @@
WelsMbIntraPredictionConstruction (pCtx, pCurLayer, 1);
} else if (IS_INTER (pCurLayer->pMbType[pCurLayer->iMbXyIndex])) { //InterMB
if (0 == pCurLayer->pCbp[pCurLayer->iMbXyIndex]) { //uiCbp==0 include SKIP
- WelsMbInterPrediction (pCtx, pCurLayer);
+ if (!CheckRefPics (pCtx)) {
+ return ERR_INFO_MB_RECON_FAIL;
+ }
+ return WelsMbInterPrediction (pCtx, pCurLayer);
} else {
WelsMbInterConstruction (pCtx, pCurLayer);
}
@@ -2783,7 +2808,7 @@
return ERR_NONE;
}
-void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu) {
+void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu) {
pFunc->pWelsSetNonZeroCountFunc = WelsNonZeroCount_c;
pFunc->pWelsBlockZero16x16Func = WelsBlockZero16x16_c;
pFunc->pWelsBlockZero8x8Func = WelsBlockZero8x8_c;
--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -165,6 +165,24 @@
return ERR_NONE;
}
+static void ResetRefPicReferences (const PWelsDecoderContext& pCtx, const PPicture& inPPic) {
+ //seach and reset the references of deleted references.
+ for (int32_t list = LIST_0; list < LIST_A; ++list) {
+ int32_t refIdx = 0;
+ PPicture pPic = pCtx->sRefPic.pRefList[list][refIdx];
+ while (refIdx < MAX_DPB_COUNT && pPic != NULL) {
+ ++refIdx;
+ int32_t ref = 0;
+ while (ref < MAX_DPB_COUNT && *pPic->pRefPic[ref] != NULL) {
+ if (*pPic->pRefPic[ref] == inPPic) {
+ *pPic->pRefPic[ref] = NULL;
+ }
+ ++ref;
+ }
+ }
+ }
+}
+
static int32_t DecreasePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, const int32_t kiOldSize,
const int32_t kiPicWidth, const int32_t kiPicHeight, const int32_t kiNewSize) {
PPicBuff pPicOldBuf = *ppPicBuf;
@@ -212,6 +230,7 @@
for (iPicIdx = iDelIdx; iPicIdx < kiOldSize; iPicIdx++) {
if (iPrevPicIdx != iPicIdx) {
if (pPicOldBuf->ppPic[iPicIdx] != NULL) {
+ ResetRefPicReferences (pCtx, pPicOldBuf->ppPic[iPicIdx]);
FreePicture (pPicOldBuf->ppPic[iPicIdx], pMa);
pPicOldBuf->ppPic[iPicIdx] = NULL;
}
@@ -826,7 +845,8 @@
const int32_t kiPicWidth = kiMbWidth << 4;
const int32_t kiPicHeight = kiMbHeight << 4;
//fix Bugzilla Bug1479656 reallocate temp dec picture
- if (pCtx->pTempDec != NULL) {
+ if (pCtx->pTempDec != NULL && (pCtx->pTempDec->iWidthInPixel != kiPicWidth
+ || pCtx->pTempDec->iHeightInPixel != kiPicHeight)) {
FreePicture (pCtx->pTempDec, pCtx->pMemAlign);
pCtx->pTempDec = AllocPicture (pCtx, pCtx->pSps->iMbWidth << 4, pCtx->pSps->iMbHeight << 4);
}
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -2720,7 +2720,10 @@
DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future use
if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) {
- MarkECFrameAsRef (pCtx);
+ if (MarkECFrameAsRef (pCtx) == ERR_INFO_INVALID_PTR) {
+ pCtx->iErrorCode |= dsRefListNullPtrs;
+ return false;
+ }
}
} else if (pCtx->pParam->bParseOnly) { //clear parse only internal data status
pCtx->pParserBsInfo->iNalNum = 0;
--- a/codec/decoder/core/src/manage_dec_ref.cpp
+++ b/codec/decoder/core/src/manage_dec_ref.cpp
@@ -792,6 +792,9 @@
if (pRefPic->uiShortRefCount[LIST_0] > 0) {
// Check the duplicate frame_num in short ref list
for (int32_t iPos = 0; iPos < pRefPic->uiShortRefCount[LIST_0]; iPos++) {
+ if (!pRefPic->pShortRefList[LIST_0][iPos]) {
+ return ERR_INFO_INVALID_PTR;
+ }
if (pPic->iFrameNum == pRefPic->pShortRefList[LIST_0][iPos]->iFrameNum) {
// Replace the previous ref pic with the new one with the same frame_num
pRefPic->pShortRefList[LIST_0][iPos] = pPic;
@@ -819,6 +822,9 @@
pRefPic->pLongRefList[LIST_0][pRefPic->uiLongRefCount[LIST_0]] = pPic;
} else {
for (i = 0; i < pRefPic->uiLongRefCount[LIST_0]; i++) {
+ if (!pRefPic->pLongRefList[LIST_0][i]) {
+ return ERR_INFO_INVALID_PTR;
+ }
if (pRefPic->pLongRefList[LIST_0][i]->iLongTermFrameIdx > pPic->iLongTermFrameIdx) {
break;
}
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -593,6 +593,12 @@
}
return dsErrorFree;
}
+ if (m_pDecContext->iErrorCode & dsRefListNullPtrs) {
+ if (ResetDecoder()) {
+ return dsRefListNullPtrs;
+ }
+ return dsErrorFree;
+ }
//for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss.
if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) ||
(VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) {