add new SpsPpsStrategy and UT
This commit is contained in:
parent
e9ec603fd7
commit
98ed302990
@ -385,6 +385,17 @@ typedef enum {
|
|||||||
HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality
|
HIGH_COMPLEXITY ///< high complexity, lowest speed, high quality
|
||||||
} ECOMPLEXITY_MODE;
|
} ECOMPLEXITY_MODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enumulate for the stategy of SPS/PPS strategy
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CONSTANT_ID = 0, ///< constant id in SPS/PPS
|
||||||
|
INCREASING_ID = 0x01, ///< SPS/PPS id increases at each IDR
|
||||||
|
SPS_LISTING = 0x02, ///< using SPS in the existing list if possible
|
||||||
|
SPS_LISTING_AND_PPS_INCREASING = 0x03,
|
||||||
|
SPS_PPS_LISTING = 0x06,
|
||||||
|
} EParameterSetStrategy;
|
||||||
|
|
||||||
// TODO: Refine the parameters definition.
|
// TODO: Refine the parameters definition.
|
||||||
/**
|
/**
|
||||||
* @brief SVC Encoding Parameters
|
* @brief SVC Encoding Parameters
|
||||||
@ -421,7 +432,7 @@ typedef struct TagEncParamExt {
|
|||||||
ECOMPLEXITY_MODE iComplexityMode;
|
ECOMPLEXITY_MODE iComplexityMode;
|
||||||
unsigned int uiIntraPeriod; ///< period of Intra frame
|
unsigned int uiIntraPeriod; ///< period of Intra frame
|
||||||
int iNumRefFrame; ///< number of reference frame used
|
int iNumRefFrame; ///< number of reference frame used
|
||||||
bool bEnableSpsPpsIdAddition; ///< false:not adjust ID in SPS/PPS; true: adjust ID in SPS/PPS
|
int iSpsPpsIdStrategy; ///< different stategy in adjust ID in SPS/PPS: 0- constant ID, 1-additional ID, 6-mapping and additional
|
||||||
bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL
|
bool bPrefixNalAddingCtrl; ///< false:not use Prefix NAL; true: use Prefix NAL
|
||||||
bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI
|
bool bEnableSSEI; ///< false:not use SSEI; true: use SSEI -- TODO: planning to remove the interface of SSEI
|
||||||
bool bSimulcastAVC; ///< (when encoding more than 1 spatial layer) false: use SVC syntax for higher layers; true: use Simulcast AVC -- coming soon
|
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
|
|||||||
pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str());
|
pSvcParam.uiIntraPeriod = atoi (strTag[1].c_str());
|
||||||
} else if (strTag[0].compare ("MaxNalSize") == 0) {
|
} else if (strTag[0].compare ("MaxNalSize") == 0) {
|
||||||
pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str());
|
pSvcParam.uiMaxNalSize = atoi (strTag[1].c_str());
|
||||||
} else if (strTag[0].compare ("EnableSpsPpsIDAddition") == 0) {
|
} else if (strTag[0].compare ("SpsPpsIDStrategy") == 0) {
|
||||||
pSvcParam.bEnableSpsPpsIdAddition = atoi (strTag[1].c_str()) ? true : false;
|
pSvcParam.iSpsPpsIdStrategy = atoi (strTag[1].c_str());
|
||||||
} else if (strTag[0].compare ("EnableScalableSEI") == 0) {
|
} else if (strTag[0].compare ("EnableScalableSEI") == 0) {
|
||||||
pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false;
|
pSvcParam.bEnableSSEI = atoi (strTag[1].c_str()) ? true : false;
|
||||||
} else if (strTag[0].compare ("EnableFrameCropping") == 0) {
|
} else if (strTag[0].compare ("EnableFrameCropping") == 0) {
|
||||||
@ -421,7 +421,7 @@ int ParseCommandLine (int argc, char** argv, SSourcePicture* pSrcPic, SEncParamE
|
|||||||
pSvcParam.uiMaxNalSize = atoi (argv[n++]);
|
pSvcParam.uiMaxNalSize = atoi (argv[n++]);
|
||||||
|
|
||||||
else if (!strcmp (pCommand, "-spsid") && (n < argc))
|
else if (!strcmp (pCommand, "-spsid") && (n < argc))
|
||||||
pSvcParam.bEnableSpsPpsIdAddition = atoi (argv[n++]) ? true : false;
|
pSvcParam.iSpsPpsIdStrategy = atoi (argv[n++]);
|
||||||
|
|
||||||
else if (!strcmp (pCommand, "-cabac") && (n < argc))
|
else if (!strcmp (pCommand, "-cabac") && (n < argc))
|
||||||
pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]);
|
pSvcParam.iEntropyCodingModeFlag = atoi (argv[n++]);
|
||||||
@ -591,7 +591,7 @@ int FillSpecificParameters (SEncParamExt& sParam) {
|
|||||||
sParam.bEnableLongTermReference = 0; // long term reference control
|
sParam.bEnableLongTermReference = 0; // long term reference control
|
||||||
sParam.iLtrMarkPeriod = 30;
|
sParam.iLtrMarkPeriod = 30;
|
||||||
sParam.uiIntraPeriod = 320; // period of Intra frame
|
sParam.uiIntraPeriod = 320; // period of Intra frame
|
||||||
sParam.bEnableSpsPpsIdAddition = 1;
|
sParam.iSpsPpsIdStrategy = INCREASING_ID;
|
||||||
sParam.bPrefixNalAddingCtrl = 0;
|
sParam.bPrefixNalAddingCtrl = 0;
|
||||||
sParam.iComplexityMode = MEDIUM_COMPLEXITY;
|
sParam.iComplexityMode = MEDIUM_COMPLEXITY;
|
||||||
int iIndexLayer = 0;
|
int iIndexLayer = 0;
|
||||||
|
@ -141,8 +141,26 @@ int32_t WelsInitPps (SWelsPPS* pPps,
|
|||||||
const bool kbDeblockingFilterPresentFlag,
|
const bool kbDeblockingFilterPresentFlag,
|
||||||
const bool kbUsingSubsetSps,
|
const bool kbUsingSubsetSps,
|
||||||
const bool kbEntropyCodingModeFlag);
|
const bool kbEntropyCodingModeFlag);
|
||||||
|
|
||||||
int32_t WelsCheckRefFrameLimitationNumRefFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
|
int32_t WelsCheckRefFrameLimitationNumRefFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
|
||||||
int32_t WelsCheckRefFrameLimitationLevelIdcFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
|
int32_t WelsCheckRefFrameLimitationLevelIdcFirst (SLogContext* pLogCtx, SWelsSvcCodingParam* pParam);
|
||||||
int32_t WelsAdjustLevel( SSpatialLayerConfig* pSpatialLayer);
|
|
||||||
|
int32_t WelsAdjustLevel (SSpatialLayerConfig* pSpatialLayer);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief check if the current parameter can found a presenting sps
|
||||||
|
* \param pParam the current encoding paramter in SWelsSvcCodingParam
|
||||||
|
* \param kbUseSubsetSps bool
|
||||||
|
* \param iDlayerIndex int, the index of current D layer
|
||||||
|
* \param iDlayerCount int, the number of total D layer
|
||||||
|
* \param pSpsArray array of all the stored SPSs
|
||||||
|
* \param pSubsetArray array of all the stored Subset-SPSs
|
||||||
|
* \return 0 - successful
|
||||||
|
* -1 - cannot find existing SPS for current encoder parameter
|
||||||
|
*/
|
||||||
|
int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||||
|
const int32_t iDlayerCount, const int32_t iSpsNumInUse,
|
||||||
|
SWelsSPS* pSpsArray,
|
||||||
|
SSubsetSps* pSubsetArray);
|
||||||
}
|
}
|
||||||
#endif//WELS_ACCESS_UNIT_PARSER_H__
|
#endif//WELS_ACCESS_UNIT_PARSER_H__
|
||||||
|
@ -48,7 +48,7 @@ namespace WelsEnc {
|
|||||||
* \param pEncCtx sWelsEncCtx*
|
* \param pEncCtx sWelsEncCtx*
|
||||||
* \return successful - 0; otherwise none 0 for failed
|
* \return successful - 0; otherwise none 0 for failed
|
||||||
*/
|
*/
|
||||||
int32_t RequestMemorySvc (sWelsEncCtx** ppCtx);
|
int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief free memory in SVC core encoder
|
* \brief free memory in SVC core encoder
|
||||||
|
@ -191,6 +191,7 @@ typedef struct TagWelsEncCtx {
|
|||||||
SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible
|
SSubsetSps* pSubsetArray; // MAX_SPS_COUNT by standard compatible
|
||||||
SSubsetSps* pSubsetSps;
|
SSubsetSps* pSubsetSps;
|
||||||
int32_t iSpsNum; // number of pSps used
|
int32_t iSpsNum; // number of pSps used
|
||||||
|
int32_t iSubsetSpsNum; // number of pSps used
|
||||||
int32_t iPpsNum; // number of pPps used
|
int32_t iPpsNum; // number of pPps used
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
@ -216,6 +217,7 @@ typedef struct TagWelsEncCtx {
|
|||||||
pDqIdcMap; // overall DQ map of full scalability in specific frame (All full D/T/Q layers involved) // pDqIdcMap[dq_index] for each SDqIdc pData
|
pDqIdcMap; // overall DQ map of full scalability in specific frame (All full D/T/Q layers involved) // pDqIdcMap[dq_index] for each SDqIdc pData
|
||||||
|
|
||||||
SParaSetOffset sPSOVector;
|
SParaSetOffset sPSOVector;
|
||||||
|
SParaSetOffset* pPSOVector;
|
||||||
CMemoryAlign* pMemAlign;
|
CMemoryAlign* pMemAlign;
|
||||||
|
|
||||||
#if defined(STAT_OUTPUT)
|
#if defined(STAT_OUTPUT)
|
||||||
|
@ -75,7 +75,8 @@ void GomValidCheck (const int32_t kiMbWidth, const int32_t kiMbHeight, int32_t*
|
|||||||
* \param para SWelsSvcCodingParam*
|
* \param para SWelsSvcCodingParam*
|
||||||
* \return successful - 0; otherwise none 0 for failed
|
* \return successful - 0; otherwise none 0 for failed
|
||||||
*/
|
*/
|
||||||
int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pPara, SLogContext* pLogCtx);
|
int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pPara, SLogContext* pLogCtx,
|
||||||
|
SExistingParasetList* pExistingParasetList);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief uninitialize Wels encoder core library
|
* \brief uninitialize Wels encoder core library
|
||||||
|
@ -162,7 +162,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
param.bEnableAdaptiveQuant = true; // adaptive quantization control
|
param.bEnableAdaptiveQuant = true; // adaptive quantization control
|
||||||
param.bEnableFrameSkip = true; // frame skipping
|
param.bEnableFrameSkip = true; // frame skipping
|
||||||
param.bEnableLongTermReference = false; // long term reference control
|
param.bEnableLongTermReference = false; // long term reference control
|
||||||
param.bEnableSpsPpsIdAddition = true; // pSps pPps id addition control
|
param.iSpsPpsIdStrategy = INCREASING_ID; // pSps pPps id addition control
|
||||||
param.bPrefixNalAddingCtrl = false; // prefix NAL adding control
|
param.bPrefixNalAddingCtrl = false; // prefix NAL adding control
|
||||||
param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded
|
param.iSpatialLayerNum = 1; // number of dependency(Spatial/CGS) layers used to be encoded
|
||||||
param.iTemporalLayerNum = 1; // number of temporal layer specified
|
param.iTemporalLayerNum = 1; // number of temporal layer specified
|
||||||
@ -350,8 +350,8 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
|
|
||||||
bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;
|
bPrefixNalAddingCtrl = pCodingParam.bPrefixNalAddingCtrl;
|
||||||
|
|
||||||
bEnableSpsPpsIdAddition =
|
iSpsPpsIdStrategy =
|
||||||
pCodingParam.bEnableSpsPpsIdAddition;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.
|
pCodingParam.iSpsPpsIdStrategy;//For SVC meeting application, to avoid mosaic issue caused by cross-IDR reference.
|
||||||
//SHOULD enable this feature.
|
//SHOULD enable this feature.
|
||||||
|
|
||||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||||
@ -477,6 +477,18 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
|
|
||||||
} SWelsSvcCodingParam;
|
} SWelsSvcCodingParam;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct TagExistingParasetList {
|
||||||
|
SWelsSPS sSps[MAX_SPS_COUNT];
|
||||||
|
SSubsetSps sSubsetSps[MAX_SPS_COUNT];
|
||||||
|
SWelsPPS sPps[MAX_PPS_COUNT];
|
||||||
|
|
||||||
|
uint32_t uiInUseSpsNum;
|
||||||
|
uint32_t uiInUseSubsetSpsNum;
|
||||||
|
uint32_t uiInUsePpsNum;
|
||||||
|
} SExistingParasetList;
|
||||||
|
|
||||||
|
|
||||||
static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
|
static inline int32_t FreeCodingParam (SWelsSvcCodingParam** pParam, CMemoryAlign* pMa) {
|
||||||
if (pParam == NULL || *pParam == NULL || pMa == NULL)
|
if (pParam == NULL || *pParam == NULL || pMa == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -83,9 +83,15 @@ typedef struct TagParaSetOffset {
|
|||||||
bool
|
bool
|
||||||
bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far
|
bPpsIdMappingIntoSubsetsps[MAX_DQ_LAYER_NUM/*+1*/]; // need not extra +1 due no MGS and FMO case so far
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
bool bEnableSpsPpsIdAddition;
|
int32_t iSpsPpsIdStrategy;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint32_t uiInUseSpsNum;
|
||||||
|
uint32_t uiInUseSubsetSpsNum;
|
||||||
|
uint32_t uiInUsePpsNum;
|
||||||
} SParaSetOffset;
|
} SParaSetOffset;
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,6 +171,7 @@
|
|||||||
|
|
||||||
#define UNAVAILABLE_DQ_ID ((uint8_t)(-1))
|
#define UNAVAILABLE_DQ_ID ((uint8_t)(-1))
|
||||||
#define LAYER_NUM_EXCHANGEABLE 2
|
#define LAYER_NUM_EXCHANGEABLE 2
|
||||||
|
#define INVALID_ID (-1)
|
||||||
|
|
||||||
#define NAL_HEADER_ADD_0X30BYTES 50
|
#define NAL_HEADER_ADD_0X30BYTES 50
|
||||||
|
|
||||||
|
@ -336,27 +336,27 @@ int32_t WelsWriteSubsetSpsSyntax (SSubsetSps* pSubsetSps, SBitStringAux* pBitStr
|
|||||||
* \note Call it in case EWelsNalUnitType is PPS.
|
* \note Call it in case EWelsNalUnitType is PPS.
|
||||||
*************************************************************************************
|
*************************************************************************************
|
||||||
*/
|
*/
|
||||||
int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* sPSOVector) {
|
int32_t WelsWritePpsSyntax (SWelsPPS* pPps, SBitStringAux* pBitStringAux, SParaSetOffset* pPSOVector) {
|
||||||
SBitStringAux* pLocalBitStringAux = pBitStringAux;
|
SBitStringAux* pLocalBitStringAux = pBitStringAux;
|
||||||
|
|
||||||
bool bUsedSubset = sPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId];
|
const int32_t kiParameterSetType = (pPSOVector != NULL) ? (pPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId] ?
|
||||||
int32_t iParameterSetType = (bUsedSubset ? PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS);
|
PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS) : 0;
|
||||||
|
|
||||||
BsWriteUE (pLocalBitStringAux, pPps->iPpsId +
|
BsWriteUE (pLocalBitStringAux, pPps->iPpsId
|
||||||
sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]);
|
+ ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]) : 0));
|
||||||
BsWriteUE (pLocalBitStringAux, pPps->iSpsId +
|
BsWriteUE (pLocalBitStringAux, pPps->iSpsId
|
||||||
sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId]);
|
+ ((pPSOVector != NULL) ? (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId]) : 0));
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
//SParaSetOffset use, 110421
|
//SParaSetOffset use, 110421
|
||||||
if (sPSOVector->bEnableSpsPpsIdAddition) {
|
if ((pPSOVector != NULL) && (INCREASING_ID & pPSOVector->iSpsPpsIdStrategy)) {
|
||||||
const int32_t kiTmpSpsIdInBs = pPps->iSpsId +
|
const int32_t kiTmpSpsIdInBs = pPps->iSpsId +
|
||||||
sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId];
|
pPSOVector->sParaSetOffsetVariable[kiParameterSetType].iParaSetIdDelta[pPps->iSpsId];
|
||||||
const int32_t tmp_pps_id_in_bs = pPps->iPpsId +
|
const int32_t tmp_pps_id_in_bs = pPps->iPpsId +
|
||||||
sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId];
|
pPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId];
|
||||||
assert (MAX_SPS_COUNT > kiTmpSpsIdInBs);
|
assert (MAX_SPS_COUNT > kiTmpSpsIdInBs);
|
||||||
assert (MAX_PPS_COUNT > tmp_pps_id_in_bs);
|
assert (MAX_PPS_COUNT > tmp_pps_id_in_bs);
|
||||||
assert (sPSOVector->sParaSetOffsetVariable[iParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]);
|
assert (pPSOVector->sParaSetOffsetVariable[kiParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -323,6 +323,12 @@ int32_t ParamValidationExt (SLogContext* pLogCtx, SWelsSvcCodingParam* pCodingPa
|
|||||||
pCodingParam->bDeblockingParallelFlag = true;
|
pCodingParam->bDeblockingParallelFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pCodingParam->iSpatialLayerNum > 1 && (SPS_LISTING & pCodingParam->iSpsPpsIdStrategy)) {
|
||||||
|
WelsLog (pLogCtx, WELS_LOG_INFO,
|
||||||
|
"ParamValidationExt(), iSpsPpsIdStrategy adjusted to CONSTANT_ID");
|
||||||
|
pCodingParam->iSpsPpsIdStrategy = CONSTANT_ID;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) {
|
for (i = 0; i < pCodingParam->iSpatialLayerNum; ++ i) {
|
||||||
SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i];
|
SSpatialLayerConfig* pSpatialLayer = &pCodingParam->sSpatialLayers[i];
|
||||||
const int32_t kiPicWidth = pSpatialLayer->iVideoWidth;
|
const int32_t kiPicWidth = pSpatialLayer->iVideoWidth;
|
||||||
@ -665,8 +671,12 @@ static inline int32_t AcquireLayersNals (sWelsEncCtx** ppCtx, SWelsSvcCodingPara
|
|||||||
++ iDIndex;
|
++ iDIndex;
|
||||||
} while (iDIndex < iNumDependencyLayers);
|
} while (iDIndex < iNumDependencyLayers);
|
||||||
|
|
||||||
|
// count parasets
|
||||||
iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) +
|
iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) +
|
||||||
iCountNumLayers; // plus iCountNumLayers for reserved application
|
iCountNumLayers // plus iCountNumLayers for reserved application
|
||||||
|
+ ((SPS_LISTING & pParam->iSpsPpsIdStrategy) ? MAX_SPS_COUNT : 0) //for Sps
|
||||||
|
+ (((SPS_LISTING & pParam->iSpsPpsIdStrategy) && (iNumDependencyLayers > 1)) ? MAX_SPS_COUNT : 0) //for SubsetSps
|
||||||
|
+ ((SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) ? MAX_PPS_COUNT : 0);
|
||||||
|
|
||||||
// to check number of layers / nals / slices dependencies, 12/8/2010
|
// to check number of layers / nals / slices dependencies, 12/8/2010
|
||||||
if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) {
|
if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) {
|
||||||
@ -847,9 +857,9 @@ void FreeMbCache (SMbCache* pMbCache, CMemoryAlign* pMa) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
static int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||||
const int32_t iDlayerCount, const int32_t kiSpsId,
|
const int32_t iDlayerCount, const int32_t kiSpsId,
|
||||||
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) {
|
SWelsSPS*& pSps, SSubsetSps*& pSubsetSps) {
|
||||||
int32_t iRet = 0;
|
int32_t iRet = 0;
|
||||||
|
|
||||||
if (!kbUseSubsetSps) {
|
if (!kbUseSubsetSps) {
|
||||||
@ -866,9 +876,6 @@ int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const
|
|||||||
iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
iRet = WelsInitSps (pSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||||
pParam->iMaxNumRefFrame,
|
pParam->iMaxNumRefFrame,
|
||||||
kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
|
kiSpsId, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
iRet = WelsInitSubsetSps (pSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||||
pParam->iMaxNumRefFrame,
|
pParam->iMaxNumRefFrame,
|
||||||
@ -877,12 +884,131 @@ int32_t WelsGenerateNewSps (sWelsEncCtx* pCtx, const bool kbUseSubsetSps, const
|
|||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool CheckMatchedSps (SWelsSPS* const pSps1, SWelsSPS* const pSps2) {
|
||||||
|
|
||||||
|
if ((pSps1->iMbWidth != pSps2->iMbWidth)
|
||||||
|
|| (pSps1->iMbHeight != pSps2->iMbHeight)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pSps1->uiLog2MaxFrameNum != pSps2->uiLog2MaxFrameNum)
|
||||||
|
|| (pSps1->iLog2MaxPocLsb != pSps2->iLog2MaxPocLsb)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pSps1->iNumRefFrames != pSps2->iNumRefFrames) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pSps1->bFrameCroppingFlag != pSps2->bFrameCroppingFlag)
|
||||||
|
|| (pSps1->sFrameCrop.iCropLeft != pSps2->sFrameCrop.iCropLeft)
|
||||||
|
|| (pSps1->sFrameCrop.iCropRight != pSps2->sFrameCrop.iCropRight)
|
||||||
|
|| (pSps1->sFrameCrop.iCropTop != pSps2->sFrameCrop.iCropTop)
|
||||||
|
|| (pSps1->sFrameCrop.iCropBottom != pSps2->sFrameCrop.iCropBottom)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pSps1->uiProfileIdc != pSps2->uiProfileIdc)
|
||||||
|
|| (pSps1->bConstraintSet0Flag != pSps2->bConstraintSet0Flag)
|
||||||
|
|| (pSps1->bConstraintSet1Flag != pSps2->bConstraintSet1Flag)
|
||||||
|
|| (pSps1->bConstraintSet2Flag != pSps2->bConstraintSet2Flag)
|
||||||
|
|| (pSps1->bConstraintSet3Flag != pSps2->bConstraintSet3Flag)
|
||||||
|
|| (pSps1->iLevelIdc != pSps2->iLevelIdc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CheckMatchedSubsetSps (SSubsetSps* const pSubsetSps1, SSubsetSps* const pSubsetSps2) {
|
||||||
|
if (!CheckMatchedSps (&pSubsetSps1->pSps, &pSubsetSps2->pSps)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pSubsetSps1->sSpsSvcExt.iExtendedSpatialScalability != pSubsetSps2->sSpsSvcExt.iExtendedSpatialScalability)
|
||||||
|
|| (pSubsetSps1->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag)
|
||||||
|
|| (pSubsetSps1->sSpsSvcExt.bSeqTcoeffLevelPredFlag != pSubsetSps2->sSpsSvcExt.bSeqTcoeffLevelPredFlag)
|
||||||
|
|| (pSubsetSps1->sSpsSvcExt.bSliceHeaderRestrictionFlag != pSubsetSps2->sSpsSvcExt.bSliceHeaderRestrictionFlag)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t FindExistingSps (SWelsSvcCodingParam* pParam, const bool kbUseSubsetSps, const int32_t iDlayerIndex,
|
||||||
|
const int32_t iDlayerCount, const int32_t iSpsNumInUse,
|
||||||
|
SWelsSPS* pSpsArray,
|
||||||
|
SSubsetSps* pSubsetArray) {
|
||||||
|
SSpatialLayerConfig* pDlayerParam = &pParam->sSpatialLayers[iDlayerIndex];
|
||||||
|
|
||||||
|
assert (iSpsNumInUse <= MAX_SPS_COUNT);
|
||||||
|
if (!kbUseSubsetSps) {
|
||||||
|
SWelsSPS sTmpSps;
|
||||||
|
WelsInitSps (&sTmpSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||||
|
pParam->iMaxNumRefFrame,
|
||||||
|
0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||||
|
for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
|
||||||
|
if (CheckMatchedSps (&sTmpSps, &pSpsArray[iId])) {
|
||||||
|
return iId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SSubsetSps sTmpSubsetSps;
|
||||||
|
WelsInitSubsetSps (&sTmpSubsetSps, pDlayerParam, &pParam->sDependencyLayers[iDlayerIndex], pParam->uiIntraPeriod,
|
||||||
|
pParam->iMaxNumRefFrame,
|
||||||
|
0, pParam->bEnableFrameCroppingFlag, pParam->iRCMode != RC_OFF_MODE);
|
||||||
|
|
||||||
|
for (int32_t iId = 0; iId < iSpsNumInUse; iId++) {
|
||||||
|
if (CheckMatchedSubsetSps (&sTmpSubsetSps, &pSubsetArray[iId])) {
|
||||||
|
return iId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t FindExistingPps (SWelsSPS* pSps, SSubsetSps* pSubsetSps, const bool kbUseSubsetSps, const int32_t iSpsId,
|
||||||
|
const bool kbEntropyCodingFlag, const int32_t iPpsNumInUse,
|
||||||
|
SWelsPPS* pPpsArray) {
|
||||||
|
#if !defined(DISABLE_FMO_FEATURE)
|
||||||
|
// feature not supported yet
|
||||||
|
return INVALID_ID;
|
||||||
|
#endif//!DISABLE_FMO_FEATURE
|
||||||
|
|
||||||
|
SWelsPPS sTmpPps;
|
||||||
|
WelsInitPps (&sTmpPps,
|
||||||
|
pSps,
|
||||||
|
pSubsetSps,
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
kbUseSubsetSps,
|
||||||
|
kbEntropyCodingFlag);
|
||||||
|
|
||||||
|
assert (iPpsNumInUse <= MAX_PPS_COUNT);
|
||||||
|
for (int32_t iId = 0; iId < iPpsNumInUse; iId++) {
|
||||||
|
if ((sTmpPps.iSpsId == pPpsArray[iId].iSpsId)
|
||||||
|
&& (sTmpPps.bEntropyCodingModeFlag == pPpsArray[iId].bEntropyCodingModeFlag)
|
||||||
|
&& (sTmpPps.iPicInitQp == pPpsArray[iId].iPicInitQp)
|
||||||
|
&& (sTmpPps.iPicInitQs == pPpsArray[iId].iPicInitQs)
|
||||||
|
&& (sTmpPps.uiChromaQpIndexOffset == pPpsArray[iId].uiChromaQpIndexOffset)
|
||||||
|
&& (sTmpPps.bDeblockingFilterControlPresentFlag == pPpsArray[iId].bDeblockingFilterControlPresentFlag)
|
||||||
|
) {
|
||||||
|
return iId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return INVALID_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available
|
* \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available
|
||||||
* \pParam pCtx sWelsEncCtx*
|
* \pParam pCtx sWelsEncCtx*
|
||||||
* \return 0 - successful; otherwise failed
|
* \return 0 - successful; otherwise failed
|
||||||
*/
|
*/
|
||||||
static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
|
static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList) {
|
||||||
SWelsSvcCodingParam* pParam = NULL;
|
SWelsSvcCodingParam* pParam = NULL;
|
||||||
SWelsSPS* pSps = NULL;
|
SWelsSPS* pSps = NULL;
|
||||||
SSubsetSps* pSubsetSps = NULL;
|
SSubsetSps* pSubsetSps = NULL;
|
||||||
@ -1045,14 +1171,51 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010
|
// for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010
|
||||||
(*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsPPS), "pPPSArray");
|
// SPS
|
||||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
|
if (! (SPS_LISTING & pParam->iSpsPpsIdStrategy)) {
|
||||||
|
(*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray");
|
||||||
|
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
|
||||||
|
if (iDlayerCount > 1) {
|
||||||
|
(*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray");
|
||||||
|
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// pParam->iSpsPpsIdStrategy == SPS_LISTING_AND_PPS_INCREASING
|
||||||
|
// new memory
|
||||||
|
(*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "pSpsArray");
|
||||||
|
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
|
||||||
|
|
||||||
(*ppCtx)->pSpsArray = (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray");
|
(*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "pSubsetArray");
|
||||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
|
|
||||||
if (iDlayerCount > 1) {
|
|
||||||
(*ppCtx)->pSubsetArray = (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray");
|
|
||||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))
|
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))
|
||||||
|
|
||||||
|
// copy from existing if the pointer exists
|
||||||
|
if (NULL != pExistingParasetList) {
|
||||||
|
(*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum;
|
||||||
|
(*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum;
|
||||||
|
memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||||
|
memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// PPS
|
||||||
|
if (! (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy)) {
|
||||||
|
(*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsPPS), "pPPSArray");
|
||||||
|
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
|
||||||
|
} else {
|
||||||
|
(*ppCtx)->pPPSArray = (SWelsPPS*)pMa->WelsMalloc (MAX_PPS_COUNT * sizeof (SWelsPPS), "pPPSArray");
|
||||||
|
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
|
||||||
|
|
||||||
|
|
||||||
|
// copy from existing if the pointer exists
|
||||||
|
if (NULL != pExistingParasetList) {
|
||||||
|
(*ppCtx)->sPSOVector.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum;
|
||||||
|
memcpy ((*ppCtx)->pPPSArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (INCREASING_ID & pParam->iSpsPpsIdStrategy) {
|
||||||
|
(*ppCtx)->pPSOVector = & ((*ppCtx)->sPSOVector);
|
||||||
|
} else {
|
||||||
|
(*ppCtx)->pPSOVector = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap");
|
(*ppCtx)->pDqIdcMap = (SDqIdc*)pMa->WelsMallocz (iDlayerCount * sizeof (SDqIdc), "pDqIdcMap");
|
||||||
@ -1066,12 +1229,79 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
|
|||||||
|
|
||||||
pDqIdc->uiSpatialId = iDlayerIndex;
|
pDqIdc->uiSpatialId = iDlayerIndex;
|
||||||
|
|
||||||
WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
|
if (! (SPS_LISTING & pParam->iSpsPpsIdStrategy)) {
|
||||||
iDlayerCount, iSpsId, pSps, pSubsetSps);
|
WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
|
||||||
|
iDlayerCount, iSpsId, pSps, pSubsetSps);
|
||||||
|
} else {
|
||||||
|
//SPS_LISTING_AND_PPS_INCREASING == pParam->iSpsPpsIdStrategy
|
||||||
|
//check if the current param can fit in an existing SPS
|
||||||
|
const int32_t kiFoundSpsId = FindExistingSps ((*ppCtx)->pSvcParam, bUseSubsetSps, iDlayerIndex, iDlayerCount,
|
||||||
|
bUseSubsetSps ? ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum) : ((*ppCtx)->sPSOVector.uiInUseSpsNum),
|
||||||
|
(*ppCtx)->pSpsArray,
|
||||||
|
(*ppCtx)->pSubsetArray);
|
||||||
|
|
||||||
pPps = & (*ppCtx)->pPPSArray[iPpsId];
|
|
||||||
// initialize pPps
|
if (INVALID_ID != kiFoundSpsId) {
|
||||||
WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
|
//if yes, set pSps or pSubsetSps to it
|
||||||
|
iSpsId = kiFoundSpsId;
|
||||||
|
if (!bUseSubsetSps) {
|
||||||
|
pSps = & ((*ppCtx)->pSpsArray[kiFoundSpsId]);
|
||||||
|
} else {
|
||||||
|
pSubsetSps = & ((*ppCtx)->pSubsetArray[kiFoundSpsId]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//if no, generate a new SPS as usual
|
||||||
|
if ((SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) && (MAX_PPS_COUNT <= (*ppCtx)->sPSOVector.uiInUsePpsNum)) {
|
||||||
|
//check if we can generate new SPS or not
|
||||||
|
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
|
||||||
|
"InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
|
||||||
|
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||||
|
}
|
||||||
|
|
||||||
|
iSpsId = (!bUseSubsetSps) ? ((*ppCtx)->sPSOVector.uiInUseSpsNum++) : ((*ppCtx)->sPSOVector.uiInUseSubsetSpsNum++);
|
||||||
|
if (iSpsId >= MAX_SPS_COUNT) {
|
||||||
|
if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) {
|
||||||
|
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
|
||||||
|
"InitDqLayers(), cannot generate new SPS under the SPS_PPS_LISTING mode!");
|
||||||
|
return ENC_RETURN_UNSUPPORTED_PARA;
|
||||||
|
}
|
||||||
|
// reset current list
|
||||||
|
if (!bUseSubsetSps) {
|
||||||
|
(*ppCtx)->sPSOVector.uiInUseSpsNum = 1;
|
||||||
|
memset ((*ppCtx)->pSpsArray, 0, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||||
|
} else {
|
||||||
|
(*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = 1;
|
||||||
|
memset ((*ppCtx)->pSubsetArray, 0, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||||
|
}
|
||||||
|
iSpsId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WelsGenerateNewSps (*ppCtx, bUseSubsetSps, iDlayerIndex,
|
||||||
|
iDlayerCount, iSpsId, pSps, pSubsetSps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy)) {
|
||||||
|
pPps = & (*ppCtx)->pPPSArray[iPpsId];
|
||||||
|
// initialize pPps
|
||||||
|
WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
|
||||||
|
} else {
|
||||||
|
const int32_t kiFoundPpsId = FindExistingPps (pSps, pSubsetSps, bUseSubsetSps, iSpsId,
|
||||||
|
pParam->iEntropyCodingModeFlag != 0,
|
||||||
|
(*ppCtx)->sPSOVector.uiInUsePpsNum,
|
||||||
|
(*ppCtx)->pPPSArray);
|
||||||
|
|
||||||
|
|
||||||
|
if (INVALID_ID != kiFoundPpsId) {
|
||||||
|
//if yes, set pPps to it
|
||||||
|
iPpsId = kiFoundPpsId;
|
||||||
|
pPps = & ((*ppCtx)->pPPSArray[kiFoundPpsId]);
|
||||||
|
} else {
|
||||||
|
iPpsId = ((*ppCtx)->sPSOVector.uiInUsePpsNum++);
|
||||||
|
pPps = & (*ppCtx)->pPPSArray[iPpsId];
|
||||||
|
WelsInitPps (pPps, pSps, pSubsetSps, iPpsId, true, bUseSubsetSps, pParam->iEntropyCodingModeFlag != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Not using FMO in SVC coding so far, come back if need FMO
|
// Not using FMO in SVC coding so far, come back if need FMO
|
||||||
{
|
{
|
||||||
@ -1085,7 +1315,7 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
|
|||||||
if (iResult) {
|
if (iResult) {
|
||||||
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult);
|
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSlicePEncCtx failed(%d)!", iResult);
|
||||||
FreeMemorySvc (ppCtx);
|
FreeMemorySvc (ppCtx);
|
||||||
return 1;
|
return iResult;
|
||||||
}
|
}
|
||||||
(*ppCtx)->ppDqLayerList[iDlayerIndex]->pSliceEncCtx = & (*ppCtx)->pSliceCtxList[iDlayerIndex];
|
(*ppCtx)->ppDqLayerList[iDlayerIndex]->pSliceEncCtx = & (*ppCtx)->pSliceCtxList[iDlayerIndex];
|
||||||
}
|
}
|
||||||
@ -1097,12 +1327,23 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx) {
|
|||||||
if (bUseSubsetSps)
|
if (bUseSubsetSps)
|
||||||
++ iSpsId;
|
++ iSpsId;
|
||||||
++ iPpsId;
|
++ iPpsId;
|
||||||
++ (*ppCtx)->iSpsNum;
|
if (bUseSubsetSps) {
|
||||||
|
++ (*ppCtx)->iSubsetSpsNum;
|
||||||
|
} else {
|
||||||
|
++ (*ppCtx)->iSpsNum;
|
||||||
|
}
|
||||||
++ (*ppCtx)->iPpsNum;
|
++ (*ppCtx)->iPpsNum;
|
||||||
|
|
||||||
++ iDlayerIndex;
|
++ iDlayerIndex;
|
||||||
}
|
}
|
||||||
return 0;
|
if (SPS_LISTING & pParam->iSpsPpsIdStrategy) {
|
||||||
|
(*ppCtx)->iSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
|
||||||
|
(*ppCtx)->iSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
|
||||||
|
}
|
||||||
|
if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) {
|
||||||
|
(*ppCtx)->iPpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum;
|
||||||
|
}
|
||||||
|
return ENC_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AllocStrideTables (sWelsEncCtx** ppCtx, const int32_t kiNumSpatialLayers) {
|
int32_t AllocStrideTables (sWelsEncCtx** ppCtx, const int32_t kiNumSpatialLayers) {
|
||||||
@ -1411,7 +1652,7 @@ void GetMvMvdRange (SWelsSvcCodingParam* pParam, int32_t& iMvRange, int32_t& iMv
|
|||||||
|
|
||||||
iMvdRange = WELS_MIN (iMvdRange, iFixMvdRange);
|
iMvdRange = WELS_MIN (iMvdRange, iFixMvdRange);
|
||||||
}
|
}
|
||||||
int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingParasetList) {
|
||||||
SWelsSvcCodingParam* pParam = (*ppCtx)->pSvcParam;
|
SWelsSvcCodingParam* pParam = (*ppCtx)->pSvcParam;
|
||||||
CMemoryAlign* pMa = (*ppCtx)->pMemAlign;
|
CMemoryAlign* pMa = (*ppCtx)->pMemAlign;
|
||||||
SSpatialLayerConfig* pFinalSpatial = NULL;
|
SSpatialLayerConfig* pFinalSpatial = NULL;
|
||||||
@ -1616,7 +1857,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) {
|
|||||||
|
|
||||||
//End of pVaa memory allocation
|
//End of pVaa memory allocation
|
||||||
|
|
||||||
iResult = InitDqLayers (ppCtx);
|
iResult = InitDqLayers (ppCtx, pExistingParasetList);
|
||||||
if (iResult) {
|
if (iResult) {
|
||||||
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult);
|
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "RequestMemorySvc(), InitDqLayers failed(%d)!", iResult);
|
||||||
FreeMemorySvc (ppCtx);
|
FreeMemorySvc (ppCtx);
|
||||||
@ -2130,7 +2371,8 @@ int32_t GetMultipleThreadIdc (SLogContext* pLogCtx, SWelsSvcCodingParam* pCoding
|
|||||||
* \pParam pParam SWelsSvcCodingParam*
|
* \pParam pParam SWelsSvcCodingParam*
|
||||||
* \return successful - 0; otherwise none 0 for failed
|
* \return successful - 0; otherwise none 0 for failed
|
||||||
*/
|
*/
|
||||||
int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx) {
|
int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingParam, SLogContext* pLogCtx,
|
||||||
|
SExistingParasetList* pExistingParasetList) {
|
||||||
sWelsEncCtx* pCtx = NULL;
|
sWelsEncCtx* pCtx = NULL;
|
||||||
int32_t iRet = 0;
|
int32_t iRet = 0;
|
||||||
int16_t iSliceNum = 1; // number of slices used
|
int16_t iSliceNum = 1; // number of slices used
|
||||||
@ -2189,7 +2431,7 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
|||||||
|
|
||||||
pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum;
|
pCtx->iActiveThreadsNum = pCodingParam->iCountThreadsNum;
|
||||||
pCtx->iMaxSliceCount = iSliceNum;
|
pCtx->iMaxSliceCount = iSliceNum;
|
||||||
iRet = RequestMemorySvc (&pCtx);
|
iRet = RequestMemorySvc (&pCtx, pExistingParasetList);
|
||||||
if (iRet != 0) {
|
if (iRet != 0) {
|
||||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), RequestMemorySvc failed return %d.", iRet);
|
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), RequestMemorySvc failed return %d.", iRet);
|
||||||
FreeMemorySvc (&pCtx);
|
FreeMemorySvc (&pCtx);
|
||||||
@ -2553,18 +2795,26 @@ void WelsInitCurrentLayer (sWelsEncCtx* pCtx,
|
|||||||
iSliceCount = GetCurrentSliceNum (pCurDq->pSliceEncCtx);
|
iSliceCount = GetCurrentSliceNum (pCurDq->pSliceEncCtx);
|
||||||
assert (iSliceCount > 0);
|
assert (iSliceCount > 0);
|
||||||
|
|
||||||
pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = pDqIdc->iPpsId;
|
int32_t iCurPpsId = pDqIdc->iPpsId;
|
||||||
|
int32_t iCurSpsId = pDqIdc->iSpsId;
|
||||||
|
|
||||||
|
if (SPS_PPS_LISTING == pParam->iSpsPpsIdStrategy) {
|
||||||
|
iCurPpsId = pCtx->sPSOVector.iPpsIdList[pDqIdc->iPpsId][WELS_ABS (pCtx->uiIdrPicId - 1) % MAX_PPS_COUNT];
|
||||||
|
}
|
||||||
|
|
||||||
|
pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId = iCurPpsId;
|
||||||
pCurDq->sLayerInfo.pPpsP =
|
pCurDq->sLayerInfo.pPpsP =
|
||||||
pBaseSlice->sSliceHeaderExt.sSliceHeader.pPps = &pCtx->pPPSArray[pBaseSlice->sSliceHeaderExt.sSliceHeader.iPpsId];
|
pBaseSlice->sSliceHeaderExt.sSliceHeader.pPps = &pCtx->pPPSArray[iCurPpsId];
|
||||||
pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId = pDqIdc->iSpsId;
|
|
||||||
|
pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId = iCurSpsId;
|
||||||
if (kbUseSubsetSpsFlag) {
|
if (kbUseSubsetSpsFlag) {
|
||||||
pCurDq->sLayerInfo.pSubsetSpsP = &pCtx->pSubsetArray[pDqIdc->iSpsId];
|
pCurDq->sLayerInfo.pSubsetSpsP = &pCtx->pSubsetArray[iCurSpsId];
|
||||||
pCurDq->sLayerInfo.pSpsP =
|
pCurDq->sLayerInfo.pSpsP =
|
||||||
pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCurDq->sLayerInfo.pSubsetSpsP->pSps;
|
pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCurDq->sLayerInfo.pSubsetSpsP->pSps;
|
||||||
} else {
|
} else {
|
||||||
pCurDq->sLayerInfo.pSubsetSpsP = NULL;
|
pCurDq->sLayerInfo.pSubsetSpsP = NULL;
|
||||||
pCurDq->sLayerInfo.pSpsP =
|
pCurDq->sLayerInfo.pSpsP =
|
||||||
pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCtx->pSpsArray[pBaseSlice->sSliceHeaderExt.sSliceHeader.iSpsId];
|
pBaseSlice->sSliceHeaderExt.sSliceHeader.pSps = &pCtx->pSpsArray[iCurSpsId];
|
||||||
}
|
}
|
||||||
|
|
||||||
pSlice = pBaseSlice;
|
pSlice = pBaseSlice;
|
||||||
@ -2865,46 +3115,68 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
|||||||
/* write all SPS */
|
/* write all SPS */
|
||||||
iIdx = 0;
|
iIdx = 0;
|
||||||
while (iIdx < pCtx->iSpsNum) {
|
while (iIdx < pCtx->iSpsNum) {
|
||||||
SDqIdc* pDqIdc = &pCtx->pDqIdcMap[iIdx];
|
|
||||||
const int32_t kiDid = pDqIdc->uiSpatialId;
|
|
||||||
const bool kbUsingSubsetSps = (kiDid > BASE_DEPENDENCY_ID);
|
|
||||||
|
|
||||||
iNal = pCtx->pOut->iNalIndex;
|
iNal = pCtx->pOut->iNalIndex;
|
||||||
|
|
||||||
if (pCtx->pSvcParam->bEnableSpsPpsIdAddition) {
|
if (INCREASING_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) {
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
pCtx->sPSOVector.bEnableSpsPpsIdAddition = 1;
|
pCtx->sPSOVector.iSpsPpsIdStrategy = INCREASING_ID;
|
||||||
assert (kiDid < MAX_DEPENDENCY_LAYER);
|
|
||||||
assert (iIdx < MAX_DQ_LAYER_NUM);
|
assert (iIdx < MAX_DQ_LAYER_NUM);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[kbUsingSubsetSps ? PARA_SET_TYPE_SUBSETSPS :
|
ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS]),
|
||||||
PARA_SET_TYPE_AVCSPS]),
|
pCtx->pSpsArray[0].uiSpsId,
|
||||||
(kbUsingSubsetSps) ? (pCtx->pSubsetArray[iIdx - 1].pSps.uiSpsId) : (pCtx->pSpsArray[0].uiSpsId),
|
|
||||||
MAX_SPS_COUNT);
|
MAX_SPS_COUNT);
|
||||||
} else {
|
} else if (CONSTANT_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) {
|
||||||
memset (& (pCtx->sPSOVector), 0, sizeof (pCtx->sPSOVector));
|
memset (& (pCtx->sPSOVector), 0, sizeof (pCtx->sPSOVector));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kbUsingSubsetSps) {
|
/* generate sequence parameters set */
|
||||||
iId = iIdx - 1;
|
iId = (SPS_LISTING & pCtx->pSvcParam->iSpsPpsIdStrategy) ? iIdx : 0;
|
||||||
|
|
||||||
/* generate Subset SPS */
|
WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST);
|
||||||
WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST);
|
WelsWriteSpsNal (&pCtx->pSpsArray[iId], &pCtx->pOut->sBsWrite,
|
||||||
|
& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0]));
|
||||||
|
WelsUnloadNal (pCtx->pOut);
|
||||||
|
|
||||||
WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite,
|
iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
|
||||||
& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0]));
|
pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length
|
||||||
WelsUnloadNal (pCtx->pOut);
|
pCtx->pFrameBs + pCtx->iPosBsBuffer,
|
||||||
} else {
|
&iNalLength);
|
||||||
iId = 0;
|
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
|
||||||
|
pNalLen[iCountNal] = iNalLength;
|
||||||
|
|
||||||
/* generate sequence parameters set */
|
pCtx->iPosBsBuffer += iNalLength;
|
||||||
WelsLoadNal (pCtx->pOut, NAL_UNIT_SPS, NRI_PRI_HIGHEST);
|
iSize += iNalLength;
|
||||||
WelsWriteSpsNal (&pCtx->pSpsArray[0], &pCtx->pOut->sBsWrite,
|
|
||||||
& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_AVCSPS].iParaSetIdDelta[0]));
|
++ iIdx;
|
||||||
WelsUnloadNal (pCtx->pOut);
|
++ iCountNal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write all Subset SPS */
|
||||||
|
iIdx = 0;
|
||||||
|
while (iIdx < pCtx->iSubsetSpsNum) {
|
||||||
|
iNal = pCtx->pOut->iNalIndex;
|
||||||
|
|
||||||
|
if (INCREASING_ID == pCtx->pSvcParam->iSpsPpsIdStrategy) {
|
||||||
|
#if _DEBUG
|
||||||
|
pCtx->sPSOVector.iSpsPpsIdStrategy = INCREASING_ID;
|
||||||
|
assert (iIdx < MAX_DQ_LAYER_NUM);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ParasetIdAdditionIdAdjust (& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS]),
|
||||||
|
pCtx->pSubsetArray[iIdx].pSps.uiSpsId,
|
||||||
|
MAX_SPS_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iId = iIdx;
|
||||||
|
|
||||||
|
/* generate Subset SPS */
|
||||||
|
WelsLoadNal (pCtx->pOut, NAL_UNIT_SUBSET_SPS, NRI_PRI_HIGHEST);
|
||||||
|
|
||||||
|
WelsWriteSubsetSpsSyntax (&pCtx->pSubsetArray[iId], &pCtx->pOut->sBsWrite,
|
||||||
|
& (pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_SUBSETSPS].iParaSetIdDelta[0]));
|
||||||
|
WelsUnloadNal (pCtx->pOut);
|
||||||
|
|
||||||
iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
|
iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
|
||||||
pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length
|
pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length
|
||||||
pCtx->pFrameBs + pCtx->iPosBsBuffer,
|
pCtx->pFrameBs + pCtx->iPosBsBuffer,
|
||||||
@ -2921,8 +3193,30 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
|||||||
|
|
||||||
/* write all PPS */
|
/* write all PPS */
|
||||||
iIdx = 0;
|
iIdx = 0;
|
||||||
|
if ((SPS_PPS_LISTING == pCtx->pSvcParam->iSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) {
|
||||||
|
assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM);
|
||||||
|
|
||||||
|
//Generate PPS LIST
|
||||||
|
int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum;
|
||||||
|
|
||||||
|
for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) {
|
||||||
|
for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) {
|
||||||
|
pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) {
|
||||||
|
memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS));
|
||||||
|
pCtx->pPPSArray[iPpsId].iPpsId = iPpsId;
|
||||||
|
pCtx->iPpsNum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert (pCtx->iPpsNum == MAX_PPS_COUNT);
|
||||||
|
pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum;
|
||||||
|
}
|
||||||
|
|
||||||
while (iIdx < pCtx->iPpsNum) {
|
while (iIdx < pCtx->iPpsNum) {
|
||||||
if (pCtx->pSvcParam->bEnableSpsPpsIdAddition) {
|
if ((INCREASING_ID & pCtx->pSvcParam->iSpsPpsIdStrategy)) {
|
||||||
//para_set_type = 2: PPS, use MAX_PPS_COUNT
|
//para_set_type = 2: PPS, use MAX_PPS_COUNT
|
||||||
ParasetIdAdditionIdAdjust (&pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS], pCtx->pPPSArray[iIdx].iPpsId,
|
ParasetIdAdditionIdAdjust (&pCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS], pCtx->pPPSArray[iIdx].iPpsId,
|
||||||
MAX_PPS_COUNT);
|
MAX_PPS_COUNT);
|
||||||
@ -2931,7 +3225,8 @@ int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pN
|
|||||||
iNal = pCtx->pOut->iNalIndex;
|
iNal = pCtx->pOut->iNalIndex;
|
||||||
/* generate picture parameter set */
|
/* generate picture parameter set */
|
||||||
WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST);
|
WelsLoadNal (pCtx->pOut, NAL_UNIT_PPS, NRI_PRI_HIGHEST);
|
||||||
WelsWritePpsSyntax (&pCtx->pPPSArray[iIdx], &pCtx->pOut->sBsWrite, & (pCtx->sPSOVector));
|
WelsWritePpsSyntax (&pCtx->pPPSArray[iIdx], &pCtx->pOut->sBsWrite,
|
||||||
|
((SPS_PPS_LISTING != pCtx->pSvcParam->iSpsPpsIdStrategy)) ? (& (pCtx->sPSOVector)) : NULL);
|
||||||
WelsUnloadNal (pCtx->pOut);
|
WelsUnloadNal (pCtx->pOut);
|
||||||
|
|
||||||
iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
|
iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
|
||||||
@ -3237,7 +3532,6 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
|||||||
iDidList[iSpatialIdx] = iCurDid;
|
iDidList[iSpatialIdx] = iCurDid;
|
||||||
|
|
||||||
// Encoding this picture might mulitiple sQualityStat layers potentially be encoded as followed
|
// Encoding this picture might mulitiple sQualityStat layers potentially be encoded as followed
|
||||||
|
|
||||||
switch (pParam->sSliceCfg.uiSliceMode) {
|
switch (pParam->sSliceCfg.uiSliceMode) {
|
||||||
case SM_FIXEDSLCNUM_SLICE:
|
case SM_FIXEDSLCNUM_SLICE:
|
||||||
case SM_AUTO_SLICE: {
|
case SM_AUTO_SLICE: {
|
||||||
@ -3829,7 +4123,8 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
|||||||
(pOldParam->iLTRRefNum != pNewParam->iLTRRefNum) ||
|
(pOldParam->iLTRRefNum != pNewParam->iLTRRefNum) ||
|
||||||
(pOldParam->iMultipleThreadIdc != pNewParam->iMultipleThreadIdc) ||
|
(pOldParam->iMultipleThreadIdc != pNewParam->iMultipleThreadIdc) ||
|
||||||
(pOldParam->bEnableBackgroundDetection != pNewParam->bEnableBackgroundDetection) ||
|
(pOldParam->bEnableBackgroundDetection != pNewParam->bEnableBackgroundDetection) ||
|
||||||
(pOldParam->bEnableAdaptiveQuant != pNewParam->bEnableAdaptiveQuant);
|
(pOldParam->bEnableAdaptiveQuant != pNewParam->bEnableAdaptiveQuant) ||
|
||||||
|
(pOldParam->iSpsPpsIdStrategy != pNewParam->iSpsPpsIdStrategy);
|
||||||
if (pNewParam->iMaxNumRefFrame > pOldParam->iMaxNumRefFrame) {
|
if (pNewParam->iMaxNumRefFrame > pOldParam->iMaxNumRefFrame) {
|
||||||
bNeedReset = true;
|
bNeedReset = true;
|
||||||
}
|
}
|
||||||
@ -3876,35 +4171,75 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bNeedReset) {
|
if (bNeedReset) {
|
||||||
SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE];
|
|
||||||
uint16_t uiTmpIdrPicId;//this is for LTR!
|
|
||||||
SLogContext sLogCtx = (*ppCtx)->sLogCtx;
|
SLogContext sLogCtx = (*ppCtx)->sLogCtx;
|
||||||
for (int32_t k = 0; k < PARA_SET_TYPE; k++)
|
|
||||||
memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool));
|
int32_t iOldSpsPpsIdStrategy = pOldParam->iSpsPpsIdStrategy;
|
||||||
memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable,
|
SParaSetOffsetVariable sTmpPsoVariable[PARA_SET_TYPE];
|
||||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
int32_t iTmpPpsIdList[MAX_DQ_LAYER_NUM * MAX_PPS_COUNT];
|
||||||
uiTmpIdrPicId = (*ppCtx)->uiIdrPicId;
|
uint16_t uiTmpIdrPicId = (*ppCtx)->uiIdrPicId;//this is for LTR!
|
||||||
|
|
||||||
SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics;
|
SEncoderStatistics sTempEncoderStatistics = (*ppCtx)->sEncoderStatistics;
|
||||||
|
|
||||||
|
SExistingParasetList sExistingParasetList;
|
||||||
|
SExistingParasetList* pExistingParasetList = NULL;
|
||||||
|
|
||||||
|
if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->iSpsPpsIdStrategy)) {
|
||||||
|
for (int32_t k = 0; k < PARA_SET_TYPE; k++) {
|
||||||
|
memset (((*ppCtx)->sPSOVector.sParaSetOffsetVariable[k].bUsedParaSetIdInBs), 0, MAX_PPS_COUNT * sizeof (bool));
|
||||||
|
}
|
||||||
|
memcpy (sTmpPsoVariable, (*ppCtx)->sPSOVector.sParaSetOffsetVariable,
|
||||||
|
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||||
|
|
||||||
|
if ((SPS_LISTING & iOldSpsPpsIdStrategy)
|
||||||
|
&& (SPS_LISTING & pNewParam->iSpsPpsIdStrategy)) {
|
||||||
|
pExistingParasetList = &sExistingParasetList;
|
||||||
|
sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
|
||||||
|
sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
|
||||||
|
memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||||
|
memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy)
|
||||||
|
&& (SPS_PPS_LISTING == pNewParam->iSpsPpsIdStrategy)) {
|
||||||
|
pExistingParasetList = &sExistingParasetList;
|
||||||
|
sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
|
||||||
|
sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
|
||||||
|
sExistingParasetList.uiInUsePpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum;
|
||||||
|
memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
|
||||||
|
memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
|
||||||
|
memcpy (sExistingParasetList.sPps, (*ppCtx)->pPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
|
||||||
|
|
||||||
|
memcpy (iTmpPpsIdList, ((*ppCtx)->sPSOVector.iPpsIdList), MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WelsUninitEncoderExt (ppCtx);
|
WelsUninitEncoderExt (ppCtx);
|
||||||
|
|
||||||
/* Update new parameters */
|
/* Update new parameters */
|
||||||
if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx))
|
if (WelsInitEncoderExt (ppCtx, pNewParam, &sLogCtx, pExistingParasetList))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// reset the scaled spatial picture size
|
// reset the scaled spatial picture size
|
||||||
(*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
|
(*ppCtx)->pVpp->WelsPreprocessReset (*ppCtx);
|
||||||
//if WelsInitEncoderExt succeed
|
//if WelsInitEncoderExt succeed
|
||||||
|
|
||||||
//load back the needed structure
|
|
||||||
//for FLEXIBLE_PARASET_ID
|
|
||||||
memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
|
|
||||||
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
|
||||||
//for LTR
|
//for LTR
|
||||||
(*ppCtx)->uiIdrPicId = uiTmpIdrPicId;
|
(*ppCtx)->uiIdrPicId = uiTmpIdrPicId;
|
||||||
|
|
||||||
//for sEncoderStatistics
|
//for sEncoderStatistics
|
||||||
(*ppCtx)->sEncoderStatistics = sTempEncoderStatistics;
|
(*ppCtx)->sEncoderStatistics = sTempEncoderStatistics;
|
||||||
|
|
||||||
|
//load back the needed structure for iSpsPpsIdStrategy
|
||||||
|
if ((CONSTANT_ID != iOldSpsPpsIdStrategy) && (CONSTANT_ID != pNewParam->iSpsPpsIdStrategy)) {
|
||||||
|
memcpy ((*ppCtx)->sPSOVector.sParaSetOffsetVariable, sTmpPsoVariable,
|
||||||
|
(PARA_SET_TYPE)*sizeof (SParaSetOffsetVariable)); // confirmed_safe_unsafe_usage
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy)
|
||||||
|
&& (SPS_PPS_LISTING == pNewParam->iSpsPpsIdStrategy)) {
|
||||||
|
memcpy (((*ppCtx)->sPSOVector.iPpsIdList), iTmpPpsIdList, MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */
|
/* maybe adjustment introduced in bitrate or little settings adjustment and so on.. */
|
||||||
pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT,
|
pNewParam->iNumRefFrame = WELS_CLIP3 (pNewParam->iNumRefFrame, MIN_REF_PIC_COUNT,
|
||||||
@ -3919,7 +4254,7 @@ int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewPa
|
|||||||
pOldParam->fMaxFrameRate = pNewParam->fMaxFrameRate; // maximal frame rate [Hz / fps]
|
pOldParam->fMaxFrameRate = pNewParam->fMaxFrameRate; // maximal frame rate [Hz / fps]
|
||||||
pOldParam->iComplexityMode = pNewParam->iComplexityMode; // color space of input sequence
|
pOldParam->iComplexityMode = pNewParam->iComplexityMode; // color space of input sequence
|
||||||
pOldParam->uiIntraPeriod = pNewParam->uiIntraPeriod; // intra period (multiple of GOP size as desired)
|
pOldParam->uiIntraPeriod = pNewParam->uiIntraPeriod; // intra period (multiple of GOP size as desired)
|
||||||
pOldParam->bEnableSpsPpsIdAddition = pNewParam->bEnableSpsPpsIdAddition;
|
pOldParam->iSpsPpsIdStrategy = pNewParam->iSpsPpsIdStrategy;
|
||||||
pOldParam->bPrefixNalAddingCtrl = pNewParam->bPrefixNalAddingCtrl;
|
pOldParam->bPrefixNalAddingCtrl = pNewParam->bPrefixNalAddingCtrl;
|
||||||
pOldParam->iNumRefFrame = pNewParam->iNumRefFrame; // number of reference frame used
|
pOldParam->iNumRefFrame = pNewParam->iNumRefFrame; // number of reference frame used
|
||||||
pOldParam->uiGopSize = pNewParam->uiGopSize;
|
pOldParam->uiGopSize = pNewParam->uiGopSize;
|
||||||
|
@ -237,7 +237,8 @@ void WriteRefPicMarking (SBitStringAux* pBs, SSliceHeader* pSliceHeader, SNalUni
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, int32_t* pPpsIdDelta) {
|
void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
|
||||||
|
int32_t* pPpsIdDelta) {
|
||||||
SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
|
SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
|
||||||
SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
|
SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
|
||||||
SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
|
SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
|
||||||
@ -246,7 +247,7 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur
|
|||||||
BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
|
BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
|
||||||
BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
|
BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
|
||||||
|
|
||||||
BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId]);
|
BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + ((pPpsIdDelta != NULL) ? pPpsIdDelta[pSliceHeader->pPps->iPpsId] : 0));
|
||||||
|
|
||||||
BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
|
BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
|
||||||
|
|
||||||
@ -301,7 +302,8 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice, int32_t* pPpsIdDelta) {
|
void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
|
||||||
|
int32_t* pPpsIdDelta) {
|
||||||
SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
|
SWelsSPS* pSps = pCurLayer->sLayerInfo.pSpsP;
|
||||||
SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
|
SWelsPPS* pPps = pCurLayer->sLayerInfo.pPpsP;
|
||||||
SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP;
|
SSubsetSps* pSubSps = pCurLayer->sLayerInfo.pSubsetSpsP;
|
||||||
@ -312,7 +314,7 @@ void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* p
|
|||||||
BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
|
BsWriteUE (pBs, pSliceHeader->iFirstMbInSlice);
|
||||||
BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
|
BsWriteUE (pBs, pSliceHeader->eSliceType); /* same type things */
|
||||||
|
|
||||||
BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + pPpsIdDelta[pSliceHeader->pPps->iPpsId]);
|
BsWriteUE (pBs, pSliceHeader->pPps->iPpsId + ((pPpsIdDelta != NULL) ? pPpsIdDelta[pSliceHeader->pPps->iPpsId] : 0));
|
||||||
|
|
||||||
BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
|
BsWriteBits (pBs, pSps->uiLog2MaxFrameNum, pSliceHeader->iFrameNum);
|
||||||
|
|
||||||
@ -727,11 +729,12 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const
|
|||||||
|
|
||||||
WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice);
|
WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice);
|
||||||
|
|
||||||
|
|
||||||
g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pEncCtx, pBs, pCurLayer, pCurSlice,
|
g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pEncCtx, pBs, pCurLayer, pCurSlice,
|
||||||
& (pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0]));
|
((SPS_PPS_LISTING != pEncCtx->pSvcParam->iSpsPpsIdStrategy) ? (&
|
||||||
|
(pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[0])) : NULL));
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
if (pEncCtx->sPSOVector.bEnableSpsPpsIdAddition) {
|
if (INCREASING_ID & pEncCtx->sPSOVector.iSpsPpsIdStrategy) {
|
||||||
const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId;
|
const int32_t kiEncoderPpsId = pCurSlice->sSliceHeaderExt.sSliceHeader.pPps->iPpsId;
|
||||||
const int32_t kiTmpPpsIdInBs = kiEncoderPpsId +
|
const int32_t kiTmpPpsIdInBs = kiEncoderPpsId +
|
||||||
pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ];
|
pEncCtx->sPSOVector.sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[ kiEncoderPpsId ];
|
||||||
|
@ -332,7 +332,7 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) {
|
|||||||
m_iMaxPicHeight = pCfg->iPicHeight;
|
m_iMaxPicHeight = pCfg->iPicHeight;
|
||||||
|
|
||||||
TraceParamInfo (pCfg);
|
TraceParamInfo (pCfg);
|
||||||
if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx)) {
|
if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx, NULL)) {
|
||||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.");
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.");
|
||||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG,
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG,
|
||||||
"Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d",
|
"Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d",
|
||||||
@ -477,6 +477,7 @@ int CWelsH264SVCEncoder::ForceIntraFrame (bool bIDR) {
|
|||||||
}
|
}
|
||||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||||
"CWelsH264SVCEncoder::ForceIntraFrame(), bIDR= %d", bIDR);
|
"CWelsH264SVCEncoder::ForceIntraFrame(), bIDR= %d", bIDR);
|
||||||
|
|
||||||
ForceCodingIDR (m_pEncContext);
|
ForceCodingIDR (m_pEncContext);
|
||||||
|
|
||||||
m_pEncContext->sEncoderStatistics.uiIDRReqNum++;
|
m_pEncContext->sEncoderStatistics.uiIDRReqNum++;
|
||||||
@ -486,8 +487,8 @@ int CWelsH264SVCEncoder::ForceIntraFrame (bool bIDR) {
|
|||||||
void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
|
void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
|
||||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||||
"iUsageType = %d,iPicWidth= %d;iPicHeight= %d;iTargetBitrate= %d;iMaxBitrate= %d;iRCMode= %d;iPaddingFlag= %d;iTemporalLayerNum= %d;iSpatialLayerNum= %d;fFrameRate= %.6ff;uiIntraPeriod= %d;\
|
"iUsageType = %d,iPicWidth= %d;iPicHeight= %d;iTargetBitrate= %d;iMaxBitrate= %d;iRCMode= %d;iPaddingFlag= %d;iTemporalLayerNum= %d;iSpatialLayerNum= %d;fFrameRate= %.6ff;uiIntraPeriod= %d;\
|
||||||
bEnableSpsPpsIdAddition = %d;bPrefixNalAddingCtrl = %d;bEnableDenoise= %d;bEnableBackgroundDetection= %d;bEnableAdaptiveQuant= %d;bEnableFrameSkip= %d;bEnableLongTermReference= %d;iLtrMarkPeriod= %d;\
|
iSpsPpsIdStrategy = %d;bPrefixNalAddingCtrl = %d;bEnableDenoise= %d;bEnableBackgroundDetection= %d;bEnableAdaptiveQuant= %d;bEnableFrameSkip= %d;bEnableLongTermReference= %d;iLtrMarkPeriod= %d;\
|
||||||
iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d",
|
iComplexityMode = %d;iNumRefFrame = %d;iEntropyCodingModeFlag = %d;uiMaxNalSize = %d;iLTRRefNum = %d;iMultipleThreadIdc = %d;iLoopFilterDisableIdc = %d (offset(alpha/beta): %d,%d)",
|
||||||
pParam->iUsageType,
|
pParam->iUsageType,
|
||||||
pParam->iPicWidth,
|
pParam->iPicWidth,
|
||||||
pParam->iPicHeight,
|
pParam->iPicHeight,
|
||||||
@ -499,7 +500,7 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
|
|||||||
pParam->iSpatialLayerNum,
|
pParam->iSpatialLayerNum,
|
||||||
pParam->fMaxFrameRate,
|
pParam->fMaxFrameRate,
|
||||||
pParam->uiIntraPeriod,
|
pParam->uiIntraPeriod,
|
||||||
pParam->bEnableSpsPpsIdAddition,
|
pParam->iSpsPpsIdStrategy,
|
||||||
pParam->bPrefixNalAddingCtrl,
|
pParam->bPrefixNalAddingCtrl,
|
||||||
pParam->bEnableDenoise,
|
pParam->bEnableDenoise,
|
||||||
pParam->bEnableBackgroundDetection,
|
pParam->bEnableBackgroundDetection,
|
||||||
@ -513,7 +514,9 @@ void CWelsH264SVCEncoder::TraceParamInfo (SEncParamExt* pParam) {
|
|||||||
pParam->uiMaxNalSize,
|
pParam->uiMaxNalSize,
|
||||||
pParam->iLTRRefNum,
|
pParam->iLTRRefNum,
|
||||||
pParam->iMultipleThreadIdc,
|
pParam->iMultipleThreadIdc,
|
||||||
pParam->iLoopFilterDisableIdc
|
pParam->iLoopFilterDisableIdc,
|
||||||
|
pParam->iLoopFilterAlphaC0Offset,
|
||||||
|
pParam->iLoopFilterBetaOffset
|
||||||
);
|
);
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
int32_t iSpatialLayers = (pParam->iSpatialLayerNum < MAX_SPATIAL_LAYER_NUM) ? (pParam->iSpatialLayerNum) :
|
int32_t iSpatialLayers = (pParam->iSpatialLayerNum < MAX_SPATIAL_LAYER_NUM) ? (pParam->iSpatialLayerNum) :
|
||||||
@ -706,16 +709,26 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
|||||||
#endif//OUTPUT_BIT_STREAM
|
#endif//OUTPUT_BIT_STREAM
|
||||||
if (sEncodingParam.iSpatialLayerNum < 1
|
if (sEncodingParam.iSpatialLayerNum < 1
|
||||||
|| sEncodingParam.iSpatialLayerNum > MAX_SPATIAL_LAYER_NUM) { // verify number of spatial layer
|
|| sEncodingParam.iSpatialLayerNum > MAX_SPATIAL_LAYER_NUM) { // verify number of spatial layer
|
||||||
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||||
|
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, iSpatialLayerNum(%d) failed!",
|
||||||
|
sEncodingParam.iSpatialLayerNum);
|
||||||
return cmInitParaError;
|
return cmInitParaError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sConfig.ParamTranscode (sEncodingParam)) {
|
if (sConfig.ParamTranscode (sEncodingParam)) {
|
||||||
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||||
|
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, ParamTranscode failed!");
|
||||||
return cmInitParaError;
|
return cmInitParaError;
|
||||||
}
|
}
|
||||||
if (sConfig.iSpatialLayerNum < 1) {
|
if (sConfig.iSpatialLayerNum < 1) {
|
||||||
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||||
|
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, iSpatialLayerNum(%d) failed!",
|
||||||
|
sConfig.iSpatialLayerNum);
|
||||||
return cmInitParaError;
|
return cmInitParaError;
|
||||||
}
|
}
|
||||||
if (sConfig.DetermineTemporalSettings()) {
|
if (sConfig.DetermineTemporalSettings()) {
|
||||||
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
|
||||||
|
"CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, DetermineTemporalSettings failed!");
|
||||||
return cmInitParaError;
|
return cmInitParaError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -898,11 +911,17 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: {
|
case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: {
|
||||||
bool iValue = * ((bool*)pOption);
|
int32_t iValue = * ((int32_t*)pOption);
|
||||||
|
if (((iValue > INCREASING_ID) || (m_pEncContext->pSvcParam->iSpsPpsIdStrategy > INCREASING_ID))
|
||||||
m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition = iValue;
|
&& m_pEncContext->pSvcParam->iSpsPpsIdStrategy != iValue) {
|
||||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption enable SPS/PPS ID = %d ",
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR,
|
||||||
m_pEncContext->pSvcParam->bEnableSpsPpsIdAddition);
|
" 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",
|
||||||
|
m_pEncContext->pSvcParam->iSpsPpsIdStrategy, iValue);
|
||||||
|
return cmInitParaError;
|
||||||
|
}
|
||||||
|
m_pEncContext->pSvcParam->iSpsPpsIdStrategy = iValue;
|
||||||
|
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO, " CWelsH264SVCEncoder::SetOption iSpsPpsIdStrategy = %d ",
|
||||||
|
m_pEncContext->pSvcParam->iSpsPpsIdStrategy);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENCODER_OPTION_CURRENT_PATH: {
|
case ENCODER_OPTION_CURRENT_PATH: {
|
||||||
|
@ -88,26 +88,25 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar
|
|||||||
BaseDecoderTest::TearDown();
|
BaseDecoderTest::TearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void prepareParam (int iLayers, int iSlices, int width, int height, float framerate) {
|
virtual void prepareParam (int iLayers, int iSlices, int width, int height, float framerate, SEncParamExt* pParam) {
|
||||||
memset (¶m_, 0, sizeof (SEncParamExt));
|
memset (pParam, 0, sizeof (SEncParamExt));
|
||||||
param_.iUsageType = CAMERA_VIDEO_REAL_TIME;
|
pParam->iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||||
param_.iPicWidth = width;
|
pParam->iPicWidth = width;
|
||||||
param_.iPicHeight = height;
|
pParam->iPicHeight = height;
|
||||||
param_.fMaxFrameRate = framerate;
|
pParam->fMaxFrameRate = framerate;
|
||||||
param_.iRCMode = RC_OFF_MODE; //rc off
|
pParam->iRCMode = RC_OFF_MODE; //rc off
|
||||||
param_.iMultipleThreadIdc = 1; //single thread
|
pParam->iMultipleThreadIdc = 1; //single thread
|
||||||
param_.iSpatialLayerNum = iLayers;
|
pParam->iSpatialLayerNum = iLayers;
|
||||||
param_.iNumRefFrame = AUTO_REF_PIC_COUNT;
|
pParam->iNumRefFrame = AUTO_REF_PIC_COUNT;
|
||||||
for (int i = 0; i < iLayers; i++) {
|
for (int i = 0; i < iLayers; i++) {
|
||||||
param_.sSpatialLayers[i].iVideoWidth = width >> (iLayers - i - 1);
|
pParam->sSpatialLayers[i].iVideoWidth = width >> (iLayers - i - 1);
|
||||||
param_.sSpatialLayers[i].iVideoHeight = height >> (iLayers - i - 1);
|
pParam->sSpatialLayers[i].iVideoHeight = height >> (iLayers - i - 1);
|
||||||
param_.sSpatialLayers[i].fFrameRate = framerate;
|
pParam->sSpatialLayers[i].fFrameRate = framerate;
|
||||||
param_.sSpatialLayers[i].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
|
pParam->sSpatialLayers[i].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
|
||||||
param_.sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceNum = iSlices;
|
pParam->sSpatialLayers[i].sSliceCfg.sSliceArgument.uiSliceNum = iSlices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) {
|
virtual void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam) {
|
||||||
//for encoder
|
//for encoder
|
||||||
//I420: 1(Y) + 1/4(U) + 1/4(V)
|
//I420: 1(Y) + 1/4(U) + 1/4(V)
|
||||||
@ -147,6 +146,15 @@ class EncodeDecodeTestBase : public ::testing::TestWithParam<EncodeDecodeFilePar
|
|||||||
len = layerInfo.pNalLengthInByte[iSliceNum];
|
len = layerInfo.pNalLengthInByte[iSliceNum];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual int GetRandWidth() {
|
||||||
|
return (WELS_CLIP3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 2, MAX_WIDTH));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int GetRandHeight() {
|
||||||
|
return (WELS_CLIP3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 2, MAX_HEIGHT));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SEncParamExt param_;
|
SEncParamExt param_;
|
||||||
BufferedData buf_;
|
BufferedData buf_;
|
||||||
@ -171,8 +179,8 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase {
|
|||||||
EncodeDecodeTestBase::TearDown();
|
EncodeDecodeTestBase::TearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareParam (int iLayers, int iSlices, int width, int height, float framerate) {
|
void prepareParam (int iLayers, int iSlices, int width, int height, float framerate, SEncParamExt* pParam) {
|
||||||
EncodeDecodeTestBase::prepareParam (iLayers, iSlices, width, height, framerate);
|
EncodeDecodeTestBase::prepareParam (iLayers, iSlices, width, height, framerate, pParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitialEncDec (int iWidth, int iHeight);
|
void InitialEncDec (int iWidth, int iHeight);
|
||||||
@ -192,6 +200,24 @@ class EncodeDecodeTestAPI : public EncodeDecodeTestBase {
|
|||||||
else if (1 == iCheckTypeIndex)
|
else if (1 == iCheckTypeIndex)
|
||||||
ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason);
|
ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EncDecOneFrame (const int iWidth, const int iHeight, const int iFrame, FILE* pfEnc) {
|
||||||
|
int iLen = 0, rv;
|
||||||
|
InitialEncDec (iWidth, iHeight);
|
||||||
|
EncodeOneFrame (iFrame);
|
||||||
|
|
||||||
|
//extract target layer data
|
||||||
|
encToDecData (info, iLen);
|
||||||
|
//call decoder
|
||||||
|
unsigned char* pData[3] = { NULL };
|
||||||
|
memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
|
||||||
|
rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iLen, pData, &dstBufInfo_);
|
||||||
|
EXPECT_TRUE (rv == cmResultSuccess) << " rv = " << rv << " iFrameIdx = " << iFrame;
|
||||||
|
|
||||||
|
if (NULL != pfEnc) {
|
||||||
|
fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, pfEnc);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void EncodeDecodeTestAPI::InitialEncDec (int iWidth, int iHeight) {
|
void EncodeDecodeTestAPI::InitialEncDec (int iWidth, int iHeight) {
|
||||||
@ -234,7 +260,7 @@ void EncodeDecodeTestAPI::RandomParamExtCombination() {
|
|||||||
param_.iNumRefFrame = AUTO_REF_PIC_COUNT;
|
param_.iNumRefFrame = AUTO_REF_PIC_COUNT;
|
||||||
param_.iMultipleThreadIdc = rand();
|
param_.iMultipleThreadIdc = rand();
|
||||||
|
|
||||||
param_.bEnableSpsPpsIdAddition = (rand() % 2 == 0) ? false : true;
|
param_.iSpsPpsIdStrategy = rand() % 3;
|
||||||
param_.bPrefixNalAddingCtrl = (rand() % 2 == 0) ? false : true;
|
param_.bPrefixNalAddingCtrl = (rand() % 2 == 0) ? false : true;
|
||||||
param_.bEnableSSEI = (rand() % 2 == 0) ? false : true;
|
param_.bEnableSSEI = (rand() % 2 == 0) ? false : true;
|
||||||
param_.iPaddingFlag = rand() % 2;
|
param_.iPaddingFlag = rand() % 2;
|
||||||
@ -462,7 +488,7 @@ static const EncodeDecodeFileParamBase kFileParamArray[] = {
|
|||||||
|
|
||||||
TEST_P (EncodeDecodeTestAPI, DecoderVclNal) {
|
TEST_P (EncodeDecodeTestAPI, DecoderVclNal) {
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -498,7 +524,7 @@ TEST_P (EncodeDecodeTestAPI, DecoderVclNal) {
|
|||||||
|
|
||||||
TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) {
|
TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) {
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -535,7 +561,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) {
|
|||||||
|
|
||||||
TEST_P (EncodeDecodeTestAPI, GetOptionIDR) {
|
TEST_P (EncodeDecodeTestAPI, GetOptionIDR) {
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -554,7 +580,8 @@ TEST_P (EncodeDecodeTestAPI, GetOptionIDR) {
|
|||||||
int32_t iSpsPpsIdAddition = 0;
|
int32_t iSpsPpsIdAddition = 0;
|
||||||
int iIdx = 0;
|
int iIdx = 0;
|
||||||
while (iIdx <= p.numframes) {
|
while (iIdx <= p.numframes) {
|
||||||
iSpsPpsIdAddition = rand() % 2;
|
iSpsPpsIdAddition = rand() %
|
||||||
|
2; //the current strategy supports more than 2 modes, but the switch between the modes>2 is not allowed
|
||||||
iIDRPeriod = (rand() % 150) + 1;
|
iIDRPeriod = (rand() % 150) + 1;
|
||||||
encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
|
encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
|
||||||
encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition);
|
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
|
|||||||
|
|
||||||
TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) {
|
TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLIDR) {
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -809,7 +836,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_ALLLTR) {
|
|||||||
SLTRMarkingFeedback m_LTR_Marking_Feedback;
|
SLTRMarkingFeedback m_LTR_Marking_Feedback;
|
||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -868,7 +895,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionLTR_Engine) {
|
|||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
m_LTR_Recover_Request.uiIDRPicId = 0;
|
m_LTR_Recover_Request.uiIDRPicId = 0;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -918,7 +945,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_DISABLE) {
|
|||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
m_LTR_Recover_Request.uiIDRPicId = 0;
|
m_LTR_Recover_Request.uiIDRPicId = 0;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.bEnableLongTermReference = true;
|
param_.bEnableLongTermReference = true;
|
||||||
param_.iLTRRefNum = 1;
|
param_.iLTRRefNum = 1;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
@ -985,7 +1012,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) {
|
|||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
m_LTR_Recover_Request.uiIDRPicId = 0;
|
m_LTR_Recover_Request.uiIDRPicId = 0;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -1036,7 +1063,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) {
|
|||||||
|
|
||||||
TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) {
|
TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) {
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -1086,7 +1113,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_NOPREFIX) {
|
|||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
m_LTR_Recover_Request.uiIDRPicId = 0;
|
m_LTR_Recover_Request.uiIDRPicId = 0;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.bPrefixNalAddingCtrl = false;
|
param_.bPrefixNalAddingCtrl = false;
|
||||||
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
@ -1155,7 +1182,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_WITH_PREFIX_NOLOSS) {
|
|||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
m_LTR_Recover_Request.uiIDRPicId = 0;
|
m_LTR_Recover_Request.uiIDRPicId = 0;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.bPrefixNalAddingCtrl = true;
|
param_.bPrefixNalAddingCtrl = true;
|
||||||
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
||||||
param_.iSpatialLayerNum = 1;
|
param_.iSpatialLayerNum = 1;
|
||||||
@ -1210,7 +1237,7 @@ TEST_P (EncodeDecodeTestAPI, GetOptionTid_SVC_L1_NOLOSS) {
|
|||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
m_LTR_Recover_Request.uiIDRPicId = 0;
|
m_LTR_Recover_Request.uiIDRPicId = 0;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (2, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (2, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
||||||
param_.iSpatialLayerNum = 2;
|
param_.iSpatialLayerNum = 2;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
@ -1266,7 +1293,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace) {
|
|||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
m_LTR_Recover_Request.uiIDRPicId = 0;
|
m_LTR_Recover_Request.uiIDRPicId = 0;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iSpatialLayerNum = 1;
|
param_.iSpatialLayerNum = 1;
|
||||||
|
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
@ -1330,7 +1357,7 @@ TEST_P (EncodeDecodeTestAPI, SetOption_Trace_NULL) {
|
|||||||
SLTRRecoverRequest m_LTR_Recover_Request;
|
SLTRRecoverRequest m_LTR_Recover_Request;
|
||||||
m_LTR_Recover_Request.uiIDRPicId = 0;
|
m_LTR_Recover_Request.uiIDRPicId = 0;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iSpatialLayerNum = 1;
|
param_.iSpatialLayerNum = 1;
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -1393,7 +1420,7 @@ TEST_P (EncodeDecodeTestAPI, SetOptionECIDC_GeneralSliceChange) {
|
|||||||
uint32_t uiEcIdc;
|
uint32_t uiEcIdc;
|
||||||
uint32_t uiGet;
|
uint32_t uiGet;
|
||||||
EncodeDecodeFileParamBase p = GetParam();
|
EncodeDecodeFileParamBase p = GetParam();
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iSpatialLayerNum = 1;
|
param_.iSpatialLayerNum = 1;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
@ -1473,7 +1500,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) {
|
|||||||
uint32_t uiEcIdc;
|
uint32_t uiEcIdc;
|
||||||
uint32_t uiGet;
|
uint32_t uiGet;
|
||||||
EncodeDecodeFileParamBase p = kFileParamArray[0];
|
EncodeDecodeFileParamBase p = kFileParamArray[0];
|
||||||
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iSpatialLayerNum = 1;
|
param_.iSpatialLayerNum = 1;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
@ -1612,7 +1639,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) {
|
|||||||
uint32_t uiEcIdc = 2; //default set as SLICE_COPY
|
uint32_t uiEcIdc = 2; //default set as SLICE_COPY
|
||||||
uint32_t uiGet;
|
uint32_t uiGet;
|
||||||
EncodeDecodeFileParamBase p = kFileParamArray[0];
|
EncodeDecodeFileParamBase p = kFileParamArray[0];
|
||||||
prepareParam (1, 2, p.width, p.height, p.frameRate);
|
prepareParam (1, 2, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iSpatialLayerNum = 1;
|
param_.iSpatialLayerNum = 1;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
@ -1745,7 +1772,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) {
|
|||||||
uint32_t uiEcIdc;
|
uint32_t uiEcIdc;
|
||||||
uint32_t uiGet;
|
uint32_t uiGet;
|
||||||
EncodeDecodeFileParamBase p = kFileParamArray[0];
|
EncodeDecodeFileParamBase p = kFileParamArray[0];
|
||||||
prepareParam (1, 2, p.width, p.height, p.frameRate);
|
prepareParam (1, 2, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iSpatialLayerNum = 1;
|
param_.iSpatialLayerNum = 1;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
@ -1914,7 +1941,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_I) {
|
|||||||
EncodeDecodeFileParamBase p = kSVCSwitch[0];
|
EncodeDecodeFileParamBase p = kSVCSwitch[0];
|
||||||
p.width = p.width << 2;
|
p.width = p.width << 2;
|
||||||
p.height = p.height << 2;
|
p.height = p.height << 2;
|
||||||
prepareParam (4, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (4, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
||||||
param_.iSpatialLayerNum = 4;
|
param_.iSpatialLayerNum = 4;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
@ -1979,7 +2006,7 @@ TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_P) {
|
|||||||
int iLastDid = 0;
|
int iLastDid = 0;
|
||||||
p.width = p.width << 2;
|
p.width = p.width << 2;
|
||||||
p.height = p.height << 2;
|
p.height = p.height << 2;
|
||||||
prepareParam (4, p.slicenum, p.width, p.height, p.frameRate);
|
prepareParam (4, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
param_.iTemporalLayerNum = (rand() % 4) + 1;
|
||||||
param_.iSpatialLayerNum = 4;
|
param_.iSpatialLayerNum = 4;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
@ -2065,7 +2092,7 @@ TEST_F (EncodeDecodeTestAPI, SetOptionEncParamExt) {
|
|||||||
int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
|
int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
|
||||||
int iSliceNum = 1;
|
int iSliceNum = 1;
|
||||||
encoder_->GetDefaultParams (¶m_);
|
encoder_->GetDefaultParams (¶m_);
|
||||||
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate);
|
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
|
||||||
|
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
ASSERT_TRUE (rv == cmResultSuccess);
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
@ -2128,8 +2155,8 @@ class DecodeCrashTestAPI : public EncodeDecodeTestBase {
|
|||||||
ASSERT_TRUE (ucBuf_ == NULL);
|
ASSERT_TRUE (ucBuf_ == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate) {
|
void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate, SEncParamExt* pParam) {
|
||||||
EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate);
|
EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate, pParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam);
|
void prepareEncDecParam (const EncodeDecodeFileParamBase EncDecFileParam);
|
||||||
@ -2203,11 +2230,11 @@ TEST_F (DecodeCrashTestAPI, DecoderCrashTest) {
|
|||||||
int iSeed = rand() % 3; //3 indicates the length of kParamArray[] used in the following
|
int iSeed = rand() % 3; //3 indicates the length of kParamArray[] used in the following
|
||||||
EncodeDecodeParamBase p = kParamArray[iSeed];
|
EncodeDecodeParamBase p = kParamArray[iSeed];
|
||||||
//Initialize Encoder
|
//Initialize Encoder
|
||||||
prepareParam (1, 1, p.width, p.height, p.frameRate);
|
prepareParam (1, 1, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iRCMode = RC_BITRATE_MODE;
|
param_.iRCMode = RC_BITRATE_MODE;
|
||||||
param_.iTargetBitrate = p.iTarBitrate;
|
param_.iTargetBitrate = p.iTarBitrate;
|
||||||
param_.uiIntraPeriod = 0;
|
param_.uiIntraPeriod = 0;
|
||||||
param_.bEnableSpsPpsIdAddition = true;
|
param_.iSpsPpsIdStrategy = INCREASING_ID;
|
||||||
param_.bEnableBackgroundDetection = true;
|
param_.bEnableBackgroundDetection = true;
|
||||||
param_.bEnableSceneChangeDetect = true;
|
param_.bEnableSceneChangeDetect = true;
|
||||||
param_.bPrefixNalAddingCtrl = true;
|
param_.bPrefixNalAddingCtrl = true;
|
||||||
@ -2398,7 +2425,7 @@ TEST_F (DecodeParseAPI, ParseOnly_General) {
|
|||||||
p.height = iHeight_;
|
p.height = iHeight_;
|
||||||
p.frameRate = kiFrameRate;
|
p.frameRate = kiFrameRate;
|
||||||
p.numframes = kiFrameNum;
|
p.numframes = kiFrameNum;
|
||||||
prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate);
|
prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iSpatialLayerNum = kiTotalLayer;
|
param_.iSpatialLayerNum = kiTotalLayer;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
@ -2475,7 +2502,7 @@ TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) {
|
|||||||
p.height = iHeight_;
|
p.height = iHeight_;
|
||||||
p.frameRate = kiFrameRate;
|
p.frameRate = kiFrameRate;
|
||||||
p.numframes = 5;
|
p.numframes = 5;
|
||||||
prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate);
|
prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate, ¶m_);
|
||||||
param_.iSpatialLayerNum = iLayerNum;
|
param_.iSpatialLayerNum = iLayerNum;
|
||||||
encoder_->Uninitialize();
|
encoder_->Uninitialize();
|
||||||
int rv = encoder_->InitializeExt (¶m_);
|
int rv = encoder_->InitializeExt (¶m_);
|
||||||
@ -2525,3 +2552,434 @@ TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) {
|
|||||||
} //while
|
} //while
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#define DEBUG_FILE_SAVE2
|
||||||
|
TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING1) {
|
||||||
|
|
||||||
|
int iWidth = GetRandWidth();
|
||||||
|
int iHeight = GetRandHeight();
|
||||||
|
float fFrameRate = rand() + 0.5f;
|
||||||
|
int iEncFrameNum = 0;
|
||||||
|
int iSpatialLayerNum = 1;
|
||||||
|
int iSliceNum = 1;
|
||||||
|
|
||||||
|
// prepare params
|
||||||
|
SEncParamExt sParam1;
|
||||||
|
SEncParamExt sParam2;
|
||||||
|
SEncParamExt sParam3;
|
||||||
|
encoder_->GetDefaultParams (&sParam1);
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
|
||||||
|
sParam1.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
|
||||||
|
//prepare param2
|
||||||
|
memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
|
||||||
|
while (sParam2.iPicWidth == sParam1.iPicWidth) {
|
||||||
|
sParam2.iPicWidth = GetRandWidth();
|
||||||
|
}
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
|
||||||
|
sParam2.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
|
||||||
|
//prepare param3
|
||||||
|
memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
|
||||||
|
while (sParam3.iPicHeight == sParam1.iPicHeight) {
|
||||||
|
sParam3.iPicHeight = GetRandHeight();
|
||||||
|
}
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
|
||||||
|
sParam3.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
|
||||||
|
|
||||||
|
//prepare output if needed
|
||||||
|
FILE* fEnc = NULL;
|
||||||
|
#ifdef DEBUG_FILE_SAVE2
|
||||||
|
fEnc = fopen ("enc2.264", "wb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Test part#1
|
||||||
|
// step#1: pParam1
|
||||||
|
//int TraceLevel = WELS_LOG_INFO;
|
||||||
|
//encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
|
||||||
|
int rv = encoder_->InitializeExt (&sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
|
||||||
|
sParam1.iPicHeight;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// new IDR
|
||||||
|
rv = encoder_->ForceIntraFrame (true);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// step#2: pParam2
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam2.iPicWidth << "x" <<
|
||||||
|
sParam2.iPicHeight;
|
||||||
|
EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// new IDR
|
||||||
|
rv = encoder_->ForceIntraFrame (true);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// step#3: back to pParam1
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
|
||||||
|
sParam1.iPicHeight;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// step#4: back to pParam2
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << sParam2.iPicWidth << sParam2.iPicHeight;
|
||||||
|
EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILE_SAVE2
|
||||||
|
fclose (fEnc);
|
||||||
|
#endif
|
||||||
|
rv = encoder_->Uninitialize();
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
|
||||||
|
// Test part#2
|
||||||
|
// step#1: pParam1
|
||||||
|
rv = encoder_->InitializeExt (&sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam3: rv = " << rv;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILE_SAVE2
|
||||||
|
fEnc = fopen ("enc3.264", "wb");
|
||||||
|
#endif
|
||||||
|
iEncFrameNum = 0;
|
||||||
|
EncDecOneFrame (sParam3.iPicWidth, sParam3.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILE_SAVE2
|
||||||
|
fclose (fEnc);
|
||||||
|
#endif
|
||||||
|
rv = encoder_->Uninitialize();
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEBUG_FILE_SAVE5
|
||||||
|
TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING2) {
|
||||||
|
//usage 3: 2 Params with different num_ref, encode IDR0, P1, IDR2;
|
||||||
|
//the bs will show two SPS and different PPS
|
||||||
|
|
||||||
|
int iWidth = GetRandWidth();
|
||||||
|
int iHeight = GetRandHeight();
|
||||||
|
float fFrameRate = rand() + 0.5f;
|
||||||
|
int iEncFrameNum = 0;
|
||||||
|
int iSpatialLayerNum = 1;
|
||||||
|
int iSliceNum = 1;
|
||||||
|
|
||||||
|
// prepare params
|
||||||
|
SEncParamExt sParam1;
|
||||||
|
SEncParamExt sParam2;
|
||||||
|
encoder_->GetDefaultParams (&sParam1);
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
|
||||||
|
sParam1.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
|
||||||
|
sParam1.iTemporalLayerNum = 1;
|
||||||
|
//prepare param2
|
||||||
|
memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
|
||||||
|
sParam2.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
|
||||||
|
sParam2.iTemporalLayerNum = 3;
|
||||||
|
|
||||||
|
//prepare output if needed
|
||||||
|
FILE* fEnc = NULL;
|
||||||
|
#ifdef DEBUG_FILE_SAVE5
|
||||||
|
fEnc = fopen ("encID2.264", "wb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// step#1: pParam1
|
||||||
|
int rv = encoder_->InitializeExt (&sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
|
||||||
|
sParam1.iPicHeight;
|
||||||
|
|
||||||
|
// step#2: pParam2
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
|
||||||
|
|
||||||
|
// step#3: set back to pParam1, with a smaller num_ref, it still uses the previous SPS
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam1: rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// new IDR, PPS increases
|
||||||
|
rv = encoder_->ForceIntraFrame (true);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
rv = encoder_->Uninitialize();
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILE_SAVE5
|
||||||
|
fclose (fEnc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING3) {
|
||||||
|
|
||||||
|
int iWidth = GetRandWidth();
|
||||||
|
int iHeight = GetRandHeight();
|
||||||
|
float fFrameRate = rand() + 0.5f;
|
||||||
|
int iEncFrameNum = 0;
|
||||||
|
int iSpatialLayerNum = 1;
|
||||||
|
int iSliceNum = 1;
|
||||||
|
|
||||||
|
// prepare params
|
||||||
|
SEncParamExt sParam1;
|
||||||
|
SEncParamExt sParam2;
|
||||||
|
encoder_->GetDefaultParams (&sParam1);
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
|
||||||
|
sParam1.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
|
||||||
|
|
||||||
|
//prepare output if needed
|
||||||
|
FILE* fEnc = NULL;
|
||||||
|
#ifdef DEBUG_FILE_SAVE2
|
||||||
|
fEnc = fopen ("enc4.264", "wb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// step#1: pParam1
|
||||||
|
int rv = encoder_->InitializeExt (&sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
|
||||||
|
|
||||||
|
int max_count = 65; // make it more then twice as MAX_SPS_COUNT
|
||||||
|
std::vector<int> vWidthTable;
|
||||||
|
vWidthTable.push_back (sParam1.iPicWidth);
|
||||||
|
|
||||||
|
std::vector<int>::iterator vWidthTableIt;
|
||||||
|
for (int times = 0; times < max_count; times++) {
|
||||||
|
//prepare param2
|
||||||
|
memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
|
||||||
|
do {
|
||||||
|
sParam2.iPicWidth = GetRandWidth();
|
||||||
|
vWidthTableIt = std::find (vWidthTable.begin(), vWidthTable.end(), sParam2.iPicWidth);
|
||||||
|
} while (vWidthTableIt == vWidthTable.end());
|
||||||
|
vWidthTable.push_back (sParam2.iPicWidth);
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
|
||||||
|
sParam2.iSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
|
||||||
|
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv << ", sParam2.iPicWidth=" <<
|
||||||
|
sParam2.iPicWidth;
|
||||||
|
} // end of setting loop
|
||||||
|
|
||||||
|
EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILE_SAVE2
|
||||||
|
fclose (fEnc);
|
||||||
|
#endif
|
||||||
|
rv = encoder_->Uninitialize();
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#define DEBUG_FILE_SAVE6
|
||||||
|
TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING1) {
|
||||||
|
//usage 1: 1 resolution Params, encode IDR0, P1, IDR2;
|
||||||
|
//the bs will show same SPS and different PPS
|
||||||
|
// PPS: pic_parameter_set_id 1 ( 0)
|
||||||
|
// PPS: seq_parameter_set_id 1 ( 0)
|
||||||
|
// PPS: pic_parameter_set_id 010 ( 1)
|
||||||
|
// PPS: seq_parameter_set_id 1 ( 0)
|
||||||
|
// SH: slice_type 011 ( 2)
|
||||||
|
// SH: pic_parameter_set_id 1 ( 0)
|
||||||
|
// SH: slice_type 1 ( 0)
|
||||||
|
// SH: pic_parameter_set_id 1 ( 0)
|
||||||
|
// SH: slice_type 011 ( 2)
|
||||||
|
// SH: pic_parameter_set_id 010 ( 1)
|
||||||
|
int iWidth = GetRandWidth();
|
||||||
|
int iHeight = GetRandHeight();
|
||||||
|
float fFrameRate = rand() + 0.5f;
|
||||||
|
int iEncFrameNum = 0;
|
||||||
|
int iSpatialLayerNum = 1;
|
||||||
|
int iSliceNum = 1;
|
||||||
|
|
||||||
|
// prepare params
|
||||||
|
SEncParamExt sParam1;
|
||||||
|
encoder_->GetDefaultParams (&sParam1);
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
|
||||||
|
sParam1.iSpsPpsIdStrategy = SPS_PPS_LISTING;
|
||||||
|
|
||||||
|
//prepare output if needed
|
||||||
|
FILE* fEnc = NULL;
|
||||||
|
#ifdef DEBUG_FILE_SAVE6
|
||||||
|
fEnc = fopen ("encLIST1.264", "wb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// step#1: pParam1
|
||||||
|
int rv = encoder_->InitializeExt (&sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
|
||||||
|
sParam1.iPicHeight;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// new IDR
|
||||||
|
rv = encoder_->ForceIntraFrame (true);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
rv = encoder_->Uninitialize();
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILE_SAVE6
|
||||||
|
fclose (fEnc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING2) {
|
||||||
|
//usage 2: 2 resolution Params, encode IDR0, IDR1, IDR2;
|
||||||
|
//the bs will show two SPS and different PPS
|
||||||
|
// === SPS LIST ===
|
||||||
|
//SPS: seq_parameter_set_id 1 ( 0) -- PARAM1
|
||||||
|
//SPS: seq_parameter_set_id 010 ( 1) -- PARAM2
|
||||||
|
// === PPS LIST ===
|
||||||
|
//PPS: pic_parameter_set_id 1 ( 0)
|
||||||
|
//PPS: seq_parameter_set_id 1 ( 0)
|
||||||
|
//PPS: pic_parameter_set_id 010 ( 1)
|
||||||
|
//PPS: seq_parameter_set_id 010 ( 1)
|
||||||
|
//PPS: pic_parameter_set_id 011 ( 2) -- PPS2 - SPS0
|
||||||
|
//PPS: seq_parameter_set_id 1 ( 0)
|
||||||
|
//PPS: pic_parameter_set_id 00100 ( 3) -- PPS3 - SPS1
|
||||||
|
//PPS: seq_parameter_set_id 010 ( 1)
|
||||||
|
//PPS: pic_parameter_set_id 00101 ( 4) -- PPS4 - SPS0
|
||||||
|
//PPS: seq_parameter_set_id 1 ( 0)
|
||||||
|
// === VCL LAYER ===
|
||||||
|
//SH: slice_type 011 ( 2) -- PARAM2
|
||||||
|
//SH: pic_parameter_set_id 010 ( 1) -- PPS1 - SPS1 - PARAM2
|
||||||
|
//SH: slice_type 011 ( 2) -- PARAM1
|
||||||
|
//SH: pic_parameter_set_id 011 ( 2) -- PPS2 - SPS0 - PARAM1
|
||||||
|
//SH: slice_type 011 ( 2) -- PARAM1
|
||||||
|
//SH: pic_parameter_set_id 00101 ( 4) -- PPS4 - SPS0 - PARAM1
|
||||||
|
|
||||||
|
int iWidth = GetRandWidth();
|
||||||
|
int iHeight = GetRandHeight();
|
||||||
|
float fFrameRate = rand() + 0.5f;
|
||||||
|
int iEncFrameNum = 0;
|
||||||
|
int iSpatialLayerNum = 1;
|
||||||
|
int iSliceNum = 1;
|
||||||
|
|
||||||
|
// prepare params
|
||||||
|
SEncParamExt sParam1;
|
||||||
|
SEncParamExt sParam2;
|
||||||
|
encoder_->GetDefaultParams (&sParam1);
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
|
||||||
|
sParam1.iSpsPpsIdStrategy = SPS_PPS_LISTING;
|
||||||
|
//prepare param2
|
||||||
|
memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
|
||||||
|
while (sParam2.iPicWidth == sParam1.iPicWidth) {
|
||||||
|
sParam2.iPicWidth = GetRandWidth();
|
||||||
|
}
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
|
||||||
|
sParam2.iSpsPpsIdStrategy = SPS_PPS_LISTING;
|
||||||
|
|
||||||
|
//prepare output if needed
|
||||||
|
FILE* fEnc = NULL;
|
||||||
|
#ifdef DEBUG_FILE_SAVE5
|
||||||
|
fEnc = fopen ("encLIST2.264", "wb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// step#1: pParam1
|
||||||
|
int rv = encoder_->InitializeExt (&sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
|
||||||
|
sParam1.iPicHeight;
|
||||||
|
|
||||||
|
// step#2: pParam2
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// step#3: back to pParam1, SHOULD NOT encounter ERROR
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
|
||||||
|
sParam1.iPicHeight;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// new IDR
|
||||||
|
rv = encoder_->ForceIntraFrame (true);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
rv = encoder_->Uninitialize();
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILE_SAVE5
|
||||||
|
fclose (fEnc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING3) {
|
||||||
|
|
||||||
|
int iWidth = GetRandWidth();
|
||||||
|
int iHeight = GetRandHeight();
|
||||||
|
float fFrameRate = rand() + 0.5f;
|
||||||
|
int iEncFrameNum = 0;
|
||||||
|
int iSpatialLayerNum = 1;
|
||||||
|
int iSliceNum = 1;
|
||||||
|
|
||||||
|
// prepare params
|
||||||
|
SEncParamExt sParam1;
|
||||||
|
SEncParamExt sParam2;
|
||||||
|
SEncParamExt sParam3;
|
||||||
|
encoder_->GetDefaultParams (&sParam1);
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
|
||||||
|
sParam1.iSpsPpsIdStrategy = SPS_PPS_LISTING;
|
||||||
|
//prepare param2
|
||||||
|
memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
|
||||||
|
while (sParam2.iPicWidth == sParam1.iPicWidth) {
|
||||||
|
sParam2.iPicWidth = GetRandWidth();
|
||||||
|
}
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
|
||||||
|
sParam2.iSpsPpsIdStrategy = SPS_PPS_LISTING;
|
||||||
|
//prepare param3
|
||||||
|
memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
|
||||||
|
while (sParam3.iPicWidth == sParam1.iPicWidth || sParam3.iPicWidth == sParam2.iPicWidth) {
|
||||||
|
sParam3.iPicWidth = GetRandWidth();
|
||||||
|
}
|
||||||
|
prepareParam (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
|
||||||
|
sParam3.iSpsPpsIdStrategy = SPS_PPS_LISTING;
|
||||||
|
|
||||||
|
//prepare output if needed
|
||||||
|
FILE* fEnc = NULL;
|
||||||
|
#ifdef DEBUG_FILE_SAVE5
|
||||||
|
fEnc = fopen ("enc4.264", "wb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// step#1: ordinary encoding
|
||||||
|
int rv = encoder_->InitializeExt (&sParam1);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
|
||||||
|
sParam1.iPicHeight;
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
|
||||||
|
EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// step#2: set strategy for success
|
||||||
|
int32_t iNewStra = SPS_PPS_LISTING;
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iNewStra);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << " iNewStra=" << iNewStra;
|
||||||
|
|
||||||
|
// step#3: setting new strategy, SHOULD encounter ERROR
|
||||||
|
unsigned int TraceLevel = WELS_LOG_QUIET;
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess);
|
||||||
|
iNewStra = CONSTANT_ID;
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iNewStra);
|
||||||
|
ASSERT_TRUE (rv != cmResultSuccess);
|
||||||
|
|
||||||
|
EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
|
||||||
|
|
||||||
|
// step#4: pParam3, SHOULD encounter ERROR
|
||||||
|
rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
|
||||||
|
ASSERT_TRUE (rv != cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam3.iPicWidth << "x" <<
|
||||||
|
sParam3.iPicHeight;
|
||||||
|
|
||||||
|
rv = encoder_->Uninitialize();
|
||||||
|
ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
|
||||||
|
|
||||||
|
#ifdef DEBUG_FILE_SAVE5
|
||||||
|
fclose (fEnc);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
122
test/encoder/EncUT_ParameterSetStrategy.cpp
Normal file
122
test/encoder/EncUT_ParameterSetStrategy.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "au_set.h"
|
||||||
|
#include "param_svc.h"
|
||||||
|
#include "parameter_sets.h"
|
||||||
|
#include "wels_const.h"
|
||||||
|
|
||||||
|
using namespace WelsEnc;
|
||||||
|
|
||||||
|
class ParameterSetStrategyTest : public ::testing::Test {
|
||||||
|
public:
|
||||||
|
virtual void SetUp() {
|
||||||
|
pMa = NULL;
|
||||||
|
m_pSpsArray = NULL;
|
||||||
|
m_pSubsetArray = NULL;
|
||||||
|
|
||||||
|
pMa = new CMemoryAlign (0);
|
||||||
|
m_pSpsArray = (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "m_pSpsArray");
|
||||||
|
ASSERT_TRUE (NULL != m_pSpsArray);
|
||||||
|
m_pSubsetArray = (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "m_pSubsetArray");
|
||||||
|
ASSERT_TRUE (NULL != m_pSubsetArray);
|
||||||
|
|
||||||
|
m_pSpsArrayPointer = &m_pSpsArray[0];
|
||||||
|
m_pSubsetArrayPointer = &m_pSubsetArray[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
virtual void TearDown() {
|
||||||
|
pMa->WelsFree (m_pSpsArray, "m_pSpsArray");
|
||||||
|
pMa->WelsFree (m_pSubsetArray, "m_pSubsetArray");
|
||||||
|
delete pMa;
|
||||||
|
}
|
||||||
|
void GenerateParam (SWelsSvcCodingParam* pParam);
|
||||||
|
public:
|
||||||
|
CMemoryAlign* pMa;
|
||||||
|
SWelsSPS* m_pSpsArray;
|
||||||
|
SSubsetSps* m_pSubsetArray;
|
||||||
|
|
||||||
|
SWelsSPS* m_pSpsArrayPointer;
|
||||||
|
SSubsetSps* m_pSubsetArrayPointer;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void ParameterSetStrategyTest::GenerateParam (SWelsSvcCodingParam* pParam) {
|
||||||
|
SEncParamBase sEncParamBase;
|
||||||
|
//TODO: consider randomize it
|
||||||
|
sEncParamBase.iUsageType = CAMERA_VIDEO_REAL_TIME;
|
||||||
|
sEncParamBase.iPicWidth = 1280;
|
||||||
|
sEncParamBase.iPicHeight = 720;
|
||||||
|
sEncParamBase.iTargetBitrate = 1000000;
|
||||||
|
sEncParamBase.iRCMode = RC_BITRATE_MODE;
|
||||||
|
sEncParamBase.fMaxFrameRate = 30.0f;
|
||||||
|
pParam->ParamBaseTranscode (sEncParamBase);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F (ParameterSetStrategyTest, FindExistingSps) {
|
||||||
|
int iDlayerIndex = 0;
|
||||||
|
int iDlayerCount = 0;
|
||||||
|
bool bUseSubsetSps = false;
|
||||||
|
int iFoundId = -1;
|
||||||
|
int iRet = 0;
|
||||||
|
SSpatialLayerConfig* pDlayerParam;
|
||||||
|
|
||||||
|
//init parameter
|
||||||
|
SWelsSvcCodingParam sParam1;
|
||||||
|
GenerateParam (&sParam1);
|
||||||
|
|
||||||
|
//prepare first SPS
|
||||||
|
int iCurSpsId = 0;
|
||||||
|
int iCurSpsInUse = 1;
|
||||||
|
m_pSpsArrayPointer = &m_pSpsArray[iCurSpsId];
|
||||||
|
|
||||||
|
pDlayerParam = & (sParam1.sSpatialLayers[iDlayerIndex]);
|
||||||
|
iRet = WelsInitSps (m_pSpsArrayPointer, pDlayerParam, &sParam1.sDependencyLayers[iDlayerIndex], sParam1.uiIntraPeriod,
|
||||||
|
sParam1.iMaxNumRefFrame,
|
||||||
|
iCurSpsId, sParam1.bEnableFrameCroppingFlag, sParam1.iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||||
|
|
||||||
|
// try finding #0
|
||||||
|
iFoundId = FindExistingSps (&sParam1, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
|
||||||
|
m_pSpsArray, m_pSubsetArray);
|
||||||
|
EXPECT_EQ (iFoundId, iCurSpsId);
|
||||||
|
|
||||||
|
// try not finding
|
||||||
|
SWelsSvcCodingParam sParam2 = sParam1;
|
||||||
|
sParam2.iMaxNumRefFrame ++;
|
||||||
|
iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
|
||||||
|
m_pSpsArray, m_pSubsetArray);
|
||||||
|
EXPECT_EQ (iFoundId, INVALID_ID);
|
||||||
|
|
||||||
|
// add new sps
|
||||||
|
iCurSpsId = 1;
|
||||||
|
m_pSpsArrayPointer = &m_pSpsArray[iCurSpsId];
|
||||||
|
pDlayerParam = & (sParam2.sSpatialLayers[iDlayerIndex]);
|
||||||
|
iRet = WelsInitSps (m_pSpsArrayPointer, pDlayerParam, &sParam2.sDependencyLayers[iDlayerIndex], sParam2.uiIntraPeriod,
|
||||||
|
sParam2.iMaxNumRefFrame,
|
||||||
|
iCurSpsId, sParam2.bEnableFrameCroppingFlag, sParam2.iRCMode != RC_OFF_MODE, iDlayerCount);
|
||||||
|
iCurSpsInUse = 2;
|
||||||
|
|
||||||
|
// try finding #1
|
||||||
|
iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
|
||||||
|
m_pSpsArray, m_pSubsetArray);
|
||||||
|
EXPECT_EQ (iFoundId, iCurSpsId);
|
||||||
|
|
||||||
|
// try finding #0
|
||||||
|
iFoundId = FindExistingSps (&sParam1, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
|
||||||
|
m_pSpsArray, m_pSubsetArray);
|
||||||
|
EXPECT_EQ (iFoundId, 0);
|
||||||
|
|
||||||
|
// try not finding
|
||||||
|
if (sParam2.sDependencyLayers[0].iActualWidth > 1) {
|
||||||
|
|
||||||
|
sParam2.sDependencyLayers[0].iActualWidth--;
|
||||||
|
} else {
|
||||||
|
sParam2.sDependencyLayers[0].iActualWidth++;
|
||||||
|
}
|
||||||
|
|
||||||
|
iFoundId = FindExistingSps (&sParam2, bUseSubsetSps, iDlayerIndex, iDlayerCount, iCurSpsInUse,
|
||||||
|
m_pSpsArray, m_pSubsetArray);
|
||||||
|
EXPECT_EQ (iFoundId, INVALID_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -11,6 +11,7 @@ ENCODER_UNITTEST_CPP_SRCS=\
|
|||||||
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\
|
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryAlloc.cpp\
|
||||||
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryZero.cpp\
|
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MemoryZero.cpp\
|
||||||
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\
|
$(ENCODER_UNITTEST_SRCDIR)/EncUT_MotionEstimate.cpp\
|
||||||
|
$(ENCODER_UNITTEST_SRCDIR)/EncUT_ParameterSetStrategy.cpp\
|
||||||
$(ENCODER_UNITTEST_SRCDIR)/EncUT_Reconstruct.cpp\
|
$(ENCODER_UNITTEST_SRCDIR)/EncUT_Reconstruct.cpp\
|
||||||
$(ENCODER_UNITTEST_SRCDIR)/EncUT_Sample.cpp\
|
$(ENCODER_UNITTEST_SRCDIR)/EncUT_Sample.cpp\
|
||||||
$(ENCODER_UNITTEST_SRCDIR)/EncUT_SVC_me.cpp\
|
$(ENCODER_UNITTEST_SRCDIR)/EncUT_SVC_me.cpp\
|
||||||
|
Loading…
x
Reference in New Issue
Block a user