History

Merge pull request #1732 from sijchen/sps_list2

[Encoder] add new SpsPpsStrategy and UT

ruil2 committed 11 years ago

Commit aea10172 parents 9ba316c 98ed30216 files · +1150 −161Browse files

Unified · Split

16 files
  1. codec/api/svc/codec_app_def.h +12 −1
  2. codec/console/enc/src/welsenc.cpp +4 −4
  3. codec/encoder/core/inc/au_set.h +19 −1
  4. codec/encoder/core/inc/encoder.h +1 −1
  5. codec/encoder/core/inc/encoder_context.h +2 −0
  6. codec/encoder/core/inc/extern.h +2 −1
  7. codec/encoder/core/inc/param_svc.h +15 −3
  8. codec/encoder/core/inc/wels_common_basis.h +7 −1
  9. codec/encoder/core/inc/wels_const.h +1 −0
  10. codec/encoder/core/src/au_set.cpp +11 −11
  11. codec/encoder/core/src/encoder_ext.cpp +408 −73
  12. codec/encoder/core/src/svc_encode_slice.cpp +10 −7
  13. codec/encoder/plus/src/welsEncoderExt.cpp +29 −10
  14. test/api/encode_decode_api_test.cpp +506 −48
  15. test/encoder/EncUT_ParameterSetStrategy.cpp +122 −0
  16. test/encoder/targets.mk +1 −0
codec/api/svc/codec_app_def.h+12−1
@@ -385,6 +385,17 @@ typedef enum { · 384 unmodified lines
385 HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality385 HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality
386} ECOMPLEXITY_MODE;386} ECOMPLEXITY_MODE;
387 387
388/**
389 * @brief Enumulate for the stategy of SPS/PPS strategy
390 */
391typedef enum {
392 CONSTANT_ID = 0, ///< constant id in SPS/PPS
393 INCREASING_ID = 0x01, ///< SPS/PPS id increases at each IDR
394 SPS_LISTING = 0x02, ///< using SPS in the existing list if possible
395 SPS_LISTING_AND_PPS_INCREASING = 0x03,
396 SPS_PPS_LISTING = 0x06,
397} EParameterSetStrategy;
398
388// TODO: Refine the parameters definition.399// TODO: Refine the parameters definition.
389/**400/**
390* @brief SVC Encoding Parameters401* @brief SVC Encoding Parameters
@@ -421,7 +432,7 @@ typedef struct TagEncParamExt { · 30 unmodified lines
421 ECOMPLEXITY_MODE iComplexityMode;432 ECOMPLEXITY_MODE iComplexityMode;
422 unsigned int uiIntraPeriod; ///< period of Intra frame433 unsigned int uiIntraPeriod; ///< period of Intra frame
423 int iNumRefFrame; ///< number of reference frame used434 int iNumRefFrame; ///< number of reference frame used
424 bool bEnableSpsPpsIdAddition; ///< false:not adjust ID in SPS/PPS; true: adjust ID in SPS/PPS435 int iSpsPpsIdStrategy; ///< different stategy in adjust ID in SPS/PPS: 0- constant ID, 1-additional ID, 6-mapping and additional
425 bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL436 bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL
426 bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI437 bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI
427 bool bSimulcastAVC; ///< (when encoding more than 1 spatial layer) false: use SVC syntax for higher layers; true: use Simulcast AVC -- coming soon438 bool bSimulcastAVC; ///< (when encoding more than 1 spatial layer) false: use SVC syntax for higher layers; true: use Simulcast AVC -- coming soon
codec/console/enc/src/welsenc.cpp+4−4
@@ -232,8 +232,8 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv · 231 unmodified lines
232 pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str());232 pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str());
233 } else if (strTag[0].compare ("MaxNalSize") == 0) {233 } else if (strTag[0].compare ("MaxNalSize") == 0) {
234 pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str());234 pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str());
235 } else if (strTag[0].compare ("EnableSpsPpsIDAddition") == 0) {235 } else if (strTag[0].compare ("SpsPpsIDStrategy") == 0) {
236 pSvcParam.bEnableSpsPpsIdAddition = atoi (strTag[1].c_str()) ? true : false;236 pSvcParam.iSpsPpsIdStrategy = atoi (strTag[1].c_str());
237 } else if (strTag[0].compare ("EnableScalableSEI") == 0) {237 } else if (strTag[0].compare ("EnableScalableSEI") == 0) {
238 pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false;238 pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false;
239 } else if (strTag[0].compare ("EnableFrameCropping") == 0) {239 } else if (strTag[0].compare ("EnableFrameCropping") == 0) {
@@ -421,7 +421,7 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE · 181 unmodified lines
421 pSvcParam.uiMaxNalSize = atoi (argv[n++]);421 pSvcParam.uiMaxNalSize = atoi (argv[n++]);
422 422
423 else if (!strcmp (pCommand, "-spsid") && (n < argc))423 else if (!strcmp (pCommand, "-spsid") && (n < argc))
424 pSvcParam.bEnableSpsPpsIdAddition = atoi (argv[n++]) ? true : false;424 pSvcParam.iSpsPpsIdStrategy = atoi (argv[n++]);
425 425
426 else if (!strcmp (pCommand, "-cabac") && (n < argc))426 else if (!strcmp (pCommand, "-cabac") && (n < argc))
427 pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]);427 pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]);
@@ -591,7 +591,7 @@ int FillSpecificParameters (SEncParamExt& sParam) { · 163 unmodified lines
591 sParam.bEnableLongTermReference = 0; // long term reference control591 sParam.bEnableLongTermReference = 0; // long term reference control
592 sParam.iLtrMarkPeriod = 30;592 sParam.iLtrMarkPeriod = 30;
593 sParam.uiIntraPeriod = 320; // period of Intra frame593 sParam.uiIntraPeriod = 320; // period of Intra frame
594 sParam.bEnableSpsPpsIdAddition = 1;594 sParam.iSpsPpsIdStrategy = INCREASING_ID;
595 sParam.bPrefixNalAddingCtrl = 0;595 sParam.bPrefixNalAddingCtrl = 0;
596 sParam.iComplexityMode = MEDIUM_COMPLEXITY;596 sParam.iComplexityMode = MEDIUM_COMPLEXITY;
597 int iIndexLayer = 0;597 int iIndexLayer = 0;
codec/encoder/core/inc/au_set.h+19−1
@@ -141,8 +141,26 @@ int32_t WelsInitPps (SWelsPPS* pPps, · 140 unmodified lines
141 const bool kbDeblockingFilterPresentFlag,141 const bool kbDeblockingFilterPresentFlag,
142 const bool kbUsingSubsetSps,142 const bool kbUsingSubsetSps,
143 const bool kbEntropyCodingModeFlag);143 const bool kbEntropyCodingModeFlag);
144
144int32_t WelsCheckRefFrameLimitationNumRefFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);145int32_t WelsCheckRefFrameLimitationNumRefFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
145int32_t WelsCheckRefFrameLimitationLevelIdcFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);146int32_t WelsCheckRefFrameLimitationLevelIdcFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
146int32_t WelsAdjustLevel( SSpatialLayerConfig* pSpatialLayer);147
148int32_t WelsAdjustLevel (SSpatialLayerConfig* pSpatialLayer);
149
150/*!
151 * \brief check if the current parameter can found a presenting sps
152 * \param pParam the current encoding paramter in SWelsSvcCodingParam
153 * \param kbUseSubsetSps bool
154 * \param iDlayerIndex int, the index of current D layer
155 * \param iDlayerCount int, the number of total D layer
156 * \param pSpsArray array of all the stored SPSs
157 * \param pSubsetArray array of all the stored Subset-SPSs
158 * \return 0 - successful
159 * -1 - cannot find existing SPS for current encoder parameter
160 */
161int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
162 const int32_t iDlayerCount, const int32_t iSpsNumInUse,
163 SWelsSPS* pSpsArray,
164 SSubsetSps* pSubsetArray);
147}165}
148#endif//WELS_ACCESS_UNIT_PARSER_H__166#endif//WELS_ACCESS_UNIT_PARSER_H__
codec/encoder/core/inc/encoder.h+1−1
@@ -48,7 +48,7 @@ namespace WelsEnc { · 47 unmodified lines
48 * \param pEncCtx sWelsEncCtx*48 * \param pEncCtx sWelsEncCtx*
49 * \return successful - 0; otherwise none 0 for failed49 * \return successful - 0; otherwise none 0 for failed
50 */50 */
51int32_t RequestMemorySvc (sWelsEncCtx** ppCtx);51int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList);
52 52
53/*!53/*!
54 * \brief free memory in SVC core encoder54 * \brief free memory in SVC core encoder
codec/encoder/core/inc/encoder_context.h+2−0
@@ -191,6 +191,7 @@ typedef struct TagWelsEncCtx { · 190 unmodified lines
191 SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible191 SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible
192 SSubsetSps* pSubsetSps;192 SSubsetSps* pSubsetSps;
193 int32_t iSpsNum; // number of pSps used193 int32_t iSpsNum; // number of pSps used
194 int32_t iSubsetSpsNum; // number of pSps used
194 int32_t iPpsNum; // number of pPps used195 int32_t iPpsNum; // number of pPps used
195 196
196// Output197// Output
@@ -216,6 +217,7 @@ typedef struct TagWelsEncCtx { · 19 unmodified lines
216 pDqIdcMap; // overall DQ map of full scalability in specific frame (All full D/T/Q layers involved) // pDqIdcMap[dq_index] for each SDqIdc pData217 pDqIdcMap; // overall DQ map of full scalability in specific frame (All full D/T/Q layers involved) // pDqIdcMap[dq_index] for each SDqIdc pData
217 218
218 SParaSetOffset sPSOVector;219 SParaSetOffset sPSOVector;
220 SParaSetOffset* pPSOVector;
219 CMemoryAlign* pMemAlign;221 CMemoryAlign* pMemAlign;
220 222
221#if defined(STAT_OUTPUT)223#if defined(STAT_OUTPUT)
codec/encoder/core/inc/extern.h+2−1
@@ -75,7 +75,8 @@ void GomValidCheck (const int32_t kiMbWidth, const int32_t kiMbHeight, int32_t* · 74 unmodified lines
75 * \param para SWelsSvcCodingParam*75 * \param para SWelsSvcCodingParam*
76 * \return successful - 0; otherwise none 0 for failed76 * \return successful - 0; otherwise none 0 for failed
77 */77 */
78int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pPara, SLogContext* pLogCtx);78int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pPara, SLogContext* pLogCtx,
79 SExistingParasetList* pExistingParasetList);
79 80
80/*!81/*!
81 * \brief uninitialize Wels encoder core library82 * \brief uninitialize Wels encoder core library
codec/encoder/core/inc/param_svc.h+15−3
@@ -162,7 +162,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 161 unmodified lines
162 param.bEnableAdaptiveQuant = true; // adaptive quantization control162 param.bEnableAdaptiveQuant = true; // adaptive quantization control
163 param.bEnableFrameSkip = true; // frame skipping163 param.bEnableFrameSkip = true; // frame skipping
164 param.bEnableLongTermReference = false; // long term reference control164 param.bEnableLongTermReference = false; // long term reference control
165 param.bEnableSpsPpsIdAddition = true; // pSps pPps id addition control165 param.iSpsPpsIdStrategy = INCREASING_ID; // pSps pPps id addition control
166 param.bPrefixNalAddingCtrl = false; // prefix NAL adding control166 param.bPrefixNalAddingCtrl = false; // prefix NAL adding control
167 param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded167 param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded
168 param.iTemporalLayerNum = 1; // number of temporal layer specified168 param.iTemporalLayerNum = 1; // number of temporal layer specified
@@ -350,8 +350,8 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 181 unmodified lines
350 350
351 bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;351 bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;
352 352
353 bEnableSpsPpsIdAddition =353 iSpsPpsIdStrategy =
354 pCodingParam.bEnableSpsPpsIdAddition;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.354 pCodingParam.iSpsPpsIdStrategy;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.
355 //SHOULD enable this feature.355 //SHOULD enable this feature.
356 356
357 SSpatialLayerInternal* pDlp = &sDependencyLayers[0];357 SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
@@ -477,6 +477,18 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 119 unmodified lines
477 477
478} SWelsSvcCodingParam;478} SWelsSvcCodingParam;
479 479
480
481typedef struct TagExistingParasetList {
482 SWelsSPS sSps[MAX_SPS_COUNT];
483 SSubsetSps sSubsetSps[MAX_SPS_COUNT];
484 SWelsPPS sPps[MAX_PPS_COUNT];
485
486 uint32_t uiInUseSpsNum;
487 uint32_t uiInUseSubsetSpsNum;
488 uint32_t uiInUsePpsNum;
489} SExistingParasetList;
490
491
480static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {492static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
481 if (pParam == NULL || *pParam == NULL || pMa == NULL)493 if (pParam == NULL || *pParam == NULL || pMa == NULL)
482 return 1;494 return 1;
codec/encoder/core/inc/wels_common_basis.h+7−1
@@ -83,9 +83,15 @@ typedef struct TagParaSetOffset { · 82 unmodified lines
83 bool83 bool
84 bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far84 bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far
85 85
86 int32_t iPpsIdList[MAX_DQ_LAYER_NUM][MAX_PPS_COUNT]; //index0: max pps types; index1: for differnt IDRs, if only index0=1, index1 can reach MAX_PPS_COUNT
87
86#if _DEBUG88#if _DEBUG
87 bool bEnableSpsPpsIdAddition;89 int32_t iSpsPpsIdStrategy;
88#endif90#endif
91
92 uint32_t uiInUseSpsNum;
93 uint32_t uiInUseSubsetSpsNum;
94 uint32_t uiInUsePpsNum;
89} SParaSetOffset;95} SParaSetOffset;
90 96
91 97
codec/encoder/core/inc/wels_const.h+1−0
@@ -171,6 +171,7 @@ · 170 unmodified lines
171 171
172#define UNAVAILABLE_DQ_ID ((uint8_t)(-1))172#define UNAVAILABLE_DQ_ID ((uint8_t)(-1))
173#define LAYER_NUM_EXCHANGEABLE 2173#define LAYER_NUM_EXCHANGEABLE 2
174#define INVALID_ID (-1)
174 175
175#define NAL_HEADER_ADD_0X30BYTES 50176#define NAL_HEADER_ADD_0X30BYTES 50
176 177
codec/encoder/core/src/au_set.cpp+11−11
@@ -336,27 +336,27 @@ int32_t WelsWriteSubsetSpsSyntax (SSubsetSps* pSubsetSps, SBitStringAux* pBitStr · 335 unmodified lines
336 * \note Call it in case EWelsNalUnitType is PPS.336 * \note Call it in case EWelsNalUnitType is PPS.
337 *************************************************************************************337 *************************************************************************************
338 */338 */
339int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* sPSOVector) {339int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* pPSOVector) {
340 SBitStringAux* pLocalBitStringAux = pBitStringAux;340 SBitStringAux* pLocalBitStringAux = pBitStringAux;
341 341
342 bool bUsedSubset = sPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId];342 const int32_t kiParameterSetType = (pPSOVector != NULL) ? (pPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId] ?
343 int32_t iParameterSetType = (bUsedSubset ? PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS);343 PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS) : 0;
344 344
345 BsWriteUE (pLocalBitStringAux, pPps->iPpsId +345 BsWriteUE (pLocalBitStringAux, pPps->iPpsId
346 sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]);346 + ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]) : 0));
347 BsWriteUE (pLocalBitStringAux, pPps->iSpsId +347 BsWriteUE (pLocalBitStringAux, pPps->iSpsId
348 sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId]);348 + ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId]) : 0));
349 349
350#if _DEBUG350#if _DEBUG
351 //SParaSetOffset use, 110421351 //SParaSetOffset use, 110421
352 if (sPSOVector->bEnableSpsPpsIdAddition) {352 if ((pPSOVector != NULL) && (INCREASING_ID & pPSOVector->iSpsPpsIdStrategy)) {
353 const int32_t kiTmpSpsIdInBs = pPps->iSpsId +353 const int32_t kiTmpSpsIdInBs = pPps->iSpsId +
354 sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId];354 pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId];
355 const int32_t tmp_pps_id_in_bs = pPps->iPpsId +355 const int32_t tmp_pps_id_in_bs = pPps->iPpsId +
356 sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId];356 pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId];
357 assert (MAX_SPS_COUNT > kiTmpSpsIdInBs);357 assert (MAX_SPS_COUNT > kiTmpSpsIdInBs);
358 assert (MAX_PPS_COUNT > tmp_pps_id_in_bs);358 assert (MAX_PPS_COUNT > tmp_pps_id_in_bs);
359 assert (sPSOVector->sParaSetOffsetVariable[iParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]);359 assert (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]);
360 }360 }
361#endif361#endif
362 362
codec/encoder/core/src/encoder_ext.cpp+408−73
@@ -323,6 +323,12 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa · 322 unmodified lines
323 pCodingParam->bDeblockingParallelFlag = true;323 pCodingParam->bDeblockingParallelFlag = true;
324 }324 }
325 325
326 if (pCodingParam->iSpatialLayerNum > 1 && (SPS_LISTING & pCodingParam->iSpsPpsIdStrategy)) {
327 WelsLog (pLogCtx, WELS_LOG_INFO,
328 "ParamValidationExt(), iSpsPpsIdStrategy adjusted to CONSTANT_ID");
329 pCodingParam->iSpsPpsIdStrategy = CONSTANT_ID;
330 }
331
326 for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) {332 for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) {
327 SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i];333 SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i];
328 const int32_t kiPicWidth = pSpatialLayer->iVideoWidth;334 const int32_t kiPicWidth = pSpatialLayer->iVideoWidth;
@@ -665,8 +671,12 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara · 336 unmodified lines
665 ++ iDIndex;671 ++ iDIndex;
666 } while (iDIndex < iNumDependencyLayers);672 } while (iDIndex < iNumDependencyLayers);
667 673
674 // count parasets
668 iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) +675 iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) +
669 iCountNumLayers; // plus iCountNumLayers for reserved application676 iCountNumLayers // plus iCountNumLayers for reserved application
677 + ((SPS_LISTING & pParam->iSpsPpsIdStrategy) ? MAX_SPS_COUNT : 0) //for Sps
678 + (((SPS_LISTING & pParam->iSpsPpsIdStrategy) && (iNumDependencyLayers > 1)) ? MAX_SPS_COUNT : 0) //for SubsetSps
679 + ((SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) ? MAX_PPS_COUNT : 0);
670 680
671 // to check number of layers / nals / slices dependencies, 12/8/2010681 // to check number of layers / nals / slices dependencies, 12/8/2010
672 if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) {682 if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) {
@@ -847,9 +857,9 @@ void FreeMbCache (SMbCache* pMbCache, CMemoryAlign* pMa) { · 174 unmodified lines
847 }857 }
848}858}
849 859
850int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,860static int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
851 const int32_t iDlayerCount, const int32_t kiSpsId,861 const int32_t iDlayerCount, const int32_t kiSpsId,
852 SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) {862 SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) {
853 int32_t iRet = 0;863 int32_t iRet = 0;
854 864
855 if (!kbUseSubsetSps) {865 if (!kbUseSubsetSps) {
@@ -866,9 +876,6 @@ int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const · 10 unmodified lines
866 iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,876 iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
867 pParam->iMaxNumRefFrame,877 pParam->iMaxNumRefFrame,
868 kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);878 kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
869
870
871
872 } else {879 } else {
873 iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,880 iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
874 pParam->iMaxNumRefFrame,881 pParam->iMaxNumRefFrame,
@@ -877,12 +884,131 @@ int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const · 2 unmodified lines
877 return iRet;884 return iRet;
878}885}
879 886
887static bool CheckMatchedSps (SWelsSPS* const pSps1, SWelsSPS* const pSps2) {
888
889 if ((pSps1->iMbWidth != pSps2->iMbWidth)
890 || (pSps1->iMbHeight != pSps2->iMbHeight)) {
891 return false;
892 }
893
894 if ((pSps1->uiLog2MaxFrameNum != pSps2->uiLog2MaxFrameNum)
895 || (pSps1->iLog2MaxPocLsb != pSps2->iLog2MaxPocLsb)) {
896 return false;
897 }
898
899 if (pSps1->iNumRefFrames != pSps2->iNumRefFrames) {
900 return false;
901 }
902
903 if ((pSps1->bFrameCroppingFlag != pSps2->bFrameCroppingFlag)
904 || (pSps1->sFrameCrop.iCropLeft != pSps2->sFrameCrop.iCropLeft)
905 || (pSps1->sFrameCrop.iCropRight != pSps2->sFrameCrop.iCropRight)
906 || (pSps1->sFrameCrop.iCropTop != pSps2->sFrameCrop.iCropTop)
907 || (pSps1->sFrameCrop.iCropBottom != pSps2->sFrameCrop.iCropBottom)
908 ) {
909 return false;
910 }
911
912 if ((pSps1->uiProfileIdc != pSps2->uiProfileIdc)
913 || (pSps1->bConstraintSet0Flag != pSps2->bConstraintSet0Flag)
914 || (pSps1->bConstraintSet1Flag != pSps2->bConstraintSet1Flag)
915 || (pSps1->bConstraintSet2Flag != pSps2->bConstraintSet2Flag)
916 || (pSps1->bConstraintSet3Flag != pSps2->bConstraintSet3Flag)
917 || (pSps1->iLevelIdc != pSps2->iLevelIdc)) {
918 return false;
919 }
920
921 return true;
922}
923
924static bool CheckMatchedSubsetSps (SSubsetSps* const pSubsetSps1, SSubsetSps* const pSubsetSps2) {
925 if (!CheckMatchedSps (&pSubsetSps1->pSps, &pSubsetSps2->pSps)) {
926 return false;
927 }
928
929 if ((pSubsetSps1->sSpsSvcExt.iExtendedSpatialScalability != pSubsetSps2->sSpsSvcExt.iExtendedSpatialScalability)
930 || (pSubsetSps1->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag)
931 || (pSubsetSps1->sSpsSvcExt.bSeqTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bSeqTcoeffLevelPredFlag)
932 || (pSubsetSps1->sSpsSvcExt.bSliceHeaderRestrictionFlag != pSubsetSps2->sSpsSvcExt.bSliceHeaderRestrictionFlag)) {
933 return false;
934 }
935
936 return true;
937}
938
939int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
940 const int32_t iDlayerCount, const int32_t iSpsNumInUse,
941 SWelsSPS* pSpsArray,
942 SSubsetSps* pSubsetArray) {
943 SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
944
945 assert (iSpsNumInUse <= MAX_SPS_COUNT);
946 if (!kbUseSubsetSps) {
947 SWelsSPS sTmpSps;
948 WelsInitSps (&sTmpSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
949 pParam->iMaxNumRefFrame,
950 0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
951 for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
952 if (CheckMatchedSps (&sTmpSps, &pSpsArray[iId])) {
953 return iId;
954 }
955 }
956 } else {
957 SSubsetSps sTmpSubsetSps;
958 WelsInitSubsetSps (&sTmpSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
959 pParam->iMaxNumRefFrame,
960 0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE);
961
962 for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
963 if (CheckMatchedSubsetSps (&sTmpSubsetSps, &pSubsetArray[iId])) {
964 return iId;
965 }
966 }
967 }
968
969 return INVALID_ID;
970}
971
972int32_t FindExistingPps (SWelsSPS* pSps, SSubsetSps* pSubsetSps, const bool kbUseSubsetSps, const int32_t iSpsId,
973 const bool kbEntropyCodingFlag, const int32_t iPpsNumInUse,
974 SWelsPPS* pPpsArray) {
975#if !defined(DISABLE_FMO_FEATURE)
976 // feature not supported yet
977 return INVALID_ID;
978#endif//!DISABLE_FMO_FEATURE
979
980 SWelsPPS sTmpPps;
981 WelsInitPps (&sTmpPps,
982 pSps,
983 pSubsetSps,
984 0,
985 true,
986 kbUseSubsetSps,
987 kbEntropyCodingFlag);
988
989 assert (iPpsNumInUse <= MAX_PPS_COUNT);
990 for (int32_t iId = 0; iId < iPpsNumInUse; iId++) {
991 if ((sTmpPps.iSpsId == pPpsArray[iId].iSpsId)
992 && (sTmpPps.bEntropyCodingModeFlag == pPpsArray[iId].bEntropyCodingModeFlag)
993 && (sTmpPps.iPicInitQp == pPpsArray[iId].iPicInitQp)
994 && (sTmpPps.iPicInitQs == pPpsArray[iId].iPicInitQs)
995 && (sTmpPps.uiChromaQpIndexOffset == pPpsArray[iId].uiChromaQpIndexOffset)
996 && (sTmpPps.bDeblockingFilterControlPresentFlag == pPpsArray[iId].bDeblockingFilterControlPresentFlag)
997 ) {
998 return iId;
999 }
1000 }
1001
1002 return INVALID_ID;
1003}
1004
1005
880/*!1006/*!
881 * \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available1007 * \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available
882 * \pParam pCtx sWelsEncCtx*1008 * \pParam pCtx sWelsEncCtx*
883 * \return 0 - successful; otherwise failed1009 * \return 0 - successful; otherwise failed
884 */1010 */
885static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {1011static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList) {
886 SWelsSvcCodingParam* pParam = NULL;1012 SWelsSvcCodingParam* pParam = NULL;
887 SWelsSPS* pSps = NULL;1013 SWelsSPS* pSps = NULL;
888 SSubsetSps* pSubsetSps = NULL;1014 SSubsetSps* pSubsetSps = NULL;
@@ -1045,14 +1171,51 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { · 156 unmodified lines
1045 }1171 }
1046 1172
1047 // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/20101173 // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010
1048 (*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsPPS), "pPPSArray");1174 // SPS
1049 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))1175 if (! (SPS_LISTING & pParam->iSpsPpsIdStrategy)) {
1176 (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray");
1177 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
1178 if (iDlayerCount > 1) {
1179 (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray");
1180 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))
1181 }
1182 } else {
1183 // pParam->iSpsPpsIdStrategy == SPS_LISTING_AND_PPS_INCREASING
1184 // new memory
1185 (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "pSpsArray");
1186 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
1050 1187
1051 (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray");1188 (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "pSubsetArray");
1052 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
1053 if (iDlayerCount > 1) {
1054 (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray");
1055 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))1189 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))
1190
1191 // copy from existing if the pointer exists
1192 if (NULL != pExistingParasetList) {
1193 (*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum;
1194 (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum;
1195 memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS));
1196 memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps));
1197 }
1198 }
1199 // PPS
1200 if (! (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy)) {
1201 (*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsPPS), "pPPSArray");
1202 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
1203 } else {
1204 (*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMalloc (MAX_PPS_COUNT * sizeof (SWelsPPS), "pPPSArray");
1205 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
1206
1207
1208 // copy from existing if the pointer exists
1209 if (NULL != pExistingParasetList) {
1210 (*ppCtx)->sPSOVector.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum;
1211 memcpy ((*ppCtx)->pPPSArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
1212 }
1213 }
1214
1215 if (INCREASING_ID & pParam->iSpsPpsIdStrategy) {
1216 (*ppCtx)->pPSOVector = & ((*ppCtx)->sPSOVector);
1217 } else {
1218 (*ppCtx)->pPSOVector = NULL;
1056 }1219 }
1057 1220
1058 (*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap");1221 (*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap");
@@ -1066,12 +1229,79 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { · 7 unmodified lines
1066 1229
1067 pDqIdc->uiSpatialId = iDlayerIndex;1230 pDqIdc->uiSpatialId = iDlayerIndex;
1068 1231
1069 WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,1232 if (! (SPS_LISTING & pParam->iSpsPpsIdStrategy)) {
1070 iDlayerCount, iSpsId, pSps, pSubsetSps);1233 WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
1234 iDlayerCount, iSpsId, pSps, pSubsetSps);
1235 } else {
1236 //SPS_LISTING_AND_PPS_INCREASING == pParam->iSpsPpsIdStrategy
1237 //check if the current param can fit in an existing SPS
1238 const int32_t kiFoundSpsId = FindExistingSps ((*ppCtx)->pSvcParam, bUseSubsetSps, iDlayerIndex, iDlayerCount,
1239 bUseSubsetSps ? ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum) : ((*ppCtx)->sPSOVector.uiInUseSpsNum),
1240 (*ppCtx)->pSpsArray,
1241 (*ppCtx)->pSubsetArray);
1242
1243
1244 if (INVALID_ID != kiFoundSpsId) {
1245 //if yes, set pSps or pSubsetSps to it
1246 iSpsId = kiFoundSpsId;
1247 if (!bUseSubsetSps) {
1248 pSps = & ((*ppCtx)->pSpsArray[kiFoundSpsId]);
1249 } else {
1250 pSubsetSps = & ((*ppCtx)->pSubsetArray[kiFoundSpsId]);
1251 }
1252 } else {
1253 //if no, generate a new SPS as usual
1254 if ((SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) && (MAX_PPS_COUNT <= (*ppCtx)->sPSOVector.uiInUsePpsNum)) {
1255 //check if we can generate new SPS or not
1256 WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
1257 "InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
1258 return ENC_RETURN_UNSUPPORTED_PARA;
1259 }
1071 1260
1072 pPps = & (*ppCtx)->pPPSArray[iPpsId];1261 iSpsId = (!bUseSubsetSps) ? ((*ppCtx)->sPSOVector.uiInUseSpsNum++) : ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum++);
1073 // initialize pPps1262 if (iSpsId >= MAX_SPS_COUNT) {
1074 WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);1263 if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) {
1264 WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
1265 "InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
1266 return ENC_RETURN_UNSUPPORTED_PARA;
1267 }
1268 // reset current list
1269 if (!bUseSubsetSps) {
1270 (*ppCtx)->sPSOVector.uiInUseSpsNum = 1;
1271 memset ((*ppCtx)->pSpsArray, 0, MAX_SPS_COUNT * sizeof (SWelsSPS));
1272 } else {
1273 (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = 1;
1274 memset ((*ppCtx)->pSubsetArray, 0, MAX_SPS_COUNT * sizeof (SSubsetSps));
1275 }
1276 iSpsId = 0;
1277 }
1278
1279 WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
1280 iDlayerCount, iSpsId, pSps, pSubsetSps);
1281 }
1282 }
1283
1284 if (! (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy)) {
1285 pPps = & (*ppCtx)->pPPSArray[iPpsId];
1286 // initialize pPps
1287 WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
1288 } else {
1289 const int32_t kiFoundPpsId = FindExistingPps (pSps, pSubsetSps, bUseSubsetSps, iSpsId,
1290 pParam->iEntropyCodingModeFlag != 0,
1291 (*ppCtx)->sPSOVector.uiInUsePpsNum,
1292 (*ppCtx)->pPPSArray);
1293
1294
1295 if (INVALID_ID != kiFoundPpsId) {
1296 //if yes, set pPps to it
1297 iPpsId = kiFoundPpsId;
1298 pPps = & ((*ppCtx)->pPPSArray[kiFoundPpsId]);
1299 } else {
1300 iPpsId = ((*ppCtx)->sPSOVector.uiInUsePpsNum++);
1301 pPps = & (*ppCtx)->pPPSArray[iPpsId];
1302 WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
1303 }
1304 }
1075 1305
1076 // Not using FMO in SVC coding so far, come back if need FMO1306 // Not using FMO in SVC coding so far, come back if need FMO
1077 {1307 {
@@ -1085,7 +1315,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { · 7 unmodified lines
1085 if (iResult) {1315 if (iResult) {
1086 WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult);1316 WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult);
1087 FreeMemorySvc (ppCtx);1317 FreeMemorySvc (ppCtx);
1088 return 1;1318 return iResult;
1089 }1319 }
1090 (*ppCtx)->ppDqLayerList[iDlayerIndex]->pSliceEncCtx = & (*ppCtx)->pSliceCtxList[iDlayerIndex];1320 (*ppCtx)->ppDqLayerList[iDlayerIndex]->pSliceEncCtx = & (*ppCtx)->pSliceCtxList[iDlayerIndex];
1091 }1321 }
@@ -1097,12 +1327,23 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { · 5 unmodified lines
1097 if (bUseSubsetSps)1327 if (bUseSubsetSps)
1098 ++ iSpsId;1328 ++ iSpsId;
1099 ++ iPpsId;1329 ++ iPpsId;
1100 ++ (*ppCtx)->iSpsNum;1330 if (bUseSubsetSps) {
1331 ++ (*ppCtx)->iSubsetSpsNum;
1332 } else {
1333 ++ (*ppCtx)->iSpsNum;
1334 }
1101 ++ (*ppCtx)->iPpsNum;1335 ++ (*ppCtx)->iPpsNum;
1102 1336
1103 ++ iDlayerIndex;1337 ++ iDlayerIndex;
1104 }1338 }
1105 return 0;1339 if (SPS_LISTING & pParam->iSpsPpsIdStrategy) {
1340 (*ppCtx)->iSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
1341 (*ppCtx)->iSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
1342 }
1343 if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) {
1344 (*ppCtx)->iPpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum;
1345 }
1346 return ENC_RETURN_SUCCESS;
1106}1347}
1107 1348
1108int32_t AllocStrideTables (sWelsEncCtx** ppCtx, const int32_t kiNumSpatialLayers) {1349int32_t AllocStrideTables (sWelsEncCtx** ppCtx, const int32_t kiNumSpatialLayers) {
@@ -1411,7 +1652,7 @@ void GetMvMvdRange (SWelsSvcCodingParam* pParam, int32_t& iMvRange, int32_t& iMv · 302 unmodified lines
1411 1652
1412 iMvdRange = WELS_MIN (iMvdRange, iFixMvdRange);1653 iMvdRange = WELS_MIN (iMvdRange, iFixMvdRange);
1413}1654}
1414int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {1655int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList) {
1415 SWelsSvcCodingParam* pParam = (*ppCtx)->pSvcParam;1656 SWelsSvcCodingParam* pParam = (*ppCtx)->pSvcParam;
1416 CMemoryAlign* pMa = (*ppCtx)->pMemAlign;1657 CMemoryAlign* pMa = (*ppCtx)->pMemAlign;
1417 SSpatialLayerConfig* pFinalSpatial = NULL;1658 SSpatialLayerConfig* pFinalSpatial = NULL;
@@ -1616,7 +1857,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) { · 198 unmodified lines
1616 1857
1617 //End of pVaa memory allocation1858 //End of pVaa memory allocation
1618 1859
1619 iResult = InitDqLayers (ppCtx);1860 iResult = InitDqLayers (ppCtx, pExistingParasetList);
1620 if (iResult) {1861 if (iResult) {
1621 WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult);1862 WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult);
1622 FreeMemorySvc (ppCtx);1863 FreeMemorySvc (ppCtx);
@@ -2130,7 +2371,8 @@ int32_t GetMultipleThreadIdc (SLogContext* pLogCtx, SWelsSvcCodingParam* pCoding · 507 unmodified lines
2130 * \pParam pParam SWelsSvcCodingParam*2371 * \pParam pParam SWelsSvcCodingParam*
2131 * \return successful - 0; otherwise none 0 for failed2372 * \return successful - 0; otherwise none 0 for failed
2132 */2373 */
2133int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx) {2374int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx,
2375 SExistingParasetList* pExistingParasetList) {
2134 sWelsEncCtx* pCtx = NULL;2376 sWelsEncCtx* pCtx = NULL;
2135 int32_t iRet = 0;2377 int32_t iRet = 0;
2136 int16_t iSliceNum = 1; // number of slices used2378 int16_t iSliceNum = 1; // number of slices used
@@ -2189,7 +2431,7 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar · 52 unmodified lines
2189 2431
2190 pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum;2432 pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum;
2191 pCtx->iMaxSliceCount = iSliceNum;2433 pCtx->iMaxSliceCount = iSliceNum;
2192 iRet = RequestMemorySvc (&pCtx);2434 iRet = RequestMemorySvc (&pCtx, pExistingParasetList);
2193 if (iRet != 0) {2435 if (iRet != 0) {
2194 WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), RequestMemorySvc failed return %d.", iRet);2436 WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), RequestMemorySvc failed return %d.", iRet);
2195 FreeMemorySvc (&pCtx);2437 FreeMemorySvc (&pCtx);
@@ -2553,18 +2795,26 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx, · 357 unmodified lines
2553 iSliceCount = GetCurrentSliceNum (pCurDq->pSliceEncCtx);2795 iSliceCount = GetCurrentSliceNum (pCurDq->pSliceEncCtx);
2554 assert (iSliceCount > 0);2796 assert (iSliceCount > 0);
2555 2797
2556 pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = pDqIdc->iPpsId;2798 int32_t iCurPpsId = pDqIdc->iPpsId;
2799 int32_t iCurSpsId = pDqIdc->iSpsId;
2800
2801 if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) {
2802 iCurPpsId = pCtx->sPSOVector.iPpsIdList[pDqIdc->iPpsId][WELS_ABS (pCtx->uiIdrPicId - 1) % MAX_PPS_COUNT];
2803 }
2804
2805 pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = iCurPpsId;
2557 pCurDq->sLayerInfo.pPpsP =2806 pCurDq->sLayerInfo.pPpsP =
2558 pBaseSlice->sSliceHeaderExt.sSliceHeader.pPps = &pCtx->pPPSArray[pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId];2807 pBaseSlice->sSliceHeaderExt.sSliceHeader.pPps = &pCtx->pPPSArray[iCurPpsId];
2559 pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId = pDqIdc->iSpsId;2808
2809 pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId = iCurSpsId;
2560 if (kbUseSubsetSpsFlag) {2810 if (kbUseSubsetSpsFlag) {
2561 pCurDq->sLayerInfo.pSubsetSpsP = &pCtx->pSubsetArray[pDqIdc->iSpsId];2811 pCurDq->sLayerInfo.pSubsetSpsP = &pCtx->pSubsetArray[iCurSpsId];
2562 pCurDq->sLayerInfo.pSpsP =2812 pCurDq->sLayerInfo.pSpsP =
2563 pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCurDq->sLayerInfo.pSubsetSpsP->pSps;2813 pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCurDq->sLayerInfo.pSubsetSpsP->pSps;
2564 } else {2814 } else {
2565 pCurDq->sLayerInfo.pSubsetSpsP = NULL;2815 pCurDq->sLayerInfo.pSubsetSpsP = NULL;
2566 pCurDq->sLayerInfo.pSpsP =2816 pCurDq->sLayerInfo.pSpsP =
2567 pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCtx->pSpsArray[pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId];2817 pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCtx->pSpsArray[iCurSpsId];
2568 }2818 }
2569 2819
2570 pSlice = pBaseSlice;2820 pSlice = pBaseSlice;
@@ -2865,46 +3115,68 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 294 unmodified lines
2865 /* write all SPS */3115 /* write all SPS */
2866 iIdx = 0;3116 iIdx = 0;
2867 while (iIdx < pCtx->iSpsNum) {3117 while (iIdx < pCtx->iSpsNum) {
2868 SDqIdc* pDqIdc = &pCtx->pDqIdcMap[iIdx];
2869 const int32_t kiDid = pDqIdc->uiSpatialId;
2870 const bool kbUsingSubsetSps = (kiDid > BASE_DEPENDENCY_ID);
2871
2872 iNal = pCtx->pOut->iNalIndex;3118 iNal = pCtx->pOut->iNalIndex;
2873 3119
2874 if (pCtx->pSvcParam->bEnableSpsPpsIdAddition) {3120 if (INCREASING_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) {
2875#if _DEBUG3121#if _DEBUG
2876 pCtx->sPSOVector.bEnableSpsPpsIdAddition = 1;3122 pCtx->sPSOVector.iSpsPpsIdStrategy = INCREASING_ID;
2877 assert (kiDid < MAX_DEPENDENCY_LAYER);
2878 assert (iIdx < MAX_DQ_LAYER_NUM);3123 assert (iIdx < MAX_DQ_LAYER_NUM);
2879#endif3124#endif
2880 3125
2881 ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[kbUsingSubsetSps ? PARA_SET_TYPE_SUBSETSPS :3126 ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS]),
2882 PARA_SET_TYPE_AVCSPS]),3127 pCtx->pSpsArray[0].uiSpsId,
2883 (kbUsingSubsetSps) ? (pCtx->pSubsetArray[iIdx - 1].pSps.uiSpsId) : (pCtx->pSpsArray[0].uiSpsId),
2884 MAX_SPS_COUNT);3128 MAX_SPS_COUNT);
2885 } else {3129 } else if (CONSTANT_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) {
2886 memset (& (pCtx->sPSOVector), 0, sizeof (pCtx->sPSOVector));3130 memset (& (pCtx->sPSOVector), 0, sizeof (pCtx->sPSOVector));
2887 }3131 }
2888 3132
2889 if (kbUsingSubsetSps) {3133 /* generate sequence parameters set */
2890 iId = iIdx - 1;3134 iId = (SPS_LISTING & pCtx->pSvcParam->iSpsPpsIdStrategy) ? iIdx : 0;
2891 3135
2892 /* generate Subset SPS */3136 WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST);
2893 WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST);3137 WelsWriteSpsNal (&pCtx->pSpsArray[iId], &pCtx->pOut->sBsWrite,
3138 & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0]));
3139 WelsUnloadNal (pCtx->pOut);
2894 3140
2895 WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite,3141 iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
2896 & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0]));3142 pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length
2897 WelsUnloadNal (pCtx->pOut);3143 pCtx->pFrameBs + pCtx->iPosBsBuffer,
2898 } else {3144 &iNalLength);
2899 iId = 0;3145 WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
3146 pNalLen[iCountNal] = iNalLength;
2900 3147
2901 /* generate sequence parameters set */3148 pCtx->iPosBsBuffer += iNalLength;
2902 WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST);3149 iSize += iNalLength;
2903 WelsWriteSpsNal (&pCtx->pSpsArray[0], &pCtx->pOut->sBsWrite,3150
2904 & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0]));3151 ++ iIdx;
2905 WelsUnloadNal (pCtx->pOut);3152 ++ iCountNal;
3153 }
3154
3155 /* write all Subset SPS */
3156 iIdx = 0;
3157 while (iIdx < pCtx->iSubsetSpsNum) {
3158 iNal = pCtx->pOut->iNalIndex;
3159
3160 if (INCREASING_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) {
3161#if _DEBUG
3162 pCtx->sPSOVector.iSpsPpsIdStrategy = INCREASING_ID;
3163 assert (iIdx < MAX_DQ_LAYER_NUM);
3164#endif
3165
3166 ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS]),
3167 pCtx->pSubsetArray[iIdx].pSps.uiSpsId,
3168 MAX_SPS_COUNT);
2906 }3169 }
2907 3170
3171 iId = iIdx;
3172
3173 /* generate Subset SPS */
3174 WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST);
3175
3176 WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite,
3177 & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0]));
3178 WelsUnloadNal (pCtx->pOut);
3179
2908 iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,3180 iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
2909 pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length3181 pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length
2910 pCtx->pFrameBs + pCtx->iPosBsBuffer,3182 pCtx->pFrameBs + pCtx->iPosBsBuffer,
@@ -2921,8 +3193,30 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 10 unmodified lines
2921 3193
2922 /* write all PPS */3194 /* write all PPS */
2923 iIdx = 0;3195 iIdx = 0;
3196 if ((SPS_PPS_LISTING == pCtx->pSvcParam->iSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) {
3197 assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM);
3198
3199 //Generate PPS LIST
3200 int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum;
3201
3202 for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) {
3203 for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) {
3204 pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT);
3205 }
3206 }
3207
3208 for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) {
3209 memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS));
3210 pCtx->pPPSArray[iPpsId].iPpsId = iPpsId;
3211 pCtx->iPpsNum++;
3212 }
3213
3214 assert (pCtx->iPpsNum == MAX_PPS_COUNT);
3215 pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum;
3216 }
3217
2924 while (iIdx < pCtx->iPpsNum) {3218 while (iIdx < pCtx->iPpsNum) {
2925 if (pCtx->pSvcParam->bEnableSpsPpsIdAddition) {3219 if ((INCREASING_ID & pCtx->pSvcParam->iSpsPpsIdStrategy)) {
2926 //para_set_type = 2: PPS, use MAX_PPS_COUNT3220 //para_set_type = 2: PPS, use MAX_PPS_COUNT
2927 ParasetIdAdditionIdAdjust (&pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS], pCtx->pPPSArray[iIdx].iPpsId,3221 ParasetIdAdditionIdAdjust (&pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS], pCtx->pPPSArray[iIdx].iPpsId,
2928 MAX_PPS_COUNT);3222 MAX_PPS_COUNT);
@@ -2931,7 +3225,8 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 2 unmodified lines
2931 iNal = pCtx->pOut->iNalIndex;3225 iNal = pCtx->pOut->iNalIndex;
2932 /* generate picture parameter set */3226 /* generate picture parameter set */
2933 WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST);3227 WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST);
2934 WelsWritePpsSyntax (&pCtx->pPPSArray[iIdx], &pCtx->pOut->sBsWrite, & (pCtx->sPSOVector));3228 WelsWritePpsSyntax (&pCtx->pPPSArray[iIdx], &pCtx->pOut->sBsWrite,
3229 ((SPS_PPS_LISTING != pCtx->pSvcParam->iSpsPpsIdStrategy)) ? (& (pCtx->sPSOVector)) : NULL);
2935 WelsUnloadNal (pCtx->pOut);3230 WelsUnloadNal (pCtx->pOut);
2936 3231
2937 iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,3232 iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
@@ -3237,7 +3532,6 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 299 unmodified lines
3237 iDidList[iSpatialIdx] = iCurDid;3532 iDidList[iSpatialIdx] = iCurDid;
3238 3533
3239 // Encoding this picture might mulitiple sQualityStat layers potentially be encoded as followed3534 // Encoding this picture might mulitiple sQualityStat layers potentially be encoded as followed
3240
3241 switch (pParam->sSliceCfg.uiSliceMode) {3535 switch (pParam->sSliceCfg.uiSliceMode) {
3242 case SM_FIXEDSLCNUM_SLICE:3536 case SM_FIXEDSLCNUM_SLICE:
3243 case SM_AUTO_SLICE: {3537 case SM_AUTO_SLICE: {
@@ -3829,7 +4123,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 585 unmodified lines
3829 (pOldParam->iLTRRefNum != pNewParam->iLTRRefNum) ||4123 (pOldParam->iLTRRefNum != pNewParam->iLTRRefNum) ||
3830 (pOldParam->iMultipleThreadIdc != pNewParam->iMultipleThreadIdc) ||4124 (pOldParam->iMultipleThreadIdc != pNewParam->iMultipleThreadIdc) ||
3831 (pOldParam->bEnableBackgroundDetection != pNewParam->bEnableBackgroundDetection) ||4125 (pOldParam->bEnableBackgroundDetection != pNewParam->bEnableBackgroundDetection) ||
3832 (pOldParam->bEnableAdaptiveQuant != pNewParam->bEnableAdaptiveQuant);4126 (pOldParam->bEnableAdaptiveQuant != pNewParam->bEnableAdaptiveQuant) ||
4127 (pOldParam->iSpsPpsIdStrategy != pNewParam->iSpsPpsIdStrategy);
3833 if (pNewParam->iMaxNumRefFrame > pOldParam->iMaxNumRefFrame) {4128 if (pNewParam->iMaxNumRefFrame > pOldParam->iMaxNumRefFrame) {
3834 bNeedReset = true;4129 bNeedReset = true;
3835 }4130 }
@@ -3876,35 +4171,75 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 40 unmodified lines
3876 }4171 }
3877 4172
3878 if (bNeedReset) {4173 if (bNeedReset) {
3879 SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE];
3880 uint16_t uiTmpIdrPicId;//this is for LTR!
3881 SLogContext sLogCtx = (*ppCtx)->sLogCtx;4174 SLogContext sLogCtx = (*ppCtx)->sLogCtx;
3882 for (int32_t k = 0; k < PARA_SET_TYPE; k++)4175
3883 memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool));4176 int32_t iOldSpsPpsIdStrategy = pOldParam->iSpsPpsIdStrategy;
3884 memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable,4177 SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE];
3885 (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage4178 int32_t iTmpPpsIdList[MAX_DQ_LAYER_NUM * MAX_PPS_COUNT];
3886 uiTmpIdrPicId = (*ppCtx)->uiIdrPicId;4179 uint16_t uiTmpIdrPicId = (*ppCtx)->uiIdrPicId;//this is for LTR!
3887 4180
3888 SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics;4181 SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics;
3889 4182
4183 SExistingParasetList sExistingParasetList;
4184 SExistingParasetList* pExistingParasetList = NULL;
4185
4186 if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->iSpsPpsIdStrategy)) {
4187 for (int32_t k = 0; k < PARA_SET_TYPE; k++) {
4188 memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool));
4189 }
4190 memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable,
4191 (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
4192
4193 if ((SPS_LISTING & iOldSpsPpsIdStrategy)
4194 && (SPS_LISTING & pNewParam->iSpsPpsIdStrategy)) {
4195 pExistingParasetList = &sExistingParasetList;
4196 sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
4197 sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
4198 memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
4199 memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
4200 }
4201
4202 if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy)
4203 && (SPS_PPS_LISTING == pNewParam->iSpsPpsIdStrategy)) {
4204 pExistingParasetList = &sExistingParasetList;
4205 sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
4206 sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
4207 sExistingParasetList.uiInUsePpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum;
4208 memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
4209 memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
4210 memcpy (sExistingParasetList.sPps, (*ppCtx)->pPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
4211
4212 memcpy (iTmpPpsIdList, ((*ppCtx)->sPSOVector.iPpsIdList), MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
4213 }
4214 }
4215
4216
3890 WelsUninitEncoderExt (ppCtx);4217 WelsUninitEncoderExt (ppCtx);
3891 4218
3892 /* Update new parameters */4219 /* Update new parameters */
3893 if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx))4220 if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx, pExistingParasetList))
3894 return 1;4221 return 1;
3895 4222
3896 // reset the scaled spatial picture size4223 // reset the scaled spatial picture size
3897 (*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);4224 (*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
3898 //if WelsInitEncoderExt succeed4225 //if WelsInitEncoderExt succeed
3899 4226
3900 //load back the needed structure
3901 //for FLEXIBLE_PARASET_ID
3902 memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
3903 (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
3904 //for LTR4227 //for LTR
3905 (*ppCtx)->uiIdrPicId = uiTmpIdrPicId;4228 (*ppCtx)->uiIdrPicId = uiTmpIdrPicId;
4229
3906 //for sEncoderStatistics4230 //for sEncoderStatistics
3907 (*ppCtx)->sEncoderStatistics = sTempEncoderStatistics;4231 (*ppCtx)->sEncoderStatistics = sTempEncoderStatistics;
4232
4233 //load back the needed structure for iSpsPpsIdStrategy
4234 if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->iSpsPpsIdStrategy)) {
4235 memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
4236 (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
4237 }
4238
4239 if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy)
4240 && (SPS_PPS_LISTING == pNewParam->iSpsPpsIdStrategy)) {
4241 memcpy (((*ppCtx)->sPSOVector.iPpsIdList), iTmpPpsIdList, MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
4242 }
3908 } else {4243 } else {
3909 /* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */4244 /* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */
3910 pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT,4245 pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT,
@@ -3919,7 +4254,7 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 8 unmodified lines
3919 pOldParam->fMaxFrameRate = pNewParam->fMaxFrameRate; // maximal frame rate [Hz / fps]4254 pOldParam->fMaxFrameRate = pNewParam->fMaxFrameRate; // maximal frame rate [Hz / fps]
3920 pOldParam->iComplexityMode = pNewParam->iComplexityMode; // color space of input sequence4255 pOldParam->iComplexityMode = pNewParam->iComplexityMode; // color space of input sequence
3921 pOldParam->uiIntraPeriod = pNewParam->uiIntraPeriod; // intra period (multiple of GOP size as desired)4256 pOldParam->uiIntraPeriod = pNewParam->uiIntraPeriod; // intra period (multiple of GOP size as desired)
3922 pOldParam->bEnableSpsPpsIdAddition = pNewParam->bEnableSpsPpsIdAddition;4257 pOldParam->iSpsPpsIdStrategy = pNewParam->iSpsPpsIdStrategy;
3923 pOldParam->bPrefixNalAddingCtrl = pNewParam->bPrefixNalAddingCtrl;4258 pOldParam->bPrefixNalAddingCtrl = pNewParam->bPrefixNalAddingCtrl;
3924 pOldParam->iNumRefFrame = pNewParam->iNumRefFrame; // number of reference frame used4259 pOldParam->iNumRefFrame = pNewParam->iNumRefFrame; // number of reference frame used
3925 pOldParam->uiGopSize = pNewParam->uiGopSize;4260 pOldParam->uiGopSize = pNewParam->uiGopSize;
codec/encoder/core/src/svc_encode_slice.cpp+10−7
@@ -237,7 +237,8 @@ void WriteRefPicMarking (SBitStringAux* pBs, SSliceHeader* pSliceHeader, SNalUni · 236 unmodified lines
237 }237 }
238}238}
239 239
240void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, int32_t* pPpsIdDelta) {240void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
241 int32_t* pPpsIdDelta) {
241 SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;242 SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
242 SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;243 SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
243 SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;244 SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
@@ -246,7 +247,7 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur · 2 unmodified lines
246 BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);247 BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
247 BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */248 BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
248 249
249 BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId]);250 BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + ((pPpsIdDelta != NULL) ? pPpsIdDelta[pSliceHeader->pPps->iPpsId] : 0));
250 251
251 BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);252 BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
252 253
@@ -301,7 +302,8 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur · 48 unmodified lines
301 }302 }
302}303}
303 304
304void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, int32_t* pPpsIdDelta) {305void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
306 int32_t* pPpsIdDelta) {
305 SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;307 SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
306 SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;308 SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
307 SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP;309 SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP;
@@ -312,7 +314,7 @@ void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* p · 4 unmodified lines
312 BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);314 BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
313 BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */315 BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
314 316
315 BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId]);317 BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + ((pPpsIdDelta != NULL) ? pPpsIdDelta[pSliceHeader->pPps->iPpsId] : 0));
316 318
317 BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);319 BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
318 320
@@ -727,11 +729,12 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const · 408 unmodified lines
727 729
728 WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice);730 WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice);
729 731
730
731 g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pEncCtx, pBs, pCurLayer, pCurSlice,732 g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pEncCtx, pBs, pCurLayer, pCurSlice,
732 & (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0]));733 ((SPS_PPS_LISTING != pEncCtx->pSvcParam->iSpsPpsIdStrategy) ? (&
734 (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0])) : NULL));
735
733#if _DEBUG736#if _DEBUG
734 if (pEncCtx->sPSOVector.bEnableSpsPpsIdAddition) {737 if (INCREASING_ID & pEncCtx->sPSOVector.iSpsPpsIdStrategy) {
735 const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId;738 const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId;
736 const int32_t kiTmpPpsIdInBs = kiEncoderPpsId +739 const int32_t kiTmpPpsIdInBs = kiEncoderPpsId +
737 pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ];740 pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ];
codec/encoder/plus/src/welsEncoderExt.cpp+29−10
@@ -332,7 +332,7 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) { · 331 unmodified lines
332 m_iMaxPicHeight = pCfg->iPicHeight;332 m_iMaxPicHeight = pCfg->iPicHeight;
333 333
334 TraceParamInfo (pCfg);334 TraceParamInfo (pCfg);
335 if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx)) {335 if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx, NULL)) {
336 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.");336 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.");
337 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG,337 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG,
338 "Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d",338 "Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d",
@@ -477,6 +477,7 @@ int CWelsH264SVCEncoder::ForceIntraFrame (bool bIDR) { · 138 unmodified lines
477 }477 }
478 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,478 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
479 "CWelsH264SVCEncoder::ForceIntraFrame(), bIDR= %d", bIDR);479 "CWelsH264SVCEncoder::ForceIntraFrame(), bIDR= %d", bIDR);
480
480 ForceCodingIDR (m_pEncContext);481 ForceCodingIDR (m_pEncContext);
481 482
482 m_pEncContext->sEncoderStatistics.uiIDRReqNum++;483 m_pEncContext->sEncoderStatistics.uiIDRReqNum++;
@@ -486,8 +487,8 @@ int CWelsH264SVCEncoder::ForceIntraFrame (bool bIDR) { · 3 unmodified lines
486void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {487void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
487 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,488 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
488 "iUsageType = %d,iPicWidth= %d;iPicHeight= %d;iTargetBitrate= %d;iMaxBitrate= %d;iRCMode= %d;iPaddingFlag= %d;iTemporalLayerNum= %d;iSpatialLayerNum= %d;fFrameRate= %.6ff;uiIntraPeriod= %d;\489 "iUsageType = %d,iPicWidth= %d;iPicHeight= %d;iTargetBitrate= %d;iMaxBitrate= %d;iRCMode= %d;iPaddingFlag= %d;iTemporalLayerNum= %d;iSpatialLayerNum= %d;fFrameRate= %.6ff;uiIntraPeriod= %d;\
489 bEnableSpsPpsIdAddition = %d;bPrefixNalAddingCtrl = %d;bEnableDenoise= %d;bEnableBackgroundDetection= %d;bEnableAdaptiveQuant= %d;bEnableFrameSkip= %d;bEnableLongTermReference= %d;iLtrMarkPeriod= %d;\490 iSpsPpsIdStrategy = %d;bPrefixNalAddingCtrl = %d;bEnableDenoise= %d;bEnableBackgroundDetection= %d;bEnableAdaptiveQuant= %d;bEnableFrameSkip= %d;bEnableLongTermReference= %d;iLtrMarkPeriod= %d;\
490 iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d",491 iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d (offset(alpha/beta): %d,%d)",
491 pParam->iUsageType,492 pParam->iUsageType,
492 pParam->iPicWidth,493 pParam->iPicWidth,
493 pParam->iPicHeight,494 pParam->iPicHeight,
@@ -499,7 +500,7 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { · 5 unmodified lines
499 pParam->iSpatialLayerNum,500 pParam->iSpatialLayerNum,
500 pParam->fMaxFrameRate,501 pParam->fMaxFrameRate,
501 pParam->uiIntraPeriod,502 pParam->uiIntraPeriod,
502 pParam->bEnableSpsPpsIdAddition,503 pParam->iSpsPpsIdStrategy,
503 pParam->bPrefixNalAddingCtrl,504 pParam->bPrefixNalAddingCtrl,
504 pParam->bEnableDenoise,505 pParam->bEnableDenoise,
505 pParam->bEnableBackgroundDetection,506 pParam->bEnableBackgroundDetection,
@@ -513,7 +514,9 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { · 7 unmodified lines
513 pParam->uiMaxNalSize,514 pParam->uiMaxNalSize,
514 pParam->iLTRRefNum,515 pParam->iLTRRefNum,
515 pParam->iMultipleThreadIdc,516 pParam->iMultipleThreadIdc,
516 pParam->iLoopFilterDisableIdc517 pParam->iLoopFilterDisableIdc,
518 pParam->iLoopFilterAlphaC0Offset,
519 pParam->iLoopFilterBetaOffset
517 );520 );
518 int32_t i = 0;521 int32_t i = 0;
519 int32_t iSpatialLayers = (pParam->iSpatialLayerNum < MAX_SPATIAL_LAYER_NUM) ? (pParam->iSpatialLayerNum) :522 int32_t iSpatialLayers = (pParam->iSpatialLayerNum < MAX_SPATIAL_LAYER_NUM) ? (pParam->iSpatialLayerNum) :
@@ -706,16 +709,26 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) { · 186 unmodified lines
706#endif//OUTPUT_BIT_STREAM709#endif//OUTPUT_BIT_STREAM
707 if (sEncodingParam.iSpatialLayerNum < 1710 if (sEncodingParam.iSpatialLayerNum < 1
708 || sEncodingParam.iSpatialLayerNum > MAX_SPATIAL_LAYER_NUM) { // verify number of spatial layer711 || sEncodingParam.iSpatialLayerNum > MAX_SPATIAL_LAYER_NUM) { // verify number of spatial layer
712 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
713 "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, iSpatialLayerNum(%d) failed!",
714 sEncodingParam.iSpatialLayerNum);
709 return cmInitParaError;715 return cmInitParaError;
710 }716 }
711 717
712 if (sConfig.ParamTranscode (sEncodingParam)) {718 if (sConfig.ParamTranscode (sEncodingParam)) {
719 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
720 "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, ParamTranscode failed!");
713 return cmInitParaError;721 return cmInitParaError;
714 }722 }
715 if (sConfig.iSpatialLayerNum < 1) {723 if (sConfig.iSpatialLayerNum < 1) {
724 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
725 "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, iSpatialLayerNum(%d) failed!",
726 sConfig.iSpatialLayerNum);
716 return cmInitParaError;727 return cmInitParaError;
717 }728 }
718 if (sConfig.DetermineTemporalSettings()) {729 if (sConfig.DetermineTemporalSettings()) {
730 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
731 "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, DetermineTemporalSettings failed!");
719 return cmInitParaError;732 return cmInitParaError;
720 }733 }
721 734
@@ -898,11 +911,17 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) { · 176 unmodified lines
898 }911 }
899 break;912 break;
900 case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: {913 case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: {
901 bool iValue = * ((bool*)pOption);914 int32_t iValue = * ((int32_t*)pOption);
902 915 if (((iValue > INCREASING_ID) || (m_pEncContext->pSvcParam->iSpsPpsIdStrategy > INCREASING_ID))
903 m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition = iValue;916 && m_pEncContext->pSvcParam->iSpsPpsIdStrategy != iValue) {
904 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable SPS/PPS ID = %d ",917 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR,
905 m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition);918 " CWelsH264SVCEncoder::SetOption iSpsPpsIdStrategy changing in the middle of call is NOT allowed for iSpsPpsIdStrategy>INCREASING_ID: existing setting is %d and the new one is %d",
919 m_pEncContext->pSvcParam->iSpsPpsIdStrategy, iValue);
920 return cmInitParaError;
921 }
922 m_pEncContext->pSvcParam->iSpsPpsIdStrategy = iValue;
923 WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption iSpsPpsIdStrategy = %d ",
924 m_pEncContext->pSvcParam->iSpsPpsIdStrategy);
906 }925 }
907 break;926 break;
908 case ENCODER_OPTION_CURRENT_PATH: {927 case ENCODER_OPTION_CURRENT_PATH: {
test/api/encode_decode_api_test.cpp+506−48
@@ -88,26 +88,25 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar · 87 unmodified lines
88 BaseDecoderTest::TearDown();88 BaseDecoderTest::TearDown();
89 }89 }
90 90
91 virtual void prepareParam (int iLayers, int iSlices, int width, int height, float framerate) {91 virtual void prepareParam (int iLayers, int iSlices, int width, int height, float framerate, SEncParamExt* pParam) {
92 memset (&param_, 0, sizeof (SEncParamExt));92 memset (pParam, 0, sizeof (SEncParamExt));
93 param_.iUsageType = CAMERA_VIDEO_REAL_TIME;93 pParam->iUsageType = CAMERA_VIDEO_REAL_TIME;
94 param_.iPicWidth = width;94 pParam->iPicWidth = width;
95 param_.iPicHeight = height;95 pParam->iPicHeight = height;
96 param_.fMaxFrameRate = framerate;96 pParam->fMaxFrameRate = framerate;
97 param_.iRCMode = RC_OFF_MODE; //rc off97 pParam->iRCMode = RC_OFF_MODE; //rc off
98 param_.iMultipleThreadIdc = 1; //single thread98 pParam->iMultipleThreadIdc = 1; //single thread
99 param_.iSpatialLayerNum = iLayers;99 pParam->iSpatialLayerNum = iLayers;
100 param_.iNumRefFrame = AUTO_REF_PIC_COUNT;100 pParam->iNumRefFrame = AUTO_REF_PIC_COUNT;
101 for (int i = 0; i < iLayers; i++) {101 for (int i = 0; i < iLayers; i++) {
102 param_.sSpatialLayers[i].iVideoWidth = width >> (iLayers - i - 1);102 pParam->sSpatialLayers[i].iVideoWidth = width >> (iLayers - i - 1);
103 param_.sSpatialLayers[i].iVideoHeight = height >> (iLayers - i - 1);103 pParam->sSpatialLayers[i].iVideoHeight = height >> (iLayers - i - 1);
104 param_.sSpatialLayers[i].fFrameRate = framerate;104 pParam->sSpatialLayers[i].fFrameRate = framerate;
105 param_.sSpatialLayers[i].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;105 pParam->sSpatialLayers[i].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
106 param_.sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceNum = iSlices;106 pParam->sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceNum = iSlices;
107 }107 }
108
109
110 }108 }
109
111 virtual void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) {110 virtual void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) {
112 //for encoder111 //for encoder
113 //I420: 1(Y) + 1/4(U) + 1/4(V)112 //I420: 1(Y) + 1/4(U) + 1/4(V)
@@ -147,6 +146,15 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar · 33 unmodified lines
147 len = layerInfo.pNalLengthInByte[iSliceNum];146 len = layerInfo.pNalLengthInByte[iSliceNum];
148 }147 }
149 148
149
150 virtual int GetRandWidth() {
151 return (WELS_CLIP3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 2, MAX_WIDTH));
152 }
153
154 virtual int GetRandHeight() {
155 return (WELS_CLIP3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 2, MAX_HEIGHT));
156 }
157
150 protected:158 protected:
151 SEncParamExt param_;159 SEncParamExt param_;
152 BufferedData buf_;160 BufferedData buf_;
@@ -171,8 +179,8 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase { · 18 unmodified lines
171 EncodeDecodeTestBase::TearDown();179 EncodeDecodeTestBase::TearDown();
172 }180 }
173 181
174 void prepareParam (int iLayers, int iSlices, int width, int height, float framerate) {182 void prepareParam (int iLayers, int iSlices, int width, int height, float framerate, SEncParamExt* pParam) {
175 EncodeDecodeTestBase::prepareParam (iLayers, iSlices, width, height, framerate);183 EncodeDecodeTestBase::prepareParam (iLayers, iSlices, width, height, framerate, pParam);
176 }184 }
177 185
178 void InitialEncDec (int iWidth, int iHeight);186 void InitialEncDec (int iWidth, int iHeight);
@@ -192,6 +200,24 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase { · 13 unmodified lines
192 else if (1 == iCheckTypeIndex)200 else if (1 == iCheckTypeIndex)
193 ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason);201 ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason);
194 }202 }
203
204 void EncDecOneFrame (const int iWidth, const int iHeight, const int iFrame, FILE* pfEnc) {
205 int iLen = 0, rv;
206 InitialEncDec (iWidth, iHeight);
207 EncodeOneFrame (iFrame);
208
209 //extract target layer data
210 encToDecData (info, iLen);
211 //call decoder
212 unsigned char* pData[3] = { NULL };
213 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
214 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iLen, pData, &dstBufInfo_);
215 EXPECT_TRUE (rv == cmResultSuccess) << " rv = " << rv << " iFrameIdx = " << iFrame;
216
217 if (NULL != pfEnc) {
218 fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, pfEnc);
219 }
220 }
195};221};
196 222
197void EncodeDecodeTestAPI::InitialEncDec (int iWidth, int iHeight) {223void EncodeDecodeTestAPI::InitialEncDec (int iWidth, int iHeight) {
@@ -234,7 +260,7 @@ void EncodeDecodeTestAPI::RandomParamExtCombination() { · 36 unmodified lines
234 param_.iNumRefFrame = AUTO_REF_PIC_COUNT;260 param_.iNumRefFrame = AUTO_REF_PIC_COUNT;
235 param_.iMultipleThreadIdc = rand();261 param_.iMultipleThreadIdc = rand();
236 262
237 param_.bEnableSpsPpsIdAddition = (rand() % 2 == 0) ? false : true;263 param_.iSpsPpsIdStrategy = rand() % 3;
238 param_.bPrefixNalAddingCtrl = (rand() % 2 == 0) ? false : true;264 param_.bPrefixNalAddingCtrl = (rand() % 2 == 0) ? false : true;
239 param_.bEnableSSEI = (rand() % 2 == 0) ? false : true;265 param_.bEnableSSEI = (rand() % 2 == 0) ? false : true;
240 param_.iPaddingFlag = rand() % 2;266 param_.iPaddingFlag = rand() % 2;
@@ -462,7 +488,7 @@ static const EncodeDecodeFileParamBase kFileParamArray[] = { · 221 unmodified lines
462 488
463TEST_P (EncodeDecodeTestAPI, DecoderVclNal) {489TEST_P (EncodeDecodeTestAPI, DecoderVclNal) {
464 EncodeDecodeFileParamBase p = GetParam();490 EncodeDecodeFileParamBase p = GetParam();
465 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);491 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
466 encoder_->Uninitialize();492 encoder_->Uninitialize();
467 int rv = encoder_->InitializeExt (&param_);493 int rv = encoder_->InitializeExt (&param_);
468 ASSERT_TRUE (rv == cmResultSuccess);494 ASSERT_TRUE (rv == cmResultSuccess);
@@ -498,7 +524,7 @@ TEST_P (EncodeDecodeTestAPI, DecoderVclNal) { · 29 unmodified lines
498 524
499TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) {525TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) {
500 EncodeDecodeFileParamBase p = GetParam();526 EncodeDecodeFileParamBase p = GetParam();
501 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);527 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
502 encoder_->Uninitialize();528 encoder_->Uninitialize();
503 int rv = encoder_->InitializeExt (&param_);529 int rv = encoder_->InitializeExt (&param_);
504 ASSERT_TRUE (rv == cmResultSuccess);530 ASSERT_TRUE (rv == cmResultSuccess);
@@ -535,7 +561,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) { · 30 unmodified lines
535 561
536TEST_P (EncodeDecodeTestAPI, GetOptionIDR) {562TEST_P (EncodeDecodeTestAPI, GetOptionIDR) {
537 EncodeDecodeFileParamBase p = GetParam();563 EncodeDecodeFileParamBase p = GetParam();
538 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);564 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
539 encoder_->Uninitialize();565 encoder_->Uninitialize();
540 int rv = encoder_->InitializeExt (&param_);566 int rv = encoder_->InitializeExt (&param_);
541 ASSERT_TRUE (rv == cmResultSuccess);567 ASSERT_TRUE (rv == cmResultSuccess);
@@ -554,7 +580,8 @@ TEST_P (EncodeDecodeTestAPI, GetOptionIDR) { · 12 unmodified lines
554 int32_t iSpsPpsIdAddition = 0;580 int32_t iSpsPpsIdAddition = 0;
555 int iIdx = 0;581 int iIdx = 0;
556 while (iIdx <= p.numframes) {582 while (iIdx <= p.numframes) {
557 iSpsPpsIdAddition = rand() % 2;583 iSpsPpsIdAddition = rand() %
584 2; //the current strategy supports more than 2 modes, but the switch between the modes>2 is not allowed
558 iIDRPeriod = (rand() % 150) + 1;585 iIDRPeriod = (rand() % 150) + 1;
559 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);586 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
560 encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition);587 encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition);
@@ -776,7 +803,7 @@ int SimulateNALLoss (const unsigned char* pSrc, int& iSrcLen, std::vector<SLost · 215 unmodified lines
776 803
777TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) {804TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) {
778 EncodeDecodeFileParamBase p = GetParam();805 EncodeDecodeFileParamBase p = GetParam();
779 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);806 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
780 encoder_->Uninitialize();807 encoder_->Uninitialize();
781 int rv = encoder_->InitializeExt (&param_);808 int rv = encoder_->InitializeExt (&param_);
782 ASSERT_TRUE (rv == cmResultSuccess);809 ASSERT_TRUE (rv == cmResultSuccess);
@@ -809,7 +836,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLLTR) { · 26 unmodified lines
809 SLTRMarkingFeedback m_LTR_Marking_Feedback;836 SLTRMarkingFeedback m_LTR_Marking_Feedback;
810 SLTRRecoverRequest m_LTR_Recover_Request;837 SLTRRecoverRequest m_LTR_Recover_Request;
811 EncodeDecodeFileParamBase p = GetParam();838 EncodeDecodeFileParamBase p = GetParam();
812 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);839 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
813 encoder_->Uninitialize();840 encoder_->Uninitialize();
814 int rv = encoder_->InitializeExt (&param_);841 int rv = encoder_->InitializeExt (&param_);
815 ASSERT_TRUE (rv == cmResultSuccess);842 ASSERT_TRUE (rv == cmResultSuccess);
@@ -868,7 +895,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_Engine) { · 52 unmodified lines
868 SLTRRecoverRequest m_LTR_Recover_Request;895 SLTRRecoverRequest m_LTR_Recover_Request;
869 m_LTR_Recover_Request.uiIDRPicId = 0;896 m_LTR_Recover_Request.uiIDRPicId = 0;
870 EncodeDecodeFileParamBase p = GetParam();897 EncodeDecodeFileParamBase p = GetParam();
871 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);898 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
872 encoder_->Uninitialize();899 encoder_->Uninitialize();
873 int rv = encoder_->InitializeExt (&param_);900 int rv = encoder_->InitializeExt (&param_);
874 ASSERT_TRUE (rv == cmResultSuccess);901 ASSERT_TRUE (rv == cmResultSuccess);
@@ -918,7 +945,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_DISABLE) { · 43 unmodified lines
918 SLTRRecoverRequest m_LTR_Recover_Request;945 SLTRRecoverRequest m_LTR_Recover_Request;
919 m_LTR_Recover_Request.uiIDRPicId = 0;946 m_LTR_Recover_Request.uiIDRPicId = 0;
920 EncodeDecodeFileParamBase p = GetParam();947 EncodeDecodeFileParamBase p = GetParam();
921 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);948 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
922 param_.bEnableLongTermReference = true;949 param_.bEnableLongTermReference = true;
923 param_.iLTRRefNum = 1;950 param_.iLTRRefNum = 1;
924 encoder_->Uninitialize();951 encoder_->Uninitialize();
@@ -985,7 +1012,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) { · 60 unmodified lines
985 SLTRRecoverRequest m_LTR_Recover_Request;1012 SLTRRecoverRequest m_LTR_Recover_Request;
986 m_LTR_Recover_Request.uiIDRPicId = 0;1013 m_LTR_Recover_Request.uiIDRPicId = 0;
987 EncodeDecodeFileParamBase p = GetParam();1014 EncodeDecodeFileParamBase p = GetParam();
988 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);1015 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
989 encoder_->Uninitialize();1016 encoder_->Uninitialize();
990 int rv = encoder_->InitializeExt (&param_);1017 int rv = encoder_->InitializeExt (&param_);
991 ASSERT_TRUE (rv == cmResultSuccess);1018 ASSERT_TRUE (rv == cmResultSuccess);
@@ -1036,7 +1063,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) { · 44 unmodified lines
1036 1063
1037TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) {1064TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) {
1038 EncodeDecodeFileParamBase p = GetParam();1065 EncodeDecodeFileParamBase p = GetParam();
1039 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);1066 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
1040 encoder_->Uninitialize();1067 encoder_->Uninitialize();
1041 int rv = encoder_->InitializeExt (&param_);1068 int rv = encoder_->InitializeExt (&param_);
1042 ASSERT_TRUE (rv == cmResultSuccess);1069 ASSERT_TRUE (rv == cmResultSuccess);
@@ -1086,7 +1113,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_NOPREFIX) { · 43 unmodified lines
1086 SLTRRecoverRequest m_LTR_Recover_Request;1113 SLTRRecoverRequest m_LTR_Recover_Request;
1087 m_LTR_Recover_Request.uiIDRPicId = 0;1114 m_LTR_Recover_Request.uiIDRPicId = 0;
1088 EncodeDecodeFileParamBase p = GetParam();1115 EncodeDecodeFileParamBase p = GetParam();
1089 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);1116 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
1090 param_.bPrefixNalAddingCtrl = false;1117 param_.bPrefixNalAddingCtrl = false;
1091 param_.iTemporalLayerNum = (rand() % 4) + 1;1118 param_.iTemporalLayerNum = (rand() % 4) + 1;
1092 encoder_->Uninitialize();1119 encoder_->Uninitialize();
@@ -1155,7 +1182,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_WITH_PREFIX_NOLOSS) { · 62 unmodified lines
1155 SLTRRecoverRequest m_LTR_Recover_Request;1182 SLTRRecoverRequest m_LTR_Recover_Request;
1156 m_LTR_Recover_Request.uiIDRPicId = 0;1183 m_LTR_Recover_Request.uiIDRPicId = 0;
1157 EncodeDecodeFileParamBase p = GetParam();1184 EncodeDecodeFileParamBase p = GetParam();
1158 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);1185 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
1159 param_.bPrefixNalAddingCtrl = true;1186 param_.bPrefixNalAddingCtrl = true;
1160 param_.iTemporalLayerNum = (rand() % 4) + 1;1187 param_.iTemporalLayerNum = (rand() % 4) + 1;
1161 param_.iSpatialLayerNum = 1;1188 param_.iSpatialLayerNum = 1;
@@ -1210,7 +1237,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_SVC_L1_NOLOSS) { · 48 unmodified lines
1210 SLTRRecoverRequest m_LTR_Recover_Request;1237 SLTRRecoverRequest m_LTR_Recover_Request;
1211 m_LTR_Recover_Request.uiIDRPicId = 0;1238 m_LTR_Recover_Request.uiIDRPicId = 0;
1212 EncodeDecodeFileParamBase p = GetParam();1239 EncodeDecodeFileParamBase p = GetParam();
1213 prepareParam (2, p.slicenum, p.width, p.height, p.frameRate);1240 prepareParam (2, p.slicenum, p.width, p.height, p.frameRate, &param_);
1214 param_.iTemporalLayerNum = (rand() % 4) + 1;1241 param_.iTemporalLayerNum = (rand() % 4) + 1;
1215 param_.iSpatialLayerNum = 2;1242 param_.iSpatialLayerNum = 2;
1216 encoder_->Uninitialize();1243 encoder_->Uninitialize();
@@ -1266,7 +1293,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace) { · 49 unmodified lines
1266 SLTRRecoverRequest m_LTR_Recover_Request;1293 SLTRRecoverRequest m_LTR_Recover_Request;
1267 m_LTR_Recover_Request.uiIDRPicId = 0;1294 m_LTR_Recover_Request.uiIDRPicId = 0;
1268 EncodeDecodeFileParamBase p = GetParam();1295 EncodeDecodeFileParamBase p = GetParam();
1269 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);1296 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
1270 param_.iSpatialLayerNum = 1;1297 param_.iSpatialLayerNum = 1;
1271 1298
1272 int rv = encoder_->InitializeExt (&param_);1299 int rv = encoder_->InitializeExt (&param_);
@@ -1330,7 +1357,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace_NULL) { · 57 unmodified lines
1330 SLTRRecoverRequest m_LTR_Recover_Request;1357 SLTRRecoverRequest m_LTR_Recover_Request;
1331 m_LTR_Recover_Request.uiIDRPicId = 0;1358 m_LTR_Recover_Request.uiIDRPicId = 0;
1332 EncodeDecodeFileParamBase p = GetParam();1359 EncodeDecodeFileParamBase p = GetParam();
1333 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);1360 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
1334 param_.iSpatialLayerNum = 1;1361 param_.iSpatialLayerNum = 1;
1335 int rv = encoder_->InitializeExt (&param_);1362 int rv = encoder_->InitializeExt (&param_);
1336 ASSERT_TRUE (rv == cmResultSuccess);1363 ASSERT_TRUE (rv == cmResultSuccess);
@@ -1393,7 +1420,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECIDC_GeneralSliceChange) { · 56 unmodified lines
1393 uint32_t uiEcIdc;1420 uint32_t uiEcIdc;
1394 uint32_t uiGet;1421 uint32_t uiGet;
1395 EncodeDecodeFileParamBase p = GetParam();1422 EncodeDecodeFileParamBase p = GetParam();
1396 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);1423 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
1397 param_.iSpatialLayerNum = 1;1424 param_.iSpatialLayerNum = 1;
1398 encoder_->Uninitialize();1425 encoder_->Uninitialize();
1399 int rv = encoder_->InitializeExt (&param_);1426 int rv = encoder_->InitializeExt (&param_);
@@ -1473,7 +1500,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) { · 73 unmodified lines
1473 uint32_t uiEcIdc;1500 uint32_t uiEcIdc;
1474 uint32_t uiGet;1501 uint32_t uiGet;
1475 EncodeDecodeFileParamBase p = kFileParamArray[0];1502 EncodeDecodeFileParamBase p = kFileParamArray[0];
1476 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);1503 prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, &param_);
1477 param_.iSpatialLayerNum = 1;1504 param_.iSpatialLayerNum = 1;
1478 encoder_->Uninitialize();1505 encoder_->Uninitialize();
1479 int rv = encoder_->InitializeExt (&param_);1506 int rv = encoder_->InitializeExt (&param_);
@@ -1612,7 +1639,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) { · 132 unmodified lines
1612 uint32_t uiEcIdc = 2; //default set as SLICE_COPY1639 uint32_t uiEcIdc = 2; //default set as SLICE_COPY
1613 uint32_t uiGet;1640 uint32_t uiGet;
1614 EncodeDecodeFileParamBase p = kFileParamArray[0];1641 EncodeDecodeFileParamBase p = kFileParamArray[0];
1615 prepareParam (1, 2, p.width, p.height, p.frameRate);1642 prepareParam (1, 2, p.width, p.height, p.frameRate, &param_);
1616 param_.iSpatialLayerNum = 1;1643 param_.iSpatialLayerNum = 1;
1617 encoder_->Uninitialize();1644 encoder_->Uninitialize();
1618 int rv = encoder_->InitializeExt (&param_);1645 int rv = encoder_->InitializeExt (&param_);
@@ -1745,7 +1772,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) { · 126 unmodified lines
1745 uint32_t uiEcIdc;1772 uint32_t uiEcIdc;
1746 uint32_t uiGet;1773 uint32_t uiGet;
1747 EncodeDecodeFileParamBase p = kFileParamArray[0];1774 EncodeDecodeFileParamBase p = kFileParamArray[0];
1748 prepareParam (1, 2, p.width, p.height, p.frameRate);1775 prepareParam (1, 2, p.width, p.height, p.frameRate, &param_);
1749 param_.iSpatialLayerNum = 1;1776 param_.iSpatialLayerNum = 1;
1750 encoder_->Uninitialize();1777 encoder_->Uninitialize();
1751 int rv = encoder_->InitializeExt (&param_);1778 int rv = encoder_->InitializeExt (&param_);
@@ -1914,7 +1941,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_I) { · 162 unmodified lines
1914 EncodeDecodeFileParamBase p = kSVCSwitch[0];1941 EncodeDecodeFileParamBase p = kSVCSwitch[0];
1915 p.width = p.width << 2;1942 p.width = p.width << 2;
1916 p.height = p.height << 2;1943 p.height = p.height << 2;
1917 prepareParam (4, p.slicenum, p.width, p.height, p.frameRate);1944 prepareParam (4, p.slicenum, p.width, p.height, p.frameRate, &param_);
1918 param_.iTemporalLayerNum = (rand() % 4) + 1;1945 param_.iTemporalLayerNum = (rand() % 4) + 1;
1919 param_.iSpatialLayerNum = 4;1946 param_.iSpatialLayerNum = 4;
1920 encoder_->Uninitialize();1947 encoder_->Uninitialize();
@@ -1979,7 +2006,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_P) { · 58 unmodified lines
1979 int iLastDid = 0;2006 int iLastDid = 0;
1980 p.width = p.width << 2;2007 p.width = p.width << 2;
1981 p.height = p.height << 2;2008 p.height = p.height << 2;
1982 prepareParam (4, p.slicenum, p.width, p.height, p.frameRate);2009 prepareParam (4, p.slicenum, p.width, p.height, p.frameRate, &param_);
1983 param_.iTemporalLayerNum = (rand() % 4) + 1;2010 param_.iTemporalLayerNum = (rand() % 4) + 1;
1984 param_.iSpatialLayerNum = 4;2011 param_.iSpatialLayerNum = 4;
1985 encoder_->Uninitialize();2012 encoder_->Uninitialize();
@@ -2065,7 +2092,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionEncParamExt) { · 79 unmodified lines
2065 int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);2092 int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
2066 int iSliceNum = 1;2093 int iSliceNum = 1;
2067 encoder_->GetDefaultParams (&param_);2094 encoder_->GetDefaultParams (&param_);
2068 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate);2095 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
2069 2096
2070 int rv = encoder_->InitializeExt (&param_);2097 int rv = encoder_->InitializeExt (&param_);
2071 ASSERT_TRUE (rv == cmResultSuccess);2098 ASSERT_TRUE (rv == cmResultSuccess);
@@ -2128,8 +2155,8 @@ class DecodeCrashTestAPI : public EncodeDecodeTestBase { · 56 unmodified lines
2128 ASSERT_TRUE (ucBuf_ == NULL);2155 ASSERT_TRUE (ucBuf_ == NULL);
2129 }2156 }
2130 2157
2131 void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate) {2158 void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate, SEncParamExt* pParam) {
2132 EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate);2159 EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate, pParam);
2133 }2160 }
2134 2161
2135 void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam);2162 void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam);
@@ -2203,11 +2230,11 @@ TEST_F (DecodeCrashTestAPI, DecoderCrashTest) { · 67 unmodified lines
2203 int iSeed = rand() % 3; //3 indicates the length of kParamArray[] used in the following2230 int iSeed = rand() % 3; //3 indicates the length of kParamArray[] used in the following
2204 EncodeDecodeParamBase p = kParamArray[iSeed];2231 EncodeDecodeParamBase p = kParamArray[iSeed];
2205 //Initialize Encoder2232 //Initialize Encoder
2206 prepareParam (1, 1, p.width, p.height, p.frameRate);2233 prepareParam (1, 1, p.width, p.height, p.frameRate, &param_);
2207 param_.iRCMode = RC_BITRATE_MODE;2234 param_.iRCMode = RC_BITRATE_MODE;
2208 param_.iTargetBitrate = p.iTarBitrate;2235 param_.iTargetBitrate = p.iTarBitrate;
2209 param_.uiIntraPeriod = 0;2236 param_.uiIntraPeriod = 0;
2210 param_.bEnableSpsPpsIdAddition = true;2237 param_.iSpsPpsIdStrategy = INCREASING_ID;
2211 param_.bEnableBackgroundDetection = true;2238 param_.bEnableBackgroundDetection = true;
2212 param_.bEnableSceneChangeDetect = true;2239 param_.bEnableSceneChangeDetect = true;
2213 param_.bPrefixNalAddingCtrl = true;2240 param_.bPrefixNalAddingCtrl = true;
@@ -2398,7 +2425,7 @@ TEST_F (DecodeParseAPI, ParseOnly_General) { · 184 unmodified lines
2398 p.height = iHeight_;2425 p.height = iHeight_;
2399 p.frameRate = kiFrameRate;2426 p.frameRate = kiFrameRate;
2400 p.numframes = kiFrameNum;2427 p.numframes = kiFrameNum;
2401 prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate);2428 prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate, &param_);
2402 param_.iSpatialLayerNum = kiTotalLayer;2429 param_.iSpatialLayerNum = kiTotalLayer;
2403 encoder_->Uninitialize();2430 encoder_->Uninitialize();
2404 int rv = encoder_->InitializeExt (&param_);2431 int rv = encoder_->InitializeExt (&param_);
@@ -2475,7 +2502,7 @@ TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) { · 70 unmodified lines
2475 p.height = iHeight_;2502 p.height = iHeight_;
2476 p.frameRate = kiFrameRate;2503 p.frameRate = kiFrameRate;
2477 p.numframes = 5;2504 p.numframes = 5;
2478 prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate);2505 prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate, &param_);
2479 param_.iSpatialLayerNum = iLayerNum;2506 param_.iSpatialLayerNum = iLayerNum;
2480 encoder_->Uninitialize();2507 encoder_->Uninitialize();
2481 int rv = encoder_->InitializeExt (&param_);2508 int rv = encoder_->InitializeExt (&param_);
@@ -2525,3 +2552,434 @@ TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) { · 43 unmodified lines
2525 } //while2552 } //while
2526}2553}
2527 2554
2555//#define DEBUG_FILE_SAVE2
2556TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING1) {
2557
2558 int iWidth = GetRandWidth();
2559 int iHeight = GetRandHeight();
2560 float fFrameRate = rand() + 0.5f;
2561 int iEncFrameNum = 0;
2562 int iSpatialLayerNum = 1;
2563 int iSliceNum = 1;
2564
2565 // prepare params
2566 SEncParamExt sParam1;
2567 SEncParamExt sParam2;
2568 SEncParamExt sParam3;
2569 encoder_->GetDefaultParams (&sParam1);
2570 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
2571 sParam1.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
2572 //prepare param2
2573 memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
2574 while (sParam2.iPicWidth == sParam1.iPicWidth) {
2575 sParam2.iPicWidth = GetRandWidth();
2576 }
2577 prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
2578 sParam2.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
2579 //prepare param3
2580 memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
2581 while (sParam3.iPicHeight == sParam1.iPicHeight) {
2582 sParam3.iPicHeight = GetRandHeight();
2583 }
2584 prepareParam (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
2585 sParam3.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
2586
2587 //prepare output if needed
2588 FILE* fEnc = NULL;
2589#ifdef DEBUG_FILE_SAVE2
2590 fEnc = fopen ("enc2.264", "wb");
2591#endif
2592
2593 // Test part#1
2594 // step#1: pParam1
2595 //int TraceLevel = WELS_LOG_INFO;
2596 //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2597 int rv = encoder_->InitializeExt (&sParam1);
2598 ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
2599 sParam1.iPicHeight;
2600 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2601
2602 // new IDR
2603 rv = encoder_->ForceIntraFrame (true);
2604 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2605 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2606
2607 // step#2: pParam2
2608 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
2609 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam2.iPicWidth << "x" <<
2610 sParam2.iPicHeight;
2611 EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
2612
2613 // new IDR
2614 rv = encoder_->ForceIntraFrame (true);
2615 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2616 EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
2617
2618 // step#3: back to pParam1
2619 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
2620 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
2621 sParam1.iPicHeight;
2622 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2623
2624 // step#4: back to pParam2
2625 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
2626 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << sParam2.iPicWidth << sParam2.iPicHeight;
2627 EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
2628
2629#ifdef DEBUG_FILE_SAVE2
2630 fclose (fEnc);
2631#endif
2632 rv = encoder_->Uninitialize();
2633 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2634
2635 // Test part#2
2636 // step#1: pParam1
2637 rv = encoder_->InitializeExt (&sParam1);
2638 ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
2639 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
2640 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
2641 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
2642 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam3: rv = " << rv;
2643
2644#ifdef DEBUG_FILE_SAVE2
2645 fEnc = fopen ("enc3.264", "wb");
2646#endif
2647 iEncFrameNum = 0;
2648 EncDecOneFrame (sParam3.iPicWidth, sParam3.iPicHeight, iEncFrameNum++, fEnc);
2649
2650 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
2651 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
2652 EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
2653
2654 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
2655 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
2656 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2657
2658#ifdef DEBUG_FILE_SAVE2
2659 fclose (fEnc);
2660#endif
2661 rv = encoder_->Uninitialize();
2662 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2663}
2664
2665#define DEBUG_FILE_SAVE5
2666TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING2) {
2667 //usage 3: 2 Params with different num_ref, encode IDR0, P1, IDR2;
2668 //the bs will show two SPS and different PPS
2669
2670 int iWidth = GetRandWidth();
2671 int iHeight = GetRandHeight();
2672 float fFrameRate = rand() + 0.5f;
2673 int iEncFrameNum = 0;
2674 int iSpatialLayerNum = 1;
2675 int iSliceNum = 1;
2676
2677 // prepare params
2678 SEncParamExt sParam1;
2679 SEncParamExt sParam2;
2680 encoder_->GetDefaultParams (&sParam1);
2681 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
2682 sParam1.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
2683 sParam1.iTemporalLayerNum = 1;
2684 //prepare param2
2685 memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
2686 prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
2687 sParam2.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
2688 sParam2.iTemporalLayerNum = 3;
2689
2690 //prepare output if needed
2691 FILE* fEnc = NULL;
2692#ifdef DEBUG_FILE_SAVE5
2693 fEnc = fopen ("encID2.264", "wb");
2694#endif
2695
2696 // step#1: pParam1
2697 int rv = encoder_->InitializeExt (&sParam1);
2698 ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
2699 sParam1.iPicHeight;
2700
2701 // step#2: pParam2
2702 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
2703 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
2704
2705 // step#3: set back to pParam1, with a smaller num_ref, it still uses the previous SPS
2706 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
2707 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam1: rv = " << rv;
2708 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2709
2710 // new IDR, PPS increases
2711 rv = encoder_->ForceIntraFrame (true);
2712 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2713 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2714
2715 rv = encoder_->Uninitialize();
2716 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2717
2718#ifdef DEBUG_FILE_SAVE5
2719 fclose (fEnc);
2720#endif
2721}
2722
2723TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING3) {
2724
2725 int iWidth = GetRandWidth();
2726 int iHeight = GetRandHeight();
2727 float fFrameRate = rand() + 0.5f;
2728 int iEncFrameNum = 0;
2729 int iSpatialLayerNum = 1;
2730 int iSliceNum = 1;
2731
2732 // prepare params
2733 SEncParamExt sParam1;
2734 SEncParamExt sParam2;
2735 encoder_->GetDefaultParams (&sParam1);
2736 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
2737 sParam1.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
2738
2739 //prepare output if needed
2740 FILE* fEnc = NULL;
2741#ifdef DEBUG_FILE_SAVE2
2742 fEnc = fopen ("enc4.264", "wb");
2743#endif
2744
2745 // step#1: pParam1
2746 int rv = encoder_->InitializeExt (&sParam1);
2747 ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
2748
2749 int max_count = 65; // make it more then twice as MAX_SPS_COUNT
2750 std::vector<int> vWidthTable;
2751 vWidthTable.push_back (sParam1.iPicWidth);
2752
2753 std::vector<int>::iterator vWidthTableIt;
2754 for (int times = 0; times < max_count; times++) {
2755 //prepare param2
2756 memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
2757 do {
2758 sParam2.iPicWidth = GetRandWidth();
2759 vWidthTableIt = std::find (vWidthTable.begin(), vWidthTable.end(), sParam2.iPicWidth);
2760 } while (vWidthTableIt == vWidthTable.end());
2761 vWidthTable.push_back (sParam2.iPicWidth);
2762 prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
2763 sParam2.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
2764
2765 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
2766 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv << ", sParam2.iPicWidth=" <<
2767 sParam2.iPicWidth;
2768 } // end of setting loop
2769
2770 EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
2771
2772#ifdef DEBUG_FILE_SAVE2
2773 fclose (fEnc);
2774#endif
2775 rv = encoder_->Uninitialize();
2776 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2777}
2778
2779//#define DEBUG_FILE_SAVE6
2780TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING1) {
2781 //usage 1: 1 resolution Params, encode IDR0, P1, IDR2;
2782 //the bs will show same SPS and different PPS
2783 // PPS: pic_parameter_set_id 1 ( 0)
2784 // PPS: seq_parameter_set_id 1 ( 0)
2785 // PPS: pic_parameter_set_id 010 ( 1)
2786 // PPS: seq_parameter_set_id 1 ( 0)
2787 // SH: slice_type 011 ( 2)
2788 // SH: pic_parameter_set_id 1 ( 0)
2789 // SH: slice_type 1 ( 0)
2790 // SH: pic_parameter_set_id 1 ( 0)
2791 // SH: slice_type 011 ( 2)
2792 // SH: pic_parameter_set_id 010 ( 1)
2793 int iWidth = GetRandWidth();
2794 int iHeight = GetRandHeight();
2795 float fFrameRate = rand() + 0.5f;
2796 int iEncFrameNum = 0;
2797 int iSpatialLayerNum = 1;
2798 int iSliceNum = 1;
2799
2800 // prepare params
2801 SEncParamExt sParam1;
2802 encoder_->GetDefaultParams (&sParam1);
2803 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
2804 sParam1.iSpsPpsIdStrategy = SPS_PPS_LISTING;
2805
2806 //prepare output if needed
2807 FILE* fEnc = NULL;
2808#ifdef DEBUG_FILE_SAVE6
2809 fEnc = fopen ("encLIST1.264", "wb");
2810#endif
2811
2812 // step#1: pParam1
2813 int rv = encoder_->InitializeExt (&sParam1);
2814 ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
2815 sParam1.iPicHeight;
2816 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2817 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2818
2819 // new IDR
2820 rv = encoder_->ForceIntraFrame (true);
2821 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2822 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2823
2824 rv = encoder_->Uninitialize();
2825 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2826
2827#ifdef DEBUG_FILE_SAVE6
2828 fclose (fEnc);
2829#endif
2830}
2831
2832TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING2) {
2833 //usage 2: 2 resolution Params, encode IDR0, IDR1, IDR2;
2834 //the bs will show two SPS and different PPS
2835 // === SPS LIST ===
2836 //SPS: seq_parameter_set_id 1 ( 0) -- PARAM1
2837 //SPS: seq_parameter_set_id 010 ( 1) -- PARAM2
2838 // === PPS LIST ===
2839 //PPS: pic_parameter_set_id 1 ( 0)
2840 //PPS: seq_parameter_set_id 1 ( 0)
2841 //PPS: pic_parameter_set_id 010 ( 1)
2842 //PPS: seq_parameter_set_id 010 ( 1)
2843 //PPS: pic_parameter_set_id 011 ( 2) -- PPS2 - SPS0
2844 //PPS: seq_parameter_set_id 1 ( 0)
2845 //PPS: pic_parameter_set_id 00100 ( 3) -- PPS3 - SPS1
2846 //PPS: seq_parameter_set_id 010 ( 1)
2847 //PPS: pic_parameter_set_id 00101 ( 4) -- PPS4 - SPS0
2848 //PPS: seq_parameter_set_id 1 ( 0)
2849 // === VCL LAYER ===
2850 //SH: slice_type 011 ( 2) -- PARAM2
2851 //SH: pic_parameter_set_id 010 ( 1) -- PPS1 - SPS1 - PARAM2
2852 //SH: slice_type 011 ( 2) -- PARAM1
2853 //SH: pic_parameter_set_id 011 ( 2) -- PPS2 - SPS0 - PARAM1
2854 //SH: slice_type 011 ( 2) -- PARAM1
2855 //SH: pic_parameter_set_id 00101 ( 4) -- PPS4 - SPS0 - PARAM1
2856
2857 int iWidth = GetRandWidth();
2858 int iHeight = GetRandHeight();
2859 float fFrameRate = rand() + 0.5f;
2860 int iEncFrameNum = 0;
2861 int iSpatialLayerNum = 1;
2862 int iSliceNum = 1;
2863
2864 // prepare params
2865 SEncParamExt sParam1;
2866 SEncParamExt sParam2;
2867 encoder_->GetDefaultParams (&sParam1);
2868 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
2869 sParam1.iSpsPpsIdStrategy = SPS_PPS_LISTING;
2870 //prepare param2
2871 memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
2872 while (sParam2.iPicWidth == sParam1.iPicWidth) {
2873 sParam2.iPicWidth = GetRandWidth();
2874 }
2875 prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
2876 sParam2.iSpsPpsIdStrategy = SPS_PPS_LISTING;
2877
2878 //prepare output if needed
2879 FILE* fEnc = NULL;
2880#ifdef DEBUG_FILE_SAVE5
2881 fEnc = fopen ("encLIST2.264", "wb");
2882#endif
2883
2884 // step#1: pParam1
2885 int rv = encoder_->InitializeExt (&sParam1);
2886 ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
2887 sParam1.iPicHeight;
2888
2889 // step#2: pParam2
2890 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
2891 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
2892 EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
2893
2894 // step#3: back to pParam1, SHOULD NOT encounter ERROR
2895 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
2896 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
2897 sParam1.iPicHeight;
2898 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2899
2900 // new IDR
2901 rv = encoder_->ForceIntraFrame (true);
2902 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2903 EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
2904
2905 rv = encoder_->Uninitialize();
2906 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2907
2908#ifdef DEBUG_FILE_SAVE5
2909 fclose (fEnc);
2910#endif
2911}
2912
2913TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING3) {
2914
2915 int iWidth = GetRandWidth();
2916 int iHeight = GetRandHeight();
2917 float fFrameRate = rand() + 0.5f;
2918 int iEncFrameNum = 0;
2919 int iSpatialLayerNum = 1;
2920 int iSliceNum = 1;
2921
2922 // prepare params
2923 SEncParamExt sParam1;
2924 SEncParamExt sParam2;
2925 SEncParamExt sParam3;
2926 encoder_->GetDefaultParams (&sParam1);
2927 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
2928 sParam1.iSpsPpsIdStrategy = SPS_PPS_LISTING;
2929 //prepare param2
2930 memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
2931 while (sParam2.iPicWidth == sParam1.iPicWidth) {
2932 sParam2.iPicWidth = GetRandWidth();
2933 }
2934 prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
2935 sParam2.iSpsPpsIdStrategy = SPS_PPS_LISTING;
2936 //prepare param3
2937 memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
2938 while (sParam3.iPicWidth == sParam1.iPicWidth || sParam3.iPicWidth == sParam2.iPicWidth) {
2939 sParam3.iPicWidth = GetRandWidth();
2940 }
2941 prepareParam (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
2942 sParam3.iSpsPpsIdStrategy = SPS_PPS_LISTING;
2943
2944 //prepare output if needed
2945 FILE* fEnc = NULL;
2946#ifdef DEBUG_FILE_SAVE5
2947 fEnc = fopen ("enc4.264", "wb");
2948#endif
2949
2950 // step#1: ordinary encoding
2951 int rv = encoder_->InitializeExt (&sParam1);
2952 ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
2953 sParam1.iPicHeight;
2954 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
2955 ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
2956 EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
2957
2958 // step#2: set strategy for success
2959 int32_t iNewStra = SPS_PPS_LISTING;
2960 rv = encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iNewStra);
2961 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << " iNewStra=" << iNewStra;
2962
2963 // step#3: setting new strategy, SHOULD encounter ERROR
2964 unsigned int TraceLevel = WELS_LOG_QUIET;
2965 rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2966 ASSERT_TRUE (rv == cmResultSuccess);
2967 iNewStra = CONSTANT_ID;
2968 rv = encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iNewStra);
2969 ASSERT_TRUE (rv != cmResultSuccess);
2970
2971 EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
2972
2973 // step#4: pParam3, SHOULD encounter ERROR
2974 rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
2975 ASSERT_TRUE (rv != cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam3.iPicWidth << "x" <<
2976 sParam3.iPicHeight;
2977
2978 rv = encoder_->Uninitialize();
2979 ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2980
2981#ifdef DEBUG_FILE_SAVE5
2982 fclose (fEnc);
2983#endif
2984}
2985
test/encoder/EncUT_ParameterSetStrategy.cpp+122−0
@@ -0,0 +1,122 @@
1#include <stdlib.h>
2#include "gtest/gtest.h"
3
4#include "au_set.h"
5#include "param_svc.h"
6#include "parameter_sets.h"
7#include "wels_const.h"
8
9using namespace WelsEnc;
10
11class ParameterSetStrategyTest : public ::testing::Test {
12 public:
13 virtual void SetUp() {
14 pMa = NULL;
15 m_pSpsArray = NULL;
16 m_pSubsetArray = NULL;
17
18 pMa = new CMemoryAlign (0);
19 m_pSpsArray = (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "m_pSpsArray");
20 ASSERT_TRUE (NULL != m_pSpsArray);
21 m_pSubsetArray = (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "m_pSubsetArray");
22 ASSERT_TRUE (NULL != m_pSubsetArray);
23
24 m_pSpsArrayPointer = &m_pSpsArray[0];
25 m_pSubsetArrayPointer = &m_pSubsetArray[0];
26
27 }
28 virtual void TearDown() {
29 pMa->WelsFree (m_pSpsArray, "m_pSpsArray");
30 pMa->WelsFree (m_pSubsetArray, "m_pSubsetArray");
31 delete pMa;
32 }
33 void GenerateParam (SWelsSvcCodingParam* pParam);
34 public:
35 CMemoryAlign* pMa;
36 SWelsSPS* m_pSpsArray;
37 SSubsetSps* m_pSubsetArray;
38
39 SWelsSPS* m_pSpsArrayPointer;
40 SSubsetSps* m_pSubsetArrayPointer;
41
42};
43
44void ParameterSetStrategyTest::GenerateParam (SWelsSvcCodingParam* pParam) {
45 SEncParamBase sEncParamBase;
46 //TODO: consider randomize it
47 sEncParamBase.iUsageType = CAMERA_VIDEO_REAL_TIME;
48 sEncParamBase.iPicWidth = 1280;
49 sEncParamBase.iPicHeight = 720;
50 sEncParamBase.iTargetBitrate = 1000000;
51 sEncParamBase.iRCMode = RC_BITRATE_MODE;
52 sEncParamBase.fMaxFrameRate = 30.0f;
53 pParam->ParamBaseTranscode (sEncParamBase);
54}
55
56TEST_F (ParameterSetStrategyTest, FindExistingSps) {
57 int iDlayerIndex = 0;
58 int iDlayerCount = 0;
59 bool bUseSubsetSps = false;
60 int iFoundId = -1;
61 int iRet = 0;
62 SSpatialLayerConfig* pDlayerParam;
63
64 //init parameter
65 SWelsSvcCodingParam sParam1;
66 GenerateParam (&sParam1);
67
68 //prepare first SPS
69 int iCurSpsId = 0;
70 int iCurSpsInUse = 1;
71 m_pSpsArrayPointer = &m_pSpsArray[iCurSpsId];
72
73 pDlayerParam = & (sParam1.sSpatialLayers[iDlayerIndex]);
74 iRet = WelsInitSps (m_pSpsArrayPointer, pDlayerParam, &sParam1.sDependencyLayers[iDlayerIndex], sParam1.uiIntraPeriod,
75 sParam1.iMaxNumRefFrame,
76 iCurSpsId, sParam1.bEnableFrameCroppingFlag, sParam1.iRCMode != RC_OFF_MODE, iDlayerCount);
77
78 // try finding #0
79 iFoundId = FindExistingSps (&sParam1, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
80 m_pSpsArray, m_pSubsetArray);
81 EXPECT_EQ (iFoundId, iCurSpsId);
82
83 // try not finding
84 SWelsSvcCodingParam sParam2 = sParam1;
85 sParam2.iMaxNumRefFrame ++;
86 iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
87 m_pSpsArray, m_pSubsetArray);
88 EXPECT_EQ (iFoundId, INVALID_ID);
89
90 // add new sps
91 iCurSpsId = 1;
92 m_pSpsArrayPointer = &m_pSpsArray[iCurSpsId];
93 pDlayerParam = & (sParam2.sSpatialLayers[iDlayerIndex]);
94 iRet = WelsInitSps (m_pSpsArrayPointer, pDlayerParam, &sParam2.sDependencyLayers[iDlayerIndex], sParam2.uiIntraPeriod,
95 sParam2.iMaxNumRefFrame,
96 iCurSpsId, sParam2.bEnableFrameCroppingFlag, sParam2.iRCMode != RC_OFF_MODE, iDlayerCount);
97 iCurSpsInUse = 2;
98
99 // try finding #1
100 iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
101 m_pSpsArray, m_pSubsetArray);
102 EXPECT_EQ (iFoundId, iCurSpsId);
103
104 // try finding #0
105 iFoundId = FindExistingSps (&sParam1, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
106 m_pSpsArray, m_pSubsetArray);
107 EXPECT_EQ (iFoundId, 0);
108
109 // try not finding
110 if (sParam2.sDependencyLayers[0].iActualWidth > 1) {
111
112 sParam2.sDependencyLayers[0].iActualWidth--;
113 } else {
114 sParam2.sDependencyLayers[0].iActualWidth++;
115 }
116
117 iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
118 m_pSpsArray, m_pSubsetArray);
119 EXPECT_EQ (iFoundId, INVALID_ID);
120}
121
122
test/encoder/targets.mk+1−0
@@ -11,6 +11,7 @@ ENCODER_UNITTEST_CPP_SRCS=\ · 10 unmodified lines
11 $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\11 $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\
12 $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryZero.cpp\12 $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryZero.cpp\
13 $(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\13 $(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\
14 $(ENCODER_UNITTEST_SRCDIR)/EncUT_ParameterSetStrategy.cpp\
14 $(ENCODER_UNITTEST_SRCDIR)/EncUT_Reconstruct.cpp\15 $(ENCODER_UNITTEST_SRCDIR)/EncUT_Reconstruct.cpp\
15 $(ENCODER_UNITTEST_SRCDIR)/EncUT_Sample.cpp\16 $(ENCODER_UNITTEST_SRCDIR)/EncUT_Sample.cpp\
16 $(ENCODER_UNITTEST_SRCDIR)/EncUT_SVC_me.cpp\17 $(ENCODER_UNITTEST_SRCDIR)/EncUT_SVC_me.cpp\

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t