Showing the changes to codec/decoder/core/src/decoder_core.cpp (1 of 5 files). Show all
Unified · Split
| @@ -72,6 +72,79 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 71 unmodified lines | ||
| 72 | 72 | } |
| 73 | 73 | } |
| 74 | 74 | |
| 75 | + if (pCtx->bParseOnly) { //should exit for parse only to prevent access NULL pDstInfo | |
| 76 | + PAccessUnit pCurAu = pCtx->pAccessUnitList; | |
| 77 | + static bool bFirstIDR = true; | |
| 78 | + if (dsErrorFree == pCtx->iErrorCode) { //correct decoding, add to data buffer | |
| 79 | + SParserBsInfo* pParser = pCtx->pParserBsInfo; | |
| 80 | + SNalUnit* pCurNal = NULL; | |
| 81 | + int32_t iTotalNalLen = 0; | |
| 82 | + int32_t iNalLen = 0; | |
| 83 | + int32_t iNum = 0; | |
| 84 | + while (iNum < pParser->iNalNum) { | |
| 85 | + iTotalNalLen += pParser->iNalLenInByte[iNum++]; | |
| 86 | + } | |
| 87 | + uint8_t* pDstBuf = pParser->pDstBuff + iTotalNalLen; | |
| 88 | + int32_t iIdx = pCurAu->uiStartPos; | |
| 89 | + int32_t iEndIdx = pCurAu->uiEndPos; | |
| 90 | + uint8_t* pNalBs = NULL; | |
| 91 | + pParser->uiOutBsTimeStamp = (pCurAu->pNalUnitsList [iIdx]) ? pCurAu->pNalUnitsList [iIdx]->uiTimeStamp : 0; | |
| 92 | + //pParser->iNalNum = 0; | |
| 93 | + pParser->iSpsWidthInPixel = (pCtx->pSps->iMbWidth << 4); | |
| 94 | + pParser->iSpsHeightInPixel = (pCtx->pSps->iMbHeight << 4); | |
| 95 | + | |
| 96 | + if (pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.bIdrFlag) { //IDR | |
| 97 | + if (bFirstIDR) { //add required sps/pps | |
| 98 | + bool bSubSps = (NAL_UNIT_CODED_SLICE_EXT == pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.sNalUnitHeader.eNalUnitType); | |
| 99 | + SSpsBsInfo* pSpsBs = NULL; | |
| 100 | + SPpsBsInfo* pPpsBs = NULL; | |
| 101 | + int32_t iSpsId = pCtx->pSps->iSpsId; | |
| 102 | + int32_t iPpsId = pCtx->pPps->iPpsId; | |
| 103 | + pCtx->bParamSetsLostFlag = false; | |
| 104 | + //find required sps, pps and write into dst buff | |
| 105 | + pSpsBs = bSubSps ? &pCtx->sSubsetSpsBsInfo [iSpsId] : &pCtx->sSpsBsInfo [iSpsId]; | |
| 106 | + memcpy (pDstBuf, pSpsBs->pSpsBsBuf, pSpsBs->uiSpsBsLen); | |
| 107 | + pParser->iNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen; | |
| 108 | + pCtx->iNalLenInByte[pCtx->iNalNum ++] = pSpsBs->uiSpsBsLen; | |
| 109 | + pDstBuf += pSpsBs->uiSpsBsLen; | |
| 110 | + pPpsBs = &pCtx->sPpsBsInfo [iPpsId]; | |
| 111 | + memcpy (pDstBuf, pPpsBs->pPpsBsBuf, pPpsBs->uiPpsBsLen); | |
| 112 | + pParser->iNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen; | |
| 113 | + pDstBuf += pPpsBs->uiPpsBsLen; | |
| 114 | + bFirstIDR = false; | |
| 115 | + } | |
| 116 | + } else { //IDR required SPS, PPS | |
| 117 | + bFirstIDR = true; | |
| 118 | + } | |
| 119 | + //then VCL data re-write | |
| 120 | + while (iIdx <= iEndIdx) { | |
| 121 | + pCurNal = pCurAu->pNalUnitsList [iIdx ++]; | |
| 122 | + iNalLen = pCurNal->sNalData.sVclNal.iNalLength; | |
| 123 | + pNalBs = pCurNal->sNalData.sVclNal.pNalPos; | |
| 124 | + pParser->iNalLenInByte [pParser->iNalNum ++] = iNalLen; | |
| 125 | + memcpy (pDstBuf, pNalBs, iNalLen); | |
| 126 | + pDstBuf += iNalLen; | |
| 127 | + } | |
| 128 | + if (pCtx->iTotalNumMbRec == kiTotalNumMbInCurLayer) { //frame complete | |
| 129 | + pCtx->iTotalNumMbRec = 0; | |
| 130 | + pCtx->bFramePending = false; | |
| 131 | + } else if (pCtx->iTotalNumMbRec != 0) { //frame incomplete | |
| 132 | + pCtx->bFramePending = true; | |
| 133 | + pCtx->pDec->bIsComplete = false; | |
| 134 | + pCtx->iErrorCode |= dsFramePending; | |
| 135 | + return -1; | |
| 136 | + //pCtx->pParserBsInfo->iNalNum = 0; | |
| 137 | + } | |
| 138 | + } else { //error | |
| 139 | + pCtx->pParserBsInfo->uiOutBsTimeStamp = 0; | |
| 140 | + pCtx->pParserBsInfo->iNalNum = 0; | |
| 141 | + pCtx->pParserBsInfo->iSpsWidthInPixel = 0; | |
| 142 | + pCtx->pParserBsInfo->iSpsHeightInPixel = 0; | |
| 143 | + return -1; | |
| 144 | + } | |
| 145 | + return 0; | |
| 146 | + } | |
| 147 | + | |
| 75 | 148 | if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) { |
| 76 | 149 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, |
| 77 | 150 | "DecodeFrameConstruction(): iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d ", |
| @@ -87,15 +160,6 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 9 unmodified lines | ||
| 87 | 160 | |
| 88 | 161 | pCtx->iTotalNumMbRec = 0; |
| 89 | 162 | |
| 90 | − if (pCtx->bParseOnly) { //should exit for parse only to prevent access NULL pDstInfo | |
| 91 | − if (bFrameCompleteFlag) | |
| 92 | − return 0; | |
| 93 | − else { //incomplete frame | |
| 94 | − pCtx->pDec->bIsComplete = false; | |
| 95 | − return -1; | |
| 96 | − } | |
| 97 | − } | |
| 98 | − | |
| 99 | 163 | //////output:::normal path |
| 100 | 164 | pDstInfo->uiOutYuvTimeStamp = pPic->uiTimeStamp; |
| 101 | 165 | ppDst[0] = pPic->pData[0]; |
| @@ -401,6 +465,18 @@ int32_t InitBsBuffer (PWelsDecoderContext pCtx) { · 299 unmodified lines | ||
| 401 | 465 | pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead; |
| 402 | 466 | pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte; |
| 403 | 467 | if (pCtx->bParseOnly) { |
| 468 | + pCtx->pParserBsInfo = static_cast<SParserBsInfo*> (WelsMallocz (sizeof (SParserBsInfo), "pCtx->pParserBsInfo")); | |
| 469 | + if (pCtx->pParserBsInfo == NULL) { | |
| 470 | + return ERR_INFO_OUT_OF_MEMORY; | |
| 471 | + } | |
| 472 | + memset (pCtx->pParserBsInfo, 0, sizeof (SParserBsInfo)); | |
| 473 | + pCtx->pParserBsInfo->pDstBuff = static_cast<uint8_t*> (WelsMallocz (MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t), | |
| 474 | + "pCtx->pParserBsInfo->pDstBuff")); | |
| 475 | + if (pCtx->pParserBsInfo->pDstBuff == NULL) { | |
| 476 | + return ERR_INFO_OUT_OF_MEMORY; | |
| 477 | + } | |
| 478 | + memset (pCtx->pParserBsInfo->pDstBuff, 0, MAX_ACCESS_UNIT_CAPACITY * sizeof (uint8_t)); | |
| 479 | + | |
| 404 | 480 | if ((pCtx->sSavedData.pHead = static_cast<uint8_t*> (WelsMallocz (pCtx->iMaxBsBufferSizeInByte, |
| 405 | 481 | "pCtx->sSavedData.pHead"))) == NULL) { |
| 406 | 482 | return ERR_INFO_OUT_OF_MEMORY; |
| @@ -506,15 +582,24 @@ void WelsFreeMemory (PWelsDecoderContext pCtx) { · 99 unmodified lines | ||
| 506 | 582 | pCtx->sRawData.pEnd = NULL; |
| 507 | 583 | pCtx->sRawData.pStartPos = NULL; |
| 508 | 584 | pCtx->sRawData.pCurPos = NULL; |
| 509 | − if (pCtx->sSavedData.pHead) { | |
| 510 | − WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData->pHead"); | |
| 585 | + if (pCtx->bParseOnly) { | |
| 586 | + if (pCtx->sSavedData.pHead) { | |
| 587 | + WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData->pHead"); | |
| 588 | + } | |
| 589 | + pCtx->sSavedData.pHead = NULL; | |
| 590 | + pCtx->sSavedData.pEnd = NULL; | |
| 591 | + pCtx->sSavedData.pStartPos = NULL; | |
| 592 | + pCtx->sSavedData.pCurPos = NULL; | |
| 593 | + if (pCtx->pParserBsInfo) { | |
| 594 | + if (pCtx->pParserBsInfo->pDstBuff) { | |
| 595 | + WelsFree (pCtx->pParserBsInfo->pDstBuff, "pCtx->pParserBsInfo->pDstBuff"); | |
| 596 | + pCtx->pParserBsInfo->pDstBuff = NULL; | |
| 597 | + } | |
| 598 | + WelsFree (pCtx->pParserBsInfo, "pCtx->pParserBsInfo"); | |
| 599 | + pCtx->pParserBsInfo = NULL; | |
| 600 | + } | |
| 511 | 601 | } |
| 512 | − pCtx->sSavedData.pHead = NULL; | |
| 513 | − pCtx->sSavedData.pEnd = NULL; | |
| 514 | − pCtx->sSavedData.pStartPos = NULL; | |
| 515 | − pCtx->sSavedData.pCurPos = NULL; | |
| 516 | 602 | } |
| 517 | − | |
| 518 | 603 | /* |
| 519 | 604 | * DecodeNalHeaderExt |
| 520 | 605 | * Trigger condition: NAL_UNIT_TYPE = NAL_UNIT_PREFIX or NAL_UNIT_CODED_SLICE_EXT |
| @@ -1864,57 +1949,6 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI · 1343 unmodified lines | ||
| 1864 | 1949 | |
| 1865 | 1950 | iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo); |
| 1866 | 1951 | |
| 1867 | − if (pCtx->bParseOnly) { | |
| 1868 | − if ((dsErrorFree == pCtx->iErrorCode) && (iErr == 0)) { //frame complete, output | |
| 1869 | − SParserBsInfo* pParser = pCtx->pParserBsInfo; | |
| 1870 | − uint8_t* pDstBuf = pParser->pDstBuff; | |
| 1871 | − SNalUnit* pCurNal = NULL; | |
| 1872 | − int32_t iNalLen = 0; | |
| 1873 | − int32_t iIdx = pCurAu->uiStartPos; | |
| 1874 | − int32_t iEndIdx = pCurAu->uiEndPos; | |
| 1875 | − uint8_t* pNalBs = NULL; | |
| 1876 | − pParser->uiOutBsTimeStamp = (pCurAu->pNalUnitsList [iIdx]) ? pCurAu->pNalUnitsList [iIdx]->uiTimeStamp : 0; | |
| 1877 | − pParser->iNalNum = 0; | |
| 1878 | − pParser->iSpsWidthInPixel = (pCtx->pSps->iMbWidth << 4); | |
| 1879 | − pParser->iSpsHeightInPixel = (pCtx->pSps->iMbHeight << 4); | |
| 1880 | − | |
| 1881 | − if (pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.bIdrFlag) { //IDR | |
| 1882 | − bool bSubSps = (NAL_UNIT_CODED_SLICE_EXT == pCurAu->pNalUnitsList [iIdx]->sNalHeaderExt.sNalUnitHeader.eNalUnitType); | |
| 1883 | − SSpsBsInfo* pSpsBs = NULL; | |
| 1884 | − SPpsBsInfo* pPpsBs = NULL; | |
| 1885 | − int32_t iSpsId = pCtx->pSps->iSpsId; | |
| 1886 | − int32_t iPpsId = pCtx->pPps->iPpsId; | |
| 1887 | − pCtx->bParamSetsLostFlag = false; | |
| 1888 | − //find required sps, pps and write into dst buff | |
| 1889 | − pSpsBs = bSubSps ? &pCtx->sSubsetSpsBsInfo [iSpsId] : &pCtx->sSpsBsInfo [iSpsId]; | |
| 1890 | − memcpy (pDstBuf, pSpsBs->pSpsBsBuf, pSpsBs->uiSpsBsLen); | |
| 1891 | − pParser->iNalLenInByte [pParser->iNalNum ++] = pSpsBs->uiSpsBsLen; | |
| 1892 | − pDstBuf += pSpsBs->uiSpsBsLen; | |
| 1893 | − pPpsBs = &pCtx->sPpsBsInfo [iPpsId]; | |
| 1894 | − memcpy (pDstBuf, pPpsBs->pPpsBsBuf, pPpsBs->uiPpsBsLen); | |
| 1895 | − pParser->iNalLenInByte [pParser->iNalNum ++] = pPpsBs->uiPpsBsLen; | |
| 1896 | − pDstBuf += pPpsBs->uiPpsBsLen; | |
| 1897 | − } //IDR required SPS, PPS | |
| 1898 | − //then VCL data re-write | |
| 1899 | − while (iIdx <= iEndIdx) { | |
| 1900 | − pCurNal = pCurAu->pNalUnitsList [iIdx ++]; | |
| 1901 | − iNalLen = pCurNal->sNalData.sVclNal.iNalLength; | |
| 1902 | − pNalBs = pCurNal->sNalData.sVclNal.pNalPos; | |
| 1903 | − pParser->iNalLenInByte [pParser->iNalNum ++] = iNalLen; | |
| 1904 | − memcpy (pDstBuf, pNalBs, iNalLen); | |
| 1905 | − pDstBuf += iNalLen; | |
| 1906 | − } | |
| 1907 | − } else { //error | |
| 1908 | − pCtx->pParserBsInfo->uiOutBsTimeStamp = 0; | |
| 1909 | − pCtx->pParserBsInfo->iNalNum = 0; | |
| 1910 | − pCtx->pParserBsInfo->iSpsWidthInPixel = 0; | |
| 1911 | − pCtx->pParserBsInfo->iSpsHeightInPixel = 0; | |
| 1912 | − if (dsErrorFree == pCtx->iErrorCode) { //frame not complete | |
| 1913 | − pCtx->iErrorCode |= dsFramePending; | |
| 1914 | − } | |
| 1915 | − } | |
| 1916 | − } | |
| 1917 | − | |
| 1918 | 1952 | WelsDecodeAccessUnitEnd (pCtx); |
| 1919 | 1953 | |
| 1920 | 1954 | if (ERR_NONE != iErr) { |
| @@ -2056,6 +2090,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 135 unmodified lines | ||
| 2056 | 2090 | |
| 2057 | 2091 | if (pCtx->pDec == NULL) { |
| 2058 | 2092 | pCtx->pDec = PrefetchPic (pCtx->pPicBuff[0]); |
| 2093 | + if (pCtx->iTotalNumMbRec != 0) | |
| 2094 | + pCtx->iTotalNumMbRec = 0; | |
| 2059 | 2095 | |
| 2060 | 2096 | if (NULL == pCtx->pDec) { |
| 2061 | 2097 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, |
| @@ -2326,6 +2362,8 @@ bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferIn · 264 unmodified lines | ||
| 2326 | 2362 | if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) { |
| 2327 | 2363 | MarkECFrameAsRef (pCtx); |
| 2328 | 2364 | } |
| 2365 | + } else if (pCtx->bParseOnly) { //clear parse only internal data status | |
| 2366 | + pCtx->pParserBsInfo->iNalNum = 0; | |
| 2329 | 2367 | } else { |
| 2330 | 2368 | if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) { |
| 2331 | 2369 | pCtx->pDec = NULL; |