ref: 68fed53687643cc213e19947f9b86874ce9ffa5c
parent: 007fb470046337f06fcf695a5006f7446d12e48f
author: Sijia Chen <[email protected]>
date: Tue Sep 30 13:54:24 EDT 2014
add checking of frame rate and temporal layer setting for encoder input param Reviewed at https://rbcommons.com/s/OpenH264/r/836/
--- a/codec/encoder/core/inc/param_svc.h
+++ b/codec/encoder/core/inc/param_svc.h
@@ -284,6 +284,7 @@
iUsageType = pCodingParam.iUsageType;
iPicWidth = pCodingParam.iPicWidth;
iPicHeight = pCodingParam.iPicHeight;
+ fMaxFrameRate = fParamMaxFrameRate;
iComplexityMode = pCodingParam.iComplexityMode;
SUsedPicRect.iLeft = 0;
@@ -381,7 +382,6 @@
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 @@
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 @@
++ iIdxSpatial;
}
- fMaxFrameRate = fMaxFr;
-
SetActualPicResolution();
return 0;
@@ -454,7 +450,7 @@
* \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 @@
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 @@
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 @@
++ i;
}
iDecompStages = (int8_t)iDecStages;
+ return ENC_RETURN_SUCCESS;
}
} SWelsSvcCodingParam;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -75,7 +75,6 @@
* \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 @@
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 @@
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 @@
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);
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -346,6 +346,10 @@
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::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 @@
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 @@
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);
}
@@ -906,12 +913,12 @@
}
break;
case ENCODER_OPTION_COMPLEXITY: {
- int32_t iValue = * (static_cast<int32_t*>(pOption));
+ int32_t iValue = * (static_cast<int32_t*> (pOption));
m_pEncContext->pSvcParam->iComplexityMode = (ECOMPLEXITY_MODE)iValue;
}
break;
case ENCODER_OPTION_IS_LOSSLESS_LINK: {
- bool bValue = * (static_cast<bool*>(pOption));
+ bool bValue = * (static_cast<bool*> (pOption));
m_pEncContext->pSvcParam->bIsLosslessLink = bValue;
}
break;