add checking of frame rate and temporal layer setting for encoder input param
Reviewed at https://rbcommons.com/s/OpenH264/r/836/
This commit is contained in:
@@ -284,6 +284,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
iUsageType = pCodingParam.iUsageType;
|
||||
iPicWidth = pCodingParam.iPicWidth;
|
||||
iPicHeight = pCodingParam.iPicHeight;
|
||||
fMaxFrameRate = fParamMaxFrameRate;
|
||||
iComplexityMode = pCodingParam.iComplexityMode;
|
||||
|
||||
SUsedPicRect.iLeft = 0;
|
||||
@@ -381,7 +382,6 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
|
||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
|
||||
float fMaxFr = .0f;
|
||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||
int8_t iIdxSpatial = 0;
|
||||
while (iIdxSpatial < iSpatialLayerNum) {
|
||||
@@ -392,11 +392,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
|
||||
float fLayerFrameRate = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].fFrameRate,
|
||||
MIN_FRAME_RATE, fParamMaxFrameRate);
|
||||
pDlp->fInputFrameRate = fParamMaxFrameRate;
|
||||
pSpatialLayer->fFrameRate =
|
||||
pDlp->fInputFrameRate =
|
||||
pDlp->fOutputFrameRate = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
|
||||
if (pDlp->fInputFrameRate > fMaxFr + EPSN)
|
||||
fMaxFr = pDlp->fInputFrameRate;
|
||||
pDlp->fOutputFrameRate = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, fParamMaxFrameRate);
|
||||
|
||||
#ifdef ENABLE_FRAME_DUMP
|
||||
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
||||
@@ -427,8 +425,6 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
++ iIdxSpatial;
|
||||
}
|
||||
|
||||
fMaxFrameRate = fMaxFr;
|
||||
|
||||
SetActualPicResolution();
|
||||
|
||||
return 0;
|
||||
@@ -454,7 +450,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
* \param SWelsSvcCodingParam, and carried with known GOP size, max, input and output frame rate of each spatial
|
||||
* \return NONE (should ensure valid parameter before this procedure)
|
||||
*/
|
||||
void DetermineTemporalSettings() {
|
||||
int32_t DetermineTemporalSettings() {
|
||||
const int32_t iDecStages = WELS_LOG2 (
|
||||
uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize); //log2(uiGopSize)
|
||||
const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
|
||||
@@ -466,6 +462,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
while (i < iSpatialLayerNum) {
|
||||
const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);
|
||||
const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);
|
||||
if (UINT_MAX == kuiLogFactorInOutRate || UINT_MAX == kuiLogFactorMaxInRate) {
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
int32_t iNotCodedMask = 0;
|
||||
int8_t iMaxTemporalId = 0;
|
||||
|
||||
@@ -486,6 +485,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
pDlp->iHighestTemporalId = iMaxTemporalId;
|
||||
pDlp->iTemporalResolution = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;
|
||||
pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;
|
||||
if (pDlp->iDecompositionStages < 0) {
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
|
||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||
++ pDlp;
|
||||
@@ -493,6 +495,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
||||
++ i;
|
||||
}
|
||||
iDecompStages = (int8_t)iDecStages;
|
||||
return ENC_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
} SWelsSvcCodingParam;
|
||||
|
||||
@@ -75,7 +75,6 @@ int32_t WelsCodeOnePicPartition (sWelsEncCtx* pCtx,
|
||||
* \return successful - 0; otherwise none 0 for failed
|
||||
*/
|
||||
int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
||||
float fMaxFrameRate = 0.0f;
|
||||
const float fEpsn = 0.000001f;
|
||||
int32_t i = 0;
|
||||
|
||||
@@ -128,25 +127,13 @@ int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
}
|
||||
if (UINT_MAX == GetLogFactor (fDlp->fOutputFrameRate, fDlp->fInputFrameRate)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
||||
"Invalid settings in input frame rate(%.6f) and output frame rate(%.6f) of layer #%d config file: iResult of output frame rate divided by input frame rate should be power of 2(i.e,in/pOut=2^n)..",
|
||||
fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i);
|
||||
return ENC_RETURN_INVALIDINPUT;
|
||||
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||
"AUTO CORRECT: Invalid settings in input frame rate(%.6f) and output frame rate(%.6f) of layer #%d config file: iResult of output frame rate divided by input frame rate should be power of 2(i.e,in/pOut=2^n). \n Auto correcting Output Framerate to Input Framerate %f!\n",
|
||||
fDlp->fInputFrameRate, fDlp->fOutputFrameRate, i, fDlp->fInputFrameRate);
|
||||
fDlp->fOutputFrameRate = fDlp->fInputFrameRate;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < pCfg->iSpatialLayerNum; ++ i) {
|
||||
SSpatialLayerInternal* fDlp = &pCfg->sDependencyLayers[i];
|
||||
if (fDlp->fInputFrameRate > fMaxFrameRate)
|
||||
fMaxFrameRate = fDlp->fInputFrameRate;
|
||||
}
|
||||
|
||||
if (fMaxFrameRate > fEpsn && (fMaxFrameRate - pCfg->fMaxFrameRate > fEpsn
|
||||
|| fMaxFrameRate - pCfg->fMaxFrameRate < -fEpsn)) {
|
||||
pCfg->fMaxFrameRate = fMaxFrameRate;
|
||||
}
|
||||
|
||||
|
||||
if ((pCfg->iRCMode != RC_OFF_MODE) && (pCfg->iRCMode != RC_QUALITY_MODE) && (pCfg->iRCMode != RC_BUFFERBASED_MODE)
|
||||
&& (pCfg->iRCMode != RC_BITRATE_MODE)) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidation(),Invalid iRCMode = %d", pCfg->iRCMode);
|
||||
@@ -2026,6 +2013,11 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), ParamValidationExt failed return %d.", iRet);
|
||||
return iRet;
|
||||
}
|
||||
iRet = pCodingParam->DetermineTemporalSettings();
|
||||
if (iRet != ENC_RETURN_SUCCESS) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), DetermineTemporalSettings failed return %d (check in/out frame rate and temporal layer setting!)", iRet);
|
||||
return iRet;
|
||||
}
|
||||
iRet = GetMultipleThreadIdc (pLogCtx, pCodingParam, iSliceNum, iCacheLineSize, uiCpuFeatureFlags);
|
||||
if (iRet != 0) {
|
||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), GetMultipleThreadIdc failed return %d.", iRet);
|
||||
@@ -2045,7 +2037,6 @@ int32_t WelsInitEncoderExt (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPar
|
||||
pCtx->pMemAlign = new CMemoryAlign (iCacheLineSize);
|
||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pCtx->pMemAlign), FreeMemorySvc (&pCtx))
|
||||
|
||||
pCodingParam->DetermineTemporalSettings();
|
||||
iRet = AllocCodingParam (&pCtx->pSvcParam, pCtx->pMemAlign);
|
||||
if (iRet != 0) {
|
||||
FreeMemorySvc (&pCtx);
|
||||
|
||||
@@ -346,6 +346,10 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) {
|
||||
TraceParamInfo (pCfg);
|
||||
if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx)) {
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::Initialize(), WelsInitEncoderExt failed.");
|
||||
WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_DEBUG,
|
||||
"Problematic Input Base Param: iUsageType=%d, Resolution=%dx%d, FR=%f, TLayerNum=%d, DLayerNum=%d",
|
||||
pCfg->iUsageType, pCfg->iPicWidth, pCfg->iPicHeight, pCfg->fMaxFrameRate, pCfg->iTemporalLayerNum,
|
||||
pCfg->iSpatialLayerNum);
|
||||
Uninitialize();
|
||||
return cmInitParaError;
|
||||
}
|
||||
@@ -519,7 +523,8 @@ void CWelsH264SVCEncoder::CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelId
|
||||
}
|
||||
}
|
||||
void CWelsH264SVCEncoder::CheckReferenceNumSetting (int32_t iNumRef) {
|
||||
int32_t iRefUpperBound = (m_pEncContext->pSvcParam->iUsageType == CAMERA_VIDEO_REAL_TIME)?MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA:MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN;
|
||||
int32_t iRefUpperBound = (m_pEncContext->pSvcParam->iUsageType == CAMERA_VIDEO_REAL_TIME) ?
|
||||
MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA : MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN;
|
||||
m_pEncContext->pSvcParam->iNumRefFrame = iNumRef;
|
||||
if ((iNumRef < MIN_REF_PIC_COUNT) || (iNumRef > iRefUpperBound)) {
|
||||
m_pEncContext->pSvcParam->iNumRefFrame = AUTO_REF_PIC_COUNT;
|
||||
@@ -663,6 +668,11 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
if (sConfig.iSpatialLayerNum < 1) {
|
||||
return cmInitParaError;
|
||||
}
|
||||
if (sConfig.DetermineTemporalSettings()) {
|
||||
return cmInitParaError;
|
||||
}
|
||||
|
||||
/* New configuration available here */
|
||||
iTargetWidth = sConfig.iPicWidth;
|
||||
iTargetHeight = sConfig.iPicHeight;
|
||||
if (m_iMaxPicWidth != iTargetWidth
|
||||
@@ -676,9 +686,6 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
||||
m_uiCountFrameNum, m_iCspInternal);
|
||||
#endif//REC_FRAME_COUNT
|
||||
|
||||
/* New configuration available here */
|
||||
sConfig.DetermineTemporalSettings();
|
||||
|
||||
/* Check every field whether there is new request for memory block changed or else, Oct. 24, 2008 */
|
||||
WelsEncoderParamAdjust (&m_pEncContext, &sConfig);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user