Showing the changes to codec/decoder/core/src/error_concealment.cpp (1 of 9 files). Show all
Unified · Split
| @@ -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 |