[Encoder] add new SpsPpsStrategy and UT
Unified · Split
| @@ -385,6 +385,17 @@ typedef enum { · 384 unmodified lines | ||
| 385 | 385 | HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality |
| 386 | 386 | } ECOMPLEXITY_MODE; |
| 387 | 387 | |
| 388 | +/** | |
| 389 | + * @brief Enumulate for the stategy of SPS/PPS strategy | |
| 390 | + */ | |
| 391 | +typedef 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 | 399 | // TODO: Refine the parameters definition. |
| 389 | 400 | /** |
| 390 | 401 | * @brief SVC Encoding Parameters |
| @@ -421,7 +432,7 @@ typedef struct TagEncParamExt { · 30 unmodified lines | ||
| 421 | 432 | ECOMPLEXITY_MODE iComplexityMode; |
| 422 | 433 | unsigned int uiIntraPeriod; ///< period of Intra frame |
| 423 | 434 | int iNumRefFrame; ///< number of reference frame used |
| 424 | − bool bEnableSpsPpsIdAddition; ///< false:not adjust ID in SPS/PPS; true: adjust ID in SPS/PPS | |
| 435 | + int iSpsPpsIdStrategy; ///< different stategy in adjust ID in SPS/PPS: 0- constant ID, 1-additional ID, 6-mapping and additional | |
| 425 | 436 | bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL |
| 426 | 437 | bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI |
| 427 | 438 | bool bSimulcastAVC; ///< (when encoding more than 1 spatial layer) false: use SVC syntax for higher layers; true: use Simulcast AVC -- coming soon |
| @@ -232,8 +232,8 @@ int ParseConfig (CReadConfig& cRdCfg, SSourcePicture* pSrcPic, SEncParamExt& pSv · 231 unmodified lines | ||
| 232 | 232 | pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str()); |
| 233 | 233 | } else if (strTag[0].compare ("MaxNalSize") == 0) { |
| 234 | 234 | pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str()); |
| 235 | − } else if (strTag[0].compare ("EnableSpsPpsIDAddition") == 0) { | |
| 236 | − pSvcParam.bEnableSpsPpsIdAddition = atoi (strTag[1].c_str()) ? true : false; | |
| 235 | + } else if (strTag[0].compare ("SpsPpsIDStrategy") == 0) { | |
| 236 | + pSvcParam.iSpsPpsIdStrategy = atoi (strTag[1].c_str()); | |
| 237 | 237 | } else if (strTag[0].compare ("EnableScalableSEI") == 0) { |
| 238 | 238 | pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false; |
| 239 | 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 | 421 | pSvcParam.uiMaxNalSize = atoi (argv[n++]); |
| 422 | 422 | |
| 423 | 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 | 426 | else if (!strcmp (pCommand, "-cabac") && (n < argc)) |
| 427 | 427 | pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]); |
| @@ -591,7 +591,7 @@ int FillSpecificParameters (SEncParamExt& sParam) { · 163 unmodified lines | ||
| 591 | 591 | sParam.bEnableLongTermReference = 0; // long term reference control |
| 592 | 592 | sParam.iLtrMarkPeriod = 30; |
| 593 | 593 | sParam.uiIntraPeriod = 320; // period of Intra frame |
| 594 | − sParam.bEnableSpsPpsIdAddition = 1; | |
| 594 | + sParam.iSpsPpsIdStrategy = INCREASING_ID; | |
| 595 | 595 | sParam.bPrefixNalAddingCtrl = 0; |
| 596 | 596 | sParam.iComplexityMode = MEDIUM_COMPLEXITY; |
| 597 | 597 | int iIndexLayer = 0; |
| @@ -141,8 +141,26 @@ int32_t WelsInitPps (SWelsPPS* pPps, · 140 unmodified lines | ||
| 141 | 141 | const bool kbDeblockingFilterPresentFlag, |
| 142 | 142 | const bool kbUsingSubsetSps, |
| 143 | 143 | const bool kbEntropyCodingModeFlag); |
| 144 | + | |
| 144 | 145 | int32_t WelsCheckRefFrameLimitationNumRefFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam); |
| 145 | 146 | int32_t WelsCheckRefFrameLimitationLevelIdcFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam); |
| 146 | −int32_t WelsAdjustLevel( SSpatialLayerConfig* pSpatialLayer); | |
| 147 | + | |
| 148 | +int32_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 | + */ | |
| 161 | +int32_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 | 166 | #endif//WELS_ACCESS_UNIT_PARSER_H__ |
| @@ -48,7 +48,7 @@ namespace WelsEnc { · 47 unmodified lines | ||
| 48 | 48 | * \param pEncCtx sWelsEncCtx* |
| 49 | 49 | * \return successful - 0; otherwise none 0 for failed |
| 50 | 50 | */ |
| 51 | −int32_t RequestMemorySvc (sWelsEncCtx** ppCtx); | |
| 51 | +int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList); | |
| 52 | 52 | |
| 53 | 53 | /*! |
| 54 | 54 | * \brief free memory in SVC core encoder |
| @@ -191,6 +191,7 @@ typedef struct TagWelsEncCtx { · 190 unmodified lines | ||
| 191 | 191 | SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible |
| 192 | 192 | SSubsetSps* pSubsetSps; |
| 193 | 193 | int32_t iSpsNum; // number of pSps used |
| 194 | + int32_t iSubsetSpsNum; // number of pSps used | |
| 194 | 195 | int32_t iPpsNum; // number of pPps used |
| 195 | 196 | |
| 196 | 197 | // Output |
| @@ -216,6 +217,7 @@ typedef struct TagWelsEncCtx { · 19 unmodified lines | ||
| 216 | 217 | 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 | 219 | SParaSetOffset sPSOVector; |
| 220 | + SParaSetOffset* pPSOVector; | |
| 219 | 221 | CMemoryAlign* pMemAlign; |
| 220 | 222 | |
| 221 | 223 | #if defined(STAT_OUTPUT) |
| @@ -75,7 +75,8 @@ void GomValidCheck (const int32_t kiMbWidth, const int32_t kiMbHeight, int32_t* · 74 unmodified lines | ||
| 75 | 75 | * \param para SWelsSvcCodingParam* |
| 76 | 76 | * \return successful - 0; otherwise none 0 for failed |
| 77 | 77 | */ |
| 78 | −int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pPara, SLogContext* pLogCtx); | |
| 78 | +int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pPara, SLogContext* pLogCtx, | |
| 79 | + SExistingParasetList* pExistingParasetList); | |
| 79 | 80 | |
| 80 | 81 | /*! |
| 81 | 82 | * \brief uninitialize Wels encoder core library |
| @@ -162,7 +162,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 161 unmodified lines | ||
| 162 | 162 | param.bEnableAdaptiveQuant = true; // adaptive quantization control |
| 163 | 163 | param.bEnableFrameSkip = true; // frame skipping |
| 164 | 164 | param.bEnableLongTermReference = false; // long term reference control |
| 165 | − param.bEnableSpsPpsIdAddition = true; // pSps pPps id addition control | |
| 165 | + param.iSpsPpsIdStrategy = INCREASING_ID; // pSps pPps id addition control | |
| 166 | 166 | param.bPrefixNalAddingCtrl = false; // prefix NAL adding control |
| 167 | 167 | param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded |
| 168 | 168 | param.iTemporalLayerNum = 1; // number of temporal layer specified |
| @@ -350,8 +350,8 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 181 unmodified lines | ||
| 350 | 350 | |
| 351 | 351 | bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl; |
| 352 | 352 | |
| 353 | − bEnableSpsPpsIdAddition = | |
| 354 | − pCodingParam.bEnableSpsPpsIdAddition;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference. | |
| 353 | + iSpsPpsIdStrategy = | |
| 354 | + pCodingParam.iSpsPpsIdStrategy;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference. | |
| 355 | 355 | //SHOULD enable this feature. |
| 356 | 356 | |
| 357 | 357 | SSpatialLayerInternal* pDlp = &sDependencyLayers[0]; |
| @@ -477,6 +477,18 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 119 unmodified lines | ||
| 477 | 477 | |
| 478 | 478 | } SWelsSvcCodingParam; |
| 479 | 479 | |
| 480 | + | |
| 481 | +typedef 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 | + | |
| 480 | 492 | static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) { |
| 481 | 493 | if (pParam == NULL || *pParam == NULL || pMa == NULL) |
| 482 | 494 | return 1; |
| @@ -83,9 +83,15 @@ typedef struct TagParaSetOffset { · 82 unmodified lines | ||
| 83 | 83 | bool |
| 84 | 84 | 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 | 88 | #if _DEBUG |
| 87 | − bool bEnableSpsPpsIdAddition; | |
| 89 | + int32_t iSpsPpsIdStrategy; | |
| 88 | 90 | #endif |
| 91 | + | |
| 92 | + uint32_t uiInUseSpsNum; | |
| 93 | + uint32_t uiInUseSubsetSpsNum; | |
| 94 | + uint32_t uiInUsePpsNum; | |
| 89 | 95 | } SParaSetOffset; |
| 90 | 96 | |
| 91 | 97 | |
| @@ -171,6 +171,7 @@ · 170 unmodified lines | ||
| 171 | 171 | |
| 172 | 172 | #define UNAVAILABLE_DQ_ID ((uint8_t)(-1)) |
| 173 | 173 | #define LAYER_NUM_EXCHANGEABLE 2 |
| 174 | +#define INVALID_ID (-1) | |
| 174 | 175 | |
| 175 | 176 | #define NAL_HEADER_ADD_0X30BYTES 50 |
| 176 | 177 | |
| @@ -336,27 +336,27 @@ int32_t WelsWriteSubsetSpsSyntax (SSubsetSps* pSubsetSps, SBitStringAux* pBitStr · 335 unmodified lines | ||
| 336 | 336 | * \note Call it in case EWelsNalUnitType is PPS. |
| 337 | 337 | ************************************************************************************* |
| 338 | 338 | */ |
| 339 | −int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* sPSOVector) { | |
| 339 | +int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* pPSOVector) { | |
| 340 | 340 | SBitStringAux* pLocalBitStringAux = pBitStringAux; |
| 341 | 341 | |
| 342 | − bool bUsedSubset = sPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId]; | |
| 343 | − int32_t iParameterSetType = (bUsedSubset ? PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS); | |
| 342 | + const int32_t kiParameterSetType = (pPSOVector != NULL) ? (pPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId] ? | |
| 343 | + PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS) : 0; | |
| 344 | 344 | |
| 345 | − BsWriteUE (pLocalBitStringAux, pPps->iPpsId + | |
| 346 | − sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]); | |
| 347 | − BsWriteUE (pLocalBitStringAux, pPps->iSpsId + | |
| 348 | − sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId]); | |
| 345 | + BsWriteUE (pLocalBitStringAux, pPps->iPpsId | |
| 346 | + + ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]) : 0)); | |
| 347 | + BsWriteUE (pLocalBitStringAux, pPps->iSpsId | |
| 348 | + + ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId]) : 0)); | |
| 349 | 349 | |
| 350 | 350 | #if _DEBUG |
| 351 | 351 | //SParaSetOffset use, 110421 |
| 352 | − if (sPSOVector->bEnableSpsPpsIdAddition) { | |
| 352 | + if ((pPSOVector != NULL) && (INCREASING_ID & pPSOVector->iSpsPpsIdStrategy)) { | |
| 353 | 353 | const int32_t kiTmpSpsIdInBs = pPps->iSpsId + |
| 354 | − sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId]; | |
| 354 | + pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId]; | |
| 355 | 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 | 357 | assert (MAX_SPS_COUNT > kiTmpSpsIdInBs); |
| 358 | 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 | 361 | #endif |
| 362 | 362 | |
| @@ -323,6 +323,12 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa · 322 unmodified lines | ||
| 323 | 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 | 332 | for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) { |
| 327 | 333 | SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i]; |
| 328 | 334 | const int32_t kiPicWidth = pSpatialLayer->iVideoWidth; |
| @@ -665,8 +671,12 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara · 336 unmodified lines | ||
| 665 | 671 | ++ iDIndex; |
| 666 | 672 | } while (iDIndex < iNumDependencyLayers); |
| 667 | 673 | |
| 674 | + // count parasets | |
| 668 | 675 | iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) + |
| 669 | − iCountNumLayers; // plus iCountNumLayers for reserved application | |
| 676 | + 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 | 681 | // to check number of layers / nals / slices dependencies, 12/8/2010 |
| 672 | 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 | |
| 850 | −int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex, | |
| 851 | − const int32_t iDlayerCount, const int32_t kiSpsId, | |
| 852 | − SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) { | |
| 860 | +static int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex, | |
| 861 | + const int32_t iDlayerCount, const int32_t kiSpsId, | |
| 862 | + SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) { | |
| 853 | 863 | int32_t iRet = 0; |
| 854 | 864 | |
| 855 | 865 | if (!kbUseSubsetSps) { |
| @@ -866,9 +876,6 @@ int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const · 10 unmodified lines | ||
| 866 | 876 | iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, |
| 867 | 877 | pParam->iMaxNumRefFrame, |
| 868 | 878 | kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount); |
| 869 | − | |
| 870 | − | |
| 871 | − | |
| 872 | 879 | } else { |
| 873 | 880 | iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, |
| 874 | 881 | pParam->iMaxNumRefFrame, |
| @@ -877,12 +884,131 @@ int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const · 2 unmodified lines | ||
| 877 | 884 | return iRet; |
| 878 | 885 | } |
| 879 | 886 | |
| 887 | +static 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 | + | |
| 924 | +static 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 | + | |
| 939 | +int32_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 | + | |
| 972 | +int32_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 | 1007 | * \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available |
| 882 | 1008 | * \pParam pCtx sWelsEncCtx* |
| 883 | 1009 | * \return 0 - successful; otherwise failed |
| 884 | 1010 | */ |
| 885 | −static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { | |
| 1011 | +static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList) { | |
| 886 | 1012 | SWelsSvcCodingParam* pParam = NULL; |
| 887 | 1013 | SWelsSPS* pSps = NULL; |
| 888 | 1014 | SSubsetSps* pSubsetSps = NULL; |
| @@ -1045,14 +1171,51 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { · 156 unmodified lines | ||
| 1045 | 1171 | } |
| 1046 | 1172 | |
| 1047 | 1173 | // 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"); | |
| 1049 | − WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx)) | |
| 1174 | + // SPS | |
| 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"); | |
| 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"); | |
| 1188 | + (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "pSubsetArray"); | |
| 1055 | 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 | 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 | 1230 | pDqIdc->uiSpatialId = iDlayerIndex; |
| 1068 | 1231 | |
| 1069 | − WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex, | |
| 1070 | − iDlayerCount, iSpsId, pSps, pSubsetSps); | |
| 1232 | + if (! (SPS_LISTING & pParam->iSpsPpsIdStrategy)) { | |
| 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]; | |
| 1073 | − // initialize pPps | |
| 1074 | − WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0); | |
| 1261 | + iSpsId = (!bUseSubsetSps) ? ((*ppCtx)->sPSOVector.uiInUseSpsNum++) : ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum++); | |
| 1262 | + if (iSpsId >= MAX_SPS_COUNT) { | |
| 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 | 1306 | // 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 | 1315 | if (iResult) { |
| 1086 | 1316 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult); |
| 1087 | 1317 | FreeMemorySvc (ppCtx); |
| 1088 | − return 1; | |
| 1318 | + return iResult; | |
| 1089 | 1319 | } |
| 1090 | 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 | 1327 | if (bUseSubsetSps) |
| 1098 | 1328 | ++ iSpsId; |
| 1099 | 1329 | ++ iPpsId; |
| 1100 | − ++ (*ppCtx)->iSpsNum; | |
| 1330 | + if (bUseSubsetSps) { | |
| 1331 | + ++ (*ppCtx)->iSubsetSpsNum; | |
| 1332 | + } else { | |
| 1333 | + ++ (*ppCtx)->iSpsNum; | |
| 1334 | + } | |
| 1101 | 1335 | ++ (*ppCtx)->iPpsNum; |
| 1102 | 1336 | |
| 1103 | 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 | |
| 1108 | 1349 | int32_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 | 1653 | iMvdRange = WELS_MIN (iMvdRange, iFixMvdRange); |
| 1413 | 1654 | } |
| 1414 | −int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) { | |
| 1655 | +int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList) { | |
| 1415 | 1656 | SWelsSvcCodingParam* pParam = (*ppCtx)->pSvcParam; |
| 1416 | 1657 | CMemoryAlign* pMa = (*ppCtx)->pMemAlign; |
| 1417 | 1658 | SSpatialLayerConfig* pFinalSpatial = NULL; |
| @@ -1616,7 +1857,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) { · 198 unmodified lines | ||
| 1616 | 1857 | |
| 1617 | 1858 | //End of pVaa memory allocation |
| 1618 | 1859 | |
| 1619 | − iResult = InitDqLayers (ppCtx); | |
| 1860 | + iResult = InitDqLayers (ppCtx, pExistingParasetList); | |
| 1620 | 1861 | if (iResult) { |
| 1621 | 1862 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult); |
| 1622 | 1863 | FreeMemorySvc (ppCtx); |
| @@ -2130,7 +2371,8 @@ int32_t GetMultipleThreadIdc (SLogContext* pLogCtx, SWelsSvcCodingParam* pCoding · 507 unmodified lines | ||
| 2130 | 2371 | * \pParam pParam SWelsSvcCodingParam* |
| 2131 | 2372 | * \return successful - 0; otherwise none 0 for failed |
| 2132 | 2373 | */ |
| 2133 | −int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx) { | |
| 2374 | +int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx, | |
| 2375 | + SExistingParasetList* pExistingParasetList) { | |
| 2134 | 2376 | sWelsEncCtx* pCtx = NULL; |
| 2135 | 2377 | int32_t iRet = 0; |
| 2136 | 2378 | 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 | 2432 | pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum; |
| 2191 | 2433 | pCtx->iMaxSliceCount = iSliceNum; |
| 2192 | − iRet = RequestMemorySvc (&pCtx); | |
| 2434 | + iRet = RequestMemorySvc (&pCtx, pExistingParasetList); | |
| 2193 | 2435 | if (iRet != 0) { |
| 2194 | 2436 | WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), RequestMemorySvc failed return %d.", iRet); |
| 2195 | 2437 | FreeMemorySvc (&pCtx); |
| @@ -2553,18 +2795,26 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx, · 357 unmodified lines | ||
| 2553 | 2795 | iSliceCount = GetCurrentSliceNum (pCurDq->pSliceEncCtx); |
| 2554 | 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 | 2806 | pCurDq->sLayerInfo.pPpsP = |
| 2558 | − pBaseSlice->sSliceHeaderExt.sSliceHeader.pPps = &pCtx->pPPSArray[pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId]; | |
| 2559 | − pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId = pDqIdc->iSpsId; | |
| 2807 | + pBaseSlice->sSliceHeaderExt.sSliceHeader.pPps = &pCtx->pPPSArray[iCurPpsId]; | |
| 2808 | + | |
| 2809 | + pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId = iCurSpsId; | |
| 2560 | 2810 | if (kbUseSubsetSpsFlag) { |
| 2561 | − pCurDq->sLayerInfo.pSubsetSpsP = &pCtx->pSubsetArray[pDqIdc->iSpsId]; | |
| 2811 | + pCurDq->sLayerInfo.pSubsetSpsP = &pCtx->pSubsetArray[iCurSpsId]; | |
| 2562 | 2812 | pCurDq->sLayerInfo.pSpsP = |
| 2563 | 2813 | pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCurDq->sLayerInfo.pSubsetSpsP->pSps; |
| 2564 | 2814 | } else { |
| 2565 | 2815 | pCurDq->sLayerInfo.pSubsetSpsP = NULL; |
| 2566 | 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 | 2820 | pSlice = pBaseSlice; |
| @@ -2865,46 +3115,68 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 294 unmodified lines | ||
| 2865 | 3115 | /* write all SPS */ |
| 2866 | 3116 | iIdx = 0; |
| 2867 | 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 | 3118 | iNal = pCtx->pOut->iNalIndex; |
| 2873 | 3119 | |
| 2874 | − if (pCtx->pSvcParam->bEnableSpsPpsIdAddition) { | |
| 3120 | + if (INCREASING_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) { | |
| 2875 | 3121 | #if _DEBUG |
| 2876 | − pCtx->sPSOVector.bEnableSpsPpsIdAddition = 1; | |
| 2877 | − assert (kiDid < MAX_DEPENDENCY_LAYER); | |
| 3122 | + pCtx->sPSOVector.iSpsPpsIdStrategy = INCREASING_ID; | |
| 2878 | 3123 | assert (iIdx < MAX_DQ_LAYER_NUM); |
| 2879 | 3124 | #endif |
| 2880 | 3125 | |
| 2881 | − ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[kbUsingSubsetSps ? PARA_SET_TYPE_SUBSETSPS : | |
| 2882 | − PARA_SET_TYPE_AVCSPS]), | |
| 2883 | − (kbUsingSubsetSps) ? (pCtx->pSubsetArray[iIdx - 1].pSps.uiSpsId) : (pCtx->pSpsArray[0].uiSpsId), | |
| 3126 | + ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS]), | |
| 3127 | + pCtx->pSpsArray[0].uiSpsId, | |
| 2884 | 3128 | MAX_SPS_COUNT); |
| 2885 | − } else { | |
| 3129 | + } else if (CONSTANT_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) { | |
| 2886 | 3130 | memset (& (pCtx->sPSOVector), 0, sizeof (pCtx->sPSOVector)); |
| 2887 | 3131 | } |
| 2888 | 3132 | |
| 2889 | − if (kbUsingSubsetSps) { | |
| 2890 | − iId = iIdx - 1; | |
| 3133 | + /* generate sequence parameters set */ | |
| 3134 | + iId = (SPS_LISTING & pCtx->pSvcParam->iSpsPpsIdStrategy) ? iIdx : 0; | |
| 2891 | 3135 | |
| 2892 | − /* generate Subset SPS */ | |
| 2893 | − WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST); | |
| 3136 | + WelsLoadNal (pCtx->pOut, NAL_UNIT_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, | |
| 2896 | − & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0])); | |
| 2897 | − WelsUnloadNal (pCtx->pOut); | |
| 2898 | − } else { | |
| 2899 | − iId = 0; | |
| 3141 | + iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | |
| 3142 | + pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length | |
| 3143 | + pCtx->pFrameBs + pCtx->iPosBsBuffer, | |
| 3144 | + &iNalLength); | |
| 3145 | + WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) | |
| 3146 | + pNalLen[iCountNal] = iNalLength; | |
| 2900 | 3147 | |
| 2901 | − /* generate sequence parameters set */ | |
| 2902 | − WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST); | |
| 2903 | − WelsWriteSpsNal (&pCtx->pSpsArray[0], &pCtx->pOut->sBsWrite, | |
| 2904 | − & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0])); | |
| 2905 | − WelsUnloadNal (pCtx->pOut); | |
| 3148 | + pCtx->iPosBsBuffer += iNalLength; | |
| 3149 | + iSize += iNalLength; | |
| 3150 | + | |
| 3151 | + ++ iIdx; | |
| 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 | 3180 | iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, |
| 2909 | 3181 | pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length |
| 2910 | 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 | 3194 | /* write all PPS */ |
| 2923 | 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 | 3218 | while (iIdx < pCtx->iPpsNum) { |
| 2925 | − if (pCtx->pSvcParam->bEnableSpsPpsIdAddition) { | |
| 3219 | + if ((INCREASING_ID & pCtx->pSvcParam->iSpsPpsIdStrategy)) { | |
| 2926 | 3220 | //para_set_type = 2: PPS, use MAX_PPS_COUNT |
| 2927 | 3221 | ParasetIdAdditionIdAdjust (&pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS], pCtx->pPPSArray[iIdx].iPpsId, |
| 2928 | 3222 | MAX_PPS_COUNT); |
| @@ -2931,7 +3225,8 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 2 unmodified lines | ||
| 2931 | 3225 | iNal = pCtx->pOut->iNalIndex; |
| 2932 | 3226 | /* generate picture parameter set */ |
| 2933 | 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 | 3230 | WelsUnloadNal (pCtx->pOut); |
| 2936 | 3231 | |
| 2937 | 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 | 3532 | iDidList[iSpatialIdx] = iCurDid; |
| 3238 | 3533 | |
| 3239 | 3534 | // Encoding this picture might mulitiple sQualityStat layers potentially be encoded as followed |
| 3240 | − | |
| 3241 | 3535 | switch (pParam->sSliceCfg.uiSliceMode) { |
| 3242 | 3536 | case SM_FIXEDSLCNUM_SLICE: |
| 3243 | 3537 | case SM_AUTO_SLICE: { |
| @@ -3829,7 +4123,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 585 unmodified lines | ||
| 3829 | 4123 | (pOldParam->iLTRRefNum != pNewParam->iLTRRefNum) || |
| 3830 | 4124 | (pOldParam->iMultipleThreadIdc != pNewParam->iMultipleThreadIdc) || |
| 3831 | 4125 | (pOldParam->bEnableBackgroundDetection != pNewParam->bEnableBackgroundDetection) || |
| 3832 | − (pOldParam->bEnableAdaptiveQuant != pNewParam->bEnableAdaptiveQuant); | |
| 4126 | + (pOldParam->bEnableAdaptiveQuant != pNewParam->bEnableAdaptiveQuant) || | |
| 4127 | + (pOldParam->iSpsPpsIdStrategy != pNewParam->iSpsPpsIdStrategy); | |
| 3833 | 4128 | if (pNewParam->iMaxNumRefFrame > pOldParam->iMaxNumRefFrame) { |
| 3834 | 4129 | bNeedReset = true; |
| 3835 | 4130 | } |
| @@ -3876,35 +4171,75 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 40 unmodified lines | ||
| 3876 | 4171 | } |
| 3877 | 4172 | |
| 3878 | 4173 | if (bNeedReset) { |
| 3879 | − SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE]; | |
| 3880 | − uint16_t uiTmpIdrPicId;//this is for LTR! | |
| 3881 | 4174 | SLogContext sLogCtx = (*ppCtx)->sLogCtx; |
| 3882 | − for (int32_t k = 0; k < PARA_SET_TYPE; k++) | |
| 3883 | − memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool)); | |
| 3884 | − memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable, | |
| 3885 | − (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage | |
| 3886 | − uiTmpIdrPicId = (*ppCtx)->uiIdrPicId; | |
| 4175 | + | |
| 4176 | + int32_t iOldSpsPpsIdStrategy = pOldParam->iSpsPpsIdStrategy; | |
| 4177 | + SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE]; | |
| 4178 | + int32_t iTmpPpsIdList[MAX_DQ_LAYER_NUM * MAX_PPS_COUNT]; | |
| 4179 | + uint16_t uiTmpIdrPicId = (*ppCtx)->uiIdrPicId;//this is for LTR! | |
| 3887 | 4180 | |
| 3888 | 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 | 4217 | WelsUninitEncoderExt (ppCtx); |
| 3891 | 4218 | |
| 3892 | 4219 | /* Update new parameters */ |
| 3893 | − if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx)) | |
| 4220 | + if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx, pExistingParasetList)) | |
| 3894 | 4221 | return 1; |
| 3895 | 4222 | |
| 3896 | 4223 | // reset the scaled spatial picture size |
| 3897 | 4224 | (*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx); |
| 3898 | 4225 | //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 | 4227 | //for LTR |
| 3905 | 4228 | (*ppCtx)->uiIdrPicId = uiTmpIdrPicId; |
| 4229 | + | |
| 3906 | 4230 | //for sEncoderStatistics |
| 3907 | 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 | 4243 | } else { |
| 3909 | 4244 | /* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */ |
| 3910 | 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 | 4254 | pOldParam->fMaxFrameRate = pNewParam->fMaxFrameRate; // maximal frame rate [Hz / fps] |
| 3920 | 4255 | pOldParam->iComplexityMode = pNewParam->iComplexityMode; // color space of input sequence |
| 3921 | 4256 | pOldParam->uiIntraPeriod = pNewParam->uiIntraPeriod; // intra period (multiple of GOP size as desired) |
| 3922 | − pOldParam->bEnableSpsPpsIdAddition = pNewParam->bEnableSpsPpsIdAddition; | |
| 4257 | + pOldParam->iSpsPpsIdStrategy = pNewParam->iSpsPpsIdStrategy; | |
| 3923 | 4258 | pOldParam->bPrefixNalAddingCtrl = pNewParam->bPrefixNalAddingCtrl; |
| 3924 | 4259 | pOldParam->iNumRefFrame = pNewParam->iNumRefFrame; // number of reference frame used |
| 3925 | 4260 | pOldParam->uiGopSize = pNewParam->uiGopSize; |
| @@ -237,7 +237,8 @@ void WriteRefPicMarking (SBitStringAux* pBs, SSliceHeader* pSliceHeader, SNalUni · 236 unmodified lines | ||
| 237 | 237 | } |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | −void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, int32_t* pPpsIdDelta) { | |
| 240 | +void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, | |
| 241 | + int32_t* pPpsIdDelta) { | |
| 241 | 242 | SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP; |
| 242 | 243 | SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP; |
| 243 | 244 | SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; |
| @@ -246,7 +247,7 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur · 2 unmodified lines | ||
| 246 | 247 | BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice); |
| 247 | 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 | 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 | |
| 304 | −void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, int32_t* pPpsIdDelta) { | |
| 305 | +void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, | |
| 306 | + int32_t* pPpsIdDelta) { | |
| 305 | 307 | SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP; |
| 306 | 308 | SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP; |
| 307 | 309 | SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP; |
| @@ -312,7 +314,7 @@ void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* p · 4 unmodified lines | ||
| 312 | 314 | BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice); |
| 313 | 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 | 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 | 730 | WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice); |
| 729 | 731 | |
| 730 | − | |
| 731 | 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 | 736 | #if _DEBUG |
| 734 | − if (pEncCtx->sPSOVector.bEnableSpsPpsIdAddition) { | |
| 737 | + if (INCREASING_ID & pEncCtx->sPSOVector.iSpsPpsIdStrategy) { | |
| 735 | 738 | const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId; |
| 736 | 739 | const int32_t kiTmpPpsIdInBs = kiEncoderPpsId + |
| 737 | 740 | pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ]; |
| @@ -332,7 +332,7 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) { · 331 unmodified lines | ||
| 332 | 332 | m_iMaxPicHeight = pCfg->iPicHeight; |
| 333 | 333 | |
| 334 | 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 | 336 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed."); |
| 337 | 337 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG, |
| 338 | 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 | 478 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, |
| 479 | 479 | "CWelsH264SVCEncoder::ForceIntraFrame(), bIDR= %d", bIDR); |
| 480 | + | |
| 480 | 481 | ForceCodingIDR (m_pEncContext); |
| 481 | 482 | |
| 482 | 483 | m_pEncContext->sEncoderStatistics.uiIDRReqNum++; |
| @@ -486,8 +487,8 @@ int CWelsH264SVCEncoder::ForceIntraFrame (bool bIDR) { · 3 unmodified lines | ||
| 486 | 487 | void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { |
| 487 | 488 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, |
| 488 | 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 | − iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d", | |
| 490 | + iSpsPpsIdStrategy = %d;bPrefixNalAddingCtrl = %d;bEnableDenoise= %d;bEnableBackgroundDetection= %d;bEnableAdaptiveQuant= %d;bEnableFrameSkip= %d;bEnableLongTermReference= %d;iLtrMarkPeriod= %d;\ | |
| 491 | + iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d (offset(alpha/beta): %d,%d)", | |
| 491 | 492 | pParam->iUsageType, |
| 492 | 493 | pParam->iPicWidth, |
| 493 | 494 | pParam->iPicHeight, |
| @@ -499,7 +500,7 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { · 5 unmodified lines | ||
| 499 | 500 | pParam->iSpatialLayerNum, |
| 500 | 501 | pParam->fMaxFrameRate, |
| 501 | 502 | pParam->uiIntraPeriod, |
| 502 | − pParam->bEnableSpsPpsIdAddition, | |
| 503 | + pParam->iSpsPpsIdStrategy, | |
| 503 | 504 | pParam->bPrefixNalAddingCtrl, |
| 504 | 505 | pParam->bEnableDenoise, |
| 505 | 506 | pParam->bEnableBackgroundDetection, |
| @@ -513,7 +514,9 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { · 7 unmodified lines | ||
| 513 | 514 | pParam->uiMaxNalSize, |
| 514 | 515 | pParam->iLTRRefNum, |
| 515 | 516 | pParam->iMultipleThreadIdc, |
| 516 | − pParam->iLoopFilterDisableIdc | |
| 517 | + pParam->iLoopFilterDisableIdc, | |
| 518 | + pParam->iLoopFilterAlphaC0Offset, | |
| 519 | + pParam->iLoopFilterBetaOffset | |
| 517 | 520 | ); |
| 518 | 521 | int32_t i = 0; |
| 519 | 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 | 709 | #endif//OUTPUT_BIT_STREAM |
| 707 | 710 | if (sEncodingParam.iSpatialLayerNum < 1 |
| 708 | 711 | || 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 | 715 | return cmInitParaError; |
| 710 | 716 | } |
| 711 | 717 | |
| 712 | 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 | 721 | return cmInitParaError; |
| 714 | 722 | } |
| 715 | 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 | 727 | return cmInitParaError; |
| 717 | 728 | } |
| 718 | 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 | 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 | 912 | break; |
| 900 | 913 | case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: { |
| 901 | − bool iValue = * ((bool*)pOption); | |
| 902 | − | |
| 903 | − m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition = iValue; | |
| 904 | − WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable SPS/PPS ID = %d ", | |
| 905 | − m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition); | |
| 914 | + int32_t iValue = * ((int32_t*)pOption); | |
| 915 | + if (((iValue > INCREASING_ID) || (m_pEncContext->pSvcParam->iSpsPpsIdStrategy > INCREASING_ID)) | |
| 916 | + && m_pEncContext->pSvcParam->iSpsPpsIdStrategy != iValue) { | |
| 917 | + WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, | |
| 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 | 926 | break; |
| 908 | 927 | case ENCODER_OPTION_CURRENT_PATH: { |
| @@ -88,26 +88,25 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar · 87 unmodified lines | ||
| 88 | 88 | BaseDecoderTest::TearDown(); |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | − virtual void prepareParam (int iLayers, int iSlices, int width, int height, float framerate) { | |
| 92 | − memset (¶m_, 0, sizeof (SEncParamExt)); | |
| 93 | − param_.iUsageType = CAMERA_VIDEO_REAL_TIME; | |
| 94 | − param_.iPicWidth = width; | |
| 95 | − param_.iPicHeight = height; | |
| 96 | − param_.fMaxFrameRate = framerate; | |
| 97 | − param_.iRCMode = RC_OFF_MODE; //rc off | |
| 98 | − param_.iMultipleThreadIdc = 1; //single thread | |
| 99 | − param_.iSpatialLayerNum = iLayers; | |
| 100 | − param_.iNumRefFrame = AUTO_REF_PIC_COUNT; | |
| 91 | + virtual void prepareParam (int iLayers, int iSlices, int width, int height, float framerate, SEncParamExt* pParam) { | |
| 92 | + memset (pParam, 0, sizeof (SEncParamExt)); | |
| 93 | + pParam->iUsageType = CAMERA_VIDEO_REAL_TIME; | |
| 94 | + pParam->iPicWidth = width; | |
| 95 | + pParam->iPicHeight = height; | |
| 96 | + pParam->fMaxFrameRate = framerate; | |
| 97 | + pParam->iRCMode = RC_OFF_MODE; //rc off | |
| 98 | + pParam->iMultipleThreadIdc = 1; //single thread | |
| 99 | + pParam->iSpatialLayerNum = iLayers; | |
| 100 | + pParam->iNumRefFrame = AUTO_REF_PIC_COUNT; | |
| 101 | 101 | for (int i = 0; i < iLayers; i++) { |
| 102 | − param_.sSpatialLayers[i].iVideoWidth = width >> (iLayers - i - 1); | |
| 103 | − param_.sSpatialLayers[i].iVideoHeight = height >> (iLayers - i - 1); | |
| 104 | − param_.sSpatialLayers[i].fFrameRate = framerate; | |
| 105 | − param_.sSpatialLayers[i].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE; | |
| 106 | − param_.sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceNum = iSlices; | |
| 102 | + pParam->sSpatialLayers[i].iVideoWidth = width >> (iLayers - i - 1); | |
| 103 | + pParam->sSpatialLayers[i].iVideoHeight = height >> (iLayers - i - 1); | |
| 104 | + pParam->sSpatialLayers[i].fFrameRate = framerate; | |
| 105 | + pParam->sSpatialLayers[i].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE; | |
| 106 | + pParam->sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceNum = iSlices; | |
| 107 | 107 | } |
| 108 | − | |
| 109 | − | |
| 110 | 108 | } |
| 109 | + | |
| 111 | 110 | virtual void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) { |
| 112 | 111 | //for encoder |
| 113 | 112 | //I420: 1(Y) + 1/4(U) + 1/4(V) |
| @@ -147,6 +146,15 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar · 33 unmodified lines | ||
| 147 | 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 | 158 | protected: |
| 151 | 159 | SEncParamExt param_; |
| 152 | 160 | BufferedData buf_; |
| @@ -171,8 +179,8 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase { · 18 unmodified lines | ||
| 171 | 179 | EncodeDecodeTestBase::TearDown(); |
| 172 | 180 | } |
| 173 | 181 | |
| 174 | − void prepareParam (int iLayers, int iSlices, int width, int height, float framerate) { | |
| 175 | − EncodeDecodeTestBase::prepareParam (iLayers, iSlices, width, height, framerate); | |
| 182 | + void prepareParam (int iLayers, int iSlices, int width, int height, float framerate, SEncParamExt* pParam) { | |
| 183 | + EncodeDecodeTestBase::prepareParam (iLayers, iSlices, width, height, framerate, pParam); | |
| 176 | 184 | } |
| 177 | 185 | |
| 178 | 186 | void InitialEncDec (int iWidth, int iHeight); |
| @@ -192,6 +200,24 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase { · 13 unmodified lines | ||
| 192 | 200 | else if (1 == iCheckTypeIndex) |
| 193 | 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 | |
| 197 | 223 | void EncodeDecodeTestAPI::InitialEncDec (int iWidth, int iHeight) { |
| @@ -234,7 +260,7 @@ void EncodeDecodeTestAPI::RandomParamExtCombination() { · 36 unmodified lines | ||
| 234 | 260 | param_.iNumRefFrame = AUTO_REF_PIC_COUNT; |
| 235 | 261 | param_.iMultipleThreadIdc = rand(); |
| 236 | 262 | |
| 237 | − param_.bEnableSpsPpsIdAddition = (rand() % 2 == 0) ? false : true; | |
| 263 | + param_.iSpsPpsIdStrategy = rand() % 3; | |
| 238 | 264 | param_.bPrefixNalAddingCtrl = (rand() % 2 == 0) ? false : true; |
| 239 | 265 | param_.bEnableSSEI = (rand() % 2 == 0) ? false : true; |
| 240 | 266 | param_.iPaddingFlag = rand() % 2; |
| @@ -462,7 +488,7 @@ static const EncodeDecodeFileParamBase kFileParamArray[] = { · 221 unmodified lines | ||
| 462 | 488 | |
| 463 | 489 | TEST_P (EncodeDecodeTestAPI, DecoderVclNal) { |
| 464 | 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, ¶m_); | |
| 466 | 492 | encoder_->Uninitialize(); |
| 467 | 493 | int rv = encoder_->InitializeExt (¶m_); |
| 468 | 494 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -498,7 +524,7 @@ TEST_P (EncodeDecodeTestAPI, DecoderVclNal) { · 29 unmodified lines | ||
| 498 | 524 | |
| 499 | 525 | TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) { |
| 500 | 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, ¶m_); | |
| 502 | 528 | encoder_->Uninitialize(); |
| 503 | 529 | int rv = encoder_->InitializeExt (¶m_); |
| 504 | 530 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -535,7 +561,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) { · 30 unmodified lines | ||
| 535 | 561 | |
| 536 | 562 | TEST_P (EncodeDecodeTestAPI, GetOptionIDR) { |
| 537 | 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, ¶m_); | |
| 539 | 565 | encoder_->Uninitialize(); |
| 540 | 566 | int rv = encoder_->InitializeExt (¶m_); |
| 541 | 567 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -554,7 +580,8 @@ TEST_P (EncodeDecodeTestAPI, GetOptionIDR) { · 12 unmodified lines | ||
| 554 | 580 | int32_t iSpsPpsIdAddition = 0; |
| 555 | 581 | int iIdx = 0; |
| 556 | 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 | 585 | iIDRPeriod = (rand() % 150) + 1; |
| 559 | 586 | encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod); |
| 560 | 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 | |
| 777 | 804 | TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) { |
| 778 | 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, ¶m_); | |
| 780 | 807 | encoder_->Uninitialize(); |
| 781 | 808 | int rv = encoder_->InitializeExt (¶m_); |
| 782 | 809 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -809,7 +836,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLLTR) { · 26 unmodified lines | ||
| 809 | 836 | SLTRMarkingFeedback m_LTR_Marking_Feedback; |
| 810 | 837 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 811 | 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, ¶m_); | |
| 813 | 840 | encoder_->Uninitialize(); |
| 814 | 841 | int rv = encoder_->InitializeExt (¶m_); |
| 815 | 842 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -868,7 +895,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_Engine) { · 52 unmodified lines | ||
| 868 | 895 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 869 | 896 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 870 | 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, ¶m_); | |
| 872 | 899 | encoder_->Uninitialize(); |
| 873 | 900 | int rv = encoder_->InitializeExt (¶m_); |
| 874 | 901 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -918,7 +945,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_DISABLE) { · 43 unmodified lines | ||
| 918 | 945 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 919 | 946 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 920 | 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, ¶m_); | |
| 922 | 949 | param_.bEnableLongTermReference = true; |
| 923 | 950 | param_.iLTRRefNum = 1; |
| 924 | 951 | encoder_->Uninitialize(); |
| @@ -985,7 +1012,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) { · 60 unmodified lines | ||
| 985 | 1012 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 986 | 1013 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 987 | 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, ¶m_); | |
| 989 | 1016 | encoder_->Uninitialize(); |
| 990 | 1017 | int rv = encoder_->InitializeExt (¶m_); |
| 991 | 1018 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -1036,7 +1063,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) { · 44 unmodified lines | ||
| 1036 | 1063 | |
| 1037 | 1064 | TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) { |
| 1038 | 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, ¶m_); | |
| 1040 | 1067 | encoder_->Uninitialize(); |
| 1041 | 1068 | int rv = encoder_->InitializeExt (¶m_); |
| 1042 | 1069 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -1086,7 +1113,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_NOPREFIX) { · 43 unmodified lines | ||
| 1086 | 1113 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1087 | 1114 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1088 | 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, ¶m_); | |
| 1090 | 1117 | param_.bPrefixNalAddingCtrl = false; |
| 1091 | 1118 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1092 | 1119 | encoder_->Uninitialize(); |
| @@ -1155,7 +1182,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_WITH_PREFIX_NOLOSS) { · 62 unmodified lines | ||
| 1155 | 1182 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1156 | 1183 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1157 | 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, ¶m_); | |
| 1159 | 1186 | param_.bPrefixNalAddingCtrl = true; |
| 1160 | 1187 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1161 | 1188 | param_.iSpatialLayerNum = 1; |
| @@ -1210,7 +1237,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_SVC_L1_NOLOSS) { · 48 unmodified lines | ||
| 1210 | 1237 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1211 | 1238 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1212 | 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, ¶m_); | |
| 1214 | 1241 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1215 | 1242 | param_.iSpatialLayerNum = 2; |
| 1216 | 1243 | encoder_->Uninitialize(); |
| @@ -1266,7 +1293,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace) { · 49 unmodified lines | ||
| 1266 | 1293 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1267 | 1294 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1268 | 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, ¶m_); | |
| 1270 | 1297 | param_.iSpatialLayerNum = 1; |
| 1271 | 1298 | |
| 1272 | 1299 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1330,7 +1357,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace_NULL) { · 57 unmodified lines | ||
| 1330 | 1357 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1331 | 1358 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1332 | 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, ¶m_); | |
| 1334 | 1361 | param_.iSpatialLayerNum = 1; |
| 1335 | 1362 | int rv = encoder_->InitializeExt (¶m_); |
| 1336 | 1363 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -1393,7 +1420,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECIDC_GeneralSliceChange) { · 56 unmodified lines | ||
| 1393 | 1420 | uint32_t uiEcIdc; |
| 1394 | 1421 | uint32_t uiGet; |
| 1395 | 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, ¶m_); | |
| 1397 | 1424 | param_.iSpatialLayerNum = 1; |
| 1398 | 1425 | encoder_->Uninitialize(); |
| 1399 | 1426 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1473,7 +1500,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) { · 73 unmodified lines | ||
| 1473 | 1500 | uint32_t uiEcIdc; |
| 1474 | 1501 | uint32_t uiGet; |
| 1475 | 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, ¶m_); | |
| 1477 | 1504 | param_.iSpatialLayerNum = 1; |
| 1478 | 1505 | encoder_->Uninitialize(); |
| 1479 | 1506 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1612,7 +1639,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) { · 132 unmodified lines | ||
| 1612 | 1639 | uint32_t uiEcIdc = 2; //default set as SLICE_COPY |
| 1613 | 1640 | uint32_t uiGet; |
| 1614 | 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, ¶m_); | |
| 1616 | 1643 | param_.iSpatialLayerNum = 1; |
| 1617 | 1644 | encoder_->Uninitialize(); |
| 1618 | 1645 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1745,7 +1772,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) { · 126 unmodified lines | ||
| 1745 | 1772 | uint32_t uiEcIdc; |
| 1746 | 1773 | uint32_t uiGet; |
| 1747 | 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, ¶m_); | |
| 1749 | 1776 | param_.iSpatialLayerNum = 1; |
| 1750 | 1777 | encoder_->Uninitialize(); |
| 1751 | 1778 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1914,7 +1941,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_I) { · 162 unmodified lines | ||
| 1914 | 1941 | EncodeDecodeFileParamBase p = kSVCSwitch[0]; |
| 1915 | 1942 | p.width = p.width << 2; |
| 1916 | 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, ¶m_); | |
| 1918 | 1945 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1919 | 1946 | param_.iSpatialLayerNum = 4; |
| 1920 | 1947 | encoder_->Uninitialize(); |
| @@ -1979,7 +2006,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_P) { · 58 unmodified lines | ||
| 1979 | 2006 | int iLastDid = 0; |
| 1980 | 2007 | p.width = p.width << 2; |
| 1981 | 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, ¶m_); | |
| 1983 | 2010 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1984 | 2011 | param_.iSpatialLayerNum = 4; |
| 1985 | 2012 | encoder_->Uninitialize(); |
| @@ -2065,7 +2092,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionEncParamExt) { · 79 unmodified lines | ||
| 2065 | 2092 | int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM); |
| 2066 | 2093 | int iSliceNum = 1; |
| 2067 | 2094 | encoder_->GetDefaultParams (¶m_); |
| 2068 | − prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate); | |
| 2095 | + prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_); | |
| 2069 | 2096 | |
| 2070 | 2097 | int rv = encoder_->InitializeExt (¶m_); |
| 2071 | 2098 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -2128,8 +2155,8 @@ class DecodeCrashTestAPI : public EncodeDecodeTestBase { · 56 unmodified lines | ||
| 2128 | 2155 | ASSERT_TRUE (ucBuf_ == NULL); |
| 2129 | 2156 | } |
| 2130 | 2157 | |
| 2131 | − void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate) { | |
| 2132 | − EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate); | |
| 2158 | + void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate, SEncParamExt* pParam) { | |
| 2159 | + EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate, pParam); | |
| 2133 | 2160 | } |
| 2134 | 2161 | |
| 2135 | 2162 | void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam); |
| @@ -2203,11 +2230,11 @@ TEST_F (DecodeCrashTestAPI, DecoderCrashTest) { · 67 unmodified lines | ||
| 2203 | 2230 | int iSeed = rand() % 3; //3 indicates the length of kParamArray[] used in the following |
| 2204 | 2231 | EncodeDecodeParamBase p = kParamArray[iSeed]; |
| 2205 | 2232 | //Initialize Encoder |
| 2206 | − prepareParam (1, 1, p.width, p.height, p.frameRate); | |
| 2233 | + prepareParam (1, 1, p.width, p.height, p.frameRate, ¶m_); | |
| 2207 | 2234 | param_.iRCMode = RC_BITRATE_MODE; |
| 2208 | 2235 | param_.iTargetBitrate = p.iTarBitrate; |
| 2209 | 2236 | param_.uiIntraPeriod = 0; |
| 2210 | − param_.bEnableSpsPpsIdAddition = true; | |
| 2237 | + param_.iSpsPpsIdStrategy = INCREASING_ID; | |
| 2211 | 2238 | param_.bEnableBackgroundDetection = true; |
| 2212 | 2239 | param_.bEnableSceneChangeDetect = true; |
| 2213 | 2240 | param_.bPrefixNalAddingCtrl = true; |
| @@ -2398,7 +2425,7 @@ TEST_F (DecodeParseAPI, ParseOnly_General) { · 184 unmodified lines | ||
| 2398 | 2425 | p.height = iHeight_; |
| 2399 | 2426 | p.frameRate = kiFrameRate; |
| 2400 | 2427 | p.numframes = kiFrameNum; |
| 2401 | − prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate); | |
| 2428 | + prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate, ¶m_); | |
| 2402 | 2429 | param_.iSpatialLayerNum = kiTotalLayer; |
| 2403 | 2430 | encoder_->Uninitialize(); |
| 2404 | 2431 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -2475,7 +2502,7 @@ TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) { · 70 unmodified lines | ||
| 2475 | 2502 | p.height = iHeight_; |
| 2476 | 2503 | p.frameRate = kiFrameRate; |
| 2477 | 2504 | p.numframes = 5; |
| 2478 | − prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate); | |
| 2505 | + prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate, ¶m_); | |
| 2479 | 2506 | param_.iSpatialLayerNum = iLayerNum; |
| 2480 | 2507 | encoder_->Uninitialize(); |
| 2481 | 2508 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -2525,3 +2552,434 @@ TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) { · 43 unmodified lines | ||
| 2525 | 2552 | } //while |
| 2526 | 2553 | } |
| 2527 | 2554 | |
| 2555 | +//#define DEBUG_FILE_SAVE2 | |
| 2556 | +TEST_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 | |
| 2666 | +TEST_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 | + | |
| 2723 | +TEST_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 | |
| 2780 | +TEST_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 | + | |
| 2832 | +TEST_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 | + | |
| 2913 | +TEST_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 | + | |
| @@ -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 | + | |
| 9 | +using namespace WelsEnc; | |
| 10 | + | |
| 11 | +class 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 | + | |
| 44 | +void 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 | + | |
| 56 | +TEST_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 | + | |
| @@ -11,6 +11,7 @@ ENCODER_UNITTEST_CPP_SRCS=\ · 10 unmodified lines | ||
| 11 | 11 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\ |
| 12 | 12 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryZero.cpp\ |
| 13 | 13 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\ |
| 14 | + $(ENCODER_UNITTEST_SRCDIR)/EncUT_ParameterSetStrategy.cpp\ | |
| 14 | 15 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_Reconstruct.cpp\ |
| 15 | 16 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_Sample.cpp\ |
| 16 | 17 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_SVC_me.cpp\ |