ref: 6b4912c71608f0b20a69b459bdb1d07f8a831cce
parent: 6b503843ec8ae27185180089365dd252e647ac7e
author: Haibo Zhu <haibozhu@cisco.com>
date: Wed Aug 5 05:23:32 EDT 2015
Add protection for memcpy overlap
--- a/codec/decoder/core/src/error_concealment.cpp
+++ b/codec/decoder/core/src/error_concealment.cpp
@@ -93,6 +93,8 @@
memset (pDstPic->pData[0], 128, uiHeightInPixelY * iStrideY);
memset (pDstPic->pData[1], 128, (uiHeightInPixelY >> 1) * iStrideUV);
memset (pDstPic->pData[2], 128, (uiHeightInPixelY >> 1) * iStrideUV);
+ } else if (pSrcPic == pDstPic) {
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "DoErrorConFrameCopy()::EC memcpy overlap.");
} else { //has ref pic here
memcpy (pDstPic->pData[0], pSrcPic->pData[0], uiHeightInPixelY * iStrideY);
memcpy (pDstPic->pData[1], pSrcPic->pData[1], (uiHeightInPixelY >> 1) * iStrideUV);
@@ -117,6 +119,10 @@
uint8_t* pSrcData, *pDstData;
uint32_t iSrcStride; // = pSrcPic->iLinesize[0];
uint32_t iDstStride = pDstPic->iLinesize[0];
+ if (pSrcPic == pDstPic) {
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "DoErrorConSliceCopy()::EC memcpy overlap.");
+ return;
+ }
for (int32_t iMbY = 0; iMbY < iMbHeight; ++iMbY) {
for (int32_t iMbX = 0; iMbX < iMbWidth; ++iMbX) {
iMbXyIndex = iMbY * iMbWidth + iMbX;
@@ -384,7 +390,8 @@
sMCRefMem.iPicHeight = pDstPic->iHeightInPixel;
if (pDstPic == pSrcPic) {
// output error info, EC will be ignored in DoMbECMvCopy
- WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "DoErrorConSliceMVCopy()::pPreviousPic and pDec use same buffer, ignored.");
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "DoErrorConSliceMVCopy()::EC memcpy overlap.");
+ return;
}
}
--- a/codec/decoder/core/src/manage_dec_ref.cpp
+++ b/codec/decoder/core/src/manage_dec_ref.cpp
@@ -131,14 +131,16 @@
bCopyPrevious = bCopyPrevious && (pRef->iWidthInPixel == pCtx->pPreviousDecodedPictureInDpb->iWidthInPixel)
&& (pRef->iHeightInPixel == pCtx->pPreviousDecodedPictureInDpb->iHeightInPixel);
- if (bCopyPrevious) {
- memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);
- memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
- memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
- } else {
+ if (!bCopyPrevious) {
memset (pRef->pData[0], 128, pRef->iLinesize[0] * pRef->iHeightInPixel);
memset (pRef->pData[1], 128, pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
memset (pRef->pData[2], 128, pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
+ } else if (pRef == pCtx->pPreviousDecodedPictureInDpb) {
+ WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "WelsInitRefList()::EC memcpy overlap.");
+ } else {
+ memcpy (pRef->pData[0], pCtx->pPreviousDecodedPictureInDpb->pData[0], pRef->iLinesize[0] * pRef->iHeightInPixel);
+ memcpy (pRef->pData[1], pCtx->pPreviousDecodedPictureInDpb->pData[1], pRef->iLinesize[1] * pRef->iHeightInPixel / 2);
+ memcpy (pRef->pData[2], pCtx->pPreviousDecodedPictureInDpb->pData[2], pRef->iLinesize[2] * pRef->iHeightInPixel / 2);
}
pRef->iFrameNum = 0;
pRef->iFramePoc = 0;