shithub: openh264

Download patch

ref: b1ce6997f98da6fabb82c55cf7cb549c49953d48
parent: e1b8cd20196ae5fe83db4ba1939dc9aa1bc39089
author: xiaotianshi2 <xiaotianshimail2@gmail.com>
date: Sun Jun 28 13:19:55 EDT 2020

Add thread decoding support for multi-slice frame. Note: In each call to DecodeFrameNoDelay, iSrcLen must be the byte-size of one coded video frame.

--- a/codec/decoder/core/src/decoder.cpp
+++ b/codec/decoder/core/src/decoder.cpp
@@ -813,7 +813,7 @@
             }
             CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
             if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
-              if (pCtx->pThreadCtx == NULL) {
+              if (GetThreadCount (pCtx) <= 1) {
                 ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
               } else {
                 pCtx->pAccessUnitList->uiAvailUnitsNum = 1;
@@ -873,11 +873,11 @@
       if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) {
         iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3);
       }
-      if (pCtx->pThreadCtx == NULL) {
+      if (GetThreadCount (pCtx) <= 1) {
         CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo);
       }
       if (pCtx->bAuReadyFlag && pCtx->pAccessUnitList->uiAvailUnitsNum != 0) {
-        if (pCtx->pThreadCtx == NULL) {
+        if (GetThreadCount (pCtx) <= 1) {
           ConstructAccessUnit (pCtx, ppDst, pDstBufInfo);
         } else {
           pCtx->pAccessUnitList->uiAvailUnitsNum = 1;
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -2338,7 +2338,7 @@
  */
 int32_t ConstructAccessUnit (PWelsDecoderContext pCtx, uint8_t** ppDst, SBufferInfo* pDstInfo) {
   int32_t iErr = ERR_NONE;
-  if (pCtx->pThreadCtx == NULL) {
+  if (GetThreadCount (pCtx) <= 1) {
     iErr = InitConstructAccessUnit (pCtx, pDstInfo);
     if (ERR_NONE != iErr) {
       return iErr;
@@ -2550,7 +2550,7 @@
       isNewFrame = pCtx->pDec == NULL;
     }
     if (pCtx->pDec == NULL) {
-      if (pLastThreadCtx != NULL) {
+      if (pLastThreadCtx != NULL && iIdx == 0) {
         pLastThreadCtx->pDec->bUsedAsRef = pLastThreadCtx->pCtx->uiNalRefIdc > 0;
         if (pLastThreadCtx->pDec->bUsedAsRef) {
           for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
@@ -2686,7 +2686,19 @@
             if (pCtx->bNewSeqBegin) {
               iPrevFrameNum = 0;
             } else if (pLastThreadCtx->pDec != NULL) {
-              iPrevFrameNum = pLastThreadCtx->pDec->iFrameNum;
+              if (pLastThreadCtx->pDec->uiTimeStamp == pCtx->uiTimeStamp - 1) {
+                iPrevFrameNum = pLastThreadCtx->pDec->iFrameNum;
+                if (iPrevFrameNum == -1) iPrevFrameNum = pLastThreadCtx->pCtx->iFrameNum;
+              } else {
+                int32_t  id = pThreadCtx->sThreadInfo.uiThrNum;
+                for (int32_t i = 0; i < iThreadCount; ++i) {
+                  if (pThreadCtx[i - id].pCtx->uiTimeStamp == pCtx->uiTimeStamp - 1) {
+                    if (pThreadCtx[i - id].pDec != NULL) iPrevFrameNum = pThreadCtx[i - id].pDec->iFrameNum;
+                    if (iPrevFrameNum == -1) iPrevFrameNum = pThreadCtx[i - id].pCtx->iFrameNum;
+                    break;
+                  }
+                }
+              }
             } else {
               iPrevFrameNum = pCtx->bNewSeqBegin ? 0 : pLastThreadCtx->pCtx->iFrameNum;
             }
@@ -2734,8 +2746,10 @@
           ComputeColocatedTemporalScaling (pCtx);
 
         if (iThreadCount > 1) {
-          memset (&pCtx->lastReadyHeightOffset[0][0], -1, LIST_A * MAX_REF_PIC_COUNT * sizeof (int16_t));
-          SET_EVENT (&pThreadCtx->sSliceDecodeStart);
+          if (iIdx == 0) {
+            memset (&pCtx->lastReadyHeightOffset[0][0], -1, LIST_A * MAX_REF_PIC_COUNT * sizeof (int16_t));
+            SET_EVENT (&pThreadCtx->sSliceDecodeStart);
+          }
           iRet = WelsDecodeAndConstructSlice (pCtx);
         } else {
           iRet = WelsDecodeSlice (pCtx, bFreshSliceAvailable, pNalCur);
--- a/codec/decoder/plus/src/welsDecoderExt.cpp
+++ b/codec/decoder/plus/src/welsDecoderExt.cpp
@@ -1374,6 +1374,13 @@
       sThreadCtx.pCtx->iImgHeightInPixel = m_pLastDecThrCtx->pCtx->iImgHeightInPixel;
     }
   }
+
+  //if threadCount > 1, then each thread must contain exact one complete frame.
+  if (GetThreadCount (sThreadCtx.pCtx) > 1) {
+    sThreadCtx.pCtx->pAccessUnitList->uiAvailUnitsNum = 0;
+    sThreadCtx.pCtx->pAccessUnitList->uiActualUnitsNum = 0;
+  }
+
   int32_t iRet = DecodeFrame2WithCtx (sThreadCtx.pCtx, sThreadCtx.kpSrc, sThreadCtx.kiSrcLen, sThreadCtx.ppDst,
                                       &sThreadCtx.sDstInfo);