| @@ -194,8 +194,9 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 193 unmodified lines |
| 194 | 194 | "DecodeFrameConstruction(): iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d ", |
| 195 | 195 | pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight); |
| 196 | 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 | 198 | return ERR_INFO_MB_NUM_INADEQUATE; |
| 199 | + } |
| 199 | 200 | } else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag |
| 200 | 201 | && (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done |
| 201 | 202 | pCtx->pDec->bIsComplete = true; |
| @@ -220,9 +221,26 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 18 unmodified lines |
| 220 | 221 | ppDst[1] = ppDst[1] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset; |
| 221 | 222 | ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset; |
| 222 | 223 | pDstInfo->iBufferStatus = 1; |
| 223 | | − |
| 224 | | − bool bOutResChange = (pCtx->iLastImgWidthInPixel != pDstInfo->UsrData.sSystemBuffer.iWidth) |
| 225 | | − || (pCtx->iLastImgHeightInPixel != pDstInfo->UsrData.sSystemBuffer.iHeight); |
| 224 | + if (pCtx->pThreadCtx != NULL && pPic->bIsComplete == false) { |
| 225 | + pPic->bIsComplete = true; |
| 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 | 244 | pCtx->iLastImgWidthInPixel = pDstInfo->UsrData.sSystemBuffer.iWidth; |
| 227 | 245 | pCtx->iLastImgHeightInPixel = pDstInfo->UsrData.sSystemBuffer.iHeight; |
| 228 | 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 | 864 | * Parse slice header of bitstream in avc for storing data structure |
| 847 | 865 | */ |
| 848 | 866 | int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, const bool kbExtensionFlag) { |
| 849 | | − PNalUnit const kpCurNal = pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum - |
| 850 | | − 1]; |
| 867 | + PNalUnit const kpCurNal = |
| 868 | + pCtx->pAccessUnitList->pNalUnitsList[pCtx->pAccessUnitList->uiAvailUnitsNum - |
| 869 | + 1]; |
| 851 | 870 | |
| 852 | 871 | PNalUnitHeaderExt pNalHeaderExt = NULL; |
| 853 | 872 | PSliceHeader pSliceHead = NULL; |
| @@ -1462,7 +1481,6 @@ int32_t UpdateAccessUnit (PWelsDecoderContext pCtx) { · 608 unmodified lines |
| 1462 | 1481 | |
| 1463 | 1482 | int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWidth, const int32_t kiMaxHeight) { |
| 1464 | 1483 | int32_t i = 0; |
| 1465 | | − |
| 1466 | 1484 | WELS_VERIFY_RETURN_IF (ERR_INFO_INVALID_PARAM, (NULL == pCtx || kiMaxWidth <= 0 || kiMaxHeight <= 0)) |
| 1467 | 1485 | pCtx->sMb.iMbWidth = (kiMaxWidth + 15) >> 4; |
| 1468 | 1486 | pCtx->sMb.iMbHeight = (kiMaxHeight + 15) >> 4; |
| @@ -1508,7 +1526,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 39 unmodified lines |
| 1508 | 1526 | sizeof ( |
| 1509 | 1527 | bool), |
| 1510 | 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 | 1531 | "pCtx->sMb.pTransformSize8x8Flag[]"); |
| 1513 | 1532 | pCtx->sMb.pChromaQp[i] = (int8_t (*)[2])pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1514 | 1533 | int8_t) * 2, |
| @@ -1519,9 +1538,11 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 4 unmodified lines |
| 1519 | 1538 | int16_t) * MV_A * MB_BLOCK4x4_NUM, "pCtx->sMb.pMvd[][]"); |
| 1520 | 1539 | pCtx->sMb.pCbfDc[i] = (uint16_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (uint16_t), |
| 1521 | 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 | 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 | 1546 | "pCtx->sMb.pNzcRs[]"); |
| 1526 | 1547 | pCtx->sMb.pScaledTCoeff[i] = (int16_t (*)[MB_COEFF_LIST_SIZE])pMa->WelsMallocz (pCtx->sMb.iMbWidth * |
| 1527 | 1548 | pCtx->sMb.iMbHeight * |
| @@ -1539,20 +1560,24 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 11 unmodified lines |
| 1539 | 1560 | "pCtx->sMb.pChromaPredMode[]"); |
| 1540 | 1561 | pCtx->sMb.pCbp[i] = (int8_t*)pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int8_t), |
| 1541 | 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 | 1565 | sizeof ( |
| 1544 | 1566 | uint32_t) * MB_PARTITION_SIZE, "pCtx->sMb.pSubMbType[]"); |
| 1545 | 1567 | pCtx->sMb.pSliceIdc[i] = (int32_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t), |
| 1546 | 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 | 1571 | "pCtx->sMb.pResidualPredFlag[]"); |
| 1549 | | − pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1550 | | − int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]"); |
| 1572 | + pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * |
| 1573 | + sizeof ( |
| 1574 | + int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]"); |
| 1551 | 1575 | |
| 1552 | 1576 | pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) pMa->WelsMallocz (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 1553 | 1577 | bool), |
| 1554 | 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 | 1581 | "pCtx->pMbRefConcealedFlag[]"); |
| 1557 | 1582 | |
| 1558 | 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 | 1624 | return ERR_NONE; |
| 1600 | 1625 | } |
| 1601 | 1626 | |
| 1627 | + |
| 1628 | + |
| 1602 | 1629 | void UninitialDqLayersContext (PWelsDecoderContext pCtx) { |
| 1603 | 1630 | int32_t i = 0; |
| 1604 | 1631 | CMemoryAlign* pMa = pCtx->pMemAlign; |
| @@ -2307,39 +2334,18 @@ int32_t InitConstructAccessUnit (PWelsDecoderContext pCtx, SBufferInfo* pDstInfo · 702 unmodified lines |
| 2307 | 2334 | * 0 - success; otherwise returned error_no defined in error_no.h |
| 2308 | 2335 | */ |
| 2309 | 2336 | int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) { |
| 2310 | | − int32_t iErr; |
| 2311 | | − PAccessUnit pCurAu = pCtx->pAccessUnitList; |
| 2312 | | − pCtx->bAuReadyFlag = false; |
| 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 | | − |
| 2337 | + int32_t iErr = ERR_NONE; |
| 2338 | + if (pCtx->pThreadCtx == NULL) { |
| 2339 | + iErr = InitConstructAccessUnit (pCtx, pDstInfo); |
| 2338 | 2340 | if (ERR_NONE != iErr) { |
| 2339 | | − WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "sync picture resolution ext failed, the error is %d", iErr); |
| 2340 | 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 | 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 | 2419 | int32_t InitRefPicList (PWelsDecoderContext pCtx, const uint8_t kuiNRi, int32_t iPoc) { |
| 2414 | 2420 | int32_t iRet = ERR_NONE; |
| 2421 | + if (pCtx->pThreadCtx != NULL && pCtx->bNewSeqBegin) { |
| 2422 | + WelsResetRefPic (pCtx); |
| 2423 | + } |
| 2415 | 2424 | if (pCtx->eSliceType == B_SLICE) { |
| 2416 | 2425 | iRet = WelsInitBSliceRefList (pCtx, iPoc); |
| 2417 | 2426 | CreateImplicitWeightTable (pCtx); |
| @@ -2466,13 +2475,26 @@ void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) { · 48 unmodified lines |
| 2466 | 2475 | * Decode current access unit when current AU is completed. |
| 2467 | 2476 | */ |
| 2468 | 2477 | int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) { |
| 2469 | | − int32_t iRefCount[LIST_A]; |
| 2470 | | − PNalUnit pNalCur = NULL; |
| 2478 | + PNalUnit pNalCur = pCtx->pNalCur = NULL; |
| 2471 | 2479 | PAccessUnit pCurAu = pCtx->pAccessUnitList; |
| 2472 | 2480 | |
| 2473 | 2481 | int32_t iIdx = pCurAu->uiStartPos; |
| 2474 | 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 | 2498 | int32_t iPpsId = 0; |
| 2477 | 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 | 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 | 2511 | //update pCurDqLayer at the starting of AU decoding |
| 2490 | | − if (pCtx->bInitialDqLayersMem) { |
| 2512 | + if (pCtx->bInitialDqLayersMem || pCtx->pCurDqLayer == NULL) { |
| 2491 | 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 | 2522 | PSliceHeaderExt pShExt = NULL; |
| 2501 | 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 | 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 | 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 | 2590 | if (pCtx->iTotalNumMbRec != 0) |
| 2506 | 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 | 2605 | pCtx->pDec->uiTimeStamp = pNalCur->uiTimeStamp; |
| 2521 | 2606 | pCtx->pDec->uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp; |
| 2607 | + if (pThreadCtx != NULL) { |
| 2608 | + pThreadCtx->iPicBuffIdx = pCtx->pDec->iPicBuffIdx; |
| 2609 | + } |
| 2522 | 2610 | |
| 2523 | 2611 | if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode |
| 2524 | 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 | 2644 | pCtx->pDec->iFramePoc = pSh->iPicOrderCntLsb; // still can not obtain correct, because current do not support POCtype 2 |
| 2557 | 2645 | pCtx->pDec->bIdrFlag = pNalCur->sNalHeaderExt.bIdrFlag; |
| 2558 | 2646 | pCtx->pDec->eSliceType = pSh->eSliceType; |
| 2647 | + |
| 2559 | 2648 | memcpy (&pLayerInfo.sSliceInLayer.sSliceHeaderExt, pShExt, sizeof (SSliceHeaderExt)); //confirmed_safe_unsafe_usage |
| 2560 | 2649 | pLayerInfo.sSliceInLayer.bSliceHeaderExtFlag = pNalCur->sNalData.sVclNal.bSliceHeaderExtFlag; |
| 2561 | 2650 | pLayerInfo.sSliceInLayer.eSliceType = pSh->eSliceType; |
| @@ -2587,11 +2676,9 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 25 unmodified lines |
| 2587 | 2676 | bFreshSliceAvailable = (iCurrIdD != iLastIdD |
| 2588 | 2677 | || iCurrIdQ != iLastIdQ); // do not need condition of (first_mb == 0) due multiple slices might be disorder |
| 2589 | 2678 | |
| 2679 | + |
| 2590 | 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 | 2683 | if ((iLastIdD < 0) || //case 1: first layer |
| 2597 | 2684 | (iLastIdD == iCurrIdD)) { //case 2: same uiDId |
| @@ -2601,13 +2688,23 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 3 unmodified lines |
| 2601 | 2688 | const bool kbIdrFlag = dq_cur->sLayerInfo.sNalHeaderExt.bIdrFlag |
| 2602 | 2689 | || (dq_cur->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR); |
| 2603 | 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 | 2701 | if (!kbIdrFlag && |
| 2605 | | − pSh->iFrameNum != pCtx->pLastDecPicInfo->iPrevFrameNum && |
| 2606 | | − pSh->iFrameNum != ((pCtx->pLastDecPicInfo->iPrevFrameNum + 1) & ((1 << dq_cur->sLayerInfo.pSps->uiLog2MaxFrameNum) - |
| 2702 | + pSh->iFrameNum != iPrevFrameNum && |
| 2703 | + pSh->iFrameNum != ((iPrevFrameNum + 1) & ((1 << dq_cur->sLayerInfo.pSps->uiLog2MaxFrameNum) - |
| 2607 | 2704 | 1))) { |
| 2608 | 2705 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, |
| 2609 | 2706 | "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d", |
| 2610 | | − pCtx->pLastDecPicInfo->iPrevFrameNum, |
| 2707 | + iPrevFrameNum, |
| 2611 | 2708 | pSh->iFrameNum); |
| 2612 | 2709 | |
| 2613 | 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 | 2724 | iRet = InitRefPicList (pCtx, pCtx->uiNalRefIdc, pSh->iPicOrderCntLsb); |
| 2628 | 2725 | if (iRet) { |
| 2629 | 2726 | pCtx->bRPLRError = true; |
| @@ -2643,7 +2740,13 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBuf · 13 unmodified lines |
| 2643 | 2740 | if (pSh->eSliceType == B_SLICE && !pSh->iDirectSpatialMvPredFlag) |
| 2644 | 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 | 2751 | //Output good store_base reconstruction when enhancement quality layer occurred error for MGS key picture case |
| 2649 | 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 | 2766 | if ((iRet = WelsDecodeConstructSlice (pCtx, pNalCur)) != ERR_NONE) { |
| 2664 | 2767 | pCtx->pDec->bIsComplete = false; // reconstruction error, directly set the flag false |
| 2665 | 2768 | return iRet; |
| 2666 | 2769 | } |
| 2667 | 2770 | } |
| 2668 | 2771 | if (bAllRefComplete && pCtx->eSliceType != I_SLICE) { |
| 2669 | | − if (pCtx->sRefPic.uiRefCount[LIST_0] > 0) { |
| 2670 | | − bAllRefComplete &= CheckRefPicturesComplete (pCtx); |
| 2671 | | − } else { |
| 2672 | | − bAllRefComplete = false; |
| 2772 | + if (pCtx->pThreadCtx == NULL) { |
| 2773 | + if (pCtx->sRefPic.uiRefCount[LIST_0] > 0) { |
| 2774 | + bAllRefComplete &= CheckRefPicturesComplete (pCtx); |
| 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 | 2837 | iRet = DecodeFrameConstruction (pCtx, ppDst, pDstInfo); |
| 2725 | | − if (iRet) |
| 2838 | + if (iRet) { |
| 2839 | + if (pThreadCtx != NULL) { |
| 2840 | + SET_EVENT (&pThreadCtx->sSliceDecodeFinsh); |
| 2841 | + } |
| 2726 | 2842 | return iRet; |
| 2843 | + } |
| 2727 | 2844 | |
| 2728 | 2845 | pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC |
| 2729 | | − pCtx->bUsedAsRef = false; |
| 2730 | | − if (pCtx->uiNalRefIdc > 0) { |
| 2731 | | − pCtx->bUsedAsRef = true; |
| 2732 | | − for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) { |
| 2733 | | − uint32_t i = 0; |
| 2734 | | − while (i < MAX_DPB_COUNT && pCtx->sRefPic.pRefList[listIdx][i]) { |
| 2735 | | − pCtx->pDec->pRefPic[listIdx][i] = pCtx->sRefPic.pRefList[listIdx][i]; |
| 2736 | | − ++i; |
| 2846 | + pCtx->bUsedAsRef = pCtx->uiNalRefIdc > 0; |
| 2847 | + if (pCtx->pThreadCtx == NULL) { |
| 2848 | + if (pCtx->bUsedAsRef) { |
| 2849 | + for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) { |
| 2850 | + uint32_t i = 0; |
| 2851 | + while (i < MAX_DPB_COUNT && pCtx->sRefPic.pRefList[listIdx][i]) { |
| 2852 | + pCtx->pDec->pRefPic[listIdx][i] = pCtx->sRefPic.pRefList[listIdx][i]; |
| 2853 | + ++i; |
| 2854 | + } |
| 2737 | 2855 | } |
| 2738 | | − } |
| 2739 | | − iRet = WelsMarkAsRef (pCtx); |
| 2740 | | − if (iRet != ERR_NONE) { |
| 2741 | | − if (iRet == ERR_INFO_DUPLICATE_FRAME_NUM) |
| 2742 | | − pCtx->iErrorCode |= dsBitstreamError; |
| 2743 | | − if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) { |
| 2744 | | − pCtx->pDec = NULL; |
| 2745 | | − return iRet; |
| 2856 | + iRet = WelsMarkAsRef (pCtx); |
| 2857 | + if (iRet != ERR_NONE) { |
| 2858 | + if (iRet == ERR_INFO_DUPLICATE_FRAME_NUM) |
| 2859 | + pCtx->iErrorCode |= dsBitstreamError; |
| 2860 | + if (pCtx->pParam->eEcActiveIdc == ERROR_CON_DISABLE) { |
| 2861 | + pCtx->pDec = NULL; |
| 2862 | + 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) |
| 2749 | | − ExpandReferencingPicture (pCtx->pDec->pData, pCtx->pDec->iWidthInPixel, pCtx->pDec->iHeightInPixel, |
| 2750 | | − pCtx->pDec->iLinesize, |
| 2751 | | − pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture); |
| 2870 | + } else { |
| 2871 | + SET_EVENT (&pThreadCtx->sImageReady); |
| 2752 | 2872 | } |
| 2753 | 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 | 2878 | pCtx->pLastDecPicInfo->iPrevFrameNum = pSh->iFrameNum; |
| 2759 | 2879 | if (pCtx->pLastDecPicInfo->bLastHasMmco5) |
| 2760 | 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 | 2902 | return ERR_NONE; |
| 2764 | 2903 | } |
| 2765 | 2904 | |
| @@ -2875,6 +3014,7 @@ bool CheckRefPicturesComplete (PWelsDecoderContext pCtx) { · 109 unmodified lines |
| 2875 | 3014 | if (iRealMbIdx == -1) //caused by abnormal return of FmoNextMb() |
| 2876 | 3015 | return false; |
| 2877 | 3016 | } |
| 3017 | + |
| 2878 | 3018 | return bAllRefComplete; |
| 2879 | 3019 | } |
| 2880 | 3020 | } // namespace WelsDec |