shithub: openh264

Download patch

ref: 16cfb0a937487de4a20c9a390062b47c9641e262
parent: ca36beb3fac4a4d05d36d29ab65606557b3e0137
author: Licai Guo <guolicai@gmail.com>
date: Sun Apr 13 16:00:25 EDT 2014

add track sps change for each layer

--- a/codec/decoder/core/inc/decoder_context.h
+++ b/codec/decoder/core/inc/decoder_context.h
@@ -236,7 +236,6 @@
 
   PAccessUnit			pAccessUnitList;	// current access unit list to be performed
   PSps        pActiveLayerSps[MAX_LAYER_NUM];
-  PPps        pActiveLayerPps[MAX_LAYER_NUM];
   PSps				pSps;	// used by current AU
   PPps				pPps;	// used by current AU
   // Memory for pAccessUnitList is dynamically held till decoder destruction.
@@ -272,7 +271,7 @@
 
   uint16_t            uiCurIdrPicId;
 #endif
-
+  bool       bNewSeqBegin;
   int32_t iErrorConMethod; //
   PGetIntraPredFunc pGetI16x16LumaPredFunc[7];		//h264_predict_copy_16x16;
   PGetIntraPredFunc pGetI4x4LumaPredFunc[14];		// h264_predict_4x4_t
@@ -311,6 +310,11 @@
 
 } SWelsDecoderContext, *PWelsDecoderContext;
 
+static inline void ResetActiveSPSForEachLayer(PWelsDecoderContext pCtx) {
+  for(int i = 0; i < MAX_LAYER_NUM; i++) {
+    pCtx->pActiveLayerSps[i] = NULL;
+  }
+}
 //#ifdef __cplusplus
 //}
 //#endif//__cplusplus
--- a/codec/decoder/core/src/decoder_core.cpp
+++ b/codec/decoder/core/src/decoder_core.cpp
@@ -866,9 +866,9 @@
 
   // Added for mosaic avoidance, 11/19/2009
 #ifdef LONG_TERM_REF
-  if (pCtx->bParamSetsLostFlag)
+  if (pCtx->bParamSetsLostFlag || pCtx->bNewSeqBegin)
 #else
-  if (pCtx->bReferenceLostAtT0Flag)
+  if (pCtx->bReferenceLostAtT0Flag || pCtx->bNewSeqBegin)
 #endif
   {
     uint32_t uiActualIdx = 0;
@@ -1458,9 +1458,52 @@
   ResetCurrentAccessUnit (pCtx);
 }
 
+/* CheckNewSeqBeginAndUpdateActiveLayerSps
+ * return:
+ * true - the AU to be construct is the start of new sequence; false - not
+ */
+static bool CheckNewSeqBeginAndUpdateActiveLayerSps(PWelsDecoderContext pCtx) {
+  bool bNewSeq = false;
+  PAccessUnit pCurAu = pCtx->pAccessUnitList;
+  PSps pTmpLayerSps[MAX_LAYER_NUM];
+  for(int i = 0; i < MAX_LAYER_NUM; i++) {
+    pTmpLayerSps[i] = NULL;
+  }
+  // track the layer sps for the current au
+  for(int i = pCurAu->uiStartPos; i <= pCurAu->uiEndPos; i++) {
+    uint32_t uiDid = pCurAu->pNalUnitsList[i]->sNalHeaderExt.uiDependencyId;
+    pTmpLayerSps[uiDid] = pCurAu->pNalUnitsList[i]->sNalData.sVclNal.sSliceHeaderExt.sSliceHeader.pSps;
+  }
+  int iMaxActiveLayer, iMaxCurrentLayer;
+  for(int i = MAX_LAYER_NUM - 1; i >= 0; i--) {
+    if (pCtx->pActiveLayerSps[i] != NULL) {
+      iMaxActiveLayer = i;
+      break;
+    }
+  }
+  for(int i = MAX_LAYER_NUM - 1; i >= 0; i--) {
+    if (pTmpLayerSps[i] != NULL) {
+      iMaxCurrentLayer = i;
+      break;
+    }
+  }
+  if (iMaxCurrentLayer != iMaxActiveLayer) {
+    bNewSeq = true;
+  }
+  // fill active sps if the current sps is not null while active layer is null
+  if (!bNewSeq) {
+    for(int i = 0; i < MAX_LAYER_NUM; i++) {
+      if (pCtx->pActiveLayerSps[i] == NULL && pTmpLayerSps[i] != NULL) {
+        pCtx->pActiveLayerSps[i] = pTmpLayerSps[i];
+      }
+    }
+  } else {
+    // UpdateActiveLayerSps if new sequence start
+    memcpy(&pCtx->pActiveLayerSps[0], &pTmpLayerSps[0], MAX_LAYER_NUM * sizeof(PSps));
+  }
+  return bNewSeq;
+}
 
-
-
 /*
  * ConstructAccessUnit
  * construct an access unit for given input bitstream, maybe partial NAL Unit, one or more Units are involved to
@@ -1483,7 +1526,7 @@
 
   pCtx->bAuReadyFlag = false;
   pCtx->bLastHasMmco5 = false;
-
+  pCtx->bNewSeqBegin = CheckNewSeqBeginAndUpdateActiveLayerSps(pCtx);
   iErr = WelsDecodeAccessUnitStart (pCtx);
   GetVclNalTemporalId (pCtx);
 
@@ -1512,7 +1555,7 @@
   iErr = DecodeCurrentAccessUnit (pCtx, ppDst, iStride, &iWidth, &iHeight, pDstInfo);
 
   WelsDecodeAccessUnitEnd (pCtx);
-
+  pCtx->bNewSeqBegin = false;
   if (ERR_NONE != iErr) {
     WelsLog (pCtx, WELS_LOG_INFO, "returned error from decoding:[0x%x]\n", iErr);