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;
|
iUsageType = pCodingParam.iUsageType;
|
||||||
iPicWidth = pCodingParam.iPicWidth;
|
iPicWidth = pCodingParam.iPicWidth;
|
||||||
iPicHeight = pCodingParam.iPicHeight;
|
iPicHeight = pCodingParam.iPicHeight;
|
||||||
|
fMaxFrameRate = fParamMaxFrameRate;
|
||||||
iComplexityMode = pCodingParam.iComplexityMode;
|
iComplexityMode = pCodingParam.iComplexityMode;
|
||||||
|
|
||||||
SUsedPicRect.iLeft = 0;
|
SUsedPicRect.iLeft = 0;
|
||||||
@@ -381,7 +382,6 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
|
|
||||||
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
SSpatialLayerInternal* pDlp = &sDependencyLayers[0];
|
||||||
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
|
SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];
|
||||||
float fMaxFr = .0f;
|
|
||||||
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
EProfileIdc uiProfileIdc = PRO_BASELINE;
|
||||||
int8_t iIdxSpatial = 0;
|
int8_t iIdxSpatial = 0;
|
||||||
while (iIdxSpatial < iSpatialLayerNum) {
|
while (iIdxSpatial < iSpatialLayerNum) {
|
||||||
@@ -392,11 +392,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
|
|
||||||
float fLayerFrameRate = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].fFrameRate,
|
float fLayerFrameRate = WELS_CLIP3 (pCodingParam.sSpatialLayers[iIdxSpatial].fFrameRate,
|
||||||
MIN_FRAME_RATE, fParamMaxFrameRate);
|
MIN_FRAME_RATE, fParamMaxFrameRate);
|
||||||
|
pDlp->fInputFrameRate = fParamMaxFrameRate;
|
||||||
pSpatialLayer->fFrameRate =
|
pSpatialLayer->fFrameRate =
|
||||||
pDlp->fInputFrameRate =
|
pDlp->fOutputFrameRate = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, fParamMaxFrameRate);
|
||||||
pDlp->fOutputFrameRate = WELS_CLIP3 (fLayerFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
|
|
||||||
if (pDlp->fInputFrameRate > fMaxFr + EPSN)
|
|
||||||
fMaxFr = pDlp->fInputFrameRate;
|
|
||||||
|
|
||||||
#ifdef ENABLE_FRAME_DUMP
|
#ifdef ENABLE_FRAME_DUMP
|
||||||
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
pDlp->sRecFileName[0] = '\0'; // file to be constructed
|
||||||
@@ -427,8 +425,6 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
++ iIdxSpatial;
|
++ iIdxSpatial;
|
||||||
}
|
}
|
||||||
|
|
||||||
fMaxFrameRate = fMaxFr;
|
|
||||||
|
|
||||||
SetActualPicResolution();
|
SetActualPicResolution();
|
||||||
|
|
||||||
return 0;
|
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
|
* \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)
|
* \return NONE (should ensure valid parameter before this procedure)
|
||||||
*/
|
*/
|
||||||
void DetermineTemporalSettings() {
|
int32_t DetermineTemporalSettings() {
|
||||||
const int32_t iDecStages = WELS_LOG2 (
|
const int32_t iDecStages = WELS_LOG2 (
|
||||||
uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize); //log2(uiGopSize)
|
uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize); //log2(uiGopSize)
|
||||||
const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
|
const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];
|
||||||
@@ -466,6 +462,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
while (i < iSpatialLayerNum) {
|
while (i < iSpatialLayerNum) {
|
||||||
const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);
|
const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);
|
||||||
const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);
|
const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);
|
||||||
|
if (UINT_MAX == kuiLogFactorInOutRate || UINT_MAX == kuiLogFactorMaxInRate) {
|
||||||
|
return ENC_RETURN_INVALIDINPUT;
|
||||||
|
}
|
||||||
int32_t iNotCodedMask = 0;
|
int32_t iNotCodedMask = 0;
|
||||||
int8_t iMaxTemporalId = 0;
|
int8_t iMaxTemporalId = 0;
|
||||||
|
|
||||||
@@ -486,6 +485,9 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
pDlp->iHighestTemporalId = iMaxTemporalId;
|
pDlp->iHighestTemporalId = iMaxTemporalId;
|
||||||
pDlp->iTemporalResolution = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;
|
pDlp->iTemporalResolution = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;
|
||||||
pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;
|
pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;
|
||||||
|
if (pDlp->iDecompositionStages < 0) {
|
||||||
|
return ENC_RETURN_INVALIDINPUT;
|
||||||
|
}
|
||||||
|
|
||||||
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
uiProfileIdc = PRO_SCALABLE_BASELINE;
|
||||||
++ pDlp;
|
++ pDlp;
|
||||||
@@ -493,6 +495,7 @@ typedef struct TagWelsSvcCodingParam: SEncParamExt {
|
|||||||
++ i;
|
++ i;
|
||||||
}
|
}
|
||||||
iDecompStages = (int8_t)iDecStages;
|
iDecompStages = (int8_t)iDecStages;
|
||||||
|
return ENC_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
} SWelsSvcCodingParam;
|
} SWelsSvcCodingParam;
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ int32_t WelsCodeOnePicPartition (sWelsEncCtx* pCtx,
|
|||||||
* \return successful - 0; otherwise none 0 for failed
|
* \return successful - 0; otherwise none 0 for failed
|
||||||
*/
|
*/
|
||||||
int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
||||||
float fMaxFrameRate = 0.0f;
|
|
||||||
const float fEpsn = 0.000001f;
|
const float fEpsn = 0.000001f;
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
|
|
||||||
@@ -128,25 +127,13 @@ int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
|||||||
return ENC_RETURN_INVALIDINPUT;
|
return ENC_RETURN_INVALIDINPUT;
|
||||||
}
|
}
|
||||||
if (UINT_MAX == GetLogFactor (fDlp->fOutputFrameRate, fDlp->fInputFrameRate)) {
|
if (UINT_MAX == GetLogFactor (fDlp->fOutputFrameRate, fDlp->fInputFrameRate)) {
|
||||||
WelsLog (pLogCtx, WELS_LOG_ERROR,
|
WelsLog (pLogCtx, WELS_LOG_WARNING,
|
||||||
"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)..",
|
"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, i, fDlp->fInputFrameRate);
|
||||||
return ENC_RETURN_INVALIDINPUT;
|
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)
|
if ((pCfg->iRCMode != RC_OFF_MODE) && (pCfg->iRCMode != RC_QUALITY_MODE) && (pCfg->iRCMode != RC_BUFFERBASED_MODE)
|
||||||
&& (pCfg->iRCMode != RC_BITRATE_MODE)) {
|
&& (pCfg->iRCMode != RC_BITRATE_MODE)) {
|
||||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidation(),Invalid iRCMode = %d", pCfg->iRCMode);
|
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);
|
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), ParamValidationExt failed return %d.", iRet);
|
||||||
return 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);
|
iRet = GetMultipleThreadIdc (pLogCtx, pCodingParam, iSliceNum, iCacheLineSize, uiCpuFeatureFlags);
|
||||||
if (iRet != 0) {
|
if (iRet != 0) {
|
||||||
WelsLog (pLogCtx, WELS_LOG_ERROR, "WelsInitEncoderExt(), GetMultipleThreadIdc failed return %d.", iRet);
|
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);
|
pCtx->pMemAlign = new CMemoryAlign (iCacheLineSize);
|
||||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pCtx->pMemAlign), FreeMemorySvc (&pCtx))
|
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pCtx->pMemAlign), FreeMemorySvc (&pCtx))
|
||||||
|
|
||||||
pCodingParam->DetermineTemporalSettings();
|
|
||||||
iRet = AllocCodingParam (&pCtx->pSvcParam, pCtx->pMemAlign);
|
iRet = AllocCodingParam (&pCtx->pSvcParam, pCtx->pMemAlign);
|
||||||
if (iRet != 0) {
|
if (iRet != 0) {
|
||||||
FreeMemorySvc (&pCtx);
|
FreeMemorySvc (&pCtx);
|
||||||
|
|||||||
@@ -346,6 +346,10 @@ int CWelsH264SVCEncoder::InitializeInternal (SWelsSvcCodingParam* pCfg) {
|
|||||||
TraceParamInfo (pCfg);
|
TraceParamInfo (pCfg);
|
||||||
if (WelsInitEncoderExt (&m_pEncContext, pCfg, &m_pWelsTrace->m_sLogCtx)) {
|
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_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();
|
Uninitialize();
|
||||||
return cmInitParaError;
|
return cmInitParaError;
|
||||||
}
|
}
|
||||||
@@ -519,7 +523,8 @@ void CWelsH264SVCEncoder::CheckLevelSetting (int32_t iLayer, ELevelIdc uiLevelId
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CWelsH264SVCEncoder::CheckReferenceNumSetting (int32_t iNumRef) {
|
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;
|
m_pEncContext->pSvcParam->iNumRefFrame = iNumRef;
|
||||||
if ((iNumRef < MIN_REF_PIC_COUNT) || (iNumRef > iRefUpperBound)) {
|
if ((iNumRef < MIN_REF_PIC_COUNT) || (iNumRef > iRefUpperBound)) {
|
||||||
m_pEncContext->pSvcParam->iNumRefFrame = AUTO_REF_PIC_COUNT;
|
m_pEncContext->pSvcParam->iNumRefFrame = AUTO_REF_PIC_COUNT;
|
||||||
@@ -663,6 +668,11 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
|||||||
if (sConfig.iSpatialLayerNum < 1) {
|
if (sConfig.iSpatialLayerNum < 1) {
|
||||||
return cmInitParaError;
|
return cmInitParaError;
|
||||||
}
|
}
|
||||||
|
if (sConfig.DetermineTemporalSettings()) {
|
||||||
|
return cmInitParaError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New configuration available here */
|
||||||
iTargetWidth = sConfig.iPicWidth;
|
iTargetWidth = sConfig.iPicWidth;
|
||||||
iTargetHeight = sConfig.iPicHeight;
|
iTargetHeight = sConfig.iPicHeight;
|
||||||
if (m_iMaxPicWidth != iTargetWidth
|
if (m_iMaxPicWidth != iTargetWidth
|
||||||
@@ -676,9 +686,6 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
|||||||
m_uiCountFrameNum, m_iCspInternal);
|
m_uiCountFrameNum, m_iCspInternal);
|
||||||
#endif//REC_FRAME_COUNT
|
#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 */
|
/* Check every field whether there is new request for memory block changed or else, Oct. 24, 2008 */
|
||||||
WelsEncoderParamAdjust (&m_pEncContext, &sConfig);
|
WelsEncoderParamAdjust (&m_pEncContext, &sConfig);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user