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 | 67 | //Do error concealment using frame copy method |
| 68 | 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 | 86 | //Do error concealment using slice copy method |
| 74 | 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 | 145 | //Mark erroneous frame as Ref Pic into DPB |
| 79 | 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 | 156 | return ERR_NONE; |
| 82 | 157 | } |
| 83 | 158 | |
| 84 | 159 | bool NeedErrorCon (PWelsDecoderContext pCtx) { |
| 85 | 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 | 168 | return bNeedEC; |
| 88 | 169 | } |
| 89 | 170 | |
| 90 | 171 | // ImplementErrorConceal |
| 91 | 172 | // Do actual error concealment |
| 92 | −int32_t ImplementErrorCon (PWelsDecoderContext pCtx) { | |
| 93 | − int32_t iRet = ERR_NONE; | |
| 94 | − //TODO | |
| 95 | − return iRet; | |
| 173 | +void ImplementErrorCon (PWelsDecoderContext pCtx) { | |
| 174 | + if (!NeedErrorCon (pCtx)) | |
| 175 | + return; | |
| 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 | 195 | } // namespace WelsDec |