Showing the changes to codec/decoder/core/src/decoder_core.cpp (1 of 8 files). Show all
Unified · Split
| @@ -81,7 +81,7 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 80 unmodified lines | ||
| 81 | 81 | int32_t iNalLen = 0; |
| 82 | 82 | int32_t iNum = 0; |
| 83 | 83 | while (iNum < pParser->iNalNum) { |
| 84 | − iTotalNalLen += pParser->iNalLenInByte[iNum++]; | |
| 84 | + iTotalNalLen += pParser->pNalLenInByte[iNum++]; | |
| 85 | 85 | } |
| 86 | 86 | uint8_t* pDstBuf = pParser->pDstBuff + iTotalNalLen; |
| 87 | 87 | int32_t iIdx = pCurAu->uiStartPos; |
| @@ -96,6 +96,12 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 8 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | if (pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.bIdrFlag) { //IDR |
| 98 | 98 | if (pCtx->bFrameFinish) { //add required sps/pps |
| 99 | + if (pParser->iNalNum > pCtx->iMaxNalNum - 2) { //2 reserved for sps+pps | |
| 100 | + WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, | |
| 101 | + "DecodeFrameConstruction(): current NAL num (%d) plus sps & pps exceeds permitted num (%d). Will expand", | |
| 102 | + pParser->iNalNum, pCtx->iMaxNalNum); | |
| 103 | + WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, ExpandBsLenBuffer (pCtx, pParser->iNalNum + 2)) | |
| 104 | + } | |
| 99 | 105 | bool bSubSps = (NAL_UNIT_CODED_SLICE_EXT == pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.sNalUnitHeader.eNalUnitType); |
| 100 | 106 | SSpsBsInfo* pSpsBs = NULL; |
| 101 | 107 | SPpsBsInfo* pPpsBs = NULL; |
| @@ -114,21 +120,26 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 12 unmodified lines | ||
| 114 | 120 | return ERR_INFO_OUT_OF_MEMORY; |
| 115 | 121 | } |
| 116 | 122 | memcpy (pDstBuf, pSpsBs->pSpsBsBuf, pSpsBs->uiSpsBsLen); |
| 117 | − pParser->iNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen; | |
| 118 | − pCtx->iNalLenInByte[pCtx->iNalNum ++] = pSpsBs->uiSpsBsLen; | |
| 123 | + pParser->pNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen; | |
| 119 | 124 | pDstBuf += pSpsBs->uiSpsBsLen; |
| 120 | 125 | memcpy (pDstBuf, pPpsBs->pPpsBsBuf, pPpsBs->uiPpsBsLen); |
| 121 | − pParser->iNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen; | |
| 126 | + pParser->pNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen; | |
| 122 | 127 | pDstBuf += pPpsBs->uiPpsBsLen; |
| 123 | 128 | pCtx->bFrameFinish = false; |
| 124 | 129 | } |
| 125 | 130 | } |
| 126 | 131 | //then VCL data re-write |
| 132 | + if (pParser->iNalNum + iEndIdx - iIdx + 1 > pCtx->iMaxNalNum) { //calculate total NAL num | |
| 133 | + WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, | |
| 134 | + "DecodeFrameConstruction(): current NAL num (%d) exceeds permitted num (%d). Will expand", | |
| 135 | + pParser->iNalNum + iEndIdx - iIdx + 1, pCtx->iMaxNalNum); | |
| 136 | + WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, ExpandBsLenBuffer (pCtx, pParser->iNalNum + iEndIdx - iIdx + 1)) | |
| 137 | + } | |
| 127 | 138 | while (iIdx <= iEndIdx) { |
| 128 | 139 | pCurNal = pCurAu->pNalUnitsList [iIdx ++]; |
| 129 | 140 | iNalLen = pCurNal->sNalData.sVclNal.iNalLength; |
| 130 | 141 | pNalBs = pCurNal->sNalData.sVclNal.pNalPos; |
| 131 | − pParser->iNalLenInByte [pParser->iNalNum ++] = iNalLen; | |
| 142 | + pParser->pNalLenInByte [pParser->iNalNum ++] = iNalLen; | |
| 132 | 143 | if (pDstBuf - pParser->pDstBuff + iNalLen >= MAX_ACCESS_UNIT_CAPACITY) { |
| 133 | 144 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, |
| 134 | 145 | "DecodeFrameConstruction(): composed output size (%ld) exceeds (%d). Failed to parse. current data pos %d out of %d:, previously accumulated num: %d, total num: %d, previously accumulated len: %d, current len: %d, current buf pos: %p, header buf pos: %p \n", |
| @@ -504,6 +515,13 @@ int32_t InitBsBuffer (PWelsDecoderContext pCtx) { · 369 unmodified lines | ||
| 504 | 515 | } |
| 505 | 516 | pCtx->sSavedData.pStartPos = pCtx->sSavedData.pCurPos = pCtx->sSavedData.pHead; |
| 506 | 517 | pCtx->sSavedData.pEnd = pCtx->sSavedData.pHead + pCtx->iMaxBsBufferSizeInByte; |
| 518 | + | |
| 519 | + pCtx->iMaxNalNum = MAX_NAL_UNITS_IN_LAYER + 2; //2 reserved for SPS+PPS | |
| 520 | + pCtx->pParserBsInfo->pNalLenInByte = static_cast<int*> (pMa->WelsMallocz (pCtx->iMaxNalNum * sizeof (int), | |
| 521 | + "pCtx->pParserBsInfo->pNalLenInByte")); | |
| 522 | + if (pCtx->pParserBsInfo->pNalLenInByte == NULL) { | |
| 523 | + return ERR_INFO_OUT_OF_MEMORY; | |
| 524 | + } | |
| 507 | 525 | } |
| 508 | 526 | return ERR_NONE; |
| 509 | 527 | } |
| @@ -562,6 +580,37 @@ int32_t ExpandBsBuffer (PWelsDecoderContext pCtx, const int kiSrcLen) { · 52 unmodified lines | ||
| 562 | 580 | return ERR_NONE; |
| 563 | 581 | } |
| 564 | 582 | |
| 583 | +int32_t ExpandBsLenBuffer (PWelsDecoderContext pCtx, const int kiCurrLen) { | |
| 584 | + SParserBsInfo* pParser = pCtx->pParserBsInfo; | |
| 585 | + if (!pParser->pNalLenInByte) | |
| 586 | + return ERR_INFO_INVALID_ACCESS; | |
| 587 | + | |
| 588 | + int iNewLen = kiCurrLen; | |
| 589 | + if (kiCurrLen >= MAX_MB_SIZE + 2) { //exceeds the max MB number of level 5.2 | |
| 590 | + WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Current nal num (%d) exceededs %d.", kiCurrLen, MAX_MB_SIZE); | |
| 591 | + pCtx->iErrorCode |= dsOutOfMemory; | |
| 592 | + return ERR_INFO_OUT_OF_MEMORY; | |
| 593 | + } else { | |
| 594 | + iNewLen = kiCurrLen << 1; | |
| 595 | + iNewLen = WELS_MIN (iNewLen, MAX_MB_SIZE + 2); | |
| 596 | + } | |
| 597 | + | |
| 598 | + CMemoryAlign* pMa = pCtx->pMemAlign; | |
| 599 | + int* pNewLenBuffer = static_cast<int*> (pMa->WelsMallocz (iNewLen * sizeof (int), | |
| 600 | + "pCtx->pParserBsInfo->pNalLenInByte")); | |
| 601 | + if (pNewLenBuffer == NULL) { | |
| 602 | + pCtx->iErrorCode |= dsOutOfMemory; | |
| 603 | + return ERR_INFO_OUT_OF_MEMORY; | |
| 604 | + } | |
| 605 | + | |
| 606 | + //copy existing data from old length buffer to new | |
| 607 | + memcpy (pNewLenBuffer, pParser->pNalLenInByte, pCtx->iMaxNalNum * sizeof (int)); | |
| 608 | + pMa->WelsFree (pParser->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte"); | |
| 609 | + pParser->pNalLenInByte = pNewLenBuffer; | |
| 610 | + pCtx->iMaxNalNum = iNewLen; | |
| 611 | + return ERR_NONE; | |
| 612 | +} | |
| 613 | + | |
| 565 | 614 | int32_t CheckBsBuffer (PWelsDecoderContext pCtx, const int32_t kiSrcLen) { |
| 566 | 615 | if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY) { //exceeds max allowed data |
| 567 | 616 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Max AU size exceeded. Allowed size = %d, current size = %d", |
| @@ -633,6 +682,11 @@ void WelsFreeStaticMemory (PWelsDecoderContext pCtx) { · 65 unmodified lines | ||
| 633 | 682 | pCtx->sSavedData.pStartPos = NULL; |
| 634 | 683 | pCtx->sSavedData.pCurPos = NULL; |
| 635 | 684 | if (pCtx->pParserBsInfo) { |
| 685 | + if (pCtx->pParserBsInfo->pNalLenInByte) { | |
| 686 | + pMa->WelsFree (pCtx->pParserBsInfo->pNalLenInByte, "pCtx->pParserBsInfo->pNalLenInByte"); | |
| 687 | + pCtx->pParserBsInfo->pNalLenInByte = NULL; | |
| 688 | + pCtx->iMaxNalNum = 0; | |
| 689 | + } | |
| 636 | 690 | if (pCtx->pParserBsInfo->pDstBuff) { |
| 637 | 691 | pMa->WelsFree (pCtx->pParserBsInfo->pDstBuff, "pCtx->pParserBsInfo->pDstBuff"); |
| 638 | 692 | pCtx->pParserBsInfo->pDstBuff = NULL; |