[Encoder] add new SpsPpsStrategy and UT
Unified · Split
| @@ -385,6 +385,17 @@ typedef enum { · 384 unmodified lines | |||
| 385 | HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality | 385 | HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality |
| 386 | } ECOMPLEXITY_MODE; | 386 | } ECOMPLEXITY_MODE; |
| 387 | 387 | ||
| 388 | /** | ||
| 389 | * @brief Enumulate for the stategy of SPS/PPS strategy | ||
| 390 | */ | ||
| 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 | // TODO: Refine the parameters definition. | 399 | // TODO: Refine the parameters definition. |
| 389 | /** | 400 | /** |
| 390 | * @brief SVC Encoding Parameters | 401 | * @brief SVC Encoding Parameters |
| @@ -421,7 +432,7 @@ typedef struct TagEncParamExt { · 30 unmodified lines | |||
| 421 | ECOMPLEXITY_MODE iComplexityMode; | 432 | ECOMPLEXITY_MODE iComplexityMode; |
| 422 | unsigned int uiIntraPeriod; ///< period of Intra frame | 433 | unsigned int uiIntraPeriod; ///< period of Intra frame |
| 423 | int iNumRefFrame; ///< number of reference frame used | 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 | bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL | 436 | bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL |
| 426 | bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI | 437 | bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI |
| 427 | bool bSimulcastAVC; ///< (when encoding more than 1 spatial layer) false: use SVC syntax for higher layers; true: use Simulcast AVC -- coming soon | 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 | pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str()); | 232 | pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str()); |
| 233 | } else if (strTag[0].compare ("MaxNalSize") == 0) { | 233 | } else if (strTag[0].compare ("MaxNalSize") == 0) { |
| 234 | pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str()); | 234 | pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str()); |
| 235 | } else if (strTag[0].compare ("EnableSpsPpsIDAddition") == 0) { | 235 | } else if (strTag[0].compare ("SpsPpsIDStrategy") == 0) { |
| 236 | pSvcParam.bEnableSpsPpsIdAddition = atoi (strTag[1].c_str()) ? true : false; | 236 | pSvcParam.iSpsPpsIdStrategy = atoi (strTag[1].c_str()); |
| 237 | } else if (strTag[0].compare ("EnableScalableSEI") == 0) { | 237 | } else if (strTag[0].compare ("EnableScalableSEI") == 0) { |
| 238 | pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false; | 238 | pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false; |
| 239 | } else if (strTag[0].compare ("EnableFrameCropping") == 0) { | 239 | } else if (strTag[0].compare ("EnableFrameCropping") == 0) { |
| @@ -421,7 +421,7 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE · 181 unmodified lines | |||
| 421 | pSvcParam.uiMaxNalSize = atoi (argv[n++]); | 421 | pSvcParam.uiMaxNalSize = atoi (argv[n++]); |
| 422 | 422 | ||
| 423 | else if (!strcmp (pCommand, "-spsid") && (n < argc)) | 423 | else if (!strcmp (pCommand, "-spsid") && (n < argc)) |
| 424 | pSvcParam.bEnableSpsPpsIdAddition = atoi (argv[n++]) ? true : false; | 424 | pSvcParam.iSpsPpsIdStrategy = atoi (argv[n++]); |
| 425 | 425 | ||
| 426 | else if (!strcmp (pCommand, "-cabac") && (n < argc)) | 426 | else if (!strcmp (pCommand, "-cabac") && (n < argc)) |
| 427 | pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]); | 427 | pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]); |
| @@ -591,7 +591,7 @@ int FillSpecificParameters (SEncParamExt& sParam) { · 163 unmodified lines | |||
| 591 | sParam.bEnableLongTermReference = 0; // long term reference control | 591 | sParam.bEnableLongTermReference = 0; // long term reference control |
| 592 | sParam.iLtrMarkPeriod = 30; | 592 | sParam.iLtrMarkPeriod = 30; |
| 593 | sParam.uiIntraPeriod = 320; // period of Intra frame | 593 | sParam.uiIntraPeriod = 320; // period of Intra frame |
| 594 | sParam.bEnableSpsPpsIdAddition = 1; | 594 | sParam.iSpsPpsIdStrategy = INCREASING_ID; |
| 595 | sParam.bPrefixNalAddingCtrl = 0; | 595 | sParam.bPrefixNalAddingCtrl = 0; |
| 596 | sParam.iComplexityMode = MEDIUM_COMPLEXITY; | 596 | sParam.iComplexityMode = MEDIUM_COMPLEXITY; |
| 597 | int iIndexLayer = 0; | 597 | int iIndexLayer = 0; |
| @@ -141,8 +141,26 @@ int32_t WelsInitPps (SWelsPPS* pPps, · 140 unmodified lines | |||
| 141 | const bool kbDeblockingFilterPresentFlag, | 141 | const bool kbDeblockingFilterPresentFlag, |
| 142 | const bool kbUsingSubsetSps, | 142 | const bool kbUsingSubsetSps, |
| 143 | const bool kbEntropyCodingModeFlag); | 143 | const bool kbEntropyCodingModeFlag); |
| 144 | |||
| 144 | int32_t WelsCheckRefFrameLimitationNumRefFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam); | 145 | int32_t WelsCheckRefFrameLimitationNumRefFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam); |
| 145 | int32_t WelsCheckRefFrameLimitationLevelIdcFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam); | 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 | #endif//WELS_ACCESS_UNIT_PARSER_H__ | 166 | #endif//WELS_ACCESS_UNIT_PARSER_H__ |
| @@ -48,7 +48,7 @@ namespace WelsEnc { · 47 unmodified lines | |||
| 48 | * \param pEncCtx sWelsEncCtx* | 48 | * \param pEncCtx sWelsEncCtx* |
| 49 | * \return successful - 0; otherwise none 0 for failed | 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 | * \brief free memory in SVC core encoder | 54 | * \brief free memory in SVC core encoder |
| @@ -191,6 +191,7 @@ typedef struct TagWelsEncCtx { · 190 unmodified lines | |||
| 191 | SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible | 191 | SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible |
| 192 | SSubsetSps* pSubsetSps; | 192 | SSubsetSps* pSubsetSps; |
| 193 | int32_t iSpsNum; // number of pSps used | 193 | int32_t iSpsNum; // number of pSps used |
| 194 | int32_t iSubsetSpsNum; // number of pSps used | ||
| 194 | int32_t iPpsNum; // number of pPps used | 195 | int32_t iPpsNum; // number of pPps used |
| 195 | 196 | ||
| 196 | // Output | 197 | // Output |
| @@ -216,6 +217,7 @@ typedef struct TagWelsEncCtx { · 19 unmodified lines | |||
| 216 | pDqIdcMap; // overall DQ map of full scalability in specific frame (All full D/T/Q layers involved) // pDqIdcMap[dq_index] for each SDqIdc pData | 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 | SParaSetOffset sPSOVector; | 219 | SParaSetOffset sPSOVector; |
| 220 | SParaSetOffset* pPSOVector; | ||
| 219 | CMemoryAlign* pMemAlign; | 221 | CMemoryAlign* pMemAlign; |
| 220 | 222 | ||
| 221 | #if defined(STAT_OUTPUT) | 223 | #if defined(STAT_OUTPUT) |
| @@ -75,7 +75,8 @@ void GomValidCheck (const int32_t kiMbWidth, const int32_t kiMbHeight, int32_t* · 74 unmodified lines | |||
| 75 | * \param para SWelsSvcCodingParam* | 75 | * \param para SWelsSvcCodingParam* |
| 76 | * \return successful - 0; otherwise none 0 for failed | 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 | * \brief uninitialize Wels encoder core library | 82 | * \brief uninitialize Wels encoder core library |
| @@ -162,7 +162,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 161 unmodified lines | |||
| 162 | param.bEnableAdaptiveQuant = true; // adaptive quantization control | 162 | param.bEnableAdaptiveQuant = true; // adaptive quantization control |
| 163 | param.bEnableFrameSkip = true; // frame skipping | 163 | param.bEnableFrameSkip = true; // frame skipping |
| 164 | param.bEnableLongTermReference = false; // long term reference control | 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 | param.bPrefixNalAddingCtrl = false; // prefix NAL adding control | 166 | param.bPrefixNalAddingCtrl = false; // prefix NAL adding control |
| 167 | param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded | 167 | param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded |
| 168 | param.iTemporalLayerNum = 1; // number of temporal layer specified | 168 | param.iTemporalLayerNum = 1; // number of temporal layer specified |
| @@ -350,8 +350,8 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 181 unmodified lines | |||
| 350 | 350 | ||
| 351 | bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl; | 351 | bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl; |
| 352 | 352 | ||
| 353 | bEnableSpsPpsIdAddition = | 353 | iSpsPpsIdStrategy = |
| 354 | pCodingParam.bEnableSpsPpsIdAddition;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference. | 354 | pCodingParam.iSpsPpsIdStrategy;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference. |
| 355 | //SHOULD enable this feature. | 355 | //SHOULD enable this feature. |
| 356 | 356 | ||
| 357 | SSpatialLayerInternal* pDlp = &sDependencyLayers[0]; | 357 | SSpatialLayerInternal* pDlp = &sDependencyLayers[0]; |
| @@ -477,6 +477,18 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt { · 119 unmodified lines | |||
| 477 | 477 | ||
| 478 | } SWelsSvcCodingParam; | 478 | } SWelsSvcCodingParam; |
| 479 | 479 | ||
| 480 | |||
| 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 | static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) { | 492 | static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) { |
| 481 | if (pParam == NULL || *pParam == NULL || pMa == NULL) | 493 | if (pParam == NULL || *pParam == NULL || pMa == NULL) |
| 482 | return 1; | 494 | return 1; |
| @@ -83,9 +83,15 @@ typedef struct TagParaSetOffset { · 82 unmodified lines | |||
| 83 | bool | 83 | bool |
| 84 | bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far | 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 | #if _DEBUG | 88 | #if _DEBUG |
| 87 | bool bEnableSpsPpsIdAddition; | 89 | int32_t iSpsPpsIdStrategy; |
| 88 | #endif | 90 | #endif |
| 91 | |||
| 92 | uint32_t uiInUseSpsNum; | ||
| 93 | uint32_t uiInUseSubsetSpsNum; | ||
| 94 | uint32_t uiInUsePpsNum; | ||
| 89 | } SParaSetOffset; | 95 | } SParaSetOffset; |
| 90 | 96 | ||
| 91 | 97 | ||
| @@ -171,6 +171,7 @@ · 170 unmodified lines | |||
| 171 | 171 | ||
| 172 | #define UNAVAILABLE_DQ_ID ((uint8_t)(-1)) | 172 | #define UNAVAILABLE_DQ_ID ((uint8_t)(-1)) |
| 173 | #define LAYER_NUM_EXCHANGEABLE 2 | 173 | #define LAYER_NUM_EXCHANGEABLE 2 |
| 174 | #define INVALID_ID (-1) | ||
| 174 | 175 | ||
| 175 | #define NAL_HEADER_ADD_0X30BYTES 50 | 176 | #define NAL_HEADER_ADD_0X30BYTES 50 |
| 176 | 177 | ||
| @@ -336,27 +336,27 @@ int32_t WelsWriteSubsetSpsSyntax (SSubsetSps* pSubsetSps, SBitStringAux* pBitStr · 335 unmodified lines | |||
| 336 | * \note Call it in case EWelsNalUnitType is PPS. | 336 | * \note Call it in case EWelsNalUnitType is PPS. |
| 337 | ************************************************************************************* | 337 | ************************************************************************************* |
| 338 | */ | 338 | */ |
| 339 | int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* sPSOVector) { | 339 | int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* pPSOVector) { |
| 340 | SBitStringAux* pLocalBitStringAux = pBitStringAux; | 340 | SBitStringAux* pLocalBitStringAux = pBitStringAux; |
| 341 | 341 | ||
| 342 | bool bUsedSubset = sPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId]; | 342 | const int32_t kiParameterSetType = (pPSOVector != NULL) ? (pPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId] ? |
| 343 | int32_t iParameterSetType = (bUsedSubset ? PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS); | 343 | PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS) : 0; |
| 344 | 344 | ||
| 345 | BsWriteUE (pLocalBitStringAux, pPps->iPpsId + | 345 | BsWriteUE (pLocalBitStringAux, pPps->iPpsId |
| 346 | sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]); | 346 | + ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]) : 0)); |
| 347 | BsWriteUE (pLocalBitStringAux, pPps->iSpsId + | 347 | BsWriteUE (pLocalBitStringAux, pPps->iSpsId |
| 348 | sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId]); | 348 | + ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId]) : 0)); |
| 349 | 349 | ||
| 350 | #if _DEBUG | 350 | #if _DEBUG |
| 351 | //SParaSetOffset use, 110421 | 351 | //SParaSetOffset use, 110421 |
| 352 | if (sPSOVector->bEnableSpsPpsIdAddition) { | 352 | if ((pPSOVector != NULL) && (INCREASING_ID & pPSOVector->iSpsPpsIdStrategy)) { |
| 353 | const int32_t kiTmpSpsIdInBs = pPps->iSpsId + | 353 | const int32_t kiTmpSpsIdInBs = pPps->iSpsId + |
| 354 | sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId]; | 354 | pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId]; |
| 355 | const int32_t tmp_pps_id_in_bs = pPps->iPpsId + | 355 | const int32_t tmp_pps_id_in_bs = pPps->iPpsId + |
| 356 | sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]; | 356 | pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]; |
| 357 | assert (MAX_SPS_COUNT > kiTmpSpsIdInBs); | 357 | assert (MAX_SPS_COUNT > kiTmpSpsIdInBs); |
| 358 | assert (MAX_PPS_COUNT > tmp_pps_id_in_bs); | 358 | assert (MAX_PPS_COUNT > tmp_pps_id_in_bs); |
| 359 | assert (sPSOVector->sParaSetOffsetVariable[iParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]); | 359 | assert (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]); |
| 360 | } | 360 | } |
| 361 | #endif | 361 | #endif |
| 362 | 362 | ||
| @@ -323,6 +323,12 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa · 322 unmodified lines | |||
| 323 | pCodingParam->bDeblockingParallelFlag = true; | 323 | pCodingParam->bDeblockingParallelFlag = true; |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | if (pCodingParam->iSpatialLayerNum > 1 && (SPS_LISTING & pCodingParam->iSpsPpsIdStrategy)) { | ||
| 327 | WelsLog (pLogCtx, WELS_LOG_INFO, | ||
| 328 | "ParamValidationExt(), iSpsPpsIdStrategy adjusted to CONSTANT_ID"); | ||
| 329 | pCodingParam->iSpsPpsIdStrategy = CONSTANT_ID; | ||
| 330 | } | ||
| 331 | |||
| 326 | for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) { | 332 | for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) { |
| 327 | SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i]; | 333 | SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i]; |
| 328 | const int32_t kiPicWidth = pSpatialLayer->iVideoWidth; | 334 | const int32_t kiPicWidth = pSpatialLayer->iVideoWidth; |
| @@ -665,8 +671,12 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara · 336 unmodified lines | |||
| 665 | ++ iDIndex; | 671 | ++ iDIndex; |
| 666 | } while (iDIndex < iNumDependencyLayers); | 672 | } while (iDIndex < iNumDependencyLayers); |
| 667 | 673 | ||
| 674 | // count parasets | ||
| 668 | iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) + | 675 | iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) + |
| 669 | iCountNumLayers; // plus iCountNumLayers for reserved 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 | // to check number of layers / nals / slices dependencies, 12/8/2010 | 681 | // to check number of layers / nals / slices dependencies, 12/8/2010 |
| 672 | if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) { | 682 | if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) { |
| @@ -847,9 +857,9 @@ void FreeMbCache (SMbCache* pMbCache, CMemoryAlign* pMa) { · 174 unmodified lines | |||
| 847 | } | 857 | } |
| 848 | } | 858 | } |
| 849 | 859 | ||
| 850 | int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex, | 860 | static int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex, |
| 851 | const int32_t iDlayerCount, const int32_t kiSpsId, | 861 | const int32_t iDlayerCount, const int32_t kiSpsId, |
| 852 | SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) { | 862 | SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) { |
| 853 | int32_t iRet = 0; | 863 | int32_t iRet = 0; |
| 854 | 864 | ||
| 855 | if (!kbUseSubsetSps) { | 865 | if (!kbUseSubsetSps) { |
| @@ -866,9 +876,6 @@ int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const · 10 unmodified lines | |||
| 866 | iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, | 876 | iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, |
| 867 | pParam->iMaxNumRefFrame, | 877 | pParam->iMaxNumRefFrame, |
| 868 | kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount); | 878 | kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount); |
| 869 | |||
| 870 | |||
| 871 | |||
| 872 | } else { | 879 | } else { |
| 873 | iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, | 880 | iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod, |
| 874 | pParam->iMaxNumRefFrame, | 881 | pParam->iMaxNumRefFrame, |
| @@ -877,12 +884,131 @@ int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const · 2 unmodified lines | |||
| 877 | return iRet; | 884 | return iRet; |
| 878 | } | 885 | } |
| 879 | 886 | ||
| 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 | * \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available | 1007 | * \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available |
| 882 | * \pParam pCtx sWelsEncCtx* | 1008 | * \pParam pCtx sWelsEncCtx* |
| 883 | * \return 0 - successful; otherwise failed | 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 | SWelsSvcCodingParam* pParam = NULL; | 1012 | SWelsSvcCodingParam* pParam = NULL; |
| 887 | SWelsSPS* pSps = NULL; | 1013 | SWelsSPS* pSps = NULL; |
| 888 | SSubsetSps* pSubsetSps = NULL; | 1014 | SSubsetSps* pSubsetSps = NULL; |
| @@ -1045,14 +1171,51 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { · 156 unmodified lines | |||
| 1045 | } | 1171 | } |
| 1046 | 1172 | ||
| 1047 | // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010 | 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"); | 1174 | // SPS |
| 1049 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx)) | 1175 | if (! (SPS_LISTING & pParam->iSpsPpsIdStrategy)) { |
| 1176 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray"); | ||
| 1177 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | ||
| 1178 | if (iDlayerCount > 1) { | ||
| 1179 | (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray"); | ||
| 1180 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx)) | ||
| 1181 | } | ||
| 1182 | } else { | ||
| 1183 | // pParam->iSpsPpsIdStrategy == SPS_LISTING_AND_PPS_INCREASING | ||
| 1184 | // new memory | ||
| 1185 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "pSpsArray"); | ||
| 1186 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | ||
| 1050 | 1187 | ||
| 1051 | (*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray"); | 1188 | (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "pSubsetArray"); |
| 1052 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx)) | ||
| 1053 | if (iDlayerCount > 1) { | ||
| 1054 | (*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray"); | ||
| 1055 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx)) | 1189 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx)) |
| 1190 | |||
| 1191 | // copy from existing if the pointer exists | ||
| 1192 | if (NULL != pExistingParasetList) { | ||
| 1193 | (*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum; | ||
| 1194 | (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum; | ||
| 1195 | memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS)); | ||
| 1196 | memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps)); | ||
| 1197 | } | ||
| 1198 | } | ||
| 1199 | // PPS | ||
| 1200 | if (! (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy)) { | ||
| 1201 | (*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsPPS), "pPPSArray"); | ||
| 1202 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx)) | ||
| 1203 | } else { | ||
| 1204 | (*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMalloc (MAX_PPS_COUNT * sizeof (SWelsPPS), "pPPSArray"); | ||
| 1205 | WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx)) | ||
| 1206 | |||
| 1207 | |||
| 1208 | // copy from existing if the pointer exists | ||
| 1209 | if (NULL != pExistingParasetList) { | ||
| 1210 | (*ppCtx)->sPSOVector.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum; | ||
| 1211 | memcpy ((*ppCtx)->pPPSArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS)); | ||
| 1212 | } | ||
| 1213 | } | ||
| 1214 | |||
| 1215 | if (INCREASING_ID & pParam->iSpsPpsIdStrategy) { | ||
| 1216 | (*ppCtx)->pPSOVector = & ((*ppCtx)->sPSOVector); | ||
| 1217 | } else { | ||
| 1218 | (*ppCtx)->pPSOVector = NULL; | ||
| 1056 | } | 1219 | } |
| 1057 | 1220 | ||
| 1058 | (*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap"); | 1221 | (*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap"); |
| @@ -1066,12 +1229,79 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { · 7 unmodified lines | |||
| 1066 | 1229 | ||
| 1067 | pDqIdc->uiSpatialId = iDlayerIndex; | 1230 | pDqIdc->uiSpatialId = iDlayerIndex; |
| 1068 | 1231 | ||
| 1069 | WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex, | 1232 | if (! (SPS_LISTING & pParam->iSpsPpsIdStrategy)) { |
| 1070 | iDlayerCount, iSpsId, pSps, pSubsetSps); | 1233 | WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex, |
| 1234 | iDlayerCount, iSpsId, pSps, pSubsetSps); | ||
| 1235 | } else { | ||
| 1236 | //SPS_LISTING_AND_PPS_INCREASING == pParam->iSpsPpsIdStrategy | ||
| 1237 | //check if the current param can fit in an existing SPS | ||
| 1238 | const int32_t kiFoundSpsId = FindExistingSps ((*ppCtx)->pSvcParam, bUseSubsetSps, iDlayerIndex, iDlayerCount, | ||
| 1239 | bUseSubsetSps ? ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum) : ((*ppCtx)->sPSOVector.uiInUseSpsNum), | ||
| 1240 | (*ppCtx)->pSpsArray, | ||
| 1241 | (*ppCtx)->pSubsetArray); | ||
| 1242 | |||
| 1243 | |||
| 1244 | if (INVALID_ID != kiFoundSpsId) { | ||
| 1245 | //if yes, set pSps or pSubsetSps to it | ||
| 1246 | iSpsId = kiFoundSpsId; | ||
| 1247 | if (!bUseSubsetSps) { | ||
| 1248 | pSps = & ((*ppCtx)->pSpsArray[kiFoundSpsId]); | ||
| 1249 | } else { | ||
| 1250 | pSubsetSps = & ((*ppCtx)->pSubsetArray[kiFoundSpsId]); | ||
| 1251 | } | ||
| 1252 | } else { | ||
| 1253 | //if no, generate a new SPS as usual | ||
| 1254 | if ((SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) && (MAX_PPS_COUNT <= (*ppCtx)->sPSOVector.uiInUsePpsNum)) { | ||
| 1255 | //check if we can generate new SPS or not | ||
| 1256 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR, | ||
| 1257 | "InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!"); | ||
| 1258 | return ENC_RETURN_UNSUPPORTED_PARA; | ||
| 1259 | } | ||
| 1071 | 1260 | ||
| 1072 | pPps = & (*ppCtx)->pPPSArray[iPpsId]; | 1261 | iSpsId = (!bUseSubsetSps) ? ((*ppCtx)->sPSOVector.uiInUseSpsNum++) : ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum++); |
| 1073 | // initialize pPps | 1262 | if (iSpsId >= MAX_SPS_COUNT) { |
| 1074 | WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0); | 1263 | if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) { |
| 1264 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR, | ||
| 1265 | "InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!"); | ||
| 1266 | return ENC_RETURN_UNSUPPORTED_PARA; | ||
| 1267 | } | ||
| 1268 | // reset current list | ||
| 1269 | if (!bUseSubsetSps) { | ||
| 1270 | (*ppCtx)->sPSOVector.uiInUseSpsNum = 1; | ||
| 1271 | memset ((*ppCtx)->pSpsArray, 0, MAX_SPS_COUNT * sizeof (SWelsSPS)); | ||
| 1272 | } else { | ||
| 1273 | (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = 1; | ||
| 1274 | memset ((*ppCtx)->pSubsetArray, 0, MAX_SPS_COUNT * sizeof (SSubsetSps)); | ||
| 1275 | } | ||
| 1276 | iSpsId = 0; | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex, | ||
| 1280 | iDlayerCount, iSpsId, pSps, pSubsetSps); | ||
| 1281 | } | ||
| 1282 | } | ||
| 1283 | |||
| 1284 | if (! (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy)) { | ||
| 1285 | pPps = & (*ppCtx)->pPPSArray[iPpsId]; | ||
| 1286 | // initialize pPps | ||
| 1287 | WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0); | ||
| 1288 | } else { | ||
| 1289 | const int32_t kiFoundPpsId = FindExistingPps (pSps, pSubsetSps, bUseSubsetSps, iSpsId, | ||
| 1290 | pParam->iEntropyCodingModeFlag != 0, | ||
| 1291 | (*ppCtx)->sPSOVector.uiInUsePpsNum, | ||
| 1292 | (*ppCtx)->pPPSArray); | ||
| 1293 | |||
| 1294 | |||
| 1295 | if (INVALID_ID != kiFoundPpsId) { | ||
| 1296 | //if yes, set pPps to it | ||
| 1297 | iPpsId = kiFoundPpsId; | ||
| 1298 | pPps = & ((*ppCtx)->pPPSArray[kiFoundPpsId]); | ||
| 1299 | } else { | ||
| 1300 | iPpsId = ((*ppCtx)->sPSOVector.uiInUsePpsNum++); | ||
| 1301 | pPps = & (*ppCtx)->pPPSArray[iPpsId]; | ||
| 1302 | WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0); | ||
| 1303 | } | ||
| 1304 | } | ||
| 1075 | 1305 | ||
| 1076 | // Not using FMO in SVC coding so far, come back if need FMO | 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 | if (iResult) { | 1315 | if (iResult) { |
| 1086 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult); | 1316 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult); |
| 1087 | FreeMemorySvc (ppCtx); | 1317 | FreeMemorySvc (ppCtx); |
| 1088 | return 1; | 1318 | return iResult; |
| 1089 | } | 1319 | } |
| 1090 | (*ppCtx)->ppDqLayerList[iDlayerIndex]->pSliceEncCtx = & (*ppCtx)->pSliceCtxList[iDlayerIndex]; | 1320 | (*ppCtx)->ppDqLayerList[iDlayerIndex]->pSliceEncCtx = & (*ppCtx)->pSliceCtxList[iDlayerIndex]; |
| 1091 | } | 1321 | } |
| @@ -1097,12 +1327,23 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) { · 5 unmodified lines | |||
| 1097 | if (bUseSubsetSps) | 1327 | if (bUseSubsetSps) |
| 1098 | ++ iSpsId; | 1328 | ++ iSpsId; |
| 1099 | ++ iPpsId; | 1329 | ++ iPpsId; |
| 1100 | ++ (*ppCtx)->iSpsNum; | 1330 | if (bUseSubsetSps) { |
| 1331 | ++ (*ppCtx)->iSubsetSpsNum; | ||
| 1332 | } else { | ||
| 1333 | ++ (*ppCtx)->iSpsNum; | ||
| 1334 | } | ||
| 1101 | ++ (*ppCtx)->iPpsNum; | 1335 | ++ (*ppCtx)->iPpsNum; |
| 1102 | 1336 | ||
| 1103 | ++ iDlayerIndex; | 1337 | ++ iDlayerIndex; |
| 1104 | } | 1338 | } |
| 1105 | return 0; | 1339 | if (SPS_LISTING & pParam->iSpsPpsIdStrategy) { |
| 1340 | (*ppCtx)->iSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum; | ||
| 1341 | (*ppCtx)->iSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum; | ||
| 1342 | } | ||
| 1343 | if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) { | ||
| 1344 | (*ppCtx)->iPpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum; | ||
| 1345 | } | ||
| 1346 | return ENC_RETURN_SUCCESS; | ||
| 1106 | } | 1347 | } |
| 1107 | 1348 | ||
| 1108 | int32_t AllocStrideTables (sWelsEncCtx** ppCtx, const int32_t kiNumSpatialLayers) { | 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 | iMvdRange = WELS_MIN (iMvdRange, iFixMvdRange); | 1653 | iMvdRange = WELS_MIN (iMvdRange, iFixMvdRange); |
| 1413 | } | 1654 | } |
| 1414 | int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) { | 1655 | int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList) { |
| 1415 | SWelsSvcCodingParam* pParam = (*ppCtx)->pSvcParam; | 1656 | SWelsSvcCodingParam* pParam = (*ppCtx)->pSvcParam; |
| 1416 | CMemoryAlign* pMa = (*ppCtx)->pMemAlign; | 1657 | CMemoryAlign* pMa = (*ppCtx)->pMemAlign; |
| 1417 | SSpatialLayerConfig* pFinalSpatial = NULL; | 1658 | SSpatialLayerConfig* pFinalSpatial = NULL; |
| @@ -1616,7 +1857,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) { · 198 unmodified lines | |||
| 1616 | 1857 | ||
| 1617 | //End of pVaa memory allocation | 1858 | //End of pVaa memory allocation |
| 1618 | 1859 | ||
| 1619 | iResult = InitDqLayers (ppCtx); | 1860 | iResult = InitDqLayers (ppCtx, pExistingParasetList); |
| 1620 | if (iResult) { | 1861 | if (iResult) { |
| 1621 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult); | 1862 | WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult); |
| 1622 | FreeMemorySvc (ppCtx); | 1863 | FreeMemorySvc (ppCtx); |
| @@ -2130,7 +2371,8 @@ int32_t GetMultipleThreadIdc (SLogContext* pLogCtx, SWelsSvcCodingParam* pCoding · 507 unmodified lines | |||
| 2130 | * \pParam pParam SWelsSvcCodingParam* | 2371 | * \pParam pParam SWelsSvcCodingParam* |
| 2131 | * \return successful - 0; otherwise none 0 for failed | 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 | sWelsEncCtx* pCtx = NULL; | 2376 | sWelsEncCtx* pCtx = NULL; |
| 2135 | int32_t iRet = 0; | 2377 | int32_t iRet = 0; |
| 2136 | int16_t iSliceNum = 1; // number of slices used | 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 | pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum; | 2432 | pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum; |
| 2191 | pCtx->iMaxSliceCount = iSliceNum; | 2433 | pCtx->iMaxSliceCount = iSliceNum; |
| 2192 | iRet = RequestMemorySvc (&pCtx); | 2434 | iRet = RequestMemorySvc (&pCtx, pExistingParasetList); |
| 2193 | if (iRet != 0) { | 2435 | if (iRet != 0) { |
| 2194 | WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), RequestMemorySvc failed return %d.", iRet); | 2436 | WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), RequestMemorySvc failed return %d.", iRet); |
| 2195 | FreeMemorySvc (&pCtx); | 2437 | FreeMemorySvc (&pCtx); |
| @@ -2553,18 +2795,26 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx, · 357 unmodified lines | |||
| 2553 | iSliceCount = GetCurrentSliceNum (pCurDq->pSliceEncCtx); | 2795 | iSliceCount = GetCurrentSliceNum (pCurDq->pSliceEncCtx); |
| 2554 | assert (iSliceCount > 0); | 2796 | assert (iSliceCount > 0); |
| 2555 | 2797 | ||
| 2556 | pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = pDqIdc->iPpsId; | 2798 | int32_t iCurPpsId = pDqIdc->iPpsId; |
| 2799 | int32_t iCurSpsId = pDqIdc->iSpsId; | ||
| 2800 | |||
| 2801 | if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) { | ||
| 2802 | iCurPpsId = pCtx->sPSOVector.iPpsIdList[pDqIdc->iPpsId][WELS_ABS (pCtx->uiIdrPicId - 1) % MAX_PPS_COUNT]; | ||
| 2803 | } | ||
| 2804 | |||
| 2805 | pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = iCurPpsId; | ||
| 2557 | pCurDq->sLayerInfo.pPpsP = | 2806 | pCurDq->sLayerInfo.pPpsP = |
| 2558 | pBaseSlice->sSliceHeaderExt.sSliceHeader.pPps = &pCtx->pPPSArray[pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId]; | 2807 | pBaseSlice->sSliceHeaderExt.sSliceHeader.pPps = &pCtx->pPPSArray[iCurPpsId]; |
| 2559 | pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId = pDqIdc->iSpsId; | 2808 | |
| 2809 | pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId = iCurSpsId; | ||
| 2560 | if (kbUseSubsetSpsFlag) { | 2810 | if (kbUseSubsetSpsFlag) { |
| 2561 | pCurDq->sLayerInfo.pSubsetSpsP = &pCtx->pSubsetArray[pDqIdc->iSpsId]; | 2811 | pCurDq->sLayerInfo.pSubsetSpsP = &pCtx->pSubsetArray[iCurSpsId]; |
| 2562 | pCurDq->sLayerInfo.pSpsP = | 2812 | pCurDq->sLayerInfo.pSpsP = |
| 2563 | pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCurDq->sLayerInfo.pSubsetSpsP->pSps; | 2813 | pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCurDq->sLayerInfo.pSubsetSpsP->pSps; |
| 2564 | } else { | 2814 | } else { |
| 2565 | pCurDq->sLayerInfo.pSubsetSpsP = NULL; | 2815 | pCurDq->sLayerInfo.pSubsetSpsP = NULL; |
| 2566 | pCurDq->sLayerInfo.pSpsP = | 2816 | pCurDq->sLayerInfo.pSpsP = |
| 2567 | pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCtx->pSpsArray[pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId]; | 2817 | pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCtx->pSpsArray[iCurSpsId]; |
| 2568 | } | 2818 | } |
| 2569 | 2819 | ||
| 2570 | pSlice = pBaseSlice; | 2820 | pSlice = pBaseSlice; |
| @@ -2865,46 +3115,68 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 294 unmodified lines | |||
| 2865 | /* write all SPS */ | 3115 | /* write all SPS */ |
| 2866 | iIdx = 0; | 3116 | iIdx = 0; |
| 2867 | while (iIdx < pCtx->iSpsNum) { | 3117 | while (iIdx < pCtx->iSpsNum) { |
| 2868 | SDqIdc* pDqIdc = &pCtx->pDqIdcMap[iIdx]; | ||
| 2869 | const int32_t kiDid = pDqIdc->uiSpatialId; | ||
| 2870 | const bool kbUsingSubsetSps = (kiDid > BASE_DEPENDENCY_ID); | ||
| 2871 | |||
| 2872 | iNal = pCtx->pOut->iNalIndex; | 3118 | iNal = pCtx->pOut->iNalIndex; |
| 2873 | 3119 | ||
| 2874 | if (pCtx->pSvcParam->bEnableSpsPpsIdAddition) { | 3120 | if (INCREASING_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) { |
| 2875 | #if _DEBUG | 3121 | #if _DEBUG |
| 2876 | pCtx->sPSOVector.bEnableSpsPpsIdAddition = 1; | 3122 | pCtx->sPSOVector.iSpsPpsIdStrategy = INCREASING_ID; |
| 2877 | assert (kiDid < MAX_DEPENDENCY_LAYER); | ||
| 2878 | assert (iIdx < MAX_DQ_LAYER_NUM); | 3123 | assert (iIdx < MAX_DQ_LAYER_NUM); |
| 2879 | #endif | 3124 | #endif |
| 2880 | 3125 | ||
| 2881 | ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[kbUsingSubsetSps ? PARA_SET_TYPE_SUBSETSPS : | 3126 | ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS]), |
| 2882 | PARA_SET_TYPE_AVCSPS]), | 3127 | pCtx->pSpsArray[0].uiSpsId, |
| 2883 | (kbUsingSubsetSps) ? (pCtx->pSubsetArray[iIdx - 1].pSps.uiSpsId) : (pCtx->pSpsArray[0].uiSpsId), | ||
| 2884 | MAX_SPS_COUNT); | 3128 | MAX_SPS_COUNT); |
| 2885 | } else { | 3129 | } else if (CONSTANT_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) { |
| 2886 | memset (& (pCtx->sPSOVector), 0, sizeof (pCtx->sPSOVector)); | 3130 | memset (& (pCtx->sPSOVector), 0, sizeof (pCtx->sPSOVector)); |
| 2887 | } | 3131 | } |
| 2888 | 3132 | ||
| 2889 | if (kbUsingSubsetSps) { | 3133 | /* generate sequence parameters set */ |
| 2890 | iId = iIdx - 1; | 3134 | iId = (SPS_LISTING & pCtx->pSvcParam->iSpsPpsIdStrategy) ? iIdx : 0; |
| 2891 | 3135 | ||
| 2892 | /* generate Subset SPS */ | 3136 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST); |
| 2893 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST); | 3137 | WelsWriteSpsNal (&pCtx->pSpsArray[iId], &pCtx->pOut->sBsWrite, |
| 3138 | & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0])); | ||
| 3139 | WelsUnloadNal (pCtx->pOut); | ||
| 2894 | 3140 | ||
| 2895 | WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite, | 3141 | iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, |
| 2896 | & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0])); | 3142 | pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length |
| 2897 | WelsUnloadNal (pCtx->pOut); | 3143 | pCtx->pFrameBs + pCtx->iPosBsBuffer, |
| 2898 | } else { | 3144 | &iNalLength); |
| 2899 | iId = 0; | 3145 | WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) |
| 3146 | pNalLen[iCountNal] = iNalLength; | ||
| 2900 | 3147 | ||
| 2901 | /* generate sequence parameters set */ | 3148 | pCtx->iPosBsBuffer += iNalLength; |
| 2902 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST); | 3149 | iSize += iNalLength; |
| 2903 | WelsWriteSpsNal (&pCtx->pSpsArray[0], &pCtx->pOut->sBsWrite, | 3150 | |
| 2904 | & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0])); | 3151 | ++ iIdx; |
| 2905 | WelsUnloadNal (pCtx->pOut); | 3152 | ++ iCountNal; |
| 3153 | } | ||
| 3154 | |||
| 3155 | /* write all Subset SPS */ | ||
| 3156 | iIdx = 0; | ||
| 3157 | while (iIdx < pCtx->iSubsetSpsNum) { | ||
| 3158 | iNal = pCtx->pOut->iNalIndex; | ||
| 3159 | |||
| 3160 | if (INCREASING_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) { | ||
| 3161 | #if _DEBUG | ||
| 3162 | pCtx->sPSOVector.iSpsPpsIdStrategy = INCREASING_ID; | ||
| 3163 | assert (iIdx < MAX_DQ_LAYER_NUM); | ||
| 3164 | #endif | ||
| 3165 | |||
| 3166 | ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS]), | ||
| 3167 | pCtx->pSubsetArray[iIdx].pSps.uiSpsId, | ||
| 3168 | MAX_SPS_COUNT); | ||
| 2906 | } | 3169 | } |
| 2907 | 3170 | ||
| 3171 | iId = iIdx; | ||
| 3172 | |||
| 3173 | /* generate Subset SPS */ | ||
| 3174 | WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST); | ||
| 3175 | |||
| 3176 | WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite, | ||
| 3177 | & (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0])); | ||
| 3178 | WelsUnloadNal (pCtx->pOut); | ||
| 3179 | |||
| 2908 | iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | 3180 | iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, |
| 2909 | pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length | 3181 | pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length |
| 2910 | pCtx->pFrameBs + pCtx->iPosBsBuffer, | 3182 | pCtx->pFrameBs + pCtx->iPosBsBuffer, |
| @@ -2921,8 +3193,30 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 10 unmodified lines | |||
| 2921 | 3193 | ||
| 2922 | /* write all PPS */ | 3194 | /* write all PPS */ |
| 2923 | iIdx = 0; | 3195 | iIdx = 0; |
| 3196 | if ((SPS_PPS_LISTING == pCtx->pSvcParam->iSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) { | ||
| 3197 | assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM); | ||
| 3198 | |||
| 3199 | //Generate PPS LIST | ||
| 3200 | int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum; | ||
| 3201 | |||
| 3202 | for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) { | ||
| 3203 | for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) { | ||
| 3204 | pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT); | ||
| 3205 | } | ||
| 3206 | } | ||
| 3207 | |||
| 3208 | for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) { | ||
| 3209 | memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS)); | ||
| 3210 | pCtx->pPPSArray[iPpsId].iPpsId = iPpsId; | ||
| 3211 | pCtx->iPpsNum++; | ||
| 3212 | } | ||
| 3213 | |||
| 3214 | assert (pCtx->iPpsNum == MAX_PPS_COUNT); | ||
| 3215 | pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum; | ||
| 3216 | } | ||
| 3217 | |||
| 2924 | while (iIdx < pCtx->iPpsNum) { | 3218 | while (iIdx < pCtx->iPpsNum) { |
| 2925 | if (pCtx->pSvcParam->bEnableSpsPpsIdAddition) { | 3219 | if ((INCREASING_ID & pCtx->pSvcParam->iSpsPpsIdStrategy)) { |
| 2926 | //para_set_type = 2: PPS, use MAX_PPS_COUNT | 3220 | //para_set_type = 2: PPS, use MAX_PPS_COUNT |
| 2927 | ParasetIdAdditionIdAdjust (&pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS], pCtx->pPPSArray[iIdx].iPpsId, | 3221 | ParasetIdAdditionIdAdjust (&pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS], pCtx->pPPSArray[iIdx].iPpsId, |
| 2928 | MAX_PPS_COUNT); | 3222 | MAX_PPS_COUNT); |
| @@ -2931,7 +3225,8 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN · 2 unmodified lines | |||
| 2931 | iNal = pCtx->pOut->iNalIndex; | 3225 | iNal = pCtx->pOut->iNalIndex; |
| 2932 | /* generate picture parameter set */ | 3226 | /* generate picture parameter set */ |
| 2933 | WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST); | 3227 | WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST); |
| 2934 | WelsWritePpsSyntax (&pCtx->pPPSArray[iIdx], &pCtx->pOut->sBsWrite, & (pCtx->sPSOVector)); | 3228 | WelsWritePpsSyntax (&pCtx->pPPSArray[iIdx], &pCtx->pOut->sBsWrite, |
| 3229 | ((SPS_PPS_LISTING != pCtx->pSvcParam->iSpsPpsIdStrategy)) ? (& (pCtx->sPSOVector)) : NULL); | ||
| 2935 | WelsUnloadNal (pCtx->pOut); | 3230 | WelsUnloadNal (pCtx->pOut); |
| 2936 | 3231 | ||
| 2937 | iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, | 3232 | iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL, |
| @@ -3237,7 +3532,6 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour · 299 unmodified lines | |||
| 3237 | iDidList[iSpatialIdx] = iCurDid; | 3532 | iDidList[iSpatialIdx] = iCurDid; |
| 3238 | 3533 | ||
| 3239 | // Encoding this picture might mulitiple sQualityStat layers potentially be encoded as followed | 3534 | // Encoding this picture might mulitiple sQualityStat layers potentially be encoded as followed |
| 3240 | |||
| 3241 | switch (pParam->sSliceCfg.uiSliceMode) { | 3535 | switch (pParam->sSliceCfg.uiSliceMode) { |
| 3242 | case SM_FIXEDSLCNUM_SLICE: | 3536 | case SM_FIXEDSLCNUM_SLICE: |
| 3243 | case SM_AUTO_SLICE: { | 3537 | case SM_AUTO_SLICE: { |
| @@ -3829,7 +4123,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 585 unmodified lines | |||
| 3829 | (pOldParam->iLTRRefNum != pNewParam->iLTRRefNum) || | 4123 | (pOldParam->iLTRRefNum != pNewParam->iLTRRefNum) || |
| 3830 | (pOldParam->iMultipleThreadIdc != pNewParam->iMultipleThreadIdc) || | 4124 | (pOldParam->iMultipleThreadIdc != pNewParam->iMultipleThreadIdc) || |
| 3831 | (pOldParam->bEnableBackgroundDetection != pNewParam->bEnableBackgroundDetection) || | 4125 | (pOldParam->bEnableBackgroundDetection != pNewParam->bEnableBackgroundDetection) || |
| 3832 | (pOldParam->bEnableAdaptiveQuant != pNewParam->bEnableAdaptiveQuant); | 4126 | (pOldParam->bEnableAdaptiveQuant != pNewParam->bEnableAdaptiveQuant) || |
| 4127 | (pOldParam->iSpsPpsIdStrategy != pNewParam->iSpsPpsIdStrategy); | ||
| 3833 | if (pNewParam->iMaxNumRefFrame > pOldParam->iMaxNumRefFrame) { | 4128 | if (pNewParam->iMaxNumRefFrame > pOldParam->iMaxNumRefFrame) { |
| 3834 | bNeedReset = true; | 4129 | bNeedReset = true; |
| 3835 | } | 4130 | } |
| @@ -3876,35 +4171,75 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 40 unmodified lines | |||
| 3876 | } | 4171 | } |
| 3877 | 4172 | ||
| 3878 | if (bNeedReset) { | 4173 | if (bNeedReset) { |
| 3879 | SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE]; | ||
| 3880 | uint16_t uiTmpIdrPicId;//this is for LTR! | ||
| 3881 | SLogContext sLogCtx = (*ppCtx)->sLogCtx; | 4174 | SLogContext sLogCtx = (*ppCtx)->sLogCtx; |
| 3882 | for (int32_t k = 0; k < PARA_SET_TYPE; k++) | 4175 | |
| 3883 | memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool)); | 4176 | int32_t iOldSpsPpsIdStrategy = pOldParam->iSpsPpsIdStrategy; |
| 3884 | memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable, | 4177 | SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE]; |
| 3885 | (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage | 4178 | int32_t iTmpPpsIdList[MAX_DQ_LAYER_NUM * MAX_PPS_COUNT]; |
| 3886 | uiTmpIdrPicId = (*ppCtx)->uiIdrPicId; | 4179 | uint16_t uiTmpIdrPicId = (*ppCtx)->uiIdrPicId;//this is for LTR! |
| 3887 | 4180 | ||
| 3888 | SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics; | 4181 | SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics; |
| 3889 | 4182 | ||
| 4183 | SExistingParasetList sExistingParasetList; | ||
| 4184 | SExistingParasetList* pExistingParasetList = NULL; | ||
| 4185 | |||
| 4186 | if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->iSpsPpsIdStrategy)) { | ||
| 4187 | for (int32_t k = 0; k < PARA_SET_TYPE; k++) { | ||
| 4188 | memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool)); | ||
| 4189 | } | ||
| 4190 | memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable, | ||
| 4191 | (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage | ||
| 4192 | |||
| 4193 | if ((SPS_LISTING & iOldSpsPpsIdStrategy) | ||
| 4194 | && (SPS_LISTING & pNewParam->iSpsPpsIdStrategy)) { | ||
| 4195 | pExistingParasetList = &sExistingParasetList; | ||
| 4196 | sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum; | ||
| 4197 | sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum; | ||
| 4198 | memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS)); | ||
| 4199 | memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps)); | ||
| 4200 | } | ||
| 4201 | |||
| 4202 | if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy) | ||
| 4203 | && (SPS_PPS_LISTING == pNewParam->iSpsPpsIdStrategy)) { | ||
| 4204 | pExistingParasetList = &sExistingParasetList; | ||
| 4205 | sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum; | ||
| 4206 | sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum; | ||
| 4207 | sExistingParasetList.uiInUsePpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum; | ||
| 4208 | memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS)); | ||
| 4209 | memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps)); | ||
| 4210 | memcpy (sExistingParasetList.sPps, (*ppCtx)->pPps, MAX_PPS_COUNT * sizeof (SWelsPPS)); | ||
| 4211 | |||
| 4212 | memcpy (iTmpPpsIdList, ((*ppCtx)->sPSOVector.iPpsIdList), MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t)); | ||
| 4213 | } | ||
| 4214 | } | ||
| 4215 | |||
| 4216 | |||
| 3890 | WelsUninitEncoderExt (ppCtx); | 4217 | WelsUninitEncoderExt (ppCtx); |
| 3891 | 4218 | ||
| 3892 | /* Update new parameters */ | 4219 | /* Update new parameters */ |
| 3893 | if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx)) | 4220 | if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx, pExistingParasetList)) |
| 3894 | return 1; | 4221 | return 1; |
| 3895 | 4222 | ||
| 3896 | // reset the scaled spatial picture size | 4223 | // reset the scaled spatial picture size |
| 3897 | (*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx); | 4224 | (*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx); |
| 3898 | //if WelsInitEncoderExt succeed | 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 | //for LTR | 4227 | //for LTR |
| 3905 | (*ppCtx)->uiIdrPicId = uiTmpIdrPicId; | 4228 | (*ppCtx)->uiIdrPicId = uiTmpIdrPicId; |
| 4229 | |||
| 3906 | //for sEncoderStatistics | 4230 | //for sEncoderStatistics |
| 3907 | (*ppCtx)->sEncoderStatistics = sTempEncoderStatistics; | 4231 | (*ppCtx)->sEncoderStatistics = sTempEncoderStatistics; |
| 4232 | |||
| 4233 | //load back the needed structure for iSpsPpsIdStrategy | ||
| 4234 | if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->iSpsPpsIdStrategy)) { | ||
| 4235 | memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable, | ||
| 4236 | (PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage | ||
| 4237 | } | ||
| 4238 | |||
| 4239 | if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy) | ||
| 4240 | && (SPS_PPS_LISTING == pNewParam->iSpsPpsIdStrategy)) { | ||
| 4241 | memcpy (((*ppCtx)->sPSOVector.iPpsIdList), iTmpPpsIdList, MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t)); | ||
| 4242 | } | ||
| 3908 | } else { | 4243 | } else { |
| 3909 | /* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */ | 4244 | /* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */ |
| 3910 | pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT, | 4245 | pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT, |
| @@ -3919,7 +4254,7 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa · 8 unmodified lines | |||
| 3919 | pOldParam->fMaxFrameRate = pNewParam->fMaxFrameRate; // maximal frame rate [Hz / fps] | 4254 | pOldParam->fMaxFrameRate = pNewParam->fMaxFrameRate; // maximal frame rate [Hz / fps] |
| 3920 | pOldParam->iComplexityMode = pNewParam->iComplexityMode; // color space of input sequence | 4255 | pOldParam->iComplexityMode = pNewParam->iComplexityMode; // color space of input sequence |
| 3921 | pOldParam->uiIntraPeriod = pNewParam->uiIntraPeriod; // intra period (multiple of GOP size as desired) | 4256 | pOldParam->uiIntraPeriod = pNewParam->uiIntraPeriod; // intra period (multiple of GOP size as desired) |
| 3922 | pOldParam->bEnableSpsPpsIdAddition = pNewParam->bEnableSpsPpsIdAddition; | 4257 | pOldParam->iSpsPpsIdStrategy = pNewParam->iSpsPpsIdStrategy; |
| 3923 | pOldParam->bPrefixNalAddingCtrl = pNewParam->bPrefixNalAddingCtrl; | 4258 | pOldParam->bPrefixNalAddingCtrl = pNewParam->bPrefixNalAddingCtrl; |
| 3924 | pOldParam->iNumRefFrame = pNewParam->iNumRefFrame; // number of reference frame used | 4259 | pOldParam->iNumRefFrame = pNewParam->iNumRefFrame; // number of reference frame used |
| 3925 | pOldParam->uiGopSize = pNewParam->uiGopSize; | 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 | SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP; | 242 | SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP; |
| 242 | SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP; | 243 | SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP; |
| 243 | SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; | 244 | SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; |
| @@ -246,7 +247,7 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur · 2 unmodified lines | |||
| 246 | BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice); | 247 | BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice); |
| 247 | BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */ | 248 | BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */ |
| 248 | 249 | ||
| 249 | BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId]); | 250 | BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + ((pPpsIdDelta != NULL) ? pPpsIdDelta[pSliceHeader->pPps->iPpsId] : 0)); |
| 250 | 251 | ||
| 251 | BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum); | 252 | BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum); |
| 252 | 253 | ||
| @@ -301,7 +302,8 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur · 48 unmodified lines | |||
| 301 | } | 302 | } |
| 302 | } | 303 | } |
| 303 | 304 | ||
| 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 | SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP; | 307 | SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP; |
| 306 | SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP; | 308 | SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP; |
| 307 | SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP; | 309 | SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP; |
| @@ -312,7 +314,7 @@ void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* p · 4 unmodified lines | |||
| 312 | BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice); | 314 | BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice); |
| 313 | BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */ | 315 | BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */ |
| 314 | 316 | ||
| 315 | BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId]); | 317 | BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + ((pPpsIdDelta != NULL) ? pPpsIdDelta[pSliceHeader->pPps->iPpsId] : 0)); |
| 316 | 318 | ||
| 317 | BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum); | 319 | BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum); |
| 318 | 320 | ||
| @@ -727,11 +729,12 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const · 408 unmodified lines | |||
| 727 | 729 | ||
| 728 | WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice); | 730 | WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice); |
| 729 | 731 | ||
| 730 | |||
| 731 | g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pEncCtx, pBs, pCurLayer, pCurSlice, | 732 | g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pEncCtx, pBs, pCurLayer, pCurSlice, |
| 732 | & (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0])); | 733 | ((SPS_PPS_LISTING != pEncCtx->pSvcParam->iSpsPpsIdStrategy) ? (& |
| 734 | (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0])) : NULL)); | ||
| 735 | |||
| 733 | #if _DEBUG | 736 | #if _DEBUG |
| 734 | if (pEncCtx->sPSOVector.bEnableSpsPpsIdAddition) { | 737 | if (INCREASING_ID & pEncCtx->sPSOVector.iSpsPpsIdStrategy) { |
| 735 | const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId; | 738 | const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId; |
| 736 | const int32_t kiTmpPpsIdInBs = kiEncoderPpsId + | 739 | const int32_t kiTmpPpsIdInBs = kiEncoderPpsId + |
| 737 | pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ]; | 740 | pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ]; |
| @@ -332,7 +332,7 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) { · 331 unmodified lines | |||
| 332 | m_iMaxPicHeight = pCfg->iPicHeight; | 332 | m_iMaxPicHeight = pCfg->iPicHeight; |
| 333 | 333 | ||
| 334 | TraceParamInfo (pCfg); | 334 | TraceParamInfo (pCfg); |
| 335 | if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx)) { | 335 | if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx, NULL)) { |
| 336 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed."); | 336 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed."); |
| 337 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG, | 337 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG, |
| 338 | "Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d", | 338 | "Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d", |
| @@ -477,6 +477,7 @@ int CWelsH264SVCEncoder::ForceIntraFrame (bool bIDR) { · 138 unmodified lines | |||
| 477 | } | 477 | } |
| 478 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, | 478 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, |
| 479 | "CWelsH264SVCEncoder::ForceIntraFrame(), bIDR= %d", bIDR); | 479 | "CWelsH264SVCEncoder::ForceIntraFrame(), bIDR= %d", bIDR); |
| 480 | |||
| 480 | ForceCodingIDR (m_pEncContext); | 481 | ForceCodingIDR (m_pEncContext); |
| 481 | 482 | ||
| 482 | m_pEncContext->sEncoderStatistics.uiIDRReqNum++; | 483 | m_pEncContext->sEncoderStatistics.uiIDRReqNum++; |
| @@ -486,8 +487,8 @@ int CWelsH264SVCEncoder::ForceIntraFrame (bool bIDR) { · 3 unmodified lines | |||
| 486 | void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { | 487 | void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { |
| 487 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, | 488 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, |
| 488 | "iUsageType = %d,iPicWidth= %d;iPicHeight= %d;iTargetBitrate= %d;iMaxBitrate= %d;iRCMode= %d;iPaddingFlag= %d;iTemporalLayerNum= %d;iSpatialLayerNum= %d;fFrameRate= %.6ff;uiIntraPeriod= %d;\ | 489 | "iUsageType = %d,iPicWidth= %d;iPicHeight= %d;iTargetBitrate= %d;iMaxBitrate= %d;iRCMode= %d;iPaddingFlag= %d;iTemporalLayerNum= %d;iSpatialLayerNum= %d;fFrameRate= %.6ff;uiIntraPeriod= %d;\ |
| 489 | bEnableSpsPpsIdAddition = %d;bPrefixNalAddingCtrl = %d;bEnableDenoise= %d;bEnableBackgroundDetection= %d;bEnableAdaptiveQuant= %d;bEnableFrameSkip= %d;bEnableLongTermReference= %d;iLtrMarkPeriod= %d;\ | 490 | iSpsPpsIdStrategy = %d;bPrefixNalAddingCtrl = %d;bEnableDenoise= %d;bEnableBackgroundDetection= %d;bEnableAdaptiveQuant= %d;bEnableFrameSkip= %d;bEnableLongTermReference= %d;iLtrMarkPeriod= %d;\ |
| 490 | iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d", | 491 | iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d (offset(alpha/beta): %d,%d)", |
| 491 | pParam->iUsageType, | 492 | pParam->iUsageType, |
| 492 | pParam->iPicWidth, | 493 | pParam->iPicWidth, |
| 493 | pParam->iPicHeight, | 494 | pParam->iPicHeight, |
| @@ -499,7 +500,7 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { · 5 unmodified lines | |||
| 499 | pParam->iSpatialLayerNum, | 500 | pParam->iSpatialLayerNum, |
| 500 | pParam->fMaxFrameRate, | 501 | pParam->fMaxFrameRate, |
| 501 | pParam->uiIntraPeriod, | 502 | pParam->uiIntraPeriod, |
| 502 | pParam->bEnableSpsPpsIdAddition, | 503 | pParam->iSpsPpsIdStrategy, |
| 503 | pParam->bPrefixNalAddingCtrl, | 504 | pParam->bPrefixNalAddingCtrl, |
| 504 | pParam->bEnableDenoise, | 505 | pParam->bEnableDenoise, |
| 505 | pParam->bEnableBackgroundDetection, | 506 | pParam->bEnableBackgroundDetection, |
| @@ -513,7 +514,9 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) { · 7 unmodified lines | |||
| 513 | pParam->uiMaxNalSize, | 514 | pParam->uiMaxNalSize, |
| 514 | pParam->iLTRRefNum, | 515 | pParam->iLTRRefNum, |
| 515 | pParam->iMultipleThreadIdc, | 516 | pParam->iMultipleThreadIdc, |
| 516 | pParam->iLoopFilterDisableIdc | 517 | pParam->iLoopFilterDisableIdc, |
| 518 | pParam->iLoopFilterAlphaC0Offset, | ||
| 519 | pParam->iLoopFilterBetaOffset | ||
| 517 | ); | 520 | ); |
| 518 | int32_t i = 0; | 521 | int32_t i = 0; |
| 519 | int32_t iSpatialLayers = (pParam->iSpatialLayerNum < MAX_SPATIAL_LAYER_NUM) ? (pParam->iSpatialLayerNum) : | 522 | int32_t iSpatialLayers = (pParam->iSpatialLayerNum < MAX_SPATIAL_LAYER_NUM) ? (pParam->iSpatialLayerNum) : |
| @@ -706,16 +709,26 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) { · 186 unmodified lines | |||
| 706 | #endif//OUTPUT_BIT_STREAM | 709 | #endif//OUTPUT_BIT_STREAM |
| 707 | if (sEncodingParam.iSpatialLayerNum < 1 | 710 | if (sEncodingParam.iSpatialLayerNum < 1 |
| 708 | || sEncodingParam.iSpatialLayerNum > MAX_SPATIAL_LAYER_NUM) { // verify number of spatial layer | 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 | return cmInitParaError; | 715 | return cmInitParaError; |
| 710 | } | 716 | } |
| 711 | 717 | ||
| 712 | if (sConfig.ParamTranscode (sEncodingParam)) { | 718 | if (sConfig.ParamTranscode (sEncodingParam)) { |
| 719 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, | ||
| 720 | "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, ParamTranscode failed!"); | ||
| 713 | return cmInitParaError; | 721 | return cmInitParaError; |
| 714 | } | 722 | } |
| 715 | if (sConfig.iSpatialLayerNum < 1) { | 723 | if (sConfig.iSpatialLayerNum < 1) { |
| 724 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, | ||
| 725 | "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, iSpatialLayerNum(%d) failed!", | ||
| 726 | sConfig.iSpatialLayerNum); | ||
| 716 | return cmInitParaError; | 727 | return cmInitParaError; |
| 717 | } | 728 | } |
| 718 | if (sConfig.DetermineTemporalSettings()) { | 729 | if (sConfig.DetermineTemporalSettings()) { |
| 730 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, | ||
| 731 | "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, DetermineTemporalSettings failed!"); | ||
| 719 | return cmInitParaError; | 732 | return cmInitParaError; |
| 720 | } | 733 | } |
| 721 | 734 | ||
| @@ -898,11 +911,17 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) { · 176 unmodified lines | |||
| 898 | } | 911 | } |
| 899 | break; | 912 | break; |
| 900 | case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: { | 913 | case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: { |
| 901 | bool iValue = * ((bool*)pOption); | 914 | int32_t iValue = * ((int32_t*)pOption); |
| 902 | 915 | if (((iValue > INCREASING_ID) || (m_pEncContext->pSvcParam->iSpsPpsIdStrategy > INCREASING_ID)) | |
| 903 | m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition = iValue; | 916 | && m_pEncContext->pSvcParam->iSpsPpsIdStrategy != iValue) { |
| 904 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable SPS/PPS ID = %d ", | 917 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, |
| 905 | m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition); | 918 | " CWelsH264SVCEncoder::SetOption iSpsPpsIdStrategy changing in the middle of call is NOT allowed for iSpsPpsIdStrategy>INCREASING_ID: existing setting is %d and the new one is %d", |
| 919 | m_pEncContext->pSvcParam->iSpsPpsIdStrategy, iValue); | ||
| 920 | return cmInitParaError; | ||
| 921 | } | ||
| 922 | m_pEncContext->pSvcParam->iSpsPpsIdStrategy = iValue; | ||
| 923 | WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption iSpsPpsIdStrategy = %d ", | ||
| 924 | m_pEncContext->pSvcParam->iSpsPpsIdStrategy); | ||
| 906 | } | 925 | } |
| 907 | break; | 926 | break; |
| 908 | case ENCODER_OPTION_CURRENT_PATH: { | 927 | case ENCODER_OPTION_CURRENT_PATH: { |
| @@ -88,26 +88,25 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar · 87 unmodified lines | |||
| 88 | BaseDecoderTest::TearDown(); | 88 | BaseDecoderTest::TearDown(); |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | virtual void prepareParam (int iLayers, int iSlices, int width, int height, float framerate) { | 91 | virtual void prepareParam (int iLayers, int iSlices, int width, int height, float framerate, SEncParamExt* pParam) { |
| 92 | memset (¶m_, 0, sizeof (SEncParamExt)); | 92 | memset (pParam, 0, sizeof (SEncParamExt)); |
| 93 | param_.iUsageType = CAMERA_VIDEO_REAL_TIME; | 93 | pParam->iUsageType = CAMERA_VIDEO_REAL_TIME; |
| 94 | param_.iPicWidth = width; | 94 | pParam->iPicWidth = width; |
| 95 | param_.iPicHeight = height; | 95 | pParam->iPicHeight = height; |
| 96 | param_.fMaxFrameRate = framerate; | 96 | pParam->fMaxFrameRate = framerate; |
| 97 | param_.iRCMode = RC_OFF_MODE; //rc off | 97 | pParam->iRCMode = RC_OFF_MODE; //rc off |
| 98 | param_.iMultipleThreadIdc = 1; //single thread | 98 | pParam->iMultipleThreadIdc = 1; //single thread |
| 99 | param_.iSpatialLayerNum = iLayers; | 99 | pParam->iSpatialLayerNum = iLayers; |
| 100 | param_.iNumRefFrame = AUTO_REF_PIC_COUNT; | 100 | pParam->iNumRefFrame = AUTO_REF_PIC_COUNT; |
| 101 | for (int i = 0; i < iLayers; i++) { | 101 | for (int i = 0; i < iLayers; i++) { |
| 102 | param_.sSpatialLayers[i].iVideoWidth = width >> (iLayers - i - 1); | 102 | pParam->sSpatialLayers[i].iVideoWidth = width >> (iLayers - i - 1); |
| 103 | param_.sSpatialLayers[i].iVideoHeight = height >> (iLayers - i - 1); | 103 | pParam->sSpatialLayers[i].iVideoHeight = height >> (iLayers - i - 1); |
| 104 | param_.sSpatialLayers[i].fFrameRate = framerate; | 104 | pParam->sSpatialLayers[i].fFrameRate = framerate; |
| 105 | param_.sSpatialLayers[i].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE; | 105 | pParam->sSpatialLayers[i].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE; |
| 106 | param_.sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceNum = iSlices; | 106 | pParam->sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceNum = iSlices; |
| 107 | } | 107 | } |
| 108 | |||
| 109 | |||
| 110 | } | 108 | } |
| 109 | |||
| 111 | virtual void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) { | 110 | virtual void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) { |
| 112 | //for encoder | 111 | //for encoder |
| 113 | //I420: 1(Y) + 1/4(U) + 1/4(V) | 112 | //I420: 1(Y) + 1/4(U) + 1/4(V) |
| @@ -147,6 +146,15 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar · 33 unmodified lines | |||
| 147 | len = layerInfo.pNalLengthInByte[iSliceNum]; | 146 | len = layerInfo.pNalLengthInByte[iSliceNum]; |
| 148 | } | 147 | } |
| 149 | 148 | ||
| 149 | |||
| 150 | virtual int GetRandWidth() { | ||
| 151 | return (WELS_CLIP3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 2, MAX_WIDTH)); | ||
| 152 | } | ||
| 153 | |||
| 154 | virtual int GetRandHeight() { | ||
| 155 | return (WELS_CLIP3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 2, MAX_HEIGHT)); | ||
| 156 | } | ||
| 157 | |||
| 150 | protected: | 158 | protected: |
| 151 | SEncParamExt param_; | 159 | SEncParamExt param_; |
| 152 | BufferedData buf_; | 160 | BufferedData buf_; |
| @@ -171,8 +179,8 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase { · 18 unmodified lines | |||
| 171 | EncodeDecodeTestBase::TearDown(); | 179 | EncodeDecodeTestBase::TearDown(); |
| 172 | } | 180 | } |
| 173 | 181 | ||
| 174 | void prepareParam (int iLayers, int iSlices, int width, int height, float framerate) { | 182 | void prepareParam (int iLayers, int iSlices, int width, int height, float framerate, SEncParamExt* pParam) { |
| 175 | EncodeDecodeTestBase::prepareParam (iLayers, iSlices, width, height, framerate); | 183 | EncodeDecodeTestBase::prepareParam (iLayers, iSlices, width, height, framerate, pParam); |
| 176 | } | 184 | } |
| 177 | 185 | ||
| 178 | void InitialEncDec (int iWidth, int iHeight); | 186 | void InitialEncDec (int iWidth, int iHeight); |
| @@ -192,6 +200,24 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase { · 13 unmodified lines | |||
| 192 | else if (1 == iCheckTypeIndex) | 200 | else if (1 == iCheckTypeIndex) |
| 193 | ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason); | 201 | ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason); |
| 194 | } | 202 | } |
| 203 | |||
| 204 | void EncDecOneFrame (const int iWidth, const int iHeight, const int iFrame, FILE* pfEnc) { | ||
| 205 | int iLen = 0, rv; | ||
| 206 | InitialEncDec (iWidth, iHeight); | ||
| 207 | EncodeOneFrame (iFrame); | ||
| 208 | |||
| 209 | //extract target layer data | ||
| 210 | encToDecData (info, iLen); | ||
| 211 | //call decoder | ||
| 212 | unsigned char* pData[3] = { NULL }; | ||
| 213 | memset (&dstBufInfo_, 0, sizeof (SBufferInfo)); | ||
| 214 | rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iLen, pData, &dstBufInfo_); | ||
| 215 | EXPECT_TRUE (rv == cmResultSuccess) << " rv = " << rv << " iFrameIdx = " << iFrame; | ||
| 216 | |||
| 217 | if (NULL != pfEnc) { | ||
| 218 | fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, pfEnc); | ||
| 219 | } | ||
| 220 | } | ||
| 195 | }; | 221 | }; |
| 196 | 222 | ||
| 197 | void EncodeDecodeTestAPI::InitialEncDec (int iWidth, int iHeight) { | 223 | void EncodeDecodeTestAPI::InitialEncDec (int iWidth, int iHeight) { |
| @@ -234,7 +260,7 @@ void EncodeDecodeTestAPI::RandomParamExtCombination() { · 36 unmodified lines | |||
| 234 | param_.iNumRefFrame = AUTO_REF_PIC_COUNT; | 260 | param_.iNumRefFrame = AUTO_REF_PIC_COUNT; |
| 235 | param_.iMultipleThreadIdc = rand(); | 261 | param_.iMultipleThreadIdc = rand(); |
| 236 | 262 | ||
| 237 | param_.bEnableSpsPpsIdAddition = (rand() % 2 == 0) ? false : true; | 263 | param_.iSpsPpsIdStrategy = rand() % 3; |
| 238 | param_.bPrefixNalAddingCtrl = (rand() % 2 == 0) ? false : true; | 264 | param_.bPrefixNalAddingCtrl = (rand() % 2 == 0) ? false : true; |
| 239 | param_.bEnableSSEI = (rand() % 2 == 0) ? false : true; | 265 | param_.bEnableSSEI = (rand() % 2 == 0) ? false : true; |
| 240 | param_.iPaddingFlag = rand() % 2; | 266 | param_.iPaddingFlag = rand() % 2; |
| @@ -462,7 +488,7 @@ static const EncodeDecodeFileParamBase kFileParamArray[] = { · 221 unmodified lines | |||
| 462 | 488 | ||
| 463 | TEST_P (EncodeDecodeTestAPI, DecoderVclNal) { | 489 | TEST_P (EncodeDecodeTestAPI, DecoderVclNal) { |
| 464 | EncodeDecodeFileParamBase p = GetParam(); | 490 | EncodeDecodeFileParamBase p = GetParam(); |
| 465 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 491 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 466 | encoder_->Uninitialize(); | 492 | encoder_->Uninitialize(); |
| 467 | int rv = encoder_->InitializeExt (¶m_); | 493 | int rv = encoder_->InitializeExt (¶m_); |
| 468 | ASSERT_TRUE (rv == cmResultSuccess); | 494 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -498,7 +524,7 @@ TEST_P (EncodeDecodeTestAPI, DecoderVclNal) { · 29 unmodified lines | |||
| 498 | 524 | ||
| 499 | TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) { | 525 | TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) { |
| 500 | EncodeDecodeFileParamBase p = GetParam(); | 526 | EncodeDecodeFileParamBase p = GetParam(); |
| 501 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 527 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 502 | encoder_->Uninitialize(); | 528 | encoder_->Uninitialize(); |
| 503 | int rv = encoder_->InitializeExt (¶m_); | 529 | int rv = encoder_->InitializeExt (¶m_); |
| 504 | ASSERT_TRUE (rv == cmResultSuccess); | 530 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -535,7 +561,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) { · 30 unmodified lines | |||
| 535 | 561 | ||
| 536 | TEST_P (EncodeDecodeTestAPI, GetOptionIDR) { | 562 | TEST_P (EncodeDecodeTestAPI, GetOptionIDR) { |
| 537 | EncodeDecodeFileParamBase p = GetParam(); | 563 | EncodeDecodeFileParamBase p = GetParam(); |
| 538 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 564 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 539 | encoder_->Uninitialize(); | 565 | encoder_->Uninitialize(); |
| 540 | int rv = encoder_->InitializeExt (¶m_); | 566 | int rv = encoder_->InitializeExt (¶m_); |
| 541 | ASSERT_TRUE (rv == cmResultSuccess); | 567 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -554,7 +580,8 @@ TEST_P (EncodeDecodeTestAPI, GetOptionIDR) { · 12 unmodified lines | |||
| 554 | int32_t iSpsPpsIdAddition = 0; | 580 | int32_t iSpsPpsIdAddition = 0; |
| 555 | int iIdx = 0; | 581 | int iIdx = 0; |
| 556 | while (iIdx <= p.numframes) { | 582 | while (iIdx <= p.numframes) { |
| 557 | iSpsPpsIdAddition = rand() % 2; | 583 | iSpsPpsIdAddition = rand() % |
| 584 | 2; //the current strategy supports more than 2 modes, but the switch between the modes>2 is not allowed | ||
| 558 | iIDRPeriod = (rand() % 150) + 1; | 585 | iIDRPeriod = (rand() % 150) + 1; |
| 559 | encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod); | 586 | encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod); |
| 560 | encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition); | 587 | encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition); |
| @@ -776,7 +803,7 @@ int SimulateNALLoss (const unsigned char* pSrc, int& iSrcLen, std::vector<SLost · 215 unmodified lines | |||
| 776 | 803 | ||
| 777 | TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) { | 804 | TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) { |
| 778 | EncodeDecodeFileParamBase p = GetParam(); | 805 | EncodeDecodeFileParamBase p = GetParam(); |
| 779 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 806 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 780 | encoder_->Uninitialize(); | 807 | encoder_->Uninitialize(); |
| 781 | int rv = encoder_->InitializeExt (¶m_); | 808 | int rv = encoder_->InitializeExt (¶m_); |
| 782 | ASSERT_TRUE (rv == cmResultSuccess); | 809 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -809,7 +836,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLLTR) { · 26 unmodified lines | |||
| 809 | SLTRMarkingFeedback m_LTR_Marking_Feedback; | 836 | SLTRMarkingFeedback m_LTR_Marking_Feedback; |
| 810 | SLTRRecoverRequest m_LTR_Recover_Request; | 837 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 811 | EncodeDecodeFileParamBase p = GetParam(); | 838 | EncodeDecodeFileParamBase p = GetParam(); |
| 812 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 839 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 813 | encoder_->Uninitialize(); | 840 | encoder_->Uninitialize(); |
| 814 | int rv = encoder_->InitializeExt (¶m_); | 841 | int rv = encoder_->InitializeExt (¶m_); |
| 815 | ASSERT_TRUE (rv == cmResultSuccess); | 842 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -868,7 +895,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_Engine) { · 52 unmodified lines | |||
| 868 | SLTRRecoverRequest m_LTR_Recover_Request; | 895 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 869 | m_LTR_Recover_Request.uiIDRPicId = 0; | 896 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 870 | EncodeDecodeFileParamBase p = GetParam(); | 897 | EncodeDecodeFileParamBase p = GetParam(); |
| 871 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 898 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 872 | encoder_->Uninitialize(); | 899 | encoder_->Uninitialize(); |
| 873 | int rv = encoder_->InitializeExt (¶m_); | 900 | int rv = encoder_->InitializeExt (¶m_); |
| 874 | ASSERT_TRUE (rv == cmResultSuccess); | 901 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -918,7 +945,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_DISABLE) { · 43 unmodified lines | |||
| 918 | SLTRRecoverRequest m_LTR_Recover_Request; | 945 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 919 | m_LTR_Recover_Request.uiIDRPicId = 0; | 946 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 920 | EncodeDecodeFileParamBase p = GetParam(); | 947 | EncodeDecodeFileParamBase p = GetParam(); |
| 921 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 948 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 922 | param_.bEnableLongTermReference = true; | 949 | param_.bEnableLongTermReference = true; |
| 923 | param_.iLTRRefNum = 1; | 950 | param_.iLTRRefNum = 1; |
| 924 | encoder_->Uninitialize(); | 951 | encoder_->Uninitialize(); |
| @@ -985,7 +1012,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) { · 60 unmodified lines | |||
| 985 | SLTRRecoverRequest m_LTR_Recover_Request; | 1012 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 986 | m_LTR_Recover_Request.uiIDRPicId = 0; | 1013 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 987 | EncodeDecodeFileParamBase p = GetParam(); | 1014 | EncodeDecodeFileParamBase p = GetParam(); |
| 988 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 1015 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 989 | encoder_->Uninitialize(); | 1016 | encoder_->Uninitialize(); |
| 990 | int rv = encoder_->InitializeExt (¶m_); | 1017 | int rv = encoder_->InitializeExt (¶m_); |
| 991 | ASSERT_TRUE (rv == cmResultSuccess); | 1018 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -1036,7 +1063,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) { · 44 unmodified lines | |||
| 1036 | 1063 | ||
| 1037 | TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) { | 1064 | TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) { |
| 1038 | EncodeDecodeFileParamBase p = GetParam(); | 1065 | EncodeDecodeFileParamBase p = GetParam(); |
| 1039 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 1066 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1040 | encoder_->Uninitialize(); | 1067 | encoder_->Uninitialize(); |
| 1041 | int rv = encoder_->InitializeExt (¶m_); | 1068 | int rv = encoder_->InitializeExt (¶m_); |
| 1042 | ASSERT_TRUE (rv == cmResultSuccess); | 1069 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -1086,7 +1113,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_NOPREFIX) { · 43 unmodified lines | |||
| 1086 | SLTRRecoverRequest m_LTR_Recover_Request; | 1113 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1087 | m_LTR_Recover_Request.uiIDRPicId = 0; | 1114 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1088 | EncodeDecodeFileParamBase p = GetParam(); | 1115 | EncodeDecodeFileParamBase p = GetParam(); |
| 1089 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 1116 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1090 | param_.bPrefixNalAddingCtrl = false; | 1117 | param_.bPrefixNalAddingCtrl = false; |
| 1091 | param_.iTemporalLayerNum = (rand() % 4) + 1; | 1118 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1092 | encoder_->Uninitialize(); | 1119 | encoder_->Uninitialize(); |
| @@ -1155,7 +1182,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_WITH_PREFIX_NOLOSS) { · 62 unmodified lines | |||
| 1155 | SLTRRecoverRequest m_LTR_Recover_Request; | 1182 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1156 | m_LTR_Recover_Request.uiIDRPicId = 0; | 1183 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1157 | EncodeDecodeFileParamBase p = GetParam(); | 1184 | EncodeDecodeFileParamBase p = GetParam(); |
| 1158 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 1185 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1159 | param_.bPrefixNalAddingCtrl = true; | 1186 | param_.bPrefixNalAddingCtrl = true; |
| 1160 | param_.iTemporalLayerNum = (rand() % 4) + 1; | 1187 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1161 | param_.iSpatialLayerNum = 1; | 1188 | param_.iSpatialLayerNum = 1; |
| @@ -1210,7 +1237,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_SVC_L1_NOLOSS) { · 48 unmodified lines | |||
| 1210 | SLTRRecoverRequest m_LTR_Recover_Request; | 1237 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1211 | m_LTR_Recover_Request.uiIDRPicId = 0; | 1238 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1212 | EncodeDecodeFileParamBase p = GetParam(); | 1239 | EncodeDecodeFileParamBase p = GetParam(); |
| 1213 | prepareParam (2, p.slicenum, p.width, p.height, p.frameRate); | 1240 | prepareParam (2, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1214 | param_.iTemporalLayerNum = (rand() % 4) + 1; | 1241 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1215 | param_.iSpatialLayerNum = 2; | 1242 | param_.iSpatialLayerNum = 2; |
| 1216 | encoder_->Uninitialize(); | 1243 | encoder_->Uninitialize(); |
| @@ -1266,7 +1293,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace) { · 49 unmodified lines | |||
| 1266 | SLTRRecoverRequest m_LTR_Recover_Request; | 1293 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1267 | m_LTR_Recover_Request.uiIDRPicId = 0; | 1294 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1268 | EncodeDecodeFileParamBase p = GetParam(); | 1295 | EncodeDecodeFileParamBase p = GetParam(); |
| 1269 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 1296 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1270 | param_.iSpatialLayerNum = 1; | 1297 | param_.iSpatialLayerNum = 1; |
| 1271 | 1298 | ||
| 1272 | int rv = encoder_->InitializeExt (¶m_); | 1299 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1330,7 +1357,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace_NULL) { · 57 unmodified lines | |||
| 1330 | SLTRRecoverRequest m_LTR_Recover_Request; | 1357 | SLTRRecoverRequest m_LTR_Recover_Request; |
| 1331 | m_LTR_Recover_Request.uiIDRPicId = 0; | 1358 | m_LTR_Recover_Request.uiIDRPicId = 0; |
| 1332 | EncodeDecodeFileParamBase p = GetParam(); | 1359 | EncodeDecodeFileParamBase p = GetParam(); |
| 1333 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 1360 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1334 | param_.iSpatialLayerNum = 1; | 1361 | param_.iSpatialLayerNum = 1; |
| 1335 | int rv = encoder_->InitializeExt (¶m_); | 1362 | int rv = encoder_->InitializeExt (¶m_); |
| 1336 | ASSERT_TRUE (rv == cmResultSuccess); | 1363 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -1393,7 +1420,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECIDC_GeneralSliceChange) { · 56 unmodified lines | |||
| 1393 | uint32_t uiEcIdc; | 1420 | uint32_t uiEcIdc; |
| 1394 | uint32_t uiGet; | 1421 | uint32_t uiGet; |
| 1395 | EncodeDecodeFileParamBase p = GetParam(); | 1422 | EncodeDecodeFileParamBase p = GetParam(); |
| 1396 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 1423 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1397 | param_.iSpatialLayerNum = 1; | 1424 | param_.iSpatialLayerNum = 1; |
| 1398 | encoder_->Uninitialize(); | 1425 | encoder_->Uninitialize(); |
| 1399 | int rv = encoder_->InitializeExt (¶m_); | 1426 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1473,7 +1500,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) { · 73 unmodified lines | |||
| 1473 | uint32_t uiEcIdc; | 1500 | uint32_t uiEcIdc; |
| 1474 | uint32_t uiGet; | 1501 | uint32_t uiGet; |
| 1475 | EncodeDecodeFileParamBase p = kFileParamArray[0]; | 1502 | EncodeDecodeFileParamBase p = kFileParamArray[0]; |
| 1476 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate); | 1503 | prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1477 | param_.iSpatialLayerNum = 1; | 1504 | param_.iSpatialLayerNum = 1; |
| 1478 | encoder_->Uninitialize(); | 1505 | encoder_->Uninitialize(); |
| 1479 | int rv = encoder_->InitializeExt (¶m_); | 1506 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1612,7 +1639,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) { · 132 unmodified lines | |||
| 1612 | uint32_t uiEcIdc = 2; //default set as SLICE_COPY | 1639 | uint32_t uiEcIdc = 2; //default set as SLICE_COPY |
| 1613 | uint32_t uiGet; | 1640 | uint32_t uiGet; |
| 1614 | EncodeDecodeFileParamBase p = kFileParamArray[0]; | 1641 | EncodeDecodeFileParamBase p = kFileParamArray[0]; |
| 1615 | prepareParam (1, 2, p.width, p.height, p.frameRate); | 1642 | prepareParam (1, 2, p.width, p.height, p.frameRate, ¶m_); |
| 1616 | param_.iSpatialLayerNum = 1; | 1643 | param_.iSpatialLayerNum = 1; |
| 1617 | encoder_->Uninitialize(); | 1644 | encoder_->Uninitialize(); |
| 1618 | int rv = encoder_->InitializeExt (¶m_); | 1645 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1745,7 +1772,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) { · 126 unmodified lines | |||
| 1745 | uint32_t uiEcIdc; | 1772 | uint32_t uiEcIdc; |
| 1746 | uint32_t uiGet; | 1773 | uint32_t uiGet; |
| 1747 | EncodeDecodeFileParamBase p = kFileParamArray[0]; | 1774 | EncodeDecodeFileParamBase p = kFileParamArray[0]; |
| 1748 | prepareParam (1, 2, p.width, p.height, p.frameRate); | 1775 | prepareParam (1, 2, p.width, p.height, p.frameRate, ¶m_); |
| 1749 | param_.iSpatialLayerNum = 1; | 1776 | param_.iSpatialLayerNum = 1; |
| 1750 | encoder_->Uninitialize(); | 1777 | encoder_->Uninitialize(); |
| 1751 | int rv = encoder_->InitializeExt (¶m_); | 1778 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -1914,7 +1941,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_I) { · 162 unmodified lines | |||
| 1914 | EncodeDecodeFileParamBase p = kSVCSwitch[0]; | 1941 | EncodeDecodeFileParamBase p = kSVCSwitch[0]; |
| 1915 | p.width = p.width << 2; | 1942 | p.width = p.width << 2; |
| 1916 | p.height = p.height << 2; | 1943 | p.height = p.height << 2; |
| 1917 | prepareParam (4, p.slicenum, p.width, p.height, p.frameRate); | 1944 | prepareParam (4, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1918 | param_.iTemporalLayerNum = (rand() % 4) + 1; | 1945 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1919 | param_.iSpatialLayerNum = 4; | 1946 | param_.iSpatialLayerNum = 4; |
| 1920 | encoder_->Uninitialize(); | 1947 | encoder_->Uninitialize(); |
| @@ -1979,7 +2006,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_P) { · 58 unmodified lines | |||
| 1979 | int iLastDid = 0; | 2006 | int iLastDid = 0; |
| 1980 | p.width = p.width << 2; | 2007 | p.width = p.width << 2; |
| 1981 | p.height = p.height << 2; | 2008 | p.height = p.height << 2; |
| 1982 | prepareParam (4, p.slicenum, p.width, p.height, p.frameRate); | 2009 | prepareParam (4, p.slicenum, p.width, p.height, p.frameRate, ¶m_); |
| 1983 | param_.iTemporalLayerNum = (rand() % 4) + 1; | 2010 | param_.iTemporalLayerNum = (rand() % 4) + 1; |
| 1984 | param_.iSpatialLayerNum = 4; | 2011 | param_.iSpatialLayerNum = 4; |
| 1985 | encoder_->Uninitialize(); | 2012 | encoder_->Uninitialize(); |
| @@ -2065,7 +2092,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionEncParamExt) { · 79 unmodified lines | |||
| 2065 | int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM); | 2092 | int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM); |
| 2066 | int iSliceNum = 1; | 2093 | int iSliceNum = 1; |
| 2067 | encoder_->GetDefaultParams (¶m_); | 2094 | encoder_->GetDefaultParams (¶m_); |
| 2068 | prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate); | 2095 | prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_); |
| 2069 | 2096 | ||
| 2070 | int rv = encoder_->InitializeExt (¶m_); | 2097 | int rv = encoder_->InitializeExt (¶m_); |
| 2071 | ASSERT_TRUE (rv == cmResultSuccess); | 2098 | ASSERT_TRUE (rv == cmResultSuccess); |
| @@ -2128,8 +2155,8 @@ class DecodeCrashTestAPI : public EncodeDecodeTestBase { · 56 unmodified lines | |||
| 2128 | ASSERT_TRUE (ucBuf_ == NULL); | 2155 | ASSERT_TRUE (ucBuf_ == NULL); |
| 2129 | } | 2156 | } |
| 2130 | 2157 | ||
| 2131 | void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate) { | 2158 | void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate, SEncParamExt* pParam) { |
| 2132 | EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate); | 2159 | EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate, pParam); |
| 2133 | } | 2160 | } |
| 2134 | 2161 | ||
| 2135 | void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam); | 2162 | void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam); |
| @@ -2203,11 +2230,11 @@ TEST_F (DecodeCrashTestAPI, DecoderCrashTest) { · 67 unmodified lines | |||
| 2203 | int iSeed = rand() % 3; //3 indicates the length of kParamArray[] used in the following | 2230 | int iSeed = rand() % 3; //3 indicates the length of kParamArray[] used in the following |
| 2204 | EncodeDecodeParamBase p = kParamArray[iSeed]; | 2231 | EncodeDecodeParamBase p = kParamArray[iSeed]; |
| 2205 | //Initialize Encoder | 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 | param_.iRCMode = RC_BITRATE_MODE; | 2234 | param_.iRCMode = RC_BITRATE_MODE; |
| 2208 | param_.iTargetBitrate = p.iTarBitrate; | 2235 | param_.iTargetBitrate = p.iTarBitrate; |
| 2209 | param_.uiIntraPeriod = 0; | 2236 | param_.uiIntraPeriod = 0; |
| 2210 | param_.bEnableSpsPpsIdAddition = true; | 2237 | param_.iSpsPpsIdStrategy = INCREASING_ID; |
| 2211 | param_.bEnableBackgroundDetection = true; | 2238 | param_.bEnableBackgroundDetection = true; |
| 2212 | param_.bEnableSceneChangeDetect = true; | 2239 | param_.bEnableSceneChangeDetect = true; |
| 2213 | param_.bPrefixNalAddingCtrl = true; | 2240 | param_.bPrefixNalAddingCtrl = true; |
| @@ -2398,7 +2425,7 @@ TEST_F (DecodeParseAPI, ParseOnly_General) { · 184 unmodified lines | |||
| 2398 | p.height = iHeight_; | 2425 | p.height = iHeight_; |
| 2399 | p.frameRate = kiFrameRate; | 2426 | p.frameRate = kiFrameRate; |
| 2400 | p.numframes = kiFrameNum; | 2427 | p.numframes = kiFrameNum; |
| 2401 | prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate); | 2428 | prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate, ¶m_); |
| 2402 | param_.iSpatialLayerNum = kiTotalLayer; | 2429 | param_.iSpatialLayerNum = kiTotalLayer; |
| 2403 | encoder_->Uninitialize(); | 2430 | encoder_->Uninitialize(); |
| 2404 | int rv = encoder_->InitializeExt (¶m_); | 2431 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -2475,7 +2502,7 @@ TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) { · 70 unmodified lines | |||
| 2475 | p.height = iHeight_; | 2502 | p.height = iHeight_; |
| 2476 | p.frameRate = kiFrameRate; | 2503 | p.frameRate = kiFrameRate; |
| 2477 | p.numframes = 5; | 2504 | p.numframes = 5; |
| 2478 | prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate); | 2505 | prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate, ¶m_); |
| 2479 | param_.iSpatialLayerNum = iLayerNum; | 2506 | param_.iSpatialLayerNum = iLayerNum; |
| 2480 | encoder_->Uninitialize(); | 2507 | encoder_->Uninitialize(); |
| 2481 | int rv = encoder_->InitializeExt (¶m_); | 2508 | int rv = encoder_->InitializeExt (¶m_); |
| @@ -2525,3 +2552,434 @@ TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) { · 43 unmodified lines | |||
| 2525 | } //while | 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 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\ | 11 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\ |
| 12 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryZero.cpp\ | 12 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryZero.cpp\ |
| 13 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\ | 13 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\ |
| 14 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_ParameterSetStrategy.cpp\ | ||
| 14 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_Reconstruct.cpp\ | 15 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_Reconstruct.cpp\ |
| 15 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_Sample.cpp\ | 16 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_Sample.cpp\ |
| 16 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_SVC_me.cpp\ | 17 | $(ENCODER_UNITTEST_SRCDIR)/EncUT_SVC_me.cpp\ |