fix parseonly issues when bs is very large
Unified · Split
| @@ -104,11 +104,19 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 103 unmodified lines | |||
| 104 | pCtx->bParamSetsLostFlag = false; | 104 | pCtx->bParamSetsLostFlag = false; |
| 105 | //find required sps, pps and write into dst buff | 105 | //find required sps, pps and write into dst buff |
| 106 | pSpsBs = bSubSps ? &pCtx->sSubsetSpsBsInfo [iSpsId] : &pCtx->sSpsBsInfo [iSpsId]; | 106 | pSpsBs = bSubSps ? &pCtx->sSubsetSpsBsInfo [iSpsId] : &pCtx->sSpsBsInfo [iSpsId]; |
| 107 | pPpsBs = &pCtx->sPpsBsInfo [iPpsId]; | ||
| 108 | if (pDstBuf - pParser->pDstBuff + pSpsBs->uiSpsBsLen + pPpsBs->uiPpsBsLen >= MAX_ACCESS_UNIT_CAPACITY) { | ||
| 109 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, | ||
| 110 | "DecodeFrameConstruction(): sps pps size: (%d %d) too large. Failed to parse. \n", pSpsBs->uiSpsBsLen, | ||
| 111 | pPpsBs->uiPpsBsLen); | ||
| 112 | pCtx->iErrorCode |= dsOutOfMemory; | ||
| 113 | pCtx->pParserBsInfo->iNalNum = 0; | ||
| 114 | return ERR_INFO_OUT_OF_MEMORY; | ||
| 115 | } | ||
| 107 | memcpy (pDstBuf, pSpsBs->pSpsBsBuf, pSpsBs->uiSpsBsLen); | 116 | memcpy (pDstBuf, pSpsBs->pSpsBsBuf, pSpsBs->uiSpsBsLen); |
| 108 | pParser->iNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen; | 117 | pParser->iNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen; |
| 109 | pCtx->iNalLenInByte[pCtx->iNalNum ++] = pSpsBs->uiSpsBsLen; | 118 | pCtx->iNalLenInByte[pCtx->iNalNum ++] = pSpsBs->uiSpsBsLen; |
| 110 | pDstBuf += pSpsBs->uiSpsBsLen; | 119 | pDstBuf += pSpsBs->uiSpsBsLen; |
| 111 | pPpsBs = &pCtx->sPpsBsInfo [iPpsId]; | ||
| 112 | memcpy (pDstBuf, pPpsBs->pPpsBsBuf, pPpsBs->uiPpsBsLen); | 120 | memcpy (pDstBuf, pPpsBs->pPpsBsBuf, pPpsBs->uiPpsBsLen); |
| 113 | pParser->iNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen; | 121 | pParser->iNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen; |
| 114 | pDstBuf += pPpsBs->uiPpsBsLen; | 122 | pDstBuf += pPpsBs->uiPpsBsLen; |
| @@ -121,6 +129,15 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 6 unmodified lines | |||
| 121 | iNalLen = pCurNal->sNalData.sVclNal.iNalLength; | 129 | iNalLen = pCurNal->sNalData.sVclNal.iNalLength; |
| 122 | pNalBs = pCurNal->sNalData.sVclNal.pNalPos; | 130 | pNalBs = pCurNal->sNalData.sVclNal.pNalPos; |
| 123 | pParser->iNalLenInByte [pParser->iNalNum ++] = iNalLen; | 131 | pParser->iNalLenInByte [pParser->iNalNum ++] = iNalLen; |
| 132 | if (pDstBuf - pParser->pDstBuff + iNalLen >= MAX_ACCESS_UNIT_CAPACITY) { | ||
| 133 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, | ||
| 134 | "DecodeFrameConstruction(): composed output size (%ld) exceeds (%d). Failed to parse. \n", | ||
| 135 | (long) (pDstBuf - pParser->pDstBuff + iNalLen), MAX_ACCESS_UNIT_CAPACITY); | ||
| 136 | pCtx->iErrorCode |= dsOutOfMemory; | ||
| 137 | pCtx->pParserBsInfo->iNalNum = 0; | ||
| 138 | return ERR_INFO_OUT_OF_MEMORY; | ||
| 139 | } | ||
| 140 | |||
| 124 | memcpy (pDstBuf, pNalBs, iNalLen); | 141 | memcpy (pDstBuf, pNalBs, iNalLen); |
| 125 | pDstBuf += iNalLen; | 142 | pDstBuf += iNalLen; |
| 126 | } | 143 | } |
| @@ -497,6 +514,8 @@ int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int kiSrcLen) { · 370 unmodified lines | |||
| 497 | int32_t iNewBuffLen = WELS_MAX ((kiSrcLen * MAX_BUFFERED_NUM), (pCtx->iMaxBsBufferSizeInByte << iExpandStepShift)); | 514 | int32_t iNewBuffLen = WELS_MAX ((kiSrcLen * MAX_BUFFERED_NUM), (pCtx->iMaxBsBufferSizeInByte << iExpandStepShift)); |
| 498 | //allocate new bs buffer | 515 | //allocate new bs buffer |
| 499 | CMemoryAlign* pMa = pCtx->pMemAlign; | 516 | CMemoryAlign* pMa = pCtx->pMemAlign; |
| 517 | |||
| 518 | //Realloc sRawData | ||
| 500 | uint8_t* pNewBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sRawData.pHead")); | 519 | uint8_t* pNewBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sRawData.pHead")); |
| 501 | if (pNewBsBuff == NULL) | 520 | if (pNewBsBuff == NULL) |
| 502 | return ERR_INFO_OUT_OF_MEMORY; | 521 | return ERR_INFO_OUT_OF_MEMORY; |
| @@ -511,12 +530,28 @@ int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int kiSrcLen) { · 8 unmodified lines | |||
| 511 | 530 | ||
| 512 | //Copy current buffer status to new buffer | 531 | //Copy current buffer status to new buffer |
| 513 | memcpy (pNewBsBuff, pCtx->sRawData.pHead, pCtx->iMaxBsBufferSizeInByte); | 532 | memcpy (pNewBsBuff, pCtx->sRawData.pHead, pCtx->iMaxBsBufferSizeInByte); |
| 514 | pCtx->iMaxBsBufferSizeInByte = iNewBuffLen; | ||
| 515 | pCtx->sRawData.pStartPos = pNewBsBuff + (pCtx->sRawData.pStartPos - pCtx->sRawData.pHead); | 533 | pCtx->sRawData.pStartPos = pNewBsBuff + (pCtx->sRawData.pStartPos - pCtx->sRawData.pHead); |
| 516 | pCtx->sRawData.pCurPos = pNewBsBuff + (pCtx->sRawData.pCurPos - pCtx->sRawData.pHead); | 534 | pCtx->sRawData.pCurPos = pNewBsBuff + (pCtx->sRawData.pCurPos - pCtx->sRawData.pHead); |
| 517 | pCtx->sRawData.pEnd = pNewBsBuff + iNewBuffLen; | 535 | pCtx->sRawData.pEnd = pNewBsBuff + iNewBuffLen; |
| 518 | pMa->WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData.pHead"); | 536 | pMa->WelsFree (pCtx->sRawData.pHead, "pCtx->sRawData.pHead"); |
| 519 | pCtx->sRawData.pHead = pNewBsBuff; | 537 | pCtx->sRawData.pHead = pNewBsBuff; |
| 538 | |||
| 539 | if (pCtx->pParam->bParseOnly) { | ||
| 540 | //Realloc sSavedData | ||
| 541 | uint8_t* pNewSavedBsBuff = static_cast<uint8_t*> (pMa->WelsMallocz (iNewBuffLen, "pCtx->sSavedData.pHead")); | ||
| 542 | if (pNewSavedBsBuff == NULL) | ||
| 543 | return ERR_INFO_OUT_OF_MEMORY; | ||
| 544 | |||
| 545 | //Copy current buffer status to new buffer | ||
| 546 | memcpy (pNewSavedBsBuff, pCtx->sSavedData.pHead, pCtx->iMaxBsBufferSizeInByte); | ||
| 547 | pCtx->sSavedData.pStartPos = pNewSavedBsBuff + (pCtx->sSavedData.pStartPos - pCtx->sSavedData.pHead); | ||
| 548 | pCtx->sSavedData.pCurPos = pNewSavedBsBuff + (pCtx->sSavedData.pCurPos - pCtx->sSavedData.pHead); | ||
| 549 | pCtx->sSavedData.pEnd = pNewSavedBsBuff + iNewBuffLen; | ||
| 550 | pMa->WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData.pHead"); | ||
| 551 | pCtx->sSavedData.pHead = pNewSavedBsBuff; | ||
| 552 | } | ||
| 553 | |||
| 554 | pCtx->iMaxBsBufferSizeInByte = iNewBuffLen; | ||
| 520 | return ERR_NONE; | 555 | return ERR_NONE; |
| 521 | } | 556 | } |
| 522 | 557 | ||
| @@ -458,7 +458,10 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, · 457 unmodified lines | |||
| 458 | return dsInvalidArgument; | 458 | return dsInvalidArgument; |
| 459 | } | 459 | } |
| 460 | if (CheckBsBuffer (m_pDecContext, kiSrcLen)) { | 460 | if (CheckBsBuffer (m_pDecContext, kiSrcLen)) { |
| 461 | return dsOutOfMemory; | 461 | if (ResetDecoder()) |
| 462 | return dsOutOfMemory; | ||
| 463 | |||
| 464 | return dsErrorFree; | ||
| 462 | } | 465 | } |
| 463 | if (kiSrcLen > 0 && kpSrc != NULL) { | 466 | if (kiSrcLen > 0 && kpSrc != NULL) { |
| 464 | #ifdef OUTPUT_BIT_STREAM | 467 | #ifdef OUTPUT_BIT_STREAM |
| @@ -513,6 +516,8 @@ DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, · 48 unmodified lines | |||
| 513 | if (m_pDecContext->iErrorCode & dsOutOfMemory) { | 516 | if (m_pDecContext->iErrorCode & dsOutOfMemory) { |
| 514 | if (ResetDecoder()) | 517 | if (ResetDecoder()) |
| 515 | return dsOutOfMemory; | 518 | return dsOutOfMemory; |
| 519 | |||
| 520 | return dsErrorFree; | ||
| 516 | } | 521 | } |
| 517 | //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss. | 522 | //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss. |
| 518 | if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) || | 523 | if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) || |
| @@ -611,7 +616,10 @@ DECODING_STATE CWelsDecoder::DecodeParser (const unsigned char* kpSrc, · 92 unmodified lines | |||
| 611 | return dsInvalidArgument; | 616 | return dsInvalidArgument; |
| 612 | } | 617 | } |
| 613 | if (CheckBsBuffer (m_pDecContext, kiSrcLen)) { | 618 | if (CheckBsBuffer (m_pDecContext, kiSrcLen)) { |
| 614 | return dsOutOfMemory; | 619 | if (ResetDecoder()) |
| 620 | return dsOutOfMemory; | ||
| 621 | |||
| 622 | return dsErrorFree; | ||
| 615 | } | 623 | } |
| 616 | if (kiSrcLen > 0 && kpSrc != NULL) { | 624 | if (kiSrcLen > 0 && kpSrc != NULL) { |
| 617 | #ifdef OUTPUT_BITSTREAM | 625 | #ifdef OUTPUT_BITSTREAM |