shithub: openh264

Download patch

ref: 6b4912c71608f0b20a69b459bdb1d07f8a831cce
parent: 6b503843ec8ae27185180089365dd252e647ac7e
author: Haibo Zhu <[email protected]>
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;