shithub: openh264

Download patch

ref: ffdf9127fb0085aa4f59327716c7c570138c8296
parent: e38825402ccfa51523b41666400152c1e0437f17
author: xiaotiansf <xiaotianshimail@gmail.com>
date: Mon Nov 25 08:10:31 EST 2019

Fix a few more fixes found during creating thread unit tests.
1. set all none-zero pCurDqLayer->pNzc to 1 before a MB deblocking.
2. make ReleaseBufferedReadyPicture to behaviour to be more close between thread and non-thread.
3. Fix a typo "sSliceDecodeFinsh"

--- a/codec/console/dec/src/h264dec.cpp
+++ b/codec/console/dec/src/h264dec.cpp
@@ -142,7 +142,6 @@
     pData[2] = NULL;
     memset (&sDstBufInfo, 0, sizeof (SBufferInfo));
     sDstBufInfo.uiInBsTimeStamp = uiTimeStamp;
-    sDstBufInfo.iBufferStatus = 1;
     pDecoder->FlushFrame (pData, &sDstBufInfo);
     if (sDstBufInfo.iBufferStatus == 1) {
       pDst[0] = sDstBufInfo.pDst[0];
--- a/codec/decoder/core/inc/decoder_context.h
+++ b/codec/decoder/core/inc/decoder_context.h
@@ -538,7 +538,7 @@
   PPicture pDec;
   SWelsDecEvent sImageReady;
   SWelsDecEvent sSliceDecodeStart;
-  SWelsDecEvent sSliceDecodeFinsh;
+  SWelsDecEvent sSliceDecodeFinish;
   int32_t       iPicBuffIdx; //picBuff Index
 } SWelsDecoderThreadCTX, *PWelsDecoderThreadCTX;
 
--- a/codec/decoder/core/src/decode_slice.cpp
+++ b/codec/decoder/core/src/decode_slice.cpp
@@ -1719,7 +1719,16 @@
 
       return ERR_INFO_MB_RECON_FAIL;
     }
+    int8_t pNzc[24];
+    if (pCtx->eSliceType != I_SLICE) {
+      memcpy (pNzc, pCurDqLayer->pNzc[pCurDqLayer->iMbXyIndex], 24);
+      pCtx->sBlockFunc.pWelsSetNonZeroCountFunc (
+        pCurDqLayer->pNzc[pCurDqLayer->iMbXyIndex]); // set all none-zero nzc to 1; dbk can be opti!
+    }
     WelsDeblockingFilterMB (pCurDqLayer, pFilter, iFilterIdc, pDeblockMb);
+    if (pCtx->eSliceType != I_SLICE) {
+      memcpy (pCurDqLayer->pNzc[pCurDqLayer->iMbXyIndex], pNzc, 24);
+    }
     if (pCtx->uiNalRefIdc > 0) {
       if (pCurDqLayer->iMbX == 0 || pCurDqLayer->iMbX == pCurDqLayer->iMbWidth - 1 || pCurDqLayer->iMbY == 0
           || pCurDqLayer->iMbY == pCurDqLayer->iMbHeight - 1) {
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -2530,7 +2530,7 @@
       pSh = &pNalCur->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader;
       if (pSh->iFirstMbInSlice == 0) {
         if (pLastThreadCtx->pCtx->pDec != NULL && pLastThreadCtx->pCtx->pDec->bIsUngroupedMultiSlice) {
-          WAIT_EVENT (&pLastThreadCtx->sSliceDecodeFinsh, WELS_DEC_THREAD_WAIT_INFINITE);
+          WAIT_EVENT (&pLastThreadCtx->sSliceDecodeFinish, WELS_DEC_THREAD_WAIT_INFINITE);
         }
         pCtx->pDec = NULL;
         pCtx->iTotalNumMbRec = 0;
@@ -2537,7 +2537,7 @@
       } else if (pLastThreadCtx->pCtx->pDec != NULL) {
         if (pSh->iFrameNum == pLastThreadCtx->pCtx->pDec->iFrameNum
             && pSh->iPicOrderCntLsb == pLastThreadCtx->pCtx->pDec->iFramePoc) {
-          WAIT_EVENT (&pLastThreadCtx->sSliceDecodeFinsh, WELS_DEC_THREAD_WAIT_INFINITE);
+          WAIT_EVENT (&pLastThreadCtx->sSliceDecodeFinish, WELS_DEC_THREAD_WAIT_INFINITE);
           pCtx->pDec = pLastThreadCtx->pCtx->pDec;
           pCtx->pDec->bIsUngroupedMultiSlice = true;
           pCtx->sRefPic = pLastThreadCtx->pCtx->sRefPic;
@@ -2822,12 +2822,9 @@
       if (iThreadCount >= 1) {
         int32_t  id = pThreadCtx->sThreadInfo.uiThrNum;
         for (int32_t i = 0; i < iThreadCount; ++i) {
-          if (i != id) {
-            if (pThreadCtx[i - id].sSliceDecodeStart.isSignaled) {
-              while (pThreadCtx[i - id].pCtx->uiDecodingTimeStamp < pCtx->uiDecodingTimeStamp) {
-                WelsSleep (1);
-              }
-            }
+          if (i == id || pThreadCtx[i - id].pCtx->uiDecodingTimeStamp == 0) continue;
+          if (pThreadCtx[i - id].pCtx->uiDecodingTimeStamp < pCtx->uiDecodingTimeStamp) {
+            WAIT_EVENT (&pThreadCtx[i - id].sSliceDecodeFinish, WELS_DEC_THREAD_WAIT_INFINITE);
           }
         }
         pCtx->pLastDecPicInfo->uiDecodingTimeStamp = pCtx->uiDecodingTimeStamp;
@@ -2835,7 +2832,7 @@
       iRet = DecodeFrameConstruction (pCtx, ppDst, pDstInfo);
       if (iRet) {
         if (iThreadCount > 1) {
-          SET_EVENT (&pThreadCtx->sSliceDecodeFinsh);
+          SET_EVENT (&pThreadCtx->sSliceDecodeFinish);
         }
         return iRet;
       }
@@ -2892,9 +2889,9 @@
         }
       }
     }
-  }
-  if (iThreadCount > 1) {
-    SET_EVENT (&pThreadCtx->sSliceDecodeFinsh);
+    if (iThreadCount > 1) {
+      SET_EVENT (&pThreadCtx->sSliceDecodeFinish);
+    }
   }
   return ERR_NONE;
 }
--- a/codec/decoder/plus/inc/welsDecoderExt.h
+++ b/codec/decoder/plus/inc/welsDecoderExt.h
@@ -127,6 +127,7 @@
   int32_t                 m_DecCtxActiveCount;
   PWelsDecoderThreadCTX   m_pDecThrCtx;
   PWelsDecoderThreadCTX   m_pLastDecThrCtx;
+  int32_t                 m_iLastBufferedIdx;
   WELS_MUTEX              m_csDecoder;
   SWelsDecEvent           m_sBufferingEvent;
   SWelsDecEvent           m_sReleaseBufferEvent;
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -106,7 +106,7 @@
   }
   pThrCtx->pDec = NULL;
   if (GetThreadCount (pThrCtx->pCtx) > 1) {
-    RESET_EVENT (&pThrCtx->sSliceDecodeFinsh);
+    RESET_EVENT (&pThrCtx->sSliceDecodeFinish);
   }
   iRet |= pWelsDecoder->DecodeFrame2WithCtx (pThrCtx->pCtx, NULL, 0, pThrCtx->ppDst, &pThrCtx->sDstInfo);
 
@@ -142,7 +142,8 @@
     m_bFreezeOutput (false),
     m_DecCtxActiveCount (0),
     m_pDecThrCtx (NULL),
-    m_pLastDecThrCtx (NULL) {
+    m_pLastDecThrCtx (NULL),
+    m_iLastBufferedIdx (0) {
 #ifdef OUTPUT_BIT_STREAM
   char chFileName[1024] = { 0 };  //for .264
   int iBufUsed = 0;
@@ -314,7 +315,7 @@
       m_pDecThrCtx[i].pDec = NULL;
       CREATE_EVENT (&m_pDecThrCtx[i].sImageReady, 1, 0, NULL);
       CREATE_EVENT (&m_pDecThrCtx[i].sSliceDecodeStart, 1, 0, NULL);
-      CREATE_EVENT (&m_pDecThrCtx[i].sSliceDecodeFinsh, 1, 0, NULL);
+      CREATE_EVENT (&m_pDecThrCtx[i].sSliceDecodeFinish, 1, 0, NULL);
       CREATE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle, 0, 1, NULL);
       CREATE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsActivated, 0, 1, NULL);
       CREATE_THREAD (&m_pDecThrCtx[i].sThreadInfo.sThrHandle, pThrProcInit, (void*) (& (m_pDecThrCtx[i])));
@@ -330,7 +331,7 @@
       WAIT_THREAD (&m_pDecThrCtx[i].sThreadInfo.sThrHandle);
       CLOSE_EVENT (&m_pDecThrCtx[i].sImageReady);
       CLOSE_EVENT (&m_pDecThrCtx[i].sSliceDecodeStart);
-      CLOSE_EVENT (&m_pDecThrCtx[i].sSliceDecodeFinsh);
+      CLOSE_EVENT (&m_pDecThrCtx[i].sSliceDecodeFinish);
       CLOSE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsIdle);
       CLOSE_SEMAPHORE (&m_pDecThrCtx[i].sThreadInfo.sIsActivated);
     }
@@ -925,15 +926,43 @@
   }
   if (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_bIsBaseline) {
+      uint32_t uiDecodingTimeStamp = 0;
+      int32_t firstValidIdx = -1;
+      for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+        if (m_sPictInfoList[i].iPOC > IMinInt32) {
+          uiDecodingTimeStamp = m_sPictInfoList[i].uiDecodingTimeStamp;
+          m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
+          m_sReoderingStatus.iPictInfoIndex = i;
+          firstValidIdx = i;
+          break;
+        }
       }
-      if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC) {
-        m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
-        m_sReoderingStatus.iPictInfoIndex = i;
+      for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+        if (i == firstValidIdx) continue;
+        if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].uiDecodingTimeStamp < uiDecodingTimeStamp) {
+          uiDecodingTimeStamp = m_sPictInfoList[i].uiDecodingTimeStamp;
+          m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
+          m_sReoderingStatus.iPictInfoIndex = i;
+        }
       }
+    } else {
+      int32_t firstValidIdx = -1;
+      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;
+          firstValidIdx = i;
+          break;
+        }
+      }
+      for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+        if (i == firstValidIdx) continue;
+        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_sReoderingStatus.iMinPOC > IMinInt32) {
@@ -940,7 +969,8 @@
     m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
 #if defined (_DEBUG)
 #ifdef _MOTION_VECTOR_DUMP_
-    fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
+    fprintf (stderr, "Output POC: #%d uiDecodingTimeStamp=%d\n", m_sReoderingStatus.iLastWrittenPOC,
+             m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].uiDecodingTimeStamp);
 #endif
 #endif
     memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
@@ -1051,6 +1081,7 @@
       m_sPictInfoList[i].iPicBuffIdx = pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;
       if (GetThreadCount (pCtx) <= 1) ++pCtx->pLastDecPicInfo->pPreviousDecodedPictureInDpb->iRefCount;
       m_sPictInfoList[i].bLastGOP = false;
+      m_iLastBufferedIdx = i;
       pDstInfo->iBufferStatus = 0;
       ++m_sReoderingStatus.iNumOfPicts;
       if (i > m_sReoderingStatus.iLargestBufferedPicIndex) {
@@ -1069,11 +1100,17 @@
   }
   if (!m_bIsBaseline && m_sReoderingStatus.iLastGOPRemainPicts > 0) {
     m_sReoderingStatus.iMinPOC = IMinInt32;
+    int32_t firstValidIdx = -1;
     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;
+        firstValidIdx = i;
+        break;
       }
+    }
+    for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+      if (i == firstValidIdx) continue;
       if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC
           && m_sPictInfoList[i].bLastGOP) {
         m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
@@ -1083,7 +1120,8 @@
     m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
 #if defined (_DEBUG)
 #ifdef _MOTION_VECTOR_DUMP_
-    fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
+    fprintf (stderr, "Output POC: #%d uiDecodingTimeStamp=%d\n", m_sReoderingStatus.iLastWrittenPOC,
+             m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].uiDecodingTimeStamp);
 #endif
 #endif
     memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
@@ -1104,21 +1142,29 @@
   }
   if (m_sReoderingStatus.iNumOfPicts && m_bIsBaseline) {
     uint32_t uiDecodingTimeStamp = 0;
+    int32_t firstValidIdx = -1;
     for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
       if (m_sPictInfoList[i].iPOC > IMinInt32) {
         uiDecodingTimeStamp = m_sPictInfoList[i].uiDecodingTimeStamp;
         m_sReoderingStatus.iPictInfoIndex = i;
+        firstValidIdx = i;
         break;
       }
     }
     for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
-      if (m_sReoderingStatus.iPictInfoIndex != i && m_sPictInfoList[i].iPOC > IMinInt32
-          && m_sPictInfoList[i].sBufferInfo.uiInBsTimeStamp < uiDecodingTimeStamp) {
+      if (i == firstValidIdx) continue;
+      if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].uiDecodingTimeStamp < uiDecodingTimeStamp) {
         uiDecodingTimeStamp = m_sPictInfoList[i].uiDecodingTimeStamp;
         m_sReoderingStatus.iPictInfoIndex = i;
       }
     }
     if (uiDecodingTimeStamp > 0) {
+#if defined (_DEBUG)
+#ifdef _MOTION_VECTOR_DUMP_
+      fprintf (stderr, "Output POC: #%d uiDecodingTimeStamp=%d\n", m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].iPOC,
+               uiDecodingTimeStamp);
+#endif
+#endif
       memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));
       ppDst[0] = pDstInfo->pDst[0];
       ppDst[1] = pDstInfo->pDst[1];
@@ -1132,11 +1178,17 @@
   }
   if (m_sReoderingStatus.iNumOfPicts > 0) {
     m_sReoderingStatus.iMinPOC = IMinInt32;
+    int32_t firstValidIdx = -1;
     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;
+        firstValidIdx = i;
+        break;
       }
+    }
+    for (int32_t i = 0; i <= m_sReoderingStatus.iLargestBufferedPicIndex; ++i) {
+      if (i == firstValidIdx) continue;
       if (m_sPictInfoList[i].iPOC > IMinInt32 && m_sPictInfoList[i].iPOC < m_sReoderingStatus.iMinPOC) {
         m_sReoderingStatus.iMinPOC = m_sPictInfoList[i].iPOC;
         m_sReoderingStatus.iPictInfoIndex = i;
@@ -1144,20 +1196,16 @@
     }
   }
   if (m_sReoderingStatus.iMinPOC > IMinInt32) {
-    bool isReady = false;
-    if (pCtx != NULL) {
-      isReady = (m_sReoderingStatus.iLastWrittenPOC > IMinInt32
-                 && m_sReoderingStatus.iMinPOC - m_sReoderingStatus.iLastWrittenPOC <= 1)
-                || m_sReoderingStatus.iMinPOC < pCtx->pSliceHeader->iPicOrderCntLsb;
-    } else {
-      isReady = m_sReoderingStatus.iMinPOC == 0 || (m_sReoderingStatus.iLastWrittenPOC >= 0
-                && m_sReoderingStatus.iMinPOC <= m_sReoderingStatus.iLastWrittenPOC + 2) ;
-    }
+    int32_t iLastPOC = pCtx != NULL ? pCtx->pSliceHeader->iPicOrderCntLsb : m_sPictInfoList[m_iLastBufferedIdx].iPOC;
+    bool isReady = (m_sReoderingStatus.iLastWrittenPOC > IMinInt32
+                    && m_sReoderingStatus.iMinPOC - m_sReoderingStatus.iLastWrittenPOC <= 1)
+                   || m_sReoderingStatus.iMinPOC < iLastPOC;
     if (isReady) {
       m_sReoderingStatus.iLastWrittenPOC = m_sReoderingStatus.iMinPOC;
 #if defined (_DEBUG)
 #ifdef _MOTION_VECTOR_DUMP_
-      fprintf (stderr, "Output POC: #%d\n", m_sReoderingStatus.iLastWrittenPOC);
+      fprintf (stderr, "Output POC: #%d uiDecodingTimeStamp=%d\n", m_sReoderingStatus.iLastWrittenPOC,
+               m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].uiDecodingTimeStamp);
 #endif
 #endif
       memcpy (pDstInfo, &m_sPictInfoList[m_sReoderingStatus.iPictInfoIndex].sBufferInfo, sizeof (SBufferInfo));