shithub: openh264

Download patch

ref: 2e15351d6db168bdfa65c6b735cf20ab6fff4031
parent: 8c7aaa8421bea7876904c0f3a63fe6a3229924a1
parent: d58f90947c58a84bc6c6b9ae047bc873584f64ea
author: ruil2 <ruil2@cisco.com>
date: Mon Dec 1 09:53:17 EST 2014

Merge pull request #1567 from dongzha/FixMvCpBug

avoid using the same picture buff for prev pic and curr pic

--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -179,10 +179,11 @@
  */
 static inline int32_t GetTargetRefListSize (PWelsDecoderContext pCtx) {
   int32_t iNumRefFrames	= 0;
+  // +2 for EC MV Copy buffer exchange
   if ((pCtx == NULL) || (pCtx->pSps == NULL)) {
-    iNumRefFrames = MAX_REF_PIC_COUNT;
+    iNumRefFrames = MAX_REF_PIC_COUNT + 2;
   } else {
-    iNumRefFrames = pCtx->pSps->iNumRefFrames + 1;
+    iNumRefFrames = pCtx->pSps->iNumRefFrames + 2;
   }
 
 #ifdef LONG_TERM_REF
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -2143,6 +2143,7 @@
         } else if (pCtx->eErrorConMethod == ERROR_CON_SLICE_MV_COPY_CROSS_IDR
                    || pCtx->eErrorConMethod == ERROR_CON_SLICE_MV_COPY_CROSS_IDR_FREEZE_RES_CHANGE) {
           pCtx->pPreviousDecodedPictureInDpb = pCtx->pDec; //save ECed pic for future MV Copy use
+          pCtx->pDec = NULL;
         }
       } else {
         if (DecodeFrameConstruction (pCtx, ppDst, pDstInfo))
--- a/codec/decoder/core/src/error_concealment.cpp
+++ b/codec/decoder/core/src/error_concealment.cpp
@@ -165,6 +165,9 @@
 //Do error concealment using slice MV copy method
 void DoMbECMvCopy (PWelsDecoderContext pCtx, PPicture pDec, PPicture pRef, int32_t iMbXy, int32_t iMbX, int32_t iMbY,
                    sMCRefMember* pMCRefMem) {
+  if (pDec == pRef) {
+    return; // for protection, shall never go into this logic, error info printed outside.
+  }
   int16_t iMVs[2];
   int32_t iMbXInPix = iMbX << 4;
   int32_t iMbYInPix = iMbY << 4;
@@ -382,6 +385,10 @@
     sMCRefMem.iDstLineChroma = pDstPic->iLinesize[1];
     sMCRefMem.iPicWidth = pDstPic->iWidthInPixel;
     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.");
+    }
   }
 
   for (int32_t iMbY = 0; iMbY < iMbHeight; ++iMbY) {