Add additional function PrefetchLastPicForThread and variables for better control of threaded decoding in the case of multi-slice with one slice group contains one slice.
Showing the changes to codec/decoder/core/src/decoder_core.cpp (1 of 9 files). Show all
Unified · Split
| @@ -194,8 +194,9 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 193 unmodified lines | |||
| 194 | "DecodeFrameConstruction(): iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d ", | 194 | "DecodeFrameConstruction(): iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d ", |
| 195 | pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight); | 195 | pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight); |
| 196 | bFrameCompleteFlag = false; //return later after output buffer is done | 196 | bFrameCompleteFlag = false; //return later after output buffer is done |
| 197 | if (pCtx->bInstantDecFlag) //no-delay decoding, wait for new slice | 197 | if (pCtx->bInstantDecFlag) { //no-delay decoding, wait for new slice |
| 198 | return ERR_INFO_MB_NUM_INADEQUATE; | 198 | return ERR_INFO_MB_NUM_INADEQUATE; |
| 199 | } | ||
| 199 | } else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag | 200 | } else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag |
| 200 | && (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done | 201 | && (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done |
| 201 | pCtx->pDec->bIsComplete = true; | 202 | pCtx->pDec->bIsComplete = true; |
| @@ -220,9 +221,26 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 18 unmodified lines | |||
| 220 | ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset; | 221 | ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset; |
| 221 | ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset; | 222 | ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset; |
| 222 | pDstInfo->iBufferStatus = 1; | 223 | pDstInfo->iBufferStatus = 1; |
| 223 | 224 | if (pCtx->pThreadCtx != NULL && pPic->bIsComplete == false) { | |
| 224 | bool bOutResChange = (pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth) | 225 | pPic->bIsComplete = true; |
| 225 | || (pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight); | 226 | } |
| 227 | if (pCtx->pThreadCtx != NULL) { | ||
| 228 | uint32_t uiMbHeight = (pCtx->pDec->iHeightInPixel + 15) >> 4; | ||
| 229 | for (uint32_t i = 0; i < uiMbHeight; ++i) { | ||
| 230 | SET_EVENT (&pCtx->pDec->pReadyEvent[i]); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | bool bOutResChange = false; | ||
| 234 | if (pCtx->pThreadCtx == NULL || pCtx->pLastThreadCtx == NULL) { | ||
| 235 | bOutResChange = (pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth) | ||
| 236 | || (pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight); | ||
| 237 | } else { | ||
| 238 | if (pCtx->pLastThreadCtx != NULL) { | ||
| 239 | PWelsDecoderThreadCTX pLastThreadCtx = (PWelsDecoderThreadCTX) (pCtx->pLastThreadCtx); | ||
| 240 | bOutResChange = (pLastThreadCtx->pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth) | ||
| 241 | || (pLastThreadCtx->pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight); | ||
| 242 | } | ||
| 243 | } | ||
| 226 | pCtx->iLastImgWidthInPixel = pDstInfo->UsrData.sSystemBuffer.iWidth; | 244 | pCtx->iLastImgWidthInPixel = pDstInfo->UsrData.sSystemBuffer.iWidth; |
| 227 | pCtx->iLastImgHeightInPixel = pDstInfo->UsrData.sSystemBuffer.iHeight; | 245 | pCtx->iLastImgHeightInPixel = pDstInfo->UsrData.sSystemBuffer.iHeight; |
| 228 | if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete | 246 | if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete |
| @@ -846,8 +864,9 @@ void UpdateDecoderStatisticsForActiveParaset (SDecoderStatistics* pDecoderStatis · 617 unmodified lines | |||
| 846 | * Parse slice header of bitstream in avc for storing data structure | 864 | * Parse slice header of bitstream in avc for storing data structure |
| 847 | */ | 865 | */ |
| 848 | int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, const bool kbExtensionFlag) { | 866 | int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, const bool kbExtensionFlag) { |
| 849 | PNalUnit const kpCurNal = pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum - | 867 | PNalUnit const kpCurNal = |
| 850 | 1]; | 868 | pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum - |
| 869 | 1]; | ||
| 851 | 870 | ||
| 852 | PNalUnitHeaderExt pNalHeaderExt = NULL; | 871 | PNalUnitHeaderExt pNalHeaderExt = NULL; |
| 853 | PSliceHeader pSliceHead = NULL; | 872 | PSliceHeader pSliceHead = NULL; |
| @@ -1462,7 +1481,6 @@ int32_t UpdateAccessUnit (PWelsDecoderContext pCtx) { · 608 unmodified lines | |||
| 1462 | 1481 | ||
| 1463 | int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWidth, const int32_t kiMaxHeight) { | 1482 | int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWidth, const int32_t kiMaxHeight) { |
| 1464 | int32_t i = 0; | 1483 | int32_t i = 0; |
| 1465 | |||
| 1466 | WELS_VERIFY_RETURN_IF (ERR_INFO_INVALID_PARAM, (NULL == pCtx || kiMaxWidth <= 0 || kiMaxHeight <= 0)) | 1484 | WELS_VERIFY_RETURN_IF (ERR_INFO_INVALID_PARAM, (NULL == pCtx || kiMaxWidth <= 0 || kiMaxHeight <= 0)) |
| 1467 | pCtx->sMb.iMbWidth = (kiMaxWidth + 15) >> 4; | 1485 | pCtx->sMb.iMbWidth = (kiMaxWidth + 15) >> 4; |
| 1468 | pCtx->sMb.iMbHeight = (kiMaxHeight + 15) >> 4; | 1486 | pCtx->sMb.iMbHeight = (kiMaxHeight + 15) >> 4; |
| @@ -1508,7 +1526,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 39 unmodified lines | |||
| 1508 | sizeof ( | 1526 | sizeof ( |
| 1509 | bool), | 1527 | bool), |
| 1510 | "pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[]"); | 1528 | "pCtx->sMb.pNoSubMbPartSizeLessThan8x8Flag[]"); |
| 1511 | pCtx->sMb.pTransformSize8x8Flag[i] = (bool*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool), | 1529 | pCtx->sMb.pTransformSize8x8Flag[i] = (bool*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1530 | bool), | ||
| 1512 | "pCtx->sMb.pTransformSize8x8Flag[]"); | 1531 | "pCtx->sMb.pTransformSize8x8Flag[]"); |
| 1513 | pCtx->sMb.pChromaQp[i] = (int8_t (*)[2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( | 1532 | pCtx->sMb.pChromaQp[i] = (int8_t (*)[2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1514 | int8_t) * 2, | 1533 | int8_t) * 2, |
| @@ -1519,9 +1538,11 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 4 unmodified lines | |||
| 1519 | int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]"); | 1538 | int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]"); |
| 1520 | pCtx->sMb.pCbfDc[i] = (uint16_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint16_t), | 1539 | pCtx->sMb.pCbfDc[i] = (uint16_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint16_t), |
| 1521 | "pCtx->sMb.pCbfDc[]"); | 1540 | "pCtx->sMb.pCbfDc[]"); |
| 1522 | pCtx->sMb.pNzc[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24, | 1541 | pCtx->sMb.pNzc[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1542 | int8_t) * 24, | ||
| 1523 | "pCtx->sMb.pNzc[]"); | 1543 | "pCtx->sMb.pNzc[]"); |
| 1524 | pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t) * 24, | 1544 | pCtx->sMb.pNzcRs[i] = (int8_t (*)[24])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1545 | int8_t) * 24, | ||
| 1525 | "pCtx->sMb.pNzcRs[]"); | 1546 | "pCtx->sMb.pNzcRs[]"); |
| 1526 | pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth * | 1547 | pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth * |
| 1527 | pCtx->sMb.iMbHeight * | 1548 | pCtx->sMb.iMbHeight * |
| @@ -1539,20 +1560,24 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 11 unmodified lines | |||
| 1539 | "pCtx->sMb.pChromaPredMode[]"); | 1560 | "pCtx->sMb.pChromaPredMode[]"); |
| 1540 | pCtx->sMb.pCbp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t), | 1561 | pCtx->sMb.pCbp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t), |
| 1541 | "pCtx->sMb.pCbp[]"); | 1562 | "pCtx->sMb.pCbp[]"); |
| 1542 | pCtx->sMb.pSubMbType[i] = (uint32_t (*)[MB_PARTITION_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * | 1563 | pCtx->sMb.pSubMbType[i] = (uint32_t (*)[MB_PARTITION_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth * |
| 1564 | pCtx->sMb.iMbHeight * | ||
| 1543 | sizeof ( | 1565 | sizeof ( |
| 1544 | uint32_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]"); | 1566 | uint32_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]"); |
| 1545 | pCtx->sMb.pSliceIdc[i] = (int32_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t), | 1567 | pCtx->sMb.pSliceIdc[i] = (int32_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t), |
| 1546 | "pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/2010 | 1568 | "pCtx->sMb.pSliceIdc[]"); // using int32_t for slice_idc, 4/21/2010 |
| 1547 | pCtx->sMb.pResidualPredFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t), | 1569 | pCtx->sMb.pResidualPredFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1570 | int8_t), | ||
| 1548 | "pCtx->sMb.pResidualPredFlag[]"); | 1571 | "pCtx->sMb.pResidualPredFlag[]"); |
| 1549 | pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( | 1572 | pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * |
| 1550 | int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]"); | 1573 | sizeof ( |
| 1574 | int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]"); | ||
| 1551 | 1575 | ||
| 1552 | pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( | 1576 | pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1553 | bool), | 1577 | bool), |
| 1554 | "pCtx->sMb.pMbCorrectlyDecodedFlag[]"); | 1578 | "pCtx->sMb.pMbCorrectlyDecodedFlag[]"); |
| 1555 | pCtx->sMb.pMbRefConcealedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool), | 1579 | pCtx->sMb.pMbRefConcealedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1580 | bool), | ||
| 1556 | "pCtx->pMbRefConcealedFlag[]"); | 1581 | "pCtx->pMbRefConcealedFlag[]"); |
| 1557 | 1582 | ||
| 1558 | // check memory block valid due above allocated.. | 1583 | // check memory block valid due above allocated.. |
| @@ -1599,6 +1624,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 40 unmodified lines | |||
| 1599 | return ERR_NONE; | 1624 | return ERR_NONE; |
| 1600 | } | 1625 | } |
| 1601 | 1626 | ||
| 1627 | |||
| 1628 | |||
| 1602 | void UninitialDqLayersContext (PWelsDecoderContext pCtx) { | 1629 | void UninitialDqLayersContext (PWelsDecoderContext pCtx) { |
| 1603 | int32_t i = 0; | 1630 | int32_t i = 0; |
| 1604 | CMemoryAlign* pMa = pCtx->pMemAlign; | 1631 | CMemoryAlign* pMa = pCtx->pMemAlign; |
| @@ -2307,39 +2334,18 @@ int32_t InitConstructAccessUnit (PWelsDecoderContext pCtx, SBufferInfo* pDstInfo · 702 unmodified lines | |||
| 2307 | * 0 - success; otherwise returned error_no defined in error_no.h | 2334 | * 0 - success; otherwise returned error_no defined in error_no.h |
| 2308 | */ | 2335 | */ |
| 2309 | int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) { | 2336 | int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) { |
| 2310 | int32_t iErr; | 2337 | int32_t iErr = ERR_NONE; |
| 2311 | PAccessUnit pCurAu = pCtx->pAccessUnitList; | 2338 | if (pCtx->pThreadCtx == NULL) { |
| 2312 | pCtx->bAuReadyFlag = false; | 2339 | iErr = InitConstructAccessUnit (pCtx, pDstInfo); |
| 2313 | pCtx->pLastDecPicInfo->bLastHasMmco5 = false; | ||
| 2314 | bool bTmpNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps (pCtx); | ||
| 2315 | pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || bTmpNewSeqBegin; | ||
| 2316 | iErr = WelsDecodeAccessUnitStart (pCtx); | ||
| 2317 | GetVclNalTemporalId (pCtx); | ||
| 2318 | |||
| 2319 | if (ERR_NONE != iErr) { | ||
| 2320 | ForceResetCurrentAccessUnit (pCtx->pAccessUnitList); | ||
| 2321 | if (!pCtx->pParam->bParseOnly) | ||
| 2322 | pDstInfo->iBufferStatus = 0; | ||
| 2323 | pCtx->bNewSeqBegin = pCtx->bNewSeqBegin || pCtx->bNextNewSeqBegin; | ||
| 2324 | pCtx->bNextNewSeqBegin = false; // reset it | ||
| 2325 | if (pCtx->bNewSeqBegin) | ||
| 2326 | ResetActiveSPSForEachLayer (pCtx); | ||
| 2327 | return iErr; | ||
| 2328 | } | ||
| 2329 | |||
| 2330 | pCtx->pSps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps; | ||
| 2331 | pCtx->pPps = pCurAu->pNalUnitsList[pCurAu->uiStartPos]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pPps; | ||
| 2332 | |||
| 2333 | //try to allocate or relocate DPB memory only when new sequence is coming. | ||
| 2334 | if (pCtx->bNewSeqBegin) { | ||
| 2335 | WelsResetRefPic (pCtx); //clear ref pPic when IDR NAL | ||
| 2336 | iErr = SyncPictureResolutionExt (pCtx, pCtx->pSps->iMbWidth, pCtx->pSps->iMbHeight); | ||
| 2337 | |||
| 2338 | if (ERR_NONE != iErr) { | 2340 | if (ERR_NONE != iErr) { |
| 2339 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "sync picture resolution ext failed, the error is %d", iErr); | ||
| 2340 | return iErr; | 2341 | return iErr; |
| 2341 | } | 2342 | } |
| 2342 | } | 2343 | } |
| 2344 | if (pCtx->pCabacDecEngine == NULL) { | ||
| 2345 | pCtx->pCabacDecEngine = (SWelsCabacDecEngine*)pCtx->pMemAlign->WelsMallocz (sizeof (SWelsCabacDecEngine), | ||
| 2346 | "pCtx->pCabacDecEngine"); | ||
| 2347 | WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, (NULL == pCtx->pCabacDecEngine)) | ||
| 2348 | } | ||
| 2343 | 2349 | ||
| 2344 | iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo); | 2350 | iErr = DecodeCurrentAccessUnit (pCtx, ppDst, pDstInfo); |
| 2345 | 2351 | ||
| @@ -2412,6 +2418,9 @@ void WelsDqLayerDecodeStart (PWelsDecoderContext pCtx, PNalUnit pCurNal, PSps pS · 66 unmodified lines | |||
| 2412 | 2418 | ||
| 2413 | int32_t InitRefPicList (PWelsDecoderContext pCtx, const uint8_t kuiNRi, int32_t iPoc) { | 2419 | int32_t InitRefPicList (PWelsDecoderContext pCtx, const uint8_t kuiNRi, int32_t iPoc) { |
| 2414 | int32_t iRet = ERR_NONE; | 2420 | int32_t iRet = ERR_NONE; |
| 2421 | if (pCtx->pThreadCtx != NULL && pCtx->bNewSeqBegin) { | ||
| 2422 | WelsResetRefPic (pCtx); | ||
| 2423 | } | ||
| 2415 | if (pCtx->eSliceType == B_SLICE) { | 2424 | if (pCtx->eSliceType == B_SLICE) { |
| 2416 | iRet = WelsInitBSliceRefList (pCtx, iPoc); | 2425 | iRet = WelsInitBSliceRefList (pCtx, iPoc); |
| 2417 | CreateImplicitWeightTable (pCtx); | 2426 | CreateImplicitWeightTable (pCtx); |
| @@ -2466,13 +2475,26 @@ void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) { · 48 unmodified lines | |||
| 2466 | * Decode current access unit when current AU is completed. | 2475 | * Decode current access unit when current AU is completed. |
| 2467 | */ | 2476 | */ |
| 2468 | int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) { | 2477 | int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) { |
| 2469 | int32_t iRefCount[LIST_A]; | 2478 | PNalUnit pNalCur = pCtx->pNalCur = NULL; |
| 2470 | PNalUnit pNalCur = NULL; | ||
| 2471 | PAccessUnit pCurAu = pCtx->pAccessUnitList; | 2479 | PAccessUnit pCurAu = pCtx->pAccessUnitList; |
| 2472 | 2480 | ||
| 2473 | int32_t iIdx = pCurAu->uiStartPos; | 2481 | int32_t iIdx = pCurAu->uiStartPos; |
| 2474 | int32_t iEndIdx = pCurAu->uiEndPos; | 2482 | int32_t iEndIdx = pCurAu->uiEndPos; |
| 2475 | 2483 | ||
| 2484 | //get current thread ctx | ||
| 2485 | PWelsDecoderThreadCTX pThreadCtx = NULL; | ||
| 2486 | if (pCtx->pThreadCtx != NULL) { | ||
| 2487 | pThreadCtx = (PWelsDecoderThreadCTX)pCtx->pThreadCtx; | ||
| 2488 | } | ||
| 2489 | //get last thread ctx | ||
| 2490 | PWelsDecoderThreadCTX pLastThreadCtx = NULL; | ||
| 2491 | if (pCtx->pLastThreadCtx != NULL) { | ||
| 2492 | pLastThreadCtx = (PWelsDecoderThreadCTX) (pCtx->pLastThreadCtx); | ||
| 2493 | if (pLastThreadCtx->pDec == NULL) { | ||
| 2494 | pLastThreadCtx->pDec = PrefetchLastPicForThread (pCtx->pPicBuff, | ||
| 2495 | pLastThreadCtx->iPicBuffIdx); | ||
| 2496 | } | ||
| 2497 | } | ||
| 2476 | int32_t iPpsId = 0; | 2498 | int32_t iPpsId = 0; |
| 2477 | int32_t iRet = ERR_NONE; | 2499 | int32_t iRet = ERR_NONE; |
| 2478 | 2500 | ||
| @@ -2487,7 +2509,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 8 unmodified lines | |||
| 2487 | true; // Another fresh slice comingup for given dq layer, for multiple slices in case of header parts of slices sometimes loss over error-prone channels, 8/14/2008 | 2509 | true; // Another fresh slice comingup for given dq layer, for multiple slices in case of header parts of slices sometimes loss over error-prone channels, 8/14/2008 |
| 2488 | 2510 | ||
| 2489 | //update pCurDqLayer at the starting of AU decoding | 2511 | //update pCurDqLayer at the starting of AU decoding |
| 2490 | if (pCtx->bInitialDqLayersMem) { | 2512 | if (pCtx->bInitialDqLayersMem || pCtx->pCurDqLayer == NULL) { |
| 2491 | pCtx->pCurDqLayer = pCtx->pDqLayersList[0]; | 2513 | pCtx->pCurDqLayer = pCtx->pDqLayersList[0]; |
| 2492 | } | 2514 | } |
| 2493 | 2515 | ||
| @@ -2500,8 +2522,71 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 6 unmodified lines | |||
| 2500 | PSliceHeaderExt pShExt = NULL; | 2522 | PSliceHeaderExt pShExt = NULL; |
| 2501 | PSliceHeader pSh = NULL; | 2523 | PSliceHeader pSh = NULL; |
| 2502 | 2524 | ||
| 2525 | if (pLastThreadCtx != NULL) { | ||
| 2526 | pSh = &pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader; | ||
| 2527 | if (pSh->iFirstMbInSlice == 0) { | ||
| 2528 | if (pLastThreadCtx->pCtx->pDec != NULL && pLastThreadCtx->pCtx->pDec->bIsUngroupedMultiSlice) { | ||
| 2529 | WAIT_EVENT (&pLastThreadCtx->sSliceDecodeFinsh, WELS_DEC_THREAD_WAIT_INFINITE); | ||
| 2530 | } | ||
| 2531 | pCtx->pDec = NULL; | ||
| 2532 | pCtx->iTotalNumMbRec = 0; | ||
| 2533 | } else if (pLastThreadCtx->pCtx->pDec != NULL) { | ||
| 2534 | if (pSh->iFrameNum == pLastThreadCtx->pCtx->pDec->iFrameNum | ||
| 2535 | && pSh->iPicOrderCntLsb == pLastThreadCtx->pCtx->pDec->iFramePoc) { | ||
| 2536 | WAIT_EVENT (&pLastThreadCtx->sSliceDecodeFinsh, WELS_DEC_THREAD_WAIT_INFINITE); | ||
| 2537 | pCtx->pDec = pLastThreadCtx->pCtx->pDec; | ||
| 2538 | pCtx->pDec->bIsUngroupedMultiSlice = true; | ||
| 2539 | pCtx->sRefPic = pLastThreadCtx->pCtx->sRefPic; | ||
| 2540 | pCtx->iTotalNumMbRec = pLastThreadCtx->pCtx->iTotalNumMbRec; | ||
| 2541 | } | ||
| 2542 | } | ||
| 2543 | } | ||
| 2544 | bool isNewFrame = true; | ||
| 2545 | if (pThreadCtx != NULL) { | ||
| 2546 | isNewFrame = pCtx->pDec == NULL; | ||
| 2547 | } | ||
| 2503 | if (pCtx->pDec == NULL) { | 2548 | if (pCtx->pDec == NULL) { |
| 2549 | if (pLastThreadCtx != NULL) { | ||
| 2550 | pLastThreadCtx->pDec->bUsedAsRef = pLastThreadCtx->pCtx->uiNalRefIdc > 0; | ||
| 2551 | if (pLastThreadCtx->pDec->bUsedAsRef) { | ||
| 2552 | for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) { | ||
| 2553 | uint32_t i = 0; | ||
| 2554 | while (i < MAX_DPB_COUNT && pLastThreadCtx->pCtx->sRefPic.pRefList[listIdx][i]) { | ||
| 2555 | pLastThreadCtx->pDec->pRefPic[listIdx][i] = pLastThreadCtx->pCtx->sRefPic.pRefList[listIdx][i]; | ||
| 2556 | pLastThreadCtx->pDec->pRefPic[listIdx][i]->bAvailableFlag = false; | ||
| 2557 | ++i; | ||
| 2558 | } | ||
| 2559 | } | ||
| 2560 | pLastThreadCtx->pCtx->sTmpRefPic = pLastThreadCtx->pCtx->sRefPic; | ||
| 2561 | WelsMarkAsRef (pLastThreadCtx->pCtx, pLastThreadCtx->pDec); | ||
| 2562 | pCtx->sRefPic = pLastThreadCtx->pCtx->sTmpRefPic; | ||
| 2563 | } else { | ||
| 2564 | pCtx->sRefPic = pLastThreadCtx->pCtx->sRefPic; | ||
| 2565 | } | ||
| 2566 | //printf ("last uiDecodingTimeStamp = %d\n", pLastThreadCtx->pCtx->uiDecodingTimeStamp); | ||
| 2567 | for (int32_t i = 0; i < pCtx->sRefPic.uiRefCount[LIST_0]; ++i) { | ||
| 2568 | if (pCtx->sRefPic.pRefList[LIST_0][i] != NULL) { | ||
| 2569 | pCtx->sRefPic.pRefList[LIST_0][i]->bAvailableFlag = false; | ||
| 2570 | } | ||
| 2571 | } | ||
| 2572 | for (int32_t i = 0; i < pCtx->sRefPic.uiRefCount[LIST_1]; ++i) { | ||
| 2573 | if (pCtx->sRefPic.pRefList[LIST_1][i] != NULL) { | ||
| 2574 | pCtx->sRefPic.pRefList[LIST_1][i]->bAvailableFlag = false; | ||
| 2575 | } | ||
| 2576 | } | ||
| 2577 | } | ||
| 2504 | pCtx->pDec = PrefetchPic (pCtx->pPicBuff); | 2578 | pCtx->pDec = PrefetchPic (pCtx->pPicBuff); |
| 2579 | if (pThreadCtx != NULL) { | ||
| 2580 | if (pCtx->pDec != NULL) { | ||
| 2581 | pCtx->pDec->bAvailableFlag = false; | ||
| 2582 | pCtx->pDec->bIsUngroupedMultiSlice = false; | ||
| 2583 | pThreadCtx->pDec = pCtx->pDec; | ||
| 2584 | uint32_t uiMbHeight = (pCtx->pDec->iHeightInPixel + 15) >> 4; | ||
| 2585 | for (uint32_t i = 0; i < uiMbHeight; ++i) { | ||
| 2586 | RESET_EVENT (&pCtx->pDec->pReadyEvent[i]); | ||
| 2587 | } | ||
| 2588 | } | ||
| 2589 | } | ||
| 2505 | if (pCtx->iTotalNumMbRec != 0) | 2590 | if (pCtx->iTotalNumMbRec != 0) |
| 2506 | pCtx->iTotalNumMbRec = 0; | 2591 | pCtx->iTotalNumMbRec = 0; |
| 2507 | 2592 | ||
| @@ -2519,6 +2604,9 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 11 unmodified lines | |||
| 2519 | } | 2604 | } |
| 2520 | pCtx->pDec->uiTimeStamp = pNalCur->uiTimeStamp; | 2605 | pCtx->pDec->uiTimeStamp = pNalCur->uiTimeStamp; |
| 2521 | pCtx->pDec->uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp; | 2606 | pCtx->pDec->uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp; |
| 2607 | if (pThreadCtx != NULL) { | ||
| 2608 | pThreadCtx->iPicBuffIdx = pCtx->pDec->iPicBuffIdx; | ||
| 2609 | } | ||
| 2522 | 2610 | ||
| 2523 | if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode | 2611 | if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode |
| 2524 | for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i) | 2612 | for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i) |
| @@ -2556,6 +2644,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 31 unmodified lines | |||
| 2556 | pCtx->pDec->iFramePoc = pSh->iPicOrderCntLsb; // still can not obtain correct, because current do not support POCtype 2 | 2644 | pCtx->pDec->iFramePoc = pSh->iPicOrderCntLsb; // still can not obtain correct, because current do not support POCtype 2 |
| 2557 | pCtx->pDec->bIdrFlag = pNalCur->sNalHeaderExt.bIdrFlag; | 2645 | pCtx->pDec->bIdrFlag = pNalCur->sNalHeaderExt.bIdrFlag; |
| 2558 | pCtx->pDec->eSliceType = pSh->eSliceType; | 2646 | pCtx->pDec->eSliceType = pSh->eSliceType; |
| 2647 | |||
| 2559 | memcpy (&pLayerInfo.sSliceInLayer.sSliceHeaderExt, pShExt, sizeof (SSliceHeaderExt)); //confirmed_safe_unsafe_usage | 2648 | memcpy (&pLayerInfo.sSliceInLayer.sSliceHeaderExt, pShExt, sizeof (SSliceHeaderExt)); //confirmed_safe_unsafe_usage |
| 2560 | pLayerInfo.sSliceInLayer.bSliceHeaderExtFlag = pNalCur->sNalData.sVclNal.bSliceHeaderExtFlag; | 2649 | pLayerInfo.sSliceInLayer.bSliceHeaderExtFlag = pNalCur->sNalData.sVclNal.bSliceHeaderExtFlag; |
| 2561 | pLayerInfo.sSliceInLayer.eSliceType = pSh->eSliceType; | 2650 | pLayerInfo.sSliceInLayer.eSliceType = pSh->eSliceType; |
| @@ -2587,11 +2676,9 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 25 unmodified lines | |||
| 2587 | bFreshSliceAvailable = (iCurrIdD != iLastIdD | 2676 | bFreshSliceAvailable = (iCurrIdD != iLastIdD |
| 2588 | || iCurrIdQ != iLastIdQ); // do not need condition of (first_mb == 0) due multiple slices might be disorder | 2677 | || iCurrIdQ != iLastIdQ); // do not need condition of (first_mb == 0) due multiple slices might be disorder |
| 2589 | 2678 | ||
| 2679 | |||
| 2590 | WelsDqLayerDecodeStart (pCtx, pNalCur, pLayerInfo.pSps, pLayerInfo.pPps); | 2680 | WelsDqLayerDecodeStart (pCtx, pNalCur, pLayerInfo.pSps, pLayerInfo.pPps); |
| 2591 | 2681 | ||
| 2592 | if (iCurrIdQ == BASE_QUALITY_ID) { | ||
| 2593 | ST64 (iRefCount, LD64 (pLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.uiRefCount)); | ||
| 2594 | } | ||
| 2595 | 2682 | ||
| 2596 | if ((iLastIdD < 0) || //case 1: first layer | 2683 | if ((iLastIdD < 0) || //case 1: first layer |
| 2597 | (iLastIdD == iCurrIdD)) { //case 2: same uiDId | 2684 | (iLastIdD == iCurrIdD)) { //case 2: same uiDId |
| @@ -2601,13 +2688,23 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 3 unmodified lines | |||
| 2601 | const bool kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag | 2688 | const bool kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag |
| 2602 | || (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR); | 2689 | || (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR); |
| 2603 | // Subclause 8.2.5.2 Decoding process for gaps in frame_num | 2690 | // Subclause 8.2.5.2 Decoding process for gaps in frame_num |
| 2691 | int32_t iPrevFrameNum = pCtx->pLastDecPicInfo->iPrevFrameNum; | ||
| 2692 | if (pLastThreadCtx != NULL) { | ||
| 2693 | if (pCtx->bNewSeqBegin) { | ||
| 2694 | iPrevFrameNum = 0; | ||
| 2695 | } else if (pLastThreadCtx->pDec != NULL) { | ||
| 2696 | iPrevFrameNum = pLastThreadCtx->pDec->iFrameNum; | ||
| 2697 | } else { | ||
| 2698 | iPrevFrameNum = pCtx->bNewSeqBegin ? 0 : pLastThreadCtx->pCtx->iFrameNum; | ||
| 2699 | } | ||
| 2700 | } | ||
| 2604 | if (!kbIdrFlag && | 2701 | if (!kbIdrFlag && |
| 2605 | pSh->iFrameNum != pCtx->pLastDecPicInfo->iPrevFrameNum && | 2702 | pSh->iFrameNum != iPrevFrameNum && |
| 2606 | pSh->iFrameNum != ((pCtx->pLastDecPicInfo->iPrevFrameNum + 1) & ((1 << dq_cur->sLayerInfo.pSps->uiLog2MaxFrameNum) - | 2703 | pSh->iFrameNum != ((iPrevFrameNum + 1) & ((1 << dq_cur->sLayerInfo.pSps->uiLog2MaxFrameNum) - |
| 2607 | 1))) { | 2704 | 1))) { |
| 2608 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, | 2705 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, |
| 2609 | "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d", | 2706 | "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d", |
| 2610 | pCtx->pLastDecPicInfo->iPrevFrameNum, | 2707 | iPrevFrameNum, |
| 2611 | pSh->iFrameNum); | 2708 | pSh->iFrameNum); |
| 2612 | 2709 | ||
| 2613 | bAllRefComplete = false; | 2710 | bAllRefComplete = false; |
| @@ -2623,7 +2720,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 9 unmodified lines | |||
| 2623 | } | 2720 | } |
| 2624 | } | 2721 | } |
| 2625 | 2722 | ||
| 2626 | if (iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID) { | 2723 | if (iCurrIdD == kuiDependencyIdMax && iCurrIdQ == BASE_QUALITY_ID && isNewFrame) { |
| 2627 | iRet = InitRefPicList (pCtx, pCtx->uiNalRefIdc, pSh->iPicOrderCntLsb); | 2724 | iRet = InitRefPicList (pCtx, pCtx->uiNalRefIdc, pSh->iPicOrderCntLsb); |
| 2628 | if (iRet) { | 2725 | if (iRet) { |
| 2629 | pCtx->bRPLRError = true; | 2726 | pCtx->bRPLRError = true; |
| @@ -2643,7 +2740,13 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 13 unmodified lines | |||
| 2643 | if (pSh->eSliceType == B_SLICE && !pSh->iDirectSpatialMvPredFlag) | 2740 | if (pSh->eSliceType == B_SLICE && !pSh->iDirectSpatialMvPredFlag) |
| 2644 | ComputeColocatedTemporalScaling (pCtx); | 2741 | ComputeColocatedTemporalScaling (pCtx); |
| 2645 | 2742 | ||
| 2646 | iRet = WelsDecodeSlice (pCtx, bFreshSliceAvailable, pNalCur); | 2743 | if (pThreadCtx != NULL) { |
| 2744 | memset (&pCtx->lastReadyHeightOffset[0][0], -1, LIST_A * MAX_REF_PIC_COUNT * sizeof (int16_t)); | ||
| 2745 | SET_EVENT (&pThreadCtx->sSliceDecodeStart); | ||
| 2746 | iRet = WelsDecodeAndConstructSlice (pCtx); | ||
| 2747 | } else { | ||
| 2748 | iRet = WelsDecodeSlice (pCtx, bFreshSliceAvailable, pNalCur); | ||
| 2749 | } | ||
| 2647 | 2750 | ||
| 2648 | //Output good store_base reconstruction when enhancement quality layer occurred error for MGS key picture case | 2751 | //Output good store_base reconstruction when enhancement quality layer occurred error for MGS key picture case |
| 2649 | if (iRet != ERR_NONE) { | 2752 | if (iRet != ERR_NONE) { |
| @@ -2659,17 +2762,19 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 9 unmodified lines | |||
| 2659 | } | 2762 | } |
| 2660 | } | 2763 | } |
| 2661 | 2764 | ||
| 2662 | if (bReconstructSlice) { | 2765 | if (pThreadCtx == NULL && bReconstructSlice) { |
| 2663 | if ((iRet = WelsDecodeConstructSlice (pCtx, pNalCur)) != ERR_NONE) { | 2766 | if ((iRet = WelsDecodeConstructSlice (pCtx, pNalCur)) != ERR_NONE) { |
| 2664 | pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false | 2767 | pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false |
| 2665 | return iRet; | 2768 | return iRet; |
| 2666 | } | 2769 | } |
| 2667 | } | 2770 | } |
| 2668 | if (bAllRefComplete && pCtx->eSliceType != I_SLICE) { | 2771 | if (bAllRefComplete && pCtx->eSliceType != I_SLICE) { |
| 2669 | if (pCtx->sRefPic.uiRefCount[LIST_0] > 0) { | 2772 | if (pCtx->pThreadCtx == NULL) { |
| 2670 | bAllRefComplete &= CheckRefPicturesComplete (pCtx); | 2773 | if (pCtx->sRefPic.uiRefCount[LIST_0] > 0) { |
| 2671 | } else { | 2774 | bAllRefComplete &= CheckRefPicturesComplete (pCtx); |
| 2672 | bAllRefComplete = false; | 2775 | } else { |
| 2776 | bAllRefComplete = false; | ||
| 2777 | } | ||
| 2673 | } | 2778 | } |
| 2674 | } | 2779 | } |
| 2675 | } | 2780 | } |
| @@ -2721,34 +2826,49 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 45 unmodified lines | |||
| 2721 | } | 2826 | } |
| 2722 | } | 2827 | } |
| 2723 | 2828 | ||
| 2829 | if (pThreadCtx != NULL && pCtx->uiDecodingTimeStamp > 1 && pCtx->pLastDecPicInfo->uiDecodingTimeStamp > 0) { | ||
| 2830 | while (pCtx->uiDecodingTimeStamp > pCtx->pLastDecPicInfo->uiDecodingTimeStamp + 1) { | ||
| 2831 | WelsSleep (1); | ||
| 2832 | } | ||
| 2833 | } | ||
| 2834 | if (pThreadCtx != NULL) { | ||
| 2835 | pCtx->pLastDecPicInfo->uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp; | ||
| 2836 | } | ||
| 2724 | iRet = DecodeFrameConstruction (pCtx, ppDst, pDstInfo); | 2837 | iRet = DecodeFrameConstruction (pCtx, ppDst, pDstInfo); |
| 2725 | if (iRet) | 2838 | if (iRet) { |
| 2839 | if (pThreadCtx != NULL) { | ||
| 2840 | SET_EVENT (&pThreadCtx->sSliceDecodeFinsh); | ||
| 2841 | } | ||
| 2726 | return iRet; | 2842 | return iRet; |
| 2843 | } | ||
| 2727 | 2844 | ||
| 2728 | pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC | 2845 | pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC |
| 2729 | pCtx->bUsedAsRef = false; | 2846 | pCtx->bUsedAsRef = pCtx->uiNalRefIdc > 0; |
| 2730 | if (pCtx->uiNalRefIdc > 0) { | 2847 | if (pCtx->pThreadCtx == NULL) { |
| 2731 | pCtx->bUsedAsRef = true; | 2848 | if (pCtx->bUsedAsRef) { |
| 2732 | for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) { | 2849 | for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) { |
| 2733 | uint32_t i = 0; | 2850 | uint32_t i = 0; |
| 2734 | while (i < MAX_DPB_COUNT && pCtx->sRefPic.pRefList[listIdx][i]) { | 2851 | while (i < MAX_DPB_COUNT && pCtx->sRefPic.pRefList[listIdx][i]) { |
| 2735 | pCtx->pDec->pRefPic[listIdx][i] = pCtx->sRefPic.pRefList[listIdx][i]; | 2852 | pCtx->pDec->pRefPic[listIdx][i] = pCtx->sRefPic.pRefList[listIdx][i]; |
| 2736 | ++i; | 2853 | ++i; |
| 2854 | } | ||
| 2737 | } | 2855 | } |
| 2738 | } | 2856 | iRet = WelsMarkAsRef (pCtx); |
| 2739 | iRet = WelsMarkAsRef (pCtx); | 2857 | if (iRet != ERR_NONE) { |
| 2740 | if (iRet != ERR_NONE) { | 2858 | if (iRet == ERR_INFO_DUPLICATE_FRAME_NUM) |
| 2741 | if (iRet == ERR_INFO_DUPLICATE_FRAME_NUM) | 2859 | pCtx->iErrorCode |= dsBitstreamError; |
| 2742 | pCtx->iErrorCode |= dsBitstreamError; | 2860 | if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) { |
| 2743 | if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) { | 2861 | pCtx->pDec = NULL; |
| 2744 | pCtx->pDec = NULL; | 2862 | return iRet; |
| 2745 | return iRet; | 2863 | } |
| 2746 | } | 2864 | } |
| 2865 | if (!pCtx->pParam->bParseOnly) | ||
| 2866 | ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel, | ||
| 2867 | pCtx->pDec->iLinesize, | ||
| 2868 | pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture); | ||
| 2747 | } | 2869 | } |
| 2748 | if (!pCtx->pParam->bParseOnly) | 2870 | } else { |
| 2749 | ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel, | 2871 | SET_EVENT (&pThreadCtx->sImageReady); |
| 2750 | pCtx->pDec->iLinesize, | ||
| 2751 | pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture); | ||
| 2752 | } | 2872 | } |
| 2753 | pCtx->pDec = NULL; //after frame decoding, always set to NULL | 2873 | pCtx->pDec = NULL; //after frame decoding, always set to NULL |
| 2754 | } | 2874 | } |
| @@ -2758,8 +2878,27 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 3 unmodified lines | |||
| 2758 | pCtx->pLastDecPicInfo->iPrevFrameNum = pSh->iFrameNum; | 2878 | pCtx->pLastDecPicInfo->iPrevFrameNum = pSh->iFrameNum; |
| 2759 | if (pCtx->pLastDecPicInfo->bLastHasMmco5) | 2879 | if (pCtx->pLastDecPicInfo->bLastHasMmco5) |
| 2760 | pCtx->pLastDecPicInfo->iPrevFrameNum = 0; | 2880 | pCtx->pLastDecPicInfo->iPrevFrameNum = 0; |
| 2881 | if (pThreadCtx != NULL) { | ||
| 2882 | int32_t threadCount = pThreadCtx->sThreadInfo.uiThrMaxNum; | ||
| 2883 | int32_t id = pThreadCtx->sThreadInfo.uiThrNum; | ||
| 2884 | for (int32_t i = 0; i < threadCount; ++i) { | ||
| 2885 | if (pThreadCtx[i - id].pCtx != NULL) { | ||
| 2886 | unsigned long long uiTimeStamp = pThreadCtx[i - id].pCtx->uiTimeStamp; | ||
| 2887 | if (uiTimeStamp > 0 && pThreadCtx[i - id].pCtx->sSpsPpsCtx.iSeqId > pCtx->sSpsPpsCtx.iSeqId) { | ||
| 2888 | CopySpsPps (pThreadCtx[i - id].pCtx, pCtx); | ||
| 2889 | if (pCtx->pPicBuff != pThreadCtx[i - id].pCtx->pPicBuff) { | ||
| 2890 | pCtx->pPicBuff = pThreadCtx[i - id].pCtx->pPicBuff; | ||
| 2891 | } | ||
| 2892 | InitialDqLayersContext (pCtx, pCtx->pSps->iMbWidth << 4, pCtx->pSps->iMbHeight << 4); | ||
| 2893 | break; | ||
| 2894 | } | ||
| 2895 | } | ||
| 2896 | } | ||
| 2897 | } | ||
| 2898 | } | ||
| 2899 | if (pThreadCtx != NULL) { | ||
| 2900 | SET_EVENT (&pThreadCtx->sSliceDecodeFinsh); | ||
| 2761 | } | 2901 | } |
| 2762 | |||
| 2763 | return ERR_NONE; | 2902 | return ERR_NONE; |
| 2764 | } | 2903 | } |
| 2765 | 2904 | ||
| @@ -2875,6 +3014,7 @@ bool CheckRefPicturesComplete (PWelsDecoderContext pCtx) { · 109 unmodified lines | |||
| 2875 | if (iRealMbIdx == -1) //caused by abnormal return of FmoNextMb() | 3014 | if (iRealMbIdx == -1) //caused by abnormal return of FmoNextMb() |
| 2876 | return false; | 3015 | return false; |
| 2877 | } | 3016 | } |
| 3017 | |||
| 2878 | return bAllRefComplete; | 3018 | return bAllRefComplete; |
| 2879 | } | 3019 | } |
| 2880 | } // namespace WelsDec | 3020 | } // namespace WelsDec |