shithub: openh264

Download patch

ref: 8b881445bd17d7ced5c072601f0cd8a185bd3368
parent: fafdd88d962e93e686cf90b69b2f0b9d3d5b8bc1
author: xiaotiansf <xiaotianshimail@gmail.com>
date: Fri Oct 25 12:10:35 EDT 2019

Fix issue 3186 (fuzz 18458). Reset held picture reordering list before calling DestroyPicBuff.

It also fix SetUnRef crashing which should only loop for LIST_1 if ref pic is B_SLICE.

--- a/codec/decoder/core/inc/decoder.h
+++ b/codec/decoder/core/inc/decoder.h
@@ -172,7 +172,11 @@
 //update decoder statistics information
 void UpdateDecStat (PWelsDecoderContext pCtx, const bool kbOutput);
 //Destroy picutre buffer
-void DestroyPicBuff (PPicBuff* ppPicBuf, CMemoryAlign* pMa);
+void DestroyPicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, CMemoryAlign* pMa);
+//reset picture reodering buffer list
+void ResetReorderingPictureBuffers (PPictReoderingStatus pPictReoderingStatus, PPictInfo pPictInfo,
+                                    const bool& bFullReset);
+
 #ifdef __cplusplus
 }
 #endif//__cplusplus
--- a/codec/decoder/core/inc/decoder_context.h
+++ b/codec/decoder/core/inc/decoder_context.h
@@ -65,6 +65,7 @@
 #define  WELS_QP_MAX    51
 
 #define LONG_TERM_REF
+#define IMinInt32 -0x7FFFFFFF
 typedef struct SWels_Cabac_Element {
   uint8_t uiState;
   uint8_t uiMPS;
@@ -278,6 +279,24 @@
   bool              bLastHasMmco5;
 } SWelsLastDecPicInfo, *PWelsLastDecPicInfo;
 
+typedef struct tagPictInfo {
+  SBufferInfo             sBufferInfo;
+  int32_t                 iPOC;
+  int32_t                 iPicBuffIdx;
+  uint32_t                uiDecodingTimeStamp;
+  bool                    bLastGOP;
+  unsigned char*          pData[3];
+} SPictInfo, *PPictInfo;
+
+typedef struct tagPictReoderingStatus {
+  int32_t iPictInfoIndex;
+  int32_t iMinPOC;
+  int32_t iNumOfPicts;
+  int32_t iLastGOPRemainPicts;
+  int32_t iLastWrittenPOC;
+  int32_t iLargestBufferedPicIndex;
+} SPictReoderingStatus, *PPictReoderingStatus;
+
 /*
  *  SWelsDecoderContext: to maintail all modules data over decoder@framework
  */
@@ -492,6 +511,8 @@
   void* pLastThreadCtx;
   WELS_MUTEX* pCsDecoder;
   int16_t lastReadyHeightOffset[LIST_A][MAX_REF_PIC_COUNT]; //last ready reference MB offset
+  PPictInfo               pPictInfoList;
+  PPictReoderingStatus    pPictReoderingStatus;
 } SWelsDecoderContext, *PWelsDecoderContext;
 
 typedef struct tagSWelsDecThread {
--- a/codec/decoder/core/inc/picture.h
+++ b/codec/decoder/core/inc/picture.h
@@ -88,6 +88,7 @@
   unsigned long long uiTimeStamp;
   uint32_t    uiDecodingTimeStamp; //represent relative decoding time stamps
   int32_t     iPicBuffIdx;
+  EWelsSliceType  eSliceType;
   bool bNewSeqBegin;
   int32_t iMbEcedNum;
   int32_t iMbEcedPropNum;
--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -62,6 +62,7 @@
 
 static int32_t CreatePicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, const int32_t kiSize,
                               const int32_t kiPicWidth, const int32_t kiPicHeight) {
+
   PPicBuff pPicBuf = NULL;
   int32_t iPicIdx = 0;
   if (kiSize <= 0 || kiPicWidth <= 0 || kiPicHeight <= 0) {
@@ -80,7 +81,7 @@
 
   if (NULL == pPicBuf->ppPic) {
     pPicBuf->iCapacity = 0;
-    DestroyPicBuff (&pPicBuf, pMa);
+    DestroyPicBuff (pCtx, &pPicBuf, pMa);
     return ERR_INFO_OUT_OF_MEMORY;
   }
 
@@ -89,7 +90,7 @@
     if (NULL == pPic) {
       // init capacity first for free memory
       pPicBuf->iCapacity = iPicIdx;
-      DestroyPicBuff (&pPicBuf, pMa);
+      DestroyPicBuff (pCtx, &pPicBuf, pMa);
       return ERR_INFO_OUT_OF_MEMORY;
     }
     pPicBuf->ppPic[iPicIdx] = pPic;
@@ -123,7 +124,7 @@
 
   if (NULL == pPicNewBuf->ppPic) {
     pPicNewBuf->iCapacity = 0;
-    DestroyPicBuff (&pPicNewBuf, pMa);
+    DestroyPicBuff (pCtx, &pPicNewBuf, pMa);
     return ERR_INFO_OUT_OF_MEMORY;
   }
 
@@ -133,7 +134,7 @@
     if (NULL == pPic) {
       // Set maximum capacity as the new malloc memory at the tail
       pPicNewBuf->iCapacity = iPicIdx;
-      DestroyPicBuff (&pPicNewBuf, pMa);
+      DestroyPicBuff (pCtx, &pPicNewBuf, pMa);
       return ERR_INFO_OUT_OF_MEMORY;
     }
     pPicNewBuf->ppPic[iPicIdx] = pPic;
@@ -187,7 +188,7 @@
 
   if (NULL == pPicNewBuf->ppPic) {
     pPicNewBuf->iCapacity = 0;
-    DestroyPicBuff (&pPicNewBuf, pMa);
+    DestroyPicBuff (pCtx, &pPicNewBuf, pMa);
     return ERR_INFO_OUT_OF_MEMORY;
   }
 
@@ -254,9 +255,11 @@
   return ERR_NONE;
 }
 
-void DestroyPicBuff (PPicBuff* ppPicBuf, CMemoryAlign* pMa) {
+void DestroyPicBuff (PWelsDecoderContext pCtx, PPicBuff* ppPicBuf, CMemoryAlign* pMa) {
   PPicBuff pPicBuf = NULL;
 
+  ResetReorderingPictureBuffers (pCtx->pPictReoderingStatus, pCtx->pPictInfoList, false);
+
   if (NULL == ppPicBuf || NULL == *ppPicBuf)
     return;
 
@@ -285,6 +288,24 @@
   *ppPicBuf = NULL;
 }
 
+//reset picture reodering buffer list
+void ResetReorderingPictureBuffers (PPictReoderingStatus pPictReoderingStatus, PPictInfo pPictInfo,
+                                    const bool& fullReset) {
+  if (pPictReoderingStatus != NULL && pPictInfo != NULL) {
+    int32_t pictInfoListCount = fullReset ? 16 : (pPictReoderingStatus->iLargestBufferedPicIndex + 1);
+    pPictReoderingStatus->iPictInfoIndex = 0;
+    pPictReoderingStatus->iMinPOC = IMinInt32;
+    pPictReoderingStatus->iNumOfPicts = 0;
+    pPictReoderingStatus->iLastGOPRemainPicts = 0;
+    pPictReoderingStatus->iLastWrittenPOC = IMinInt32;
+    pPictReoderingStatus->iLargestBufferedPicIndex = 0;
+    for (int32_t i = 0; i < pictInfoListCount; ++i) {
+      pPictInfo[i].bLastGOP = false;
+      pPictInfo[i].iPOC = IMinInt32;
+    }
+  }
+}
+
 /*
  * fill data fields in default for decoder context
  */
@@ -485,7 +506,7 @@
     // for Recycled_Pic_Queue
     PPicBuff* ppPic = &pCtx->pPicBuff;
     if (NULL != ppPic && NULL != *ppPic) {
-      DestroyPicBuff (ppPic, pMa);
+      DestroyPicBuff (pCtx, ppPic, pMa);
     }
 
 
@@ -531,7 +552,7 @@
 
   PPicBuff* pPicBuff = &pCtx->pPicBuff;
   if (NULL != pPicBuff && NULL != *pPicBuff) {
-    DestroyPicBuff (pPicBuff, pMa);
+    DestroyPicBuff (pCtx, pPicBuff, pMa);
   }
 
   if (pCtx->pTempDec) {
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -2555,7 +2555,7 @@
       pCtx->pDec->iFrameNum = pSh->iFrameNum;
       pCtx->pDec->iFramePoc = pSh->iPicOrderCntLsb; // still can not obtain correct, because current do not support POCtype 2
       pCtx->pDec->bIdrFlag = pNalCur->sNalHeaderExt.bIdrFlag;
-
+      pCtx->pDec->eSliceType = pSh->eSliceType;
       memcpy (&pLayerInfo.sSliceInLayer.sSliceHeaderExt, pShExt, sizeof (SSliceHeaderExt)); //confirmed_safe_unsafe_usage
       pLayerInfo.sSliceInLayer.bSliceHeaderExtFlag      = pNalCur->sNalData.sVclNal.bSliceHeaderExtFlag;
       pLayerInfo.sSliceInLayer.eSliceType               = pSh->eSliceType;
--- a/codec/decoder/core/src/manage_dec_ref.cpp
+++ b/codec/decoder/core/src/manage_dec_ref.cpp
@@ -80,15 +80,18 @@
     pRef->uiSpatialId = -1;
     pRef->iSpsId = -1;
     pRef->bIsComplete = false;
+
+    if (pRef->eSliceType == I_SLICE) {
+      return;
+    }
+    int32_t lists = pRef->eSliceType == P_SLICE ? 1 : 2;
     for (int32_t i = 0; i < MAX_DPB_COUNT; ++i) {
-      if (pRef->pRefPic[LIST_0][i] != NULL) {
-        pRef->pRefPic[LIST_0][i]->bAvailableFlag = true;
-        pRef->pRefPic[LIST_0][i] = NULL;
+      for (int32_t list = 0; list < lists; ++list) {
+        if (pRef->pRefPic[list][i] != NULL) {
+          pRef->pRefPic[list][i]->bAvailableFlag = true;
+          pRef->pRefPic[list][i] = NULL;
+        }
       }
-      if (pRef->pRefPic[LIST_1][i] != NULL) {
-        pRef->pRefPic[LIST_1][i]->bAvailableFlag = true;
-        pRef->pRefPic[LIST_1][i] = NULL;
-      }
     }
   }
 }
@@ -189,6 +192,7 @@
         pRef->iFrameNum = 0;
         pRef->iFramePoc = 0;
         pRef->uiTemporalId = pRef->uiQualityId = 0;
+        pRef->eSliceType = pCtx->eSliceType;
         ExpandReferencingPicture (pRef->pData, pRef->iWidthInPixel, pRef->iHeightInPixel, pRef->iLinesize,
                                   pCtx->sExpandPicFunc.pfExpandLumaPicture, pCtx->sExpandPicFunc.pfExpandChromaPicture);
         AddShortTermToList (&pCtx->sRefPic, pRef);
--- a/codec/decoder/plus/inc/welsDecoderExt.h
+++ b/codec/decoder/plus/inc/welsDecoderExt.h
@@ -109,25 +109,11 @@
   virtual long EXTAPI SetOption (DECODER_OPTION eOptID, void* pOption);
   virtual long EXTAPI GetOption (DECODER_OPTION eOptID, void* pOption);
 
-  typedef struct tagPictInfo {
-    SBufferInfo             sBufferInfo;
-    int32_t                 iPOC;
-    int32_t                 iPicBuffIdx;
-    uint32_t                uiDecodingTimeStamp;
-    bool                    bLastGOP;
-    unsigned char*          pData[3];
-  } SPictInfo, *PPictInfo;
-
  private:
   PWelsDecoderContext     m_pDecContext;
   welsCodecTrace*         m_pWelsTrace;
   SPictInfo               m_sPictInfoList[16];
-  int32_t                 m_iPictInfoIndex;
-  int32_t                 m_iMinPOC;
-  int32_t                 m_iNumOfPicts;
-  int32_t                 m_iLastGOPRemainPicts;
-  int32_t                 m_LastWrittenPOC;
-  int32_t                 m_iLargestBufferedPicIndex;
+  SPictReoderingStatus    m_sReoderingStatus;
   SVlcTable               m_sVlcTable;
   SWelsLastDecPicInfo     m_sLastDecPicInfo;
   SDecoderStatistics      m_sDecoderStatistics;// For real time debugging
@@ -135,7 +121,6 @@
   int32_t InitDecoder (const SDecodingParam* pParam);
   void UninitDecoder (void);
   int32_t ResetDecoder();
-  void ResetReorderingPictureBuffers();
 
   void OutputStatisticsLog (SDecoderStatistics& sDecoderStatistics);
   DECODING_STATE ReorderPicturesInDisplay (unsigned char** ppDst, SBufferInfo* pDstInfo);
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -73,8 +73,6 @@
 
 #define _PICTURE_REORDERING_ 1
 
-static int32_t sIMinInt32 = -0x7FFFFFFF;
-
 namespace WelsDec {
 
 //////////////////////////////////////////////////////////////////////
@@ -92,13 +90,7 @@
 ***************************************************************************/
 CWelsDecoder::CWelsDecoder (void)
   : m_pDecContext (NULL),
-    m_pWelsTrace (NULL),
-    m_iPictInfoIndex (0),
-    m_iMinPOC (sIMinInt32),
-    m_iNumOfPicts (0),
-    m_iLastGOPRemainPicts (0),
-    m_LastWrittenPOC (sIMinInt32),
-    m_iLargestBufferedPicIndex (0) {
+    m_pWelsTrace (NULL) {
 #ifdef OUTPUT_BIT_STREAM
   char chFileName[1024] = { 0 };  //for .264
   int iBufUsed = 0;
@@ -120,10 +112,7 @@
     WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, "CWelsDecoder::CWelsDecoder() entry");
   }
 
-  for (int32_t i = 0; i < 16; ++i) {
-    m_sPictInfoList[i].bLastGOP = false;
-    m_sPictInfoList[i].iPOC = sIMinInt32;
-  }
+  ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, true);
 
 #ifdef OUTPUT_BIT_STREAM
   SWelsTime sCurTime;
@@ -274,6 +263,8 @@
   m_pDecContext->pLastDecPicInfo = &m_sLastDecPicInfo;
   m_pDecContext->pDecoderStatistics = &m_sDecoderStatistics;
   m_pDecContext->pVlcTable = &m_sVlcTable;
+  m_pDecContext->pPictInfoList = m_sPictInfoList;
+  m_pDecContext->pPictReoderingStatus = &m_sReoderingStatus;
   WelsDecoderDefaults (m_pDecContext, &m_pWelsTrace->m_sLogCtx);
   WelsDecoderSpsPpsDefaults (m_pDecContext->sSpsPpsCtx);
 
@@ -304,7 +295,7 @@
     WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "ResetDecoder() failed as decoder context null");
   }
 #ifdef _PICTURE_REORDERING_
-  ResetReorderingPictureBuffers();
+  ResetReorderingPictureBuffers (&m_sReoderingStatus, m_sPictInfoList, false);
 #endif
   return ERR_INFO_UNINIT;
 }
@@ -483,7 +474,7 @@
     return cmResultSuccess;
   } else if (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER == eOptID) {
     if (m_pDecContext->pSps && m_pDecContext->pSps->uiProfileIdc != 66) {
-      * ((int*)pOption) = m_iNumOfPicts > 0 ? m_iNumOfPicts : 0;
+      * ((int*)pOption) = m_sReoderingStatus.iNumOfPicts > 0 ? m_sReoderingStatus.iNumOfPicts : 0;
     } else {
       * ((int*)pOption) = 0;
     }
@@ -688,36 +679,36 @@
 
 DECODING_STATE CWelsDecoder::FlushFrame (unsigned char** ppDst,
     SBufferInfo* pDstInfo) {
-  if (m_pDecContext->bEndOfStreamFlag && m_iNumOfPicts > 0) {
-    m_iMinPOC = sIMinInt32;
-    for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
-      if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32) {
-        m_iMinPOC = m_sPictInfoList[i].iPOC;
-        m_iPictInfoIndex = i;
+  if (m_pDecContext->bEndOfStreamFlag && m_sReoderingStatus.iNumOfPicts > 0) {
+    m_sReoderingStatus.iMinPOC = IMinInt32;
+    for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+      if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {
+        m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
+        m_sReoderingStatus.iPictInfoIndex = i;
       }
-      if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC) {
-        m_iMinPOC = m_sPictInfoList[i].iPOC;
-        m_iPictInfoIndex = i;
+      if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC) {
+        m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
+        m_sReoderingStatus.iPictInfoIndex = i;
       }
     }
   }
-  if (m_iMinPOC > sIMinInt32) {
-    m_LastWrittenPOC = m_iMinPOC;
+  if (m_sReoderingStatus.iMinPOC > IMinInt32) {
+    m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
 #if defined (_DEBUG)
 #ifdef _MOTION_VECTOR_DUMP_
-    fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
+    fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
 #endif
 #endif
-    memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
-    ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
-    ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
-    ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
-    m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
-    if (m_sPictInfoList[m_iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
-      m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
-    m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
-    m_iMinPOC = sIMinInt32;
-    --m_iNumOfPicts;
+    memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
+    ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
+    ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
+    ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
+    m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
+    if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
+      m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
+    m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
+    m_sReoderingStatus.iMinPOC = IMinInt32;
+    --m_sReoderingStatus.iNumOfPicts;
   }
   return dsErrorFree;
 }
@@ -775,27 +766,27 @@
   ++m_pDecContext->uiDecodingTimeStamp;
   if (m_pDecContext->pSps->uiProfileIdc != 66 && m_pDecContext->pSps->uiProfileIdc != 83) {
     /*if (m_pDecContext->pSliceHeader->iPicOrderCntLsb == 0) {
-      m_LastWrittenPOC = 0;
+      m_sReoderingStatus.iLastWrittenPOC = 0;
       return dsErrorFree;
     }
-    if (m_iNumOfPicts == 0 && m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin
+    if (m_sReoderingStatus.iNumOfPicts == 0 && m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin
         && m_pDecContext->eSliceType != I_SLICE) {
-      m_LastWrittenPOC = m_pDecContext->pSliceHeader->iPicOrderCntLsb;
+      m_sReoderingStatus.iLastWrittenPOC = m_pDecContext->pSliceHeader->iPicOrderCntLsb;
       return dsErrorFree;
     }*/
-    if (m_iNumOfPicts && m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb
+    if (m_sReoderingStatus.iNumOfPicts && m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb
         && m_pDecContext->pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin) {
-      m_iLastGOPRemainPicts = m_iNumOfPicts;
-      for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
-        if (m_sPictInfoList[i].iPOC > sIMinInt32) {
+      m_sReoderingStatus.iLastGOPRemainPicts = m_sReoderingStatus.iNumOfPicts;
+      for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+        if (m_sPictInfoList[i].iPOC > IMinInt32) {
           m_sPictInfoList[i].bLastGOP = true;
         }
       }
     } else {
-      if (m_iNumOfPicts > 0) {
+      if (m_sReoderingStatus.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) {
+        for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
           if (m_sPictInfoList[i].iPOC == m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
             hasGOPChanged = true;
             break;
@@ -802,9 +793,9 @@
           }
         }
         if (hasGOPChanged) {
-          m_iLastGOPRemainPicts = m_iNumOfPicts;
-          for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
-            if (m_sPictInfoList[i].iPOC > sIMinInt32) {
+          m_sReoderingStatus.iLastGOPRemainPicts = m_sReoderingStatus.iNumOfPicts;
+          for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+            if (m_sPictInfoList[i].iPOC > IMinInt32) {
               m_sPictInfoList[i].bLastGOP = true;
             }
           }
@@ -812,7 +803,7 @@
       }
     }
     for (int32_t i = 0; i < 16; ++i) {
-      if (m_sPictInfoList[i].iPOC == sIMinInt32) {
+      if (m_sPictInfoList[i].iPOC == IMinInt32) {
         memcpy (&m_sPictInfoList[i].sBufferInfo, pDstInfo, sizeof (SBufferInfo));
         m_sPictInfoList[i].pData[0] = ppDst[0];
         m_sPictInfoList[i].pData[1] = ppDst[1];
@@ -823,79 +814,81 @@
         m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[i].iPicBuffIdx]->bAvailableFlag = false;
         m_sPictInfoList[i].bLastGOP = false;
         pDstInfo->iBufferStatus = 0;
-        ++m_iNumOfPicts;
-        if (i > m_iLargestBufferedPicIndex) {
-          m_iLargestBufferedPicIndex = i;
+        ++m_sReoderingStatus.iNumOfPicts;
+        if (i > m_sReoderingStatus.iLargestBufferedPicIndex) {
+          m_sReoderingStatus.iLargestBufferedPicIndex = i;
         }
         break;
       }
     }
-    if (m_iLastGOPRemainPicts > 0) {
-      m_iMinPOC = sIMinInt32;
-      for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
-        if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].bLastGOP) {
-          m_iMinPOC = m_sPictInfoList[i].iPOC;
-          m_iPictInfoIndex = i;
+    if (m_sReoderingStatus.iLastGOPRemainPicts > 0) {
+      m_sReoderingStatus.iMinPOC = IMinInt32;
+      for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+        if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].bLastGOP) {
+          m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
+          m_sReoderingStatus.iPictInfoIndex = i;
         }
-        if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC && m_sPictInfoList[i].bLastGOP) {
-          m_iMinPOC = m_sPictInfoList[i].iPOC;
-          m_iPictInfoIndex = i;
+        if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC
+            && m_sPictInfoList[i].bLastGOP) {
+          m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
+          m_sReoderingStatus.iPictInfoIndex = i;
         }
       }
-      m_LastWrittenPOC = m_iMinPOC;
+      m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
 #if defined (_DEBUG)
 #ifdef _MOTION_VECTOR_DUMP_
-      fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
+      fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
 #endif
 #endif
-      memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
-      ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
-      ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
-      ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
-      m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
-      if (m_sPictInfoList[m_iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
-        m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
-      m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
-      m_iMinPOC = sIMinInt32;
-      --m_iNumOfPicts;
-      --m_iLastGOPRemainPicts;
-      if (m_iLastGOPRemainPicts == 0) {
-        m_LastWrittenPOC = sIMinInt32;
+      memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
+      ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
+      ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
+      ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
+      m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
+      if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
+        m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
+      m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
+      m_sReoderingStatus.iMinPOC = IMinInt32;
+      --m_sReoderingStatus.iNumOfPicts;
+      --m_sReoderingStatus.iLastGOPRemainPicts;
+      if (m_sReoderingStatus.iLastGOPRemainPicts == 0) {
+        m_sReoderingStatus.iLastWrittenPOC = IMinInt32;
       }
       return iRet;
     }
-    if (m_iNumOfPicts > 0) {
-      m_iMinPOC = sIMinInt32;
-      for (int32_t i = 0; i <= m_iLargestBufferedPicIndex; ++i) {
-        if (m_iMinPOC == sIMinInt32 && m_sPictInfoList[i].iPOC > sIMinInt32) {
-          m_iMinPOC = m_sPictInfoList[i].iPOC;
-          m_iPictInfoIndex = i;
+    if (m_sReoderingStatus.iNumOfPicts > 0) {
+      m_sReoderingStatus.iMinPOC = IMinInt32;
+      for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+        if (m_sReoderingStatus.iMinPOC == IMinInt32 && m_sPictInfoList[i].iPOC > IMinInt32) {
+          m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
+          m_sReoderingStatus.iPictInfoIndex = i;
         }
-        if (m_sPictInfoList[i].iPOC > sIMinInt32 && m_sPictInfoList[i].iPOC < m_iMinPOC) {
-          m_iMinPOC = m_sPictInfoList[i].iPOC;
-          m_iPictInfoIndex = i;
+        if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC) {
+          m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
+          m_sReoderingStatus.iPictInfoIndex = i;
         }
       }
     }
-    if (m_iMinPOC > sIMinInt32) {
-      if ((m_LastWrittenPOC > sIMinInt32 && m_iMinPOC - m_LastWrittenPOC <= 1)
-          || m_iMinPOC < m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
-        m_LastWrittenPOC = m_iMinPOC;
+    if (m_sReoderingStatus.iMinPOC > IMinInt32) {
+      if ((m_sReoderingStatus.iLastWrittenPOC > IMinInt32
+           && m_sReoderingStatus.iMinPOC - m_sReoderingStatus.iLastWrittenPOC <= 1)
+          || m_sReoderingStatus.iMinPOC < m_pDecContext->pSliceHeader->iPicOrderCntLsb) {
+        m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
 #if defined (_DEBUG)
 #ifdef _MOTION_VECTOR_DUMP_
-        fprintf (stderr, "Output POC: #%d\n", m_LastWrittenPOC);
+        fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
 #endif
 #endif
-        memcpy (pDstInfo, &m_sPictInfoList[m_iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
-        ppDst[0] = m_sPictInfoList[m_iPictInfoIndex].pData[0];
-        ppDst[1] = m_sPictInfoList[m_iPictInfoIndex].pData[1];
-        ppDst[2] = m_sPictInfoList[m_iPictInfoIndex].pData[2];
-        m_sPictInfoList[m_iPictInfoIndex].iPOC = sIMinInt32;
-        if (m_sPictInfoList[m_iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
-          m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
-        m_sPictInfoList[m_iPictInfoIndex].bLastGOP = false;
-        m_iMinPOC = sIMinInt32;
-        --m_iNumOfPicts;
+        memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
+        ppDst[0] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[0];
+        ppDst[1] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[1];
+        ppDst[2] = m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].pData[2];
+        m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC = IMinInt32;
+        if (m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx < m_pDecContext->pPicBuff->iCapacity)
+          m_pDecContext->pPicBuff->ppPic[m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPicBuffIdx]->bAvailableFlag = true;
+        m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].bLastGOP = false;
+        m_sReoderingStatus.iMinPOC = IMinInt32;
+        --m_sReoderingStatus.iNumOfPicts;
         return iRet;
       }
     }
@@ -1024,19 +1017,6 @@
   DECODING_STATE state = dsErrorFree;
 
   return state;
-}
-
-void CWelsDecoder::ResetReorderingPictureBuffers() {
-  m_iPictInfoIndex = 0;
-  m_iMinPOC = sIMinInt32;
-  m_iNumOfPicts = 0;
-  m_iLastGOPRemainPicts = 0;
-  m_LastWrittenPOC = sIMinInt32;
-  m_iLargestBufferedPicIndex = 0;
-  for (int32_t i = 0; i < 16; ++i) {
-    m_sPictInfoList[i].bLastGOP = false;
-    m_sPictInfoList[i].iPOC = sIMinInt32;
-  }
 }
 
 } // namespace WelsDec