shithub: openh264

Download patch

ref: 55c154327b6a992b375703c1be9cbcb3f69d1f1e
parent: ae7bac25dcdc433b74a5a925689b52580d75e294
author: xiaotiansf <xiaotianshimail@gmail.com>
date: Sun Aug 12 12:33:32 EDT 2018

fix Bug-1479669 and Bug-1479831 in Bugizllia. When key colocated Ref Picture is lost or does not exist. B-Slice decoding has to be stoped.

--- a/codec/decoder/core/inc/mv_pred.h
+++ b/codec/decoder/core/inc/mv_pred.h
@@ -98,7 +98,8 @@
 * \param
 * \param   output iMvp[] and ref
 */
-SubMbType  PredMvBDirectSpatial (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]);
+int32_t  PredMvBDirectSpatial (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A],
+                               SubMbType& subMbType);
 
 /*!
 * \brief   get Colocated MB for both Spatial and Temporal Direct Mode
@@ -110,7 +111,7 @@
 /*!
 * \brief   get the motion predictor for B-slice temporal direct mode 16x16
 */
-void PredBDirectTemporal (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]);
+int32_t PredBDirectTemporal (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]);
 
 /*!
 * \brief   get the motion params for B-slice spatial direct mode
--- a/codec/decoder/core/src/decode_slice.cpp
+++ b/codec/decoder/core/src/decode_slice.cpp
@@ -1415,15 +1415,24 @@
     pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPicL0[0] && ppRefPicL0[0]->bIsComplete)
                             || ! (ppRefPicL1[0] && ppRefPicL1[0]->bIsComplete);
 
+
     if (pSliceHeader->iDirectSpatialMvPredFlag) {
 
       //predict direct spatial mv
-      PredMvBDirectSpatial (pCtx, pMv, ref);
+      SubMbType subMbType;
+      int32_t ret = PredMvBDirectSpatial (pCtx, pMv, ref, subMbType);
+      if (ret != ERR_NONE) {
+        return ret;
+      }
     } else {
       //temporal direct mode
       ComputeColocated (pCtx);
-      PredBDirectTemporal (pCtx, pMv, ref);
+      int32_t ret = PredBDirectTemporal (pCtx, pMv, ref);
+      if (ret != ERR_NONE) {
+        return ret;
+      }
     }
+
 
     //reset rS
     pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp; //??????????????? dqaunt of previous mb
--- a/codec/decoder/core/src/mv_pred.cpp
+++ b/codec/decoder/core/src/mv_pred.cpp
@@ -313,6 +313,12 @@
 
   PPicture colocPic = pCtx->sRefPic.pRefList[LIST_1][0];
 
+  if (colocPic == NULL) {
+    SLogContext* pLogCtx = & (pCtx->sLogCtx);
+    WelsLog (pLogCtx, WELS_LOG_ERROR, "Colocated Ref Picture for B-Slice is lost, B-Slice decoding cannot be continued!");
+    return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
+  }
+
   MbType coloc_mbType = colocPic->pMbType[iMbXy];
 
   if (IS_Inter_8x8 (coloc_mbType) && !pCtx->pSps->bDirect8x8InferenceFlag) {
@@ -328,7 +334,7 @@
 
   if (IS_INTRA (coloc_mbType)) {
     SetRectBlock (pCurLayer->iColocIntra, 4, 4, 4 * sizeof (int8_t), 1, sizeof (int8_t));
-    return 1;
+    return ERR_NONE;
   }
   SetRectBlock (pCurLayer->iColocIntra, 4, 4, 4 * sizeof (int8_t), 0, sizeof (int8_t));
 
@@ -366,18 +372,22 @@
         SetRectBlock (&pCurLayer->iColocRefIndex[1][0], 4, 4, 4, (uint8_t)REF_NOT_IN_LIST, 1);
     }
   }
-  return 1;
+  return ERR_NONE;
 }
 
-SubMbType PredMvBDirectSpatial (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]) {
+int32_t PredMvBDirectSpatial (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A],
+                              SubMbType& subMbType) {
 
+  int32_t ret = ERR_NONE;
   PDqLayer pCurLayer = pCtx->pCurDqLayer;
   int32_t iMbXy = pCurLayer->iMbXyIndex;
   bool bSkipOrDirect = (IS_SKIP (pCurLayer->pMbType[iMbXy]) | IS_DIRECT (pCurLayer->pMbType[iMbXy])) > 0;
 
   MbType mbType;
-  SubMbType subMbType;
-  GetColocatedMb (pCtx, mbType, subMbType);
+  ret = GetColocatedMb (pCtx, mbType, subMbType);
+  if (ret != ERR_NONE) {
+    return ret;
+  }
 
   bool bTopAvail, bLeftTopAvail, bRightTopAvail, bLeftAvail;
   int32_t iLeftTopType, iRightTopType, iTopType, iLeftType;
@@ -643,16 +653,20 @@
       }
     }
   }
-  return subMbType;
+  return ret;
 }
 
-void PredBDirectTemporal (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]) {
+int32_t PredBDirectTemporal (PWelsDecoderContext pCtx, int16_t iMvp[LIST_A][2], int8_t ref[LIST_A]) {
+  int32_t ret = ERR_NONE;
   PDqLayer pCurLayer = pCtx->pCurDqLayer;
   int32_t iMbXy = pCurLayer->iMbXyIndex;
   bool bSkipOrDirect = (IS_SKIP (pCurLayer->pMbType[iMbXy]) | IS_DIRECT (pCurLayer->pMbType[iMbXy])) > 0;
   MbType mbType;
   SubMbType subMbType;
-  GetColocatedMb (pCtx, mbType, subMbType);
+  ret = GetColocatedMb (pCtx, mbType, subMbType);
+  if (ret != ERR_NONE) {
+    return ret;
+  }
   PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
   if (IS_INTER_16x16 (mbType)) {
     ref[LIST_0] = 0;
@@ -748,6 +762,7 @@
       }
     }
   }
+  return ret;
 }
 
 //basic iMVs prediction unit for iMVs partition width (4, 2, 1)
--- a/codec/decoder/core/src/parse_mb_syn_cabac.cpp
+++ b/codec/decoder/core/src/parse_mb_syn_cabac.cpp
@@ -739,13 +739,22 @@
   if (IS_DIRECT (mbType)) {
 
     int16_t pMvDirect[LIST_A][2] = { { 0, 0 }, { 0, 0 } };
-    if (pSliceHeader->iDirectSpatialMvPredFlag) {
-      //predict direct spatial mv
-      PredMvBDirectSpatial (pCtx, pMvDirect, iRef);
-    } else {
-      //temporal direct 16x16 mode
-      ComputeColocated (pCtx);
-      PredBDirectTemporal (pCtx, pMvDirect, iRef);
+    if (pCtx->sRefPic.pRefList[LIST_1][0] != NULL) {
+      if (pSliceHeader->iDirectSpatialMvPredFlag) {
+        //predict direct spatial mv
+        SubMbType subMbType;
+        int32_t ret = PredMvBDirectSpatial (pCtx, pMvDirect, iRef, subMbType);
+        if (ret != ERR_NONE) {
+          return ret;
+        }
+      } else {
+        //temporal direct 16x16 mode
+        ComputeColocated (pCtx);
+        int32_t ret = PredBDirectTemporal (pCtx, pMvDirect, iRef);
+        if (ret != ERR_NONE) {
+          return ret;
+        }
+      }
     }
   } else if (IS_INTER_16x16 (mbType)) {
     iPartIdx = 0;
@@ -894,11 +903,18 @@
       if (IS_DIRECT (g_ksInterBSubMbTypeInfo[uiSubMbType].iType)) {
         if (!has_direct_called) {
           if (pSliceHeader->iDirectSpatialMvPredFlag) {
-            directSubMbType = PredMvBDirectSpatial (pCtx, pMvDirect, iRef);
+            int32_t ret = PredMvBDirectSpatial (pCtx, pMvDirect, iRef, directSubMbType);
+            if (ret != ERR_NONE) {
+              return ret;
+            }
+
           } else {
             //temporal direct mode
             ComputeColocated (pCtx);
-            PredBDirectTemporal (pCtx, pMvDirect, iRef);
+            int32_t ret = PredBDirectTemporal (pCtx, pMvDirect, iRef);
+            if (ret != ERR_NONE) {
+              return ret;
+            }
           }
           has_direct_called = true;
         }