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 | if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) { | 148 | if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) { |
| 76 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, | 149 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, |
| 77 | "DecodeFrameConstruction(): iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d ", | 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 | pCtx->iTotalNumMbRec = 0; | 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 | //////output:::normal path | 163 | //////output:::normal path |
| 100 | pDstInfo->uiOutYuvTimeStamp = pPic->uiTimeStamp; | 164 | pDstInfo->uiOutYuvTimeStamp = pPic->uiTimeStamp; |
| 101 | ppDst[0] = pPic->pData[0]; | 165 | ppDst[0] = pPic->pData[0]; |
| @@ -401,6 +465,18 @@ int32_t InitBsBuffer (PWelsDecoderContext pCtx) { · 299 unmodified lines | |||
| 401 | pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead; | 465 | pCtx->sRawData.pStartPos = pCtx->sRawData.pCurPos = pCtx->sRawData.pHead; |
| 402 | pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte; | 466 | pCtx->sRawData.pEnd = pCtx->sRawData.pHead + pCtx->iMaxBsBufferSizeInByte; |
| 403 | if (pCtx->bParseOnly) { | 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 | if ((pCtx->sSavedData.pHead = static_cast<uint8_t*> (WelsMallocz (pCtx->iMaxBsBufferSizeInByte, | 480 | if ((pCtx->sSavedData.pHead = static_cast<uint8_t*> (WelsMallocz (pCtx->iMaxBsBufferSizeInByte, |
| 405 | "pCtx->sSavedData.pHead"))) == NULL) { | 481 | "pCtx->sSavedData.pHead"))) == NULL) { |
| 406 | return ERR_INFO_OUT_OF_MEMORY; | 482 | return ERR_INFO_OUT_OF_MEMORY; |
| @@ -506,15 +582,24 @@ void WelsFreeMemory (PWelsDecoderContext pCtx) { · 99 unmodified lines | |||
| 506 | pCtx->sRawData.pEnd = NULL; | 582 | pCtx->sRawData.pEnd = NULL; |
| 507 | pCtx->sRawData.pStartPos = NULL; | 583 | pCtx->sRawData.pStartPos = NULL; |
| 508 | pCtx->sRawData.pCurPos = NULL; | 584 | pCtx->sRawData.pCurPos = NULL; |
| 509 | if (pCtx->sSavedData.pHead) { | 585 | if (pCtx->bParseOnly) { |
| 510 | WelsFree (pCtx->sSavedData.pHead, "pCtx->sSavedData->pHead"); | 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 | * DecodeNalHeaderExt | 604 | * DecodeNalHeaderExt |
| 520 | * Trigger condition: NAL_UNIT_TYPE = NAL_UNIT_PREFIX or NAL_UNIT_CODED_SLICE_EXT | 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 | iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo); | 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 | WelsDecodeAccessUnitEnd (pCtx); | 1952 | WelsDecodeAccessUnitEnd (pCtx); |
| 1919 | 1953 | ||
| 1920 | if (ERR_NONE != iErr) { | 1954 | if (ERR_NONE != iErr) { |
| @@ -2056,6 +2090,8 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 135 unmodified lines | |||
| 2056 | 2090 | ||
| 2057 | if (pCtx->pDec == NULL) { | 2091 | if (pCtx->pDec == NULL) { |
| 2058 | pCtx->pDec = PrefetchPic (pCtx->pPicBuff[0]); | 2092 | pCtx->pDec = PrefetchPic (pCtx->pPicBuff[0]); |
| 2093 | if (pCtx->iTotalNumMbRec != 0) | ||
| 2094 | pCtx->iTotalNumMbRec = 0; | ||
| 2059 | 2095 | ||
| 2060 | if (NULL == pCtx->pDec) { | 2096 | if (NULL == pCtx->pDec) { |
| 2061 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, | 2097 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, |
| @@ -2326,6 +2362,8 @@ bool CheckAndFinishLastPic (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferIn · 264 unmodified lines | |||
| 2326 | if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) { | 2362 | if (pCtx->sLastNalHdrExt.sNalUnitHeader.uiNalRefIdc > 0) { |
| 2327 | MarkECFrameAsRef (pCtx); | 2363 | MarkECFrameAsRef (pCtx); |
| 2328 | } | 2364 | } |
| 2365 | } else if (pCtx->bParseOnly) { //clear parse only internal data status | ||
| 2366 | pCtx->pParserBsInfo->iNalNum = 0; | ||
| 2329 | } else { | 2367 | } else { |
| 2330 | if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) { | 2368 | if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo)) { |
| 2331 | pCtx->pDec = NULL; | 2369 | pCtx->pDec = NULL; |