shithub: openh264

Download patch

ref: 80a06fcdd5b36be1ee8d745059432a23b59a12c8
parent: cfb22048d8d8aa6033769f50e726f27d40d0bd5b
author: xiaotiansf <[email protected]>
date: Tue Mar 12 17:58:28 EDT 2019

Fix AddressSanitizer: heap-use-after-free at decoder.cpp:178. New GOP start can be missed if GOP does not start with picture POC = 0 or the picture POC failed to decoder. The fix is to detect GOP change more accurately so that previous pictures can be flushed out immediately.

--- 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;
+            }
           }
         }
       }