History

Mainly update DecodeCurrentAccessUnit and associated functions to do threaded parallel frame decodings.

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.

xiaotiansf committed 7 years ago

Commit b0f95c41 parent 8b881449 files · +279 −89Browse files

Unified · Split

9 files
  1. codec/decoder/core/inc/decoder_context.h +3 −0
  2. codec/decoder/core/inc/pic_queue.h +2 −0
  3. codec/decoder/core/inc/picture.h +1 −0
  4. codec/decoder/core/src/decode_slice.cpp +1 −2
  5. codec/decoder/core/src/decoder.cpp +31 −4
  6. codec/decoder/core/src/decoder_core.cpp +222 −82
  7. codec/decoder/core/src/manage_dec_ref.cpp +1 −1
  8. codec/decoder/core/src/pic_queue.cpp +12 −0
  9. codec/decoder/core/src/wels_decoder_thread.cpp +6 −0
codec/decoder/core/inc/decoder_context.h+3−0
@@ -277,6 +277,7 @@ typedef struct tagSWelsLastDecPicInfo { · 276 unmodified lines
277 PPicture pPreviousDecodedPictureInDpb; //pointer to previously decoded picture in DPB for error concealment277 PPicture pPreviousDecodedPictureInDpb; //pointer to previously decoded picture in DPB for error concealment
278 int32_t iPrevFrameNum;// frame number of previous frame well decoded for non-truncated mode yet278 int32_t iPrevFrameNum;// frame number of previous frame well decoded for non-truncated mode yet
279 bool bLastHasMmco5;279 bool bLastHasMmco5;
280 uint32_t uiDecodingTimeStamp; //represent relative decoding time stamps
280} SWelsLastDecPicInfo, *PWelsLastDecPicInfo;281} SWelsLastDecPicInfo, *PWelsLastDecPicInfo;
281 282
282typedef struct tagPictInfo {283typedef struct tagPictInfo {
@@ -538,6 +539,8 @@ typedef struct tagSWelsDecThreadCtx { · 255 unmodified lines
538 PPicture pDec;539 PPicture pDec;
539 SWelsDecEvent sImageReady;540 SWelsDecEvent sImageReady;
540 SWelsDecEvent sSliceDecodeStart;541 SWelsDecEvent sSliceDecodeStart;
542 SWelsDecEvent sSliceDecodeFinsh;
543 int32_t iPicBuffIdx; //picBuff Index
541} SWelsDecoderThreadCTX, *PWelsDecoderThreadCTX;544} SWelsDecoderThreadCTX, *PWelsDecoderThreadCTX;
542 545
543static inline void ResetActiveSPSForEachLayer (PWelsDecoderContext pCtx) {546static inline void ResetActiveSPSForEachLayer (PWelsDecoderContext pCtx) {
codec/decoder/core/inc/pic_queue.h+2−0
@@ -54,6 +54,8 @@ typedef struct TagPicBuff { · 53 unmodified lines
54 54
55PPicture PrefetchPic (PPicBuff pPicBuff); // To get current node applicable55PPicture PrefetchPic (PPicBuff pPicBuff); // To get current node applicable
56PPicture PrefetchPicForThread (PPicBuff pPicBuff); // To get current node applicable in the case of threaded mode56PPicture PrefetchPicForThread (PPicBuff pPicBuff); // To get current node applicable in the case of threaded mode
57PPicture PrefetchLastPicForThread (PPicBuff pPicBuff,
58 const int32_t& iLast); // To get last node applicable in the case of threaded mode
57 59
58} // namespace WelsDec60} // namespace WelsDec
59 61
codec/decoder/core/inc/picture.h+1−0
@@ -89,6 +89,7 @@ struct SPicture { · 88 unmodified lines
89 uint32_t uiDecodingTimeStamp; //represent relative decoding time stamps89 uint32_t uiDecodingTimeStamp; //represent relative decoding time stamps
90 int32_t iPicBuffIdx;90 int32_t iPicBuffIdx;
91 EWelsSliceType eSliceType;91 EWelsSliceType eSliceType;
92 bool bIsUngroupedMultiSlice; //multi-slice picture with each each slice group contains one slice.
92 bool bNewSeqBegin;93 bool bNewSeqBegin;
93 int32_t iMbEcedNum;94 int32_t iMbEcedNum;
94 int32_t iMbEcedPropNum;95 int32_t iMbEcedPropNum;
codec/decoder/core/src/decode_slice.cpp+1−2
@@ -1736,9 +1736,8 @@ int32_t WelsDecodeAndConstructSlice (PWelsDecoderContext pCtx) { · 1735 unmodified lines
1736 if (!pCurDqLayer->pMbCorrectlyDecodedFlag[iNextMbXyIndex]) { //already con-ed, overwrite1736 if (!pCurDqLayer->pMbCorrectlyDecodedFlag[iNextMbXyIndex]) { //already con-ed, overwrite
1737 pCurDqLayer->pMbCorrectlyDecodedFlag[iNextMbXyIndex] = true;1737 pCurDqLayer->pMbCorrectlyDecodedFlag[iNextMbXyIndex] = true;
1738 pCtx->pDec->iMbEcedPropNum += (pCurDqLayer->pMbRefConcealedFlag[iNextMbXyIndex] ? 1 : 0);1738 pCtx->pDec->iMbEcedPropNum += (pCurDqLayer->pMbRefConcealedFlag[iNextMbXyIndex] ? 1 : 0);
1739 ++pCtx->iTotalNumMbRec;
1740 }1739 }
1741 1740 ++pCtx->iTotalNumMbRec;
1742 if (pCtx->iTotalNumMbRec > iTotalMbTargetLayer) {1741 if (pCtx->iTotalNumMbRec > iTotalMbTargetLayer) {
1743 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,1742 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
1744 "WelsTargetSliceConstruction():::pCtx->iTotalNumMbRec:%d, iTotalMbTargetLayer:%d",1743 "WelsTargetSliceConstruction():::pCtx->iTotalNumMbRec:%d, iTotalMbTargetLayer:%d",
codec/decoder/core/src/decoder.cpp+31−4
@@ -393,6 +393,7 @@ void WelsDecoderLastDecPicInfoDefaults (SWelsLastDecPicInfo& sLastDecPicInfo) { · 392 unmodified lines
393 sLastDecPicInfo.pPreviousDecodedPictureInDpb = NULL;393 sLastDecPicInfo.pPreviousDecodedPictureInDpb = NULL;
394 sLastDecPicInfo.iPrevFrameNum = -1;394 sLastDecPicInfo.iPrevFrameNum = -1;
395 sLastDecPicInfo.bLastHasMmco5 = false;395 sLastDecPicInfo.bLastHasMmco5 = false;
396 sLastDecPicInfo.uiDecodingTimeStamp = 0;
396}397}
397 398
398/*!399/*!
@@ -437,6 +438,9 @@ static inline int32_t GetTargetRefListSize (PWelsDecoderContext pCtx) { · 38 unmodified lines
437 iNumRefFrames = MAX_REF_PIC_COUNT + 2;438 iNumRefFrames = MAX_REF_PIC_COUNT + 2;
438 } else {439 } else {
439 iNumRefFrames = pCtx->pSps->iNumRefFrames + 2;440 iNumRefFrames = pCtx->pSps->iNumRefFrames + 2;
441 if (pCtx->pThreadCtx != NULL) {
442 iNumRefFrames = MAX_REF_PIC_COUNT + 1;
443 }
440 }444 }
441 445
442#ifdef LONG_TERM_REF446#ifdef LONG_TERM_REF
@@ -478,7 +482,9 @@ int32_t WelsRequestMem (PWelsDecoderContext pCtx, const int32_t kiMbWidth, const · 35 unmodified lines
478 && kiPicHeight == pCtx->iImgHeightInPixel) && (!bNeedChangePicQueue)) // have same scaled buffer482 && kiPicHeight == pCtx->iImgHeightInPixel) && (!bNeedChangePicQueue)) // have same scaled buffer
479 483
480 // sync update pRefList484 // sync update pRefList
481 WelsResetRefPic (pCtx); // added to sync update ref list due to pictures are free485 if (pCtx->pThreadCtx == NULL) {
486 WelsResetRefPic (pCtx); // added to sync update ref list due to pictures are free
487 }
482 488
483 if (pCtx->bHaveGotMemory && (kiPicWidth == pCtx->iImgWidthInPixel && kiPicHeight == pCtx->iImgHeightInPixel)489 if (pCtx->bHaveGotMemory && (kiPicWidth == pCtx->iImgWidthInPixel && kiPicHeight == pCtx->iImgHeightInPixel)
484 && pCtx->pPicBuff != NULL && pCtx->pPicBuff->iCapacity != iPicQueueSize) {490 && pCtx->pPicBuff != NULL && pCtx->pPicBuff->iCapacity != iPicQueueSize) {
@@ -554,6 +560,17 @@ void WelsFreeDynamicMemory (PWelsDecoderContext pCtx) { · 69 unmodified lines
554 if (NULL != pPicBuff && NULL != *pPicBuff) {560 if (NULL != pPicBuff && NULL != *pPicBuff) {
555 DestroyPicBuff (pCtx, pPicBuff, pMa);561 DestroyPicBuff (pCtx, pPicBuff, pMa);
556 }562 }
563 if (pCtx->pThreadCtx != NULL) {
564 //prevent from double destruction of PPicBuff
565 PWelsDecoderThreadCTX pThreadCtx = (PWelsDecoderThreadCTX) (pCtx->pThreadCtx);
566 int32_t threadCount = pThreadCtx->sThreadInfo.uiThrMaxNum;
567 int32_t id = pThreadCtx->sThreadInfo.uiThrNum;
568 for (int32_t i = 0; i < threadCount; ++i) {
569 if (pThreadCtx[i - id].pCtx != NULL) {
570 pThreadCtx[i - id].pCtx->pPicBuff = NULL;
571 }
572 }
573 }
557 574
558 if (pCtx->pTempDec) {575 if (pCtx->pTempDec) {
559 FreePicture (pCtx->pTempDec, pCtx->pMemAlign);576 FreePicture (pCtx->pTempDec, pCtx->pMemAlign);
@@ -796,7 +813,11 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in · 236 unmodified lines
796 }813 }
797 CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);814 CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
798 if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {815 if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
799 ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);816 if (pCtx->pThreadCtx == NULL) {
817 ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
818 } else {
819 pCtx->pAccessUnitList->uiAvailUnitsNum = 1;
820 }
800 }821 }
801 }822 }
802 DecodeFinishUpdate (pCtx);823 DecodeFinishUpdate (pCtx);
@@ -852,9 +873,15 @@ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const in · 49 unmodified lines
852 if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {873 if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
853 iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);874 iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
854 }875 }
855 CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);876 if (pCtx->pThreadCtx == NULL) {
877 CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
878 }
856 if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {879 if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
857 ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);880 if (pCtx->pThreadCtx == NULL) {
881 ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
882 } else {
883 pCtx->pAccessUnitList->uiAvailUnitsNum = 1;
884 }
858 }885 }
859 }886 }
860 DecodeFinishUpdate (pCtx);887 DecodeFinishUpdate (pCtx);
codec/decoder/core/src/decoder_core.cpp+222−82
@@ -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 done196 bFrameCompleteFlag = false; //return later after output buffer is done
197 if (pCtx->bInstantDecFlag) //no-delay decoding, wait for new slice197 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.bIdrFlag200 } else if (pCurDq->sLayerInfo.sNalHeaderExt.bIdrFlag
200 && (pCtx->iErrorCode == dsErrorFree)) { //complete non-ECed IDR frame done201 && (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 incomplete246 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 structure864 * Parse slice header of bitstream in avc for storing data structure
847 */865 */
848int32_t ParseSliceHeaderSyntaxs (PWelsDecoderContext pCtx, PBitStringAux pBs, const bool kbExtensionFlag) {866int32_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
1463int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWidth, const int32_t kiMaxHeight) {1482int32_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/20101568 "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
1602void UninitialDqLayersContext (PWelsDecoderContext pCtx) {1629void 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.h2334 * 0 - success; otherwise returned error_no defined in error_no.h
2308 */2335 */
2309int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {2336int32_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
2413int32_t InitRefPicList (PWelsDecoderContext pCtx, const uint8_t kuiNRi, int32_t iPoc) {2419int32_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 */
2468int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {2477int32_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/20082509 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 decoding2511 //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 decode2611 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 22644 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_usage2648 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 != iLastIdD2676 bFreshSliceAvailable = (iCurrIdD != iLastIdD
2588 || iCurrIdQ != iLastIdQ); // do not need condition of (first_mb == 0) due multiple slices might be disorder2677 || 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 layer2683 if ((iLastIdD < 0) || //case 1: first layer
2597 (iLastIdD == iCurrIdD)) { //case 2: same uiDId2684 (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.bIdrFlag2688 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_num2690 // 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 case2751 //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 false2767 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 EC2845 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 NULL2873 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 WelsDec3020} // namespace WelsDec
codec/decoder/core/src/manage_dec_ref.cpp+1−1
@@ -150,7 +150,7 @@ static int32_t WelsCheckAndRecoverForFutureDecoding (PWelsDecoderContext pCtx) { · 149 unmodified lines
150 && pCtx->eSliceType != SI_SLICE)) {150 && pCtx->eSliceType != SI_SLICE)) {
151 if (pCtx->pParam->eEcActiveIdc !=151 if (pCtx->pParam->eEcActiveIdc !=
152 ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0152 ERROR_CON_DISABLE) { //IDR lost!, recover it for future decoding with data all set to 0
153 PPicture pRef = pCtx->pThreadCtx != NULL ? PrefetchPicForThread (pCtx->pPicBuff) : PrefetchPic (pCtx->pPicBuff);153 PPicture pRef = PrefetchPic (pCtx->pPicBuff);
154 if (pRef != NULL) {154 if (pRef != NULL) {
155 // IDR lost, set new155 // IDR lost, set new
156 pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture156 pRef->bIsComplete = false; // Set complete flag to false for lost IDR ref picture
codec/decoder/core/src/pic_queue.cpp+12−0
@@ -217,4 +217,16 @@ PPicture PrefetchPicForThread (PPicBuff pPicBuf) { · 216 unmodified lines
217 return pPic;217 return pPic;
218}218}
219 219
220PPicture PrefetchLastPicForThread (PPicBuff pPicBuf, const int32_t& iLastPicBuffIdx) {
221 PPicture pPic = NULL;
222
223 if (pPicBuf->iCapacity == 0) {
224 return NULL;
225 }
226 if (iLastPicBuffIdx >= 0 && iLastPicBuffIdx < pPicBuf->iCapacity) {
227 pPic = pPicBuf->ppPic[iLastPicBuffIdx];
228 }
229 return pPic;
230}
231
220} // namespace WelsDec232} // namespace WelsDec
codec/decoder/core/src/wels_decoder_thread.cpp+6−0
@@ -57,6 +57,12 @@ · 56 unmodified lines
57#define HW_NCPU_NAME "hw.ncpu"57#define HW_NCPU_NAME "hw.ncpu"
58#endif58#endif
59#endif59#endif
60#ifdef ANDROID_NDK
61#include <cpu-features.h>
62#endif
63#ifdef __ANDROID__
64#include <android/api-level.h>
65#endif
60 66
61#include "wels_decoder_thread.h"67#include "wels_decoder_thread.h"
62#include <stdio.h>68#include <stdio.h>

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t