shithub: openh264

Download patch

ref: 6efeb0ef951d6196d3018e75d0860b1ada9025e0
parent: 936747e9a48094f376b9cfbca8dfa1ad9144107b
parent: 868c8e45a144b5162c19e0d1b6d18391ada74d77
author: huili2 <huili2@cisco.com>
date: Tue Sep 22 11:45:22 EDT 2015

Merge pull request #2124 from HaiboZhu/Bugfix_Duplicate_frame_num

Check the duplicate frame_num in short ref list

--- a/codec/decoder/core/inc/error_code.h
+++ b/codec/decoder/core/inc/error_code.h
@@ -184,6 +184,7 @@
 ERR_INFO_EC_NO_NEIGHBOUR_MBS,
 ERR_INFO_EC_UNEXPECTED_MB_TYPE,
 ERR_INFO_EC_NO_ENOUGH_NEIGHBOUR_MBS,
+ERR_INFO_DUPLICATE_FRAME_NUM,
 //for LTR
 ERR_INFO_INVALID_MMCO_OPCODE_BASE,
 ERR_INFO_INVALID_MMCO_SHORT2UNUSED,
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -2360,6 +2360,8 @@
       if (uiNalRefIdc > 0) {
         iRet = WelsMarkAsRef (pCtx);
         if (iRet != ERR_NONE) {
+          if (iRet == ERR_INFO_DUPLICATE_FRAME_NUM)
+            pCtx->iErrorCode |= dsBitstreamError;
           if (pCtx->eErrorConMethod == ERROR_CON_DISABLE) {
             pCtx->pDec = NULL;
             return iRet;
--- a/codec/decoder/core/src/error_concealment.cpp
+++ b/codec/decoder/core/src/error_concealment.cpp
@@ -431,6 +431,7 @@
 //Mark erroneous frame as Ref Pic into DPB
 int32_t MarkECFrameAsRef (PWelsDecoderContext pCtx) {
   int32_t iRet = WelsMarkAsRef (pCtx);
+  // Under EC mode, the ERR_INFO_DUPLICATE_FRAME_NUM does not need to be process
   if (iRet != ERR_NONE) {
     return iRet;
   }
--- a/codec/decoder/core/src/manage_dec_ref.cpp
+++ b/codec/decoder/core/src/manage_dec_ref.cpp
@@ -294,6 +294,7 @@
       if (iRet != ERR_NONE) {
         if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
           iRet = RemainOneBufferInDpbForEC (pCtx);
+          WELS_VERIFY_RETURN_IF (iRet, iRet);
         } else {
           return iRet;
         }
@@ -309,6 +310,7 @@
       if (iRet != ERR_NONE) {
         if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
           iRet = RemainOneBufferInDpbForEC (pCtx);
+          WELS_VERIFY_RETURN_IF (iRet, iRet);
         } else {
           return iRet;
         }
@@ -320,11 +322,12 @@
     if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) {
       if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) {
         iRet = RemainOneBufferInDpbForEC (pCtx);
+        WELS_VERIFY_RETURN_IF (iRet, iRet);
       } else {
         return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW;
       }
     }
-    AddShortTermToList (pRefPic, pCtx->pDec);
+    iRet = AddShortTermToList (pRefPic, pCtx->pDec);
   }
 
   return iRet;
@@ -515,6 +518,15 @@
   pPic->bIsLongRef = false;
   pPic->iLongTermFrameIdx = -1;
   if (pRefPic->uiShortRefCount[LIST_0] > 0) {
+    // Check the duplicate frame_num in short ref list
+    for (int32_t iPos = 0; iPos < pRefPic->uiShortRefCount[LIST_0]; iPos++) {
+      if (pPic->iFrameNum == pRefPic->pShortRefList[LIST_0][iPos]->iFrameNum) {
+        // Replace the previous ref pic with the new one with the same frame_num
+        pRefPic->pShortRefList[LIST_0][iPos] = pPic;
+        return ERR_INFO_DUPLICATE_FRAME_NUM;
+      }
+    }
+
     memmove (&pRefPic->pShortRefList[LIST_0][1], &pRefPic->pShortRefList[LIST_0][0],
              pRefPic->uiShortRefCount[LIST_0]*sizeof (PPicture));//confirmed_safe_unsafe_usage
   }