Showing the changes to codec/decoder/core (7 of 9 files). Show all
Unified · Split
| @@ -74,6 +74,7 @@ struct TagDqLayer { · 73 unmodified lines | |||
| 74 | int8_t (*pNzcRs)[24]; | 74 | int8_t (*pNzcRs)[24]; |
| 75 | int8_t* pResidualPredFlag; | 75 | int8_t* pResidualPredFlag; |
| 76 | int8_t* pInterPredictionDoneFlag; | 76 | int8_t* pInterPredictionDoneFlag; |
| 77 | bool* pMbCorrectlyDecodedFlag; | ||
| 77 | int16_t (*pScaledTCoeff)[MB_COEFF_LIST_SIZE]; | 78 | int16_t (*pScaledTCoeff)[MB_COEFF_LIST_SIZE]; |
| 78 | int8_t (*pIntraPredMode)[8]; //0~3 top4x4 ; 4~6 left 4x4; 7 intra16x16 | 79 | int8_t (*pIntraPredMode)[8]; //0~3 top4x4 ; 4~6 left 4x4; 7 intra16x16 |
| 79 | int8_t (*pIntra4x4FinalMode)[MB_BLOCK4x4_NUM]; | 80 | int8_t (*pIntra4x4FinalMode)[MB_BLOCK4x4_NUM]; |
| @@ -211,6 +211,7 @@ typedef struct TagWelsDecoderContext { · 210 unmodified lines | |||
| 211 | int32_t* pSliceIdc[LAYER_NUM_EXCHANGEABLE]; // using int32_t for slice_idc | 211 | int32_t* pSliceIdc[LAYER_NUM_EXCHANGEABLE]; // using int32_t for slice_idc |
| 212 | int8_t* pResidualPredFlag[LAYER_NUM_EXCHANGEABLE]; | 212 | int8_t* pResidualPredFlag[LAYER_NUM_EXCHANGEABLE]; |
| 213 | int8_t* pInterPredictionDoneFlag[LAYER_NUM_EXCHANGEABLE]; | 213 | int8_t* pInterPredictionDoneFlag[LAYER_NUM_EXCHANGEABLE]; |
| 214 | bool* pMbCorrectlyDecodedFlag[LAYER_NUM_EXCHANGEABLE]; | ||
| 214 | uint32_t iMbWidth; | 215 | uint32_t iMbWidth; |
| 215 | uint32_t iMbHeight; | 216 | uint32_t iMbHeight; |
| 216 | } sMb; | 217 | } sMb; |
| @@ -279,6 +280,7 @@ typedef struct TagWelsDecoderContext { · 62 unmodified lines | |||
| 279 | #endif | 280 | #endif |
| 280 | bool bNewSeqBegin; | 281 | bool bNewSeqBegin; |
| 281 | int32_t iErrorConMethod; // | 282 | int32_t iErrorConMethod; // |
| 283 | PPicture pPreviousDecodedPictureInDpb; //pointer to previously decoded picture in DPB for error concealment | ||
| 282 | PGetIntraPredFunc pGetI16x16LumaPredFunc[7]; //h264_predict_copy_16x16; | 284 | PGetIntraPredFunc pGetI16x16LumaPredFunc[7]; //h264_predict_copy_16x16; |
| 283 | PGetIntraPredFunc pGetI4x4LumaPredFunc[14]; // h264_predict_4x4_t | 285 | PGetIntraPredFunc pGetI4x4LumaPredFunc[14]; // h264_predict_4x4_t |
| 284 | PGetIntraPredFunc pGetIChromaPredFunc[7]; // h264_predict_8x8_t | 286 | PGetIntraPredFunc pGetIChromaPredFunc[7]; // h264_predict_8x8_t |
| @@ -293,7 +295,7 @@ typedef struct TagWelsDecoderContext { · 8 unmodified lines | |||
| 293 | 295 | ||
| 294 | /* For Block */ | 296 | /* For Block */ |
| 295 | SBlockFunc sBlockFunc; | 297 | SBlockFunc sBlockFunc; |
| 296 | /* For EC */ | 298 | |
| 297 | int32_t iCurSeqIntervalTargetDependId; | 299 | int32_t iCurSeqIntervalTargetDependId; |
| 298 | int32_t iCurSeqIntervalMaxPicWidth; | 300 | int32_t iCurSeqIntervalMaxPicWidth; |
| 299 | int32_t iCurSeqIntervalMaxPicHeight; | 301 | int32_t iCurSeqIntervalMaxPicHeight; |
| @@ -54,7 +54,7 @@ int32_t MarkECFrameAsRef (PWelsDecoderContext pCtx); · 53 unmodified lines | |||
| 54 | bool NeedErrorCon (PWelsDecoderContext pCtx); | 54 | bool NeedErrorCon (PWelsDecoderContext pCtx); |
| 55 | // ImplementErrorConceal | 55 | // ImplementErrorConceal |
| 56 | // Do actual error concealment | 56 | // Do actual error concealment |
| 57 | int32_t ImplementErrorCon (PWelsDecoderContext pCtx); | 57 | void ImplementErrorCon (PWelsDecoderContext pCtx); |
| 58 | 58 | ||
| 59 | } // namespace WelsDec | 59 | } // namespace WelsDec |
| 60 | 60 | ||
| @@ -394,6 +394,7 @@ int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNal · 393 unmodified lines | |||
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | ++pSlice->iTotalMbInCurSlice; | 396 | ++pSlice->iTotalMbInCurSlice; |
| 397 | pCurLayer->pMbCorrectlyDecodedFlag[iNextMbXyIndex] = true; | ||
| 397 | 398 | ||
| 398 | if (pSliceHeader->pPps->uiNumSliceGroups > 1) { | 399 | if (pSliceHeader->pPps->uiNumSliceGroups > 1) { |
| 399 | iNextMbXyIndex = FmoNextMb (pFmo, iNextMbXyIndex); | 400 | iNextMbXyIndex = FmoNextMb (pFmo, iNextMbXyIndex); |
| @@ -164,7 +164,8 @@ void WelsDecoderDefaults (PWelsDecoderContext pCtx) { · 163 unmodified lines | |||
| 164 | pCtx->pPicBuff[LIST_1] = NULL; | 164 | pCtx->pPicBuff[LIST_1] = NULL; |
| 165 | 165 | ||
| 166 | pCtx->bAvcBasedFlag = true; | 166 | pCtx->bAvcBasedFlag = true; |
| 167 | pCtx->iErrorConMethod = ERROR_CON_DISABLE; | 167 | pCtx->iErrorConMethod = ERROR_CON_SLICE_COPY; |
| 168 | pCtx->pPreviousDecodedPictureInDpb = NULL; | ||
| 168 | 169 | ||
| 169 | } | 170 | } |
| 170 | 171 | ||
| @@ -54,12 +54,21 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 53 unmodified lines | |||
| 54 | const int32_t kiHeight = pCurDq->iMbHeight << 4; | 54 | const int32_t kiHeight = pCurDq->iMbHeight << 4; |
| 55 | 55 | ||
| 56 | const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight; | 56 | const int32_t kiTotalNumMbInCurLayer = pCurDq->iMbWidth * pCurDq->iMbHeight; |
| 57 | bool bFrameCompleteFlag = true; | ||
| 57 | 58 | ||
| 58 | if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) { | 59 | if (pCtx->iTotalNumMbRec != kiTotalNumMbInCurLayer) { |
| 60 | if ((pCtx->iTotalNumMbRec != 0) && (I_SLICE == pCurDq->sLayerInfo.sSliceInLayer.eSliceType)) { //TODO should be IDR instead of I_SLICE! | ||
| 61 | memcpy (& (pCtx->sFrameCrop), & (pCurDq->sLayerInfo.sSliceInLayer.sSliceHeaderExt.sSliceHeader.pSps->sFrameCrop), sizeof (SPosOffset)); | ||
| 62 | #ifdef LONG_TERM_REF | ||
| 63 | pCtx->bParamSetsLostFlag = false; | ||
| 64 | #else | ||
| 65 | pCtx->bReferenceLostAtT0Flag = false; | ||
| 66 | #endif //LONG_TERM_REF | ||
| 67 | } | ||
| 59 | WelsLog (pCtx, WELS_LOG_WARNING, | 68 | WelsLog (pCtx, WELS_LOG_WARNING, |
| 60 | "DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d \n", | 69 | "DecodeFrameConstruction():::iTotalNumMbRec:%d, total_num_mb_sps:%d, cur_layer_mb_width:%d, cur_layer_mb_height:%d \n", |
| 61 | pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight); | 70 | pCtx->iTotalNumMbRec, kiTotalNumMbInCurLayer, pCurDq->iMbWidth, pCurDq->iMbHeight); |
| 62 | return -1; | 71 | bFrameCompleteFlag = false; //return later after output buffer is done |
| 63 | } | 72 | } |
| 64 | #ifdef NO_WAITING_AU | 73 | #ifdef NO_WAITING_AU |
| 65 | pCtx->iTotalNumMbRec = 0; | 74 | pCtx->iTotalNumMbRec = 0; |
| @@ -99,6 +108,14 @@ static inline int32_t DecodeFrameConstruction (PWelsDecoderContext pCtx, uint8_t · 33 unmodified lines | |||
| 99 | ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset; | 108 | ppDst[2] = ppDst[2] + pCtx->sFrameCrop.iTopOffset * pPic->iLinesize[1] + pCtx->sFrameCrop.iLeftOffset; |
| 100 | pDstInfo->iBufferStatus = 1; | 109 | pDstInfo->iBufferStatus = 1; |
| 101 | 110 | ||
| 111 | if (pCtx->iErrorConMethod == ERROR_CON_DISABLE) //no buffer output if EC is disabled and frame incomplete | ||
| 112 | pDstInfo->iBufferStatus = (int32_t) bFrameCompleteFlag; | ||
| 113 | |||
| 114 | if (!bFrameCompleteFlag) { | ||
| 115 | pCtx->iErrorCode |= dsBitstreamError; | ||
| 116 | return -1; | ||
| 117 | } | ||
| 118 | |||
| 102 | return 0; | 119 | return 0; |
| 103 | } | 120 | } |
| 104 | 121 | ||
| @@ -955,6 +972,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 850 unmodified lines | |||
| 955 | pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( | 972 | pCtx->sMb.pInterPredictionDoneFlag[i] = (int8_t*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof ( |
| 956 | int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]"); | 973 | int8_t), "pCtx->sMb.pInterPredictionDoneFlag[]"); |
| 957 | 974 | ||
| 975 | pCtx->sMb.pMbCorrectlyDecodedFlag[i] = (bool*) WelsMalloc (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (bool), "pCtx->sMb.pMbCorrectlyDecodedFlag[]"); | ||
| 976 | |||
| 958 | // check memory block valid due above allocated.. | 977 | // check memory block valid due above allocated.. |
| 959 | WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, | 978 | WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, |
| 960 | ((NULL == pCtx->sMb.pMbType[i]) || | 979 | ((NULL == pCtx->sMb.pMbType[i]) || |
| @@ -972,7 +991,8 @@ int32_t InitialDqLayersContext (PWelsDecoderContext pCtx, const int32_t kiMaxWid · 11 unmodified lines | |||
| 972 | (NULL == pCtx->sMb.pSubMbType[i]) || | 991 | (NULL == pCtx->sMb.pSubMbType[i]) || |
| 973 | (NULL == pCtx->sMb.pSliceIdc[i]) || | 992 | (NULL == pCtx->sMb.pSliceIdc[i]) || |
| 974 | (NULL == pCtx->sMb.pResidualPredFlag[i]) || | 993 | (NULL == pCtx->sMb.pResidualPredFlag[i]) || |
| 975 | (NULL == pCtx->sMb.pInterPredictionDoneFlag[i]) | 994 | (NULL == pCtx->sMb.pInterPredictionDoneFlag[i]) || |
| 995 | (NULL == pCtx->sMb.pMbCorrectlyDecodedFlag[i]) | ||
| 976 | ) | 996 | ) |
| 977 | ) | 997 | ) |
| 978 | 998 | ||
| @@ -1100,6 +1120,12 @@ void UninitialDqLayersContext (PWelsDecoderContext pCtx) { · 121 unmodified lines | |||
| 1100 | 1120 | ||
| 1101 | pCtx->sMb.pInterPredictionDoneFlag[i] = NULL; | 1121 | pCtx->sMb.pInterPredictionDoneFlag[i] = NULL; |
| 1102 | } | 1122 | } |
| 1123 | |||
| 1124 | if (pCtx->sMb.pMbCorrectlyDecodedFlag[i]) { | ||
| 1125 | WelsFree (pCtx->sMb.pMbCorrectlyDecodedFlag[i], "pCtx->sMb.pMbCorrectlyDecodedFlag[]"); | ||
| 1126 | pCtx->sMb.pMbCorrectlyDecodedFlag[i] = NULL; | ||
| 1127 | } | ||
| 1128 | |||
| 1103 | WelsFree (pDq, "pDq"); | 1129 | WelsFree (pDq, "pDq"); |
| 1104 | 1130 | ||
| 1105 | pDq = NULL; | 1131 | pDq = NULL; |
| @@ -1560,8 +1586,6 @@ int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferI · 454 unmodified lines | |||
| 1560 | pCtx->bNewSeqBegin = false; | 1586 | pCtx->bNewSeqBegin = false; |
| 1561 | if (ERR_NONE != iErr) { | 1587 | if (ERR_NONE != iErr) { |
| 1562 | WelsLog (pCtx, WELS_LOG_INFO, "returned error from decoding:[0x%x]\n", iErr); | 1588 | WelsLog (pCtx, WELS_LOG_INFO, "returned error from decoding:[0x%x]\n", iErr); |
| 1563 | |||
| 1564 | pDstInfo->iBufferStatus = 0; | ||
| 1565 | return iErr; | 1589 | return iErr; |
| 1566 | } | 1590 | } |
| 1567 | 1591 | ||
| @@ -1651,6 +1675,7 @@ void InitCurDqLayerData (PWelsDecoderContext pCtx, PDqLayer pCurDq) { · 83 unmodified lines | |||
| 1651 | pCurDq->pSubMbType = pCtx->sMb.pSubMbType[0]; | 1675 | pCurDq->pSubMbType = pCtx->sMb.pSubMbType[0]; |
| 1652 | pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0]; | 1676 | pCurDq->pInterPredictionDoneFlag = pCtx->sMb.pInterPredictionDoneFlag[0]; |
| 1653 | pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0]; | 1677 | pCurDq->pResidualPredFlag = pCtx->sMb.pResidualPredFlag[0]; |
| 1678 | pCurDq->pMbCorrectlyDecodedFlag = pCtx->sMb.pMbCorrectlyDecodedFlag[0]; | ||
| 1654 | } | 1679 | } |
| 1655 | } | 1680 | } |
| 1656 | 1681 | ||
| @@ -1725,6 +1750,7 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3 · 68 unmodified lines | |||
| 1725 | if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode | 1750 | if (pCtx->iTotalNumMbRec == 0) { //Picture start to decode |
| 1726 | for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i) | 1751 | for (int32_t i = 0; i < LAYER_NUM_EXCHANGEABLE; ++ i) |
| 1727 | memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t))); | 1752 | memset (pCtx->sMb.pSliceIdc[i], 0xff, (pCtx->sMb.iMbWidth * pCtx->sMb.iMbHeight * sizeof (int32_t))); |
| 1753 | memset (pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag, 0, pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight); | ||
| 1728 | } | 1754 | } |
| 1729 | GetI4LumaIChromaAddrTable (pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]); | 1755 | GetI4LumaIChromaAddrTable (pCtx->iDecBlockOffsetArray, pCtx->pDec->iLinesize[0], pCtx->pDec->iLinesize[1]); |
| 1730 | 1756 | ||
| @@ -1796,15 +1822,16 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3 · 65 unmodified lines | |||
| 1796 | "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d\n", pCtx->iPrevFrameNum, | 1822 | "referencing pictures lost due frame gaps exist, prev_frame_num: %d, curr_frame_num: %d\n", pCtx->iPrevFrameNum, |
| 1797 | pSh->iFrameNum); | 1823 | pSh->iFrameNum); |
| 1798 | 1824 | ||
| 1825 | pCtx->iErrorCode |= dsRefLost; | ||
| 1826 | if (pCtx->iErrorConMethod == ERROR_CON_DISABLE) { | ||
| 1799 | #ifdef LONG_TERM_REF | 1827 | #ifdef LONG_TERM_REF |
| 1800 | pCtx->bParamSetsLostFlag = true; | 1828 | pCtx->bParamSetsLostFlag = true; |
| 1801 | #else | 1829 | #else |
| 1802 | pCtx->bReferenceLostAtT0Flag = true; | 1830 | pCtx->bReferenceLostAtT0Flag = true; |
| 1803 | #endif | 1831 | #endif |
| 1804 | ResetParameterSetsState (pCtx); | 1832 | ResetParameterSetsState (pCtx); |
| 1805 | 1833 | return ERR_INFO_REFERENCE_PIC_LOST; | |
| 1806 | pCtx->iErrorCode |= dsRefLost; | 1834 | } |
| 1807 | return ERR_INFO_REFERENCE_PIC_LOST; | ||
| 1808 | } | 1835 | } |
| 1809 | } | 1836 | } |
| 1810 | 1837 | ||
| @@ -1875,6 +1902,9 @@ int32_t DecodeCurrentAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, int3 · 64 unmodified lines | |||
| 1875 | #endif | 1902 | #endif |
| 1876 | 1903 | ||
| 1877 | } | 1904 | } |
| 1905 | |||
| 1906 | pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //store latest decoded picture for EC | ||
| 1907 | |||
| 1878 | if (uiNalRefIdc > 0) { | 1908 | if (uiNalRefIdc > 0) { |
| 1879 | iRet = WelsMarkAsRef (pCtx); | 1909 | iRet = WelsMarkAsRef (pCtx); |
| 1880 | if (iRet != ERR_NONE) { | 1910 | if (iRet != ERR_NONE) { |
| @@ -66,33 +66,130 @@ void InitErrorCon (PWelsDecoderContext pCtx) { · 65 unmodified lines | |||
| 66 | 66 | ||
| 67 | //Do error concealment using frame copy method | 67 | //Do error concealment using frame copy method |
| 68 | void DoErrorConFrameCopy (PWelsDecoderContext pCtx) { | 68 | void DoErrorConFrameCopy (PWelsDecoderContext pCtx) { |
| 69 | //TODO | 69 | PPicture pDstPic = pCtx->pDec; |
| 70 | PPicture pSrcPic = pCtx->pPreviousDecodedPictureInDpb; | ||
| 71 | uint32_t uiHeightInPixelY = (pCtx->pSps->iMbHeight) << 4; | ||
| 72 | int32_t iStrideY = pDstPic->iLinesize[0]; | ||
| 73 | int32_t iStrideUV = pDstPic->iLinesize[1]; | ||
| 74 | if (pSrcPic == NULL) { //no ref pic, assign specific data to picture | ||
| 75 | memset (pDstPic->pData[0], 0, uiHeightInPixelY * iStrideY); | ||
| 76 | memset (pDstPic->pData[1], 0, (uiHeightInPixelY >> 1) * iStrideUV); | ||
| 77 | memset (pDstPic->pData[2], 0, (uiHeightInPixelY >> 1) * iStrideUV); | ||
| 78 | } else { //has ref pic here | ||
| 79 | memcpy (pDstPic->pData[0], pSrcPic->pData[0], uiHeightInPixelY * iStrideY); | ||
| 80 | memcpy (pDstPic->pData[1], pSrcPic->pData[1], (uiHeightInPixelY >> 1) * iStrideUV); | ||
| 81 | memcpy (pDstPic->pData[2], pSrcPic->pData[2], (uiHeightInPixelY >> 1) * iStrideUV); | ||
| 82 | } | ||
| 70 | } | 83 | } |
| 71 | 84 | ||
| 72 | 85 | ||
| 73 | //Do error concealment using slice copy method | 86 | //Do error concealment using slice copy method |
| 74 | void DoErrorConSliceCopy (PWelsDecoderContext pCtx) { | 87 | void DoErrorConSliceCopy (PWelsDecoderContext pCtx) { |
| 75 | //TODO | 88 | int32_t iMbWidth = (int32_t) pCtx->pSps->iMbWidth; |
| 89 | int32_t iMbHeight = (int32_t) pCtx->pSps->iMbHeight; | ||
| 90 | PPicture pDstPic = pCtx->pDec; | ||
| 91 | PPicture pSrcPic = pCtx->pPreviousDecodedPictureInDpb; | ||
| 92 | |||
| 93 | //uint8_t *pDstData[3], *pSrcData[3]; | ||
| 94 | bool* pMbCorrectlyDecodedFlag = pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag; | ||
| 95 | |||
| 96 | //Do slice copy late | ||
| 97 | int32_t iMbXyIndex; | ||
| 98 | uint8_t* pSrcData, *pDstData; | ||
| 99 | uint32_t iSrcStride; // = pSrcPic->iLinesize[0]; | ||
| 100 | uint32_t iDstStride = pDstPic->iLinesize[0]; | ||
| 101 | for (int32_t iMbY = 0; iMbY < iMbHeight; ++iMbY) { | ||
| 102 | for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) { | ||
| 103 | iMbXyIndex = iMbY * iMbWidth + iMbX; | ||
| 104 | if (!pMbCorrectlyDecodedFlag[iMbXyIndex]) { | ||
| 105 | if (pSrcPic != NULL) { | ||
| 106 | iSrcStride = pSrcPic->iLinesize[0]; | ||
| 107 | //Y component | ||
| 108 | pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16;; | ||
| 109 | pSrcData = pSrcPic->pData[0] + iMbY * 16 * iSrcStride + iMbX * 16; | ||
| 110 | pCtx->sCopyFunc.pCopyLumaFunc (pDstData, iDstStride, pSrcData, iSrcStride); | ||
| 111 | //U component | ||
| 112 | pDstData = pDstPic->pData[1] + iMbY * 8 * iDstStride / 2 + iMbX * 8; | ||
| 113 | pSrcData = pSrcPic->pData[1] + iMbY * 8 * iSrcStride / 2 + iMbX * 8; | ||
| 114 | pCtx->sCopyFunc.pCopyChromaFunc (pDstData, iDstStride / 2, pSrcData, iSrcStride / 2); | ||
| 115 | //V component | ||
| 116 | pDstData = pDstPic->pData[2] + iMbY * 8 * iDstStride / 2 + iMbX * 8; | ||
| 117 | pSrcData = pSrcPic->pData[2] + iMbY * 8 * iSrcStride / 2 + iMbX * 8; | ||
| 118 | pCtx->sCopyFunc.pCopyChromaFunc (pDstData, iDstStride / 2, pSrcData, iSrcStride / 2); | ||
| 119 | } else { //pSrcPic == NULL | ||
| 120 | //Y component | ||
| 121 | pDstData = pDstPic->pData[0] + iMbY * 16 * iDstStride + iMbX * 16; | ||
| 122 | for (int32_t i = 0; i < 16; ++i) { | ||
| 123 | memset (pDstData, 0, 16); | ||
| 124 | pDstData += iDstStride; | ||
| 125 | } | ||
| 126 | //U component | ||
| 127 | pDstData = pDstPic->pData[1] + iMbY * 8 * iDstStride / 2 + iMbX * 8; | ||
| 128 | for (int32_t i = 0; i < 8; ++i) { | ||
| 129 | memset (pDstData, 0, 8); | ||
| 130 | pDstData += iDstStride / 2; | ||
| 131 | } | ||
| 132 | //V component | ||
| 133 | pDstData = pDstPic->pData[2] + iMbY * 8 * iDstStride / 2 + iMbX * 8; | ||
| 134 | for (int32_t i = 0; i < 8; ++i) { | ||
| 135 | memset (pDstData, 0, 8); | ||
| 136 | pDstData += iDstStride / 2; | ||
| 137 | } | ||
| 138 | } // | ||
| 139 | } //!pMbCorrectlyDecodedFlag[iMbXyIndex] | ||
| 140 | } //iMbX | ||
| 141 | } //iMbY | ||
| 76 | } | 142 | } |
| 77 | 143 | ||
| 144 | |||
| 78 | //Mark erroneous frame as Ref Pic into DPB | 145 | //Mark erroneous frame as Ref Pic into DPB |
| 79 | int32_t MarkECFrameAsRef (PWelsDecoderContext pCtx) { | 146 | int32_t MarkECFrameAsRef (PWelsDecoderContext pCtx) { |
| 80 | //TODO | 147 | int32_t iRet = WelsMarkAsRef (pCtx); |
| 148 | if (iRet != ERR_NONE) { | ||
| 149 | pCtx->pDec = NULL; | ||
| 150 | return iRet; | ||
| 151 | } | ||
| 152 | ExpandReferencingPicture (pCtx->pDec, pCtx->sExpandPicFunc.pExpandLumaPicture, | ||
| 153 | pCtx->sExpandPicFunc.pExpandChromaPicture); | ||
| 154 | pCtx->pDec = NULL; | ||
| 155 | |||
| 81 | return ERR_NONE; | 156 | return ERR_NONE; |
| 82 | } | 157 | } |
| 83 | 158 | ||
| 84 | bool NeedErrorCon (PWelsDecoderContext pCtx) { | 159 | bool NeedErrorCon (PWelsDecoderContext pCtx) { |
| 85 | bool bNeedEC = false; | 160 | bool bNeedEC = false; |
| 86 | //TODO | 161 | int32_t iMbNum = pCtx->pSps->iMbWidth * pCtx->pSps->iMbHeight; |
| 162 | for (int32_t i = 0; i < iMbNum; ++i) { | ||
| 163 | if (!pCtx->pCurDqLayer->pMbCorrectlyDecodedFlag[i]) { | ||
| 164 | bNeedEC = true; | ||
| 165 | break; | ||
| 166 | } | ||
| 167 | } | ||
| 87 | return bNeedEC; | 168 | return bNeedEC; |
| 88 | } | 169 | } |
| 89 | 170 | ||
| 90 | // ImplementErrorConceal | 171 | // ImplementErrorConceal |
| 91 | // Do actual error concealment | 172 | // Do actual error concealment |
| 92 | int32_t ImplementErrorCon (PWelsDecoderContext pCtx) { | 173 | void ImplementErrorCon (PWelsDecoderContext pCtx) { |
| 93 | int32_t iRet = ERR_NONE; | 174 | if (!NeedErrorCon (pCtx)) |
| 94 | //TODO | 175 | return; |
| 95 | return iRet; | 176 | |
| 177 | if (ERROR_CON_DISABLE == pCtx->iErrorConMethod) { | ||
| 178 | pCtx->iErrorCode |= dsBitstreamError; | ||
| 179 | return; | ||
| 180 | } else if (ERROR_CON_FRAME_COPY == pCtx->iErrorConMethod) { | ||
| 181 | DoErrorConFrameCopy (pCtx); | ||
| 182 | } else if (ERROR_CON_SLICE_COPY == pCtx->iErrorConMethod) { | ||
| 183 | DoErrorConSliceCopy (pCtx); | ||
| 184 | } //TODO add other EC methods here in the future | ||
| 185 | |||
| 186 | //mark the erroneous frame as Ref pic in DPB | ||
| 187 | MarkECFrameAsRef (pCtx); | ||
| 188 | //need update frame_num due current frame is well decoded | ||
| 189 | pCtx->iPrevFrameNum = pCtx->pSliceHeader->iFrameNum; | ||
| 190 | if (pCtx->bLastHasMmco5) | ||
| 191 | pCtx->iPrevFrameNum = 0; | ||
| 192 | |||
| 96 | } | 193 | } |
| 97 | 194 | ||
| 98 | } // namespace WelsDec | 195 | } // namespace WelsDec |