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:
Sijia Chen
2014-09-30 17:54:24 +08:00
parent 007fb47004
commit 68fed53687
3 changed files with 33 additions and 32 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}