shithub: openh264

Download patch

ref: 8034863e51b87dee446532623492866083a19877
parent: 94f0a17532f5688925d7a3a92ac6da1d3e274667
parent: fa4bb220e4f072f6309a5668ee7d054d90d48839
author: huili2 <[email protected]>
date: Thu Mar 14 09:38:36 EDT 2019

Merge pull request #3109 from xiaotiansf/NewBugzilla2

Fix AddressSanitizer: heap-use-after-free at decoder.cpp:178. New GOP…

--- a/codec/decoder/core/inc/rec_mb.h
+++ b/codec/decoder/core/inc/rec_mb.h
@@ -93,7 +93,7 @@
 
 int32_t RecChroma (int32_t iMBXY, PWelsDecoderContext pCtx, int16_t* pScoeffLevel, PDqLayer pDqLayer);
 
-void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx);
+int32_t GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx);
 
 int32_t GetInterBPred (uint8_t* pPredYCbCr[3], uint8_t* pTempPredYCbCr[3], PWelsDecoderContext pCtx);
 
--- a/codec/decoder/core/src/decode_slice.cpp
+++ b/codec/decoder/core/src/decode_slice.cpp
@@ -222,7 +222,7 @@
   pDstCr = pCurLayer->pDec->pData[2] + ((iMbY * iChromaStride + iMbX) << 3);
 
   if (pCtx->eSliceType == P_SLICE) {
-    GetInterPred (pDstY, pDstCb, pDstCr, pCtx);
+    WELS_B_MB_REC_VERIFY (GetInterPred (pDstY, pDstCb, pDstCr, pCtx));
   } else {
     if (pCtx->pTempDec == NULL)
       pCtx->pTempDec = AllocPicture (pCtx, pCtx->pSps->iMbWidth << 4, pCtx->pSps->iMbHeight << 4);
@@ -314,7 +314,7 @@
   pDstCr = pCurLayer->pDec->pData[2] + ((iMbY * iChromaStride + iMbX) << 3);
 
   if (pCtx->eSliceType == P_SLICE) {
-    GetInterPred (pDstY, pDstCb, pDstCr, pCtx);
+    WELS_B_MB_REC_VERIFY (GetInterPred (pDstY, pDstCb, pDstCr, pCtx));
   } else {
     if (pCtx->pTempDec == NULL)
       pCtx->pTempDec = AllocPicture (pCtx, pCtx->pSps->iMbWidth << 4, pCtx->pSps->iMbHeight << 4);
@@ -326,7 +326,7 @@
     pDstYCbCr[0] = pDstY;
     pDstYCbCr[1] = pDstCb;
     pDstYCbCr[2] = pDstCr;
-    GetInterBPred (pDstYCbCr, pTempDstYCbCr, pCtx);
+    WELS_B_MB_REC_VERIFY (GetInterBPred (pDstYCbCr, pTempDstYCbCr, pCtx));
   }
   return ERR_NONE;
 }
--- a/codec/decoder/core/src/rec_mb.cpp
+++ b/codec/decoder/core/src/rec_mb.cpp
@@ -229,7 +229,9 @@
       pMCRefMem->pSrcY = pRefPic->pData[0];
       pMCRefMem->pSrcU = pRefPic->pData[1];
       pMCRefMem->pSrcV = pRefPic->pData[2];
-
+      if (!pMCRefMem->pSrcY || !pMCRefMem->pSrcU || !pMCRefMem->pSrcV) {
+        return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_DATA, ERR_INFO_REFERENCE_PIC_LOST);
+      }
       return ERR_NONE;
     }
   }
@@ -435,7 +437,7 @@
   }
 }
 
-void GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {
+int32_t GetInterPred (uint8_t* pPredY, uint8_t* pPredCb, uint8_t* pPredCr, PWelsDecoderContext pCtx) {
   sMCRefMember pMCRefMem;
   PDqLayer pCurDqLayer = pCtx->pCurDqLayer;
   SMcFunc* pMCFunc = &pCtx->sMcFunc;
@@ -471,7 +473,7 @@
   case MB_TYPE_16x16:
     iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
     iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
-    GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
+    WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0));
     BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 16, iMVs);
 
     if (pCurDqLayer->bUseWeightPredictionFlag) {
@@ -482,7 +484,7 @@
   case MB_TYPE_16x8:
     iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
     iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
-    GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
+    WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0));
     BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 16, 8, iMVs);
 
     if (pCurDqLayer->bUseWeightPredictionFlag) {
@@ -492,7 +494,7 @@
 
     iMVs[0] = pCurDqLayer->pMv[0][iMBXY][8][0];
     iMVs[1] = pCurDqLayer->pMv[0][iMBXY][8][1];
-    GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 8, LIST_0);
+    WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 8, LIST_0));
     pMCRefMem.pDstY = pPredY  + (iDstLineLuma << 3);
     pMCRefMem.pDstU = pPredCb + (iDstLineChroma << 2);
     pMCRefMem.pDstV = pPredCr + (iDstLineChroma << 2);
@@ -506,7 +508,7 @@
   case MB_TYPE_8x16:
     iMVs[0] = pCurDqLayer->pMv[0][iMBXY][0][0];
     iMVs[1] = pCurDqLayer->pMv[0][iMBXY][0][1];
-    GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0);
+    WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 0, LIST_0));
     BaseMC (&pMCRefMem, iMBOffsetX, iMBOffsetY, pMCFunc, 8, 16, iMVs);
     if (pCurDqLayer->bUseWeightPredictionFlag) {
       iRefIndex = pCurDqLayer->pRefIndex[0][iMBXY][0];
@@ -515,7 +517,7 @@
 
     iMVs[0] = pCurDqLayer->pMv[0][iMBXY][2][0];
     iMVs[1] = pCurDqLayer->pMv[0][iMBXY][2][1];
-    GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 2, LIST_0);
+    WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], 2, LIST_0));
     pMCRefMem.pDstY = pPredY + 8;
     pMCRefMem.pDstU = pPredCb + 4;
     pMCRefMem.pDstV = pPredCr + 4;
@@ -539,7 +541,7 @@
       iYOffset = iMBOffsetY + iBlk8Y;
 
       iIIdx = ((i >> 1) << 3) + ((i & 1) << 1);
-      GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], iIIdx, LIST_0);
+      WELS_B_MB_REC_VERIFY (GetRefPic (&pMCRefMem, pCtx, pCurDqLayer->pRefIndex[0][iMBXY], iIIdx, LIST_0));
       iRefIndex = pCurDqLayer->bUseWeightPredictionFlag ? pCurDqLayer->pRefIndex[0][iMBXY][iIIdx] : 0;
 
       pDstY = pPredY + iBlk8X + iBlk8Y * iDstLineLuma;
@@ -636,6 +638,7 @@
   default:
     break;
   }
+  return ERR_NONE;
 }
 
 int32_t GetInterBPred (uint8_t* pPredYCbCr[3], uint8_t* pTempPredYCbCr[3], PWelsDecoderContext pCtx) {
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -580,7 +580,6 @@
       NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently
 
     eNalType = m_pDecContext->sCurNalHead.eNalUnitType;
-
     if (m_pDecContext->iErrorCode & dsOutOfMemory) {
       if (ResetDecoder()) {
         return dsOutOfMemory;
@@ -762,6 +761,25 @@
         for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
           if (m_sPictInfoList[i].iPOC > sIMinInt32) {
             m_sPictInfoList[i].bLastGOP = true;
+          }
+        }
+      }
+    } else {
+      if (m_iNumOfPicts > 0) {
+        //This can happen when decoder moves to next GOP without being able to decoder first picture PicOrderCntLsb = 0
+        bool hasGOPChanged = false;
+        for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
+          if (m_sPictInfoList[i].iPOC == m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
+            hasGOPChanged = true;
+            break;
+          }
+        }
+        if (hasGOPChanged) {
+          m_iLastGOPRemainPicts = m_iNumOfPicts;
+          for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
+            if (m_sPictInfoList[i].iPOC > sIMinInt32) {
+              m_sPictInfoList[i].bLastGOP = true;
+            }
           }
         }
       }