shithub: openh264

Download patch

ref: c009183e9709a9060c84e33fe375e8ad781d08ff
parent: 25f53a2e3dd3cc978b9bf76fc14467e802c3ebf1
author: sijchen <[email protected]>
date: Mon Mar 14 07:28:44 EDT 2016

fix the lack of eSpsPpsIdStrategy==INCREASING_ID under simulcast avc on

--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -3205,6 +3205,21 @@
 
 }
 
+void eSpsPpsIdStrategy_INCREASING_ID (SParaSetOffset* pPSOVector, const uint32_t kuiId, const int iParasetType) {
+#if _DEBUG
+  pPSOVector->eSpsPpsIdStrategy = INCREASING_ID;
+  assert (iIdx < MAX_DQ_LAYER_NUM);
+#endif
+
+  ParasetIdAdditionIdAdjust (& (pPSOVector->sParaSetOffsetVariable[iParasetType]),
+                             kuiId,
+                             (iParasetType != PARA_SET_TYPE_PPS) ? MAX_SPS_COUNT : MAX_PPS_COUNT);
+}
+
+void eSpsPpsIdStrategy_CONSTANT_ID (SParaSetOffset* pPSOVector, const uint32_t kuiId, const int iParasetType) {
+  memset (pPSOVector, 0, sizeof (SParaSetOffset));
+}
+
 /*!
  * \brief   write all parameter sets introduced in SVC extension
  * \return  writing results, success or error
@@ -3227,16 +3242,9 @@
   while (iIdx < pCtx->iSpsNum) {
     // TODO (Sijia) wrap different operation of eSpsPpsIdStrategy to classes to hide the details
     if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
-#if _DEBUG
-      pCtx->sPSOVector.eSpsPpsIdStrategy = INCREASING_ID;
-      assert (iIdx < MAX_DQ_LAYER_NUM);
-#endif
-
-      ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS]),
-                                 pCtx->pSpsArray[0].uiSpsId,
-                                 MAX_SPS_COUNT);
+      eSpsPpsIdStrategy_INCREASING_ID (& (pCtx->sPSOVector), pCtx->pSpsArray[0].uiSpsId, PARA_SET_TYPE_AVCSPS);
     } else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
-      memset (& (pCtx->sPSOVector), 0, sizeof (pCtx->sPSOVector));
+      eSpsPpsIdStrategy_CONSTANT_ID (& (pCtx->sPSOVector), pCtx->pSpsArray[0].uiSpsId, PARA_SET_TYPE_AVCSPS);
     }
 
     /* generate sequence parameters set */
@@ -3257,16 +3265,10 @@
     iNal = pCtx->pOut->iNalIndex;
 
     if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
-#if _DEBUG
-      pCtx->sPSOVector.eSpsPpsIdStrategy = INCREASING_ID;
-      assert (iIdx < MAX_DQ_LAYER_NUM);
-#endif
-
-      ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS]),
-                                 pCtx->pSubsetArray[iIdx].pSps.uiSpsId,
-                                 MAX_SPS_COUNT);
+      eSpsPpsIdStrategy_INCREASING_ID (& (pCtx->sPSOVector), pCtx->pSubsetArray[iIdx].pSps.uiSpsId, PARA_SET_TYPE_SUBSETSPS);
     }
 
+
     iId = iIdx;
 
     /* generate Subset SPS */
@@ -3298,9 +3300,7 @@
   iIdx = 0;
   while (iIdx < pCtx->iPpsNum) {
     if ((INCREASING_ID & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
-      //para_set_type = 2: PPS, use MAX_PPS_COUNT
-      ParasetIdAdditionIdAdjust (&pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS], pCtx->pPPSArray[iIdx].iPpsId,
-                                 MAX_PPS_COUNT);
+      eSpsPpsIdStrategy_INCREASING_ID (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS);
     }
 
     WelsWriteOnePPS (pCtx, iIdx, iNalLength);
@@ -3515,6 +3515,12 @@
   int32_t iNalSize = 0;
   iCountNal        = 0;
 
+  if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
+    eSpsPpsIdStrategy_INCREASING_ID (& (pCtx->sPSOVector), pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS);
+  } else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
+    eSpsPpsIdStrategy_CONSTANT_ID (& (pCtx->sPSOVector), pCtx->pSpsArray[iIdx].uiSpsId, PARA_SET_TYPE_AVCSPS);
+  }
+
   iReturn          = WelsWriteOneSPS (pCtx, iIdx, iNalSize);
   WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
 
@@ -3545,6 +3551,12 @@
   //writing one NAL
   iNalSize = 0;
   iCountNal        = 0;
+
+  if (INCREASING_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
+    eSpsPpsIdStrategy_INCREASING_ID (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS);
+  } else if (CONSTANT_ID == pCtx->pSvcParam->eSpsPpsIdStrategy) {
+    eSpsPpsIdStrategy_CONSTANT_ID (& (pCtx->sPSOVector), pCtx->pPPSArray[iIdx].iPpsId, PARA_SET_TYPE_PPS);
+  }
 
   iReturn          = WelsWriteOnePPS (pCtx, iIdx, iNalSize);
   WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
--- a/test/api/encode_options_test.cpp
+++ b/test/api/encode_options_test.cpp
@@ -347,6 +347,119 @@
   int iTarBitrate;
 };
 
+//#define DEBUG_FILE_SAVE_INCREASING_ID
+TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_INCREASING_ID) {
+
+  int iWidth       = GetRandWidth();
+  int iHeight      = GetRandHeight();
+  float fFrameRate = rand() + 0.5f;
+  int iEncFrameNum = 0;
+  int iSpatialLayerNum = 1;
+  int iSliceNum        = 1;
+
+  // prepare params
+  SEncParamExt   sParam1;
+  SEncParamExt   sParam2;
+  SEncParamExt   sParam3;
+  encoder_->GetDefaultParams (&sParam1);
+  prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
+  sParam1.bSimulcastAVC = 1;
+  sParam1.eSpsPpsIdStrategy = INCREASING_ID;
+  //prepare param2
+  memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
+  while (GET_MB_WIDTH (sParam2.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth)) {
+    sParam2.iPicWidth = GetRandWidth();
+  }
+  prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
+  sParam2.bSimulcastAVC = 1;
+  sParam2.eSpsPpsIdStrategy = INCREASING_ID;
+  //prepare param3
+  memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
+  while (GET_MB_WIDTH (sParam3.iPicHeight) == GET_MB_WIDTH (sParam1.iPicHeight)) {
+    sParam3.iPicHeight = GetRandHeight();
+  }
+  prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
+  sParam3.bSimulcastAVC = 1;
+  sParam3.eSpsPpsIdStrategy = INCREASING_ID;
+
+  //prepare output if needed
+  FILE* fEnc =  NULL;
+#ifdef DEBUG_FILE_SAVE_INCREASING_ID
+  fEnc = fopen ("enc_i.264", "wb");
+#endif
+
+  // Test part#1
+  // step#1: pParam1
+  //int TraceLevel = WELS_LOG_INFO;
+  //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
+  int rv = encoder_->InitializeExt (&sParam1);
+  ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
+                                      sParam1.iPicHeight;
+  EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
+
+  // new IDR
+  rv = encoder_->ForceIntraFrame (true);
+  ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
+  EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
+
+  // step#2: pParam2
+  rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
+  ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam2.iPicWidth << "x" <<
+                                      sParam2.iPicHeight;
+  EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
+
+  // new IDR
+  rv = encoder_->ForceIntraFrame (true);
+  ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
+  EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
+
+  // step#3: back to pParam1
+  rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
+  ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
+                                      sParam1.iPicHeight;
+  EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
+
+  // step#4: back to pParam2
+  rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
+  ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << sParam2.iPicWidth << sParam2.iPicHeight;
+  EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
+
+#ifdef DEBUG_FILE_SAVE_INCREASING_ID
+  fclose (fEnc);
+#endif
+  rv = encoder_->Uninitialize();
+  ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
+
+  // Test part#2
+  // step#1: pParam1
+  rv = encoder_->InitializeExt (&sParam1);
+  ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
+  rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
+  ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
+  rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
+  ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam3: rv = " << rv;
+
+#ifdef DEBUG_FILE_SAVE_INCREASING_ID
+  fEnc = fopen ("enc3.264", "wb");
+#endif
+  iEncFrameNum = 0;
+  EncDecOneFrame (sParam3.iPicWidth, sParam3.iPicHeight, iEncFrameNum++, fEnc);
+
+  rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
+  ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
+  EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
+
+  rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
+  ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
+  EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
+
+#ifdef DEBUG_FILE_SAVE_INCREASING_ID
+  fclose (fEnc);
+#endif
+  rv = encoder_->Uninitialize();
+  ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
+}
+
 //#define DEBUG_FILE_SAVE2
 TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING1) {