From c009183e9709a9060c84e33fe375e8ad781d08ff Mon Sep 17 00:00:00 2001 From: sijchen Date: Mon, 14 Mar 2016 11:28:44 -0700 Subject: [PATCH] fix the lack of eSpsPpsIdStrategy==INCREASING_ID under simulcast avc on --- codec/encoder/core/src/encoder_ext.cpp | 52 +++++++----- test/api/encode_options_test.cpp | 113 +++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 20 deletions(-) diff --git a/codec/encoder/core/src/encoder_ext.cpp b/codec/encoder/core/src/encoder_ext.cpp index 5c755768..f1d2eaf7 100644 --- a/codec/encoder/core/src/encoder_ext.cpp +++ b/codec/encoder/core/src/encoder_ext.cpp @@ -3205,6 +3205,21 @@ void UpdatePpsList (sWelsEncCtx* pCtx) { } +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 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN 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 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN 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 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN 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 WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t iIdx, 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) @@ -3546,6 +3552,12 @@ int32_t WriteSavcParaset (sWelsEncCtx* pCtx, const int32_t iIdx, 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) diff --git a/test/api/encode_options_test.cpp b/test/api/encode_options_test.cpp index f2da4087..923fd776 100644 --- a/test/api/encode_options_test.cpp +++ b/test/api/encode_options_test.cpp @@ -347,6 +347,119 @@ struct EncodeDecodeParamBase { 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) {