ref: a6f44f5f79661d036a654964b7497550381d668d
parent: 37b64fc9d60e3ea9b8764eb1250fe9de16096c9e
parent: 45c78f438e803f454cb30786e8c35a3c0969b3bd
author: ruil2 <ruil2@cisco.com>
date: Thu Jun 19 08:25:33 EDT 2014
Merge pull request #983 from JuannyWang/delay_skip [delay skip] delay skip to relieve bitrate burst somehow
--- a/codec/console/enc/src/welsenc.cpp
+++ b/codec/console/enc/src/welsenc.cpp
@@ -153,6 +153,18 @@
}
iLeftTargetBitrate -= pDLayer->iSpatialBitrate;
}
+ } else if (strTag[0].compare ("MaxSpatialBitrate") == 0) {
+ pDLayer->iMaxSpatialBitrate = 1000 * atoi (strTag[1].c_str());
+ if (pSvcParam.iRCMode != RC_OFF_MODE) {
+ if (pDLayer->iMaxSpatialBitrate <= 0) {
+ fprintf (stderr, "Invalid max spatial bitrate(%d) in dependency layer #%d.\n", pDLayer->iMaxSpatialBitrate, iLayer);
+ return -1;
+ }
+ if (pDLayer->iMaxSpatialBitrate < pDLayer->iSpatialBitrate) {
+ fprintf (stderr, "Invalid max spatial(#%d) bitrate(%d) setting::: < layerBitrate(%d)!\n", iLayer, pDLayer->iMaxSpatialBitrate, pDLayer->iSpatialBitrate);
+ return -1;
+ }
+ }
} else if (strTag[0].compare ("InitialQP") == 0) {
sLayerCtx.iDLayerQp = atoi (strTag[1].c_str());
} else if (strTag[0].compare ("SliceMode") == 0) {
@@ -253,6 +265,12 @@
fprintf (stderr, "Invalid target bitrate setting due to RC enabled. Check TargetBitrate field please!\n");
return 1;
}
+ } else if (strTag[0].compare ("MaxOverallBitrate") == 0) {
+ pSvcParam.iMaxBitrate = 1000 * atoi (strTag[1].c_str());
+ if ((pSvcParam.iRCMode != RC_OFF_MODE) && pSvcParam.iMaxBitrate <= 0) {
+ fprintf (stderr, "Invalid max overall bitrate setting due to RC enabled. Check MaxOverallBitrate field please!\n");
+ return 1;
+ }
} else if (strTag[0].compare ("EnableDenoise") == 0) {
pSvcParam.bEnableDenoise = atoi (strTag[1].c_str()) ? true : false;
} else if (strTag[0].compare ("EnableSceneChangeDetection") == 0) {
@@ -339,6 +357,7 @@
printf (" -betaOffset BetaOffset (-6..+6): valid range\n");
printf (" -rc rate control mode: 0-quality mode; 1-bitrate mode; 2-bitrate limited mode; -1-rc off \n");
printf (" -tarb Overall target bitrate\n");
+ printf (" -maxbrTotal Overall max bitrate\n");
printf (" -numl Number Of Layers: Must exist with layer_cfg file and the number of input layer_cfg file must equal to the value set by this command\n");
printf (" The options below are layer-based: (need to be set with layer id)\n");
printf (" -lconfig (Layer) (spatial layer configure file)\n");
@@ -348,6 +367,7 @@
printf (" -frout (Layer) (output frame rate)\n");
printf (" -lqp (Layer) (base quality layer qp : must work with -ldeltaqp or -lqparr)\n");
printf (" -ltarb (Layer) (spatial layer target bitrate)\n");
+ printf (" -lmaxb (Layer) (spatial layer max bitrate)\n");
printf (" -slcmd (Layer) (spatial layer slice mode): pls refer to layerX.cfg for details ( -slcnum: set target slice num; -slcsize: set target slice size constraint ) \n");
printf (" -trace (Level)\n");
printf ("\n");
@@ -436,6 +456,9 @@
else if (!strcmp (pCommand, "-tarb") && (n < argc))
pSvcParam.iTargetBitrate = 1000*atoi (argv[n++]);
+ else if (!strcmp (pCommand, "-maxbrTotal") && (n < argc))
+ pSvcParam.iMaxBitrate = 1000*atoi (argv[n++]);
+
else if (!strcmp (pCommand, "-numl") && (n < argc)) {
pSvcParam.iSpatialLayerNum = atoi (argv[n++]);
}
@@ -484,6 +507,12 @@
pDLayer->iSpatialBitrate = 1000 * atoi (argv[n++]);
}
+ else if (!strcmp (pCommand, "-lmaxb") && (n + 1 < argc)) {
+ unsigned int iLayer = atoi (argv[n++]);
+ SSpatialLayerConfig* pDLayer = &pSvcParam.sSpatialLayers[iLayer];
+ pDLayer->iMaxSpatialBitrate = 1000 * atoi (argv[n++]);
+ }
+
else if (!strcmp (pCommand, "-slcmd") && (n + 1 < argc)) {
unsigned int iLayer = atoi (argv[n++]);
SSpatialLayerConfig* pDLayer = &pSvcParam.sSpatialLayers[iLayer];
@@ -537,6 +566,7 @@
sParam.iPicWidth = 1280; // width of picture in samples
sParam.iPicHeight = 720; // height of picture in samples
sParam.iTargetBitrate = 2500000; // target bitrate desired
+ sParam.iMaxBitrate = MAX_BIT_RATE;
sParam.iRCMode = RC_QUALITY_MODE; // rc mode control
sParam.iTemporalLayerNum = 3; // layer number at temporal level
sParam.iSpatialLayerNum = 4; // layer number at spatial level
@@ -558,6 +588,7 @@
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 90;
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 7.5f;
sParam.sSpatialLayers[iIndexLayer].iSpatialBitrate = 64000;
+ sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
++ iIndexLayer;
@@ -566,6 +597,7 @@
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 180;
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 15.0f;
sParam.sSpatialLayers[iIndexLayer].iSpatialBitrate = 160000;
+ sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
++ iIndexLayer;
@@ -574,6 +606,7 @@
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 360;
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 30.0f;
sParam.sSpatialLayers[iIndexLayer].iSpatialBitrate = 512000;
+ sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
@@ -583,6 +616,7 @@
sParam.sSpatialLayers[iIndexLayer].iVideoHeight = 720;
sParam.sSpatialLayers[iIndexLayer].fFrameRate = 30.0f;
sParam.sSpatialLayers[iIndexLayer].iSpatialBitrate = 1500000;
+ sParam.sSpatialLayers[iIndexLayer].iMaxSpatialBitrate = MAX_BIT_RATE;
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.uiSliceMode = SM_SINGLE_SLICE;
sParam.sSpatialLayers[iIndexLayer].sSliceCfg.sSliceArgument.uiSliceNum = 1;
--- a/codec/encoder/core/inc/param_svc.h
+++ b/codec/encoder/core/inc/param_svc.h
@@ -307,7 +307,10 @@
iPaddingFlag = pCodingParam.iPaddingFlag;
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
- iMaxBitrate = pCodingParam.iMaxBitrate;
+ iMaxBitrate = pCodingParam.iMaxBitrate;
+ if (iMaxBitrate < iTargetBitrate) {
+ iMaxBitrate = iTargetBitrate;
+ }
uiMaxNalSize = pCodingParam.uiMaxNalSize;
/* Denoise Control */
--- a/codec/encoder/core/inc/rc.h
+++ b/codec/encoder/core/inc/rc.h
@@ -212,6 +212,7 @@
int32_t iBufferFullnessPadding;
int32_t iPaddingSize;
int32_t iPaddingBitrateStat;
+ bool bSkipFlag;
SRCSlicing* pSlicingOverRc;
SRCTemporal* pTemporalOverRc;
@@ -218,6 +219,7 @@
} SWelsSvcRc;
typedef void (*PWelsRCPictureInitFunc) (void* pCtx);
+typedef void (*PWelsRCPictureDelayJudgeFunc) (void* pCtx);
typedef void (*PWelsRCPictureInfoUpdateFunc) (void* pCtx, int32_t iLayerSize);
typedef void (*PWelsRCMBInfoUpdateFunc) (void* pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice* pSlice);
typedef void (*PWelsRCMBInitFunc) (void* pCtx, SMB* pCurMb, SSlice* pSlice);
@@ -224,6 +226,7 @@
typedef struct WelsRcFunc_s {
PWelsRCPictureInitFunc pfWelsRcPictureInit;
+ PWelsRCPictureDelayJudgeFunc pfWelsRcPicDelayJudge;
PWelsRCPictureInfoUpdateFunc pfWelsRcPictureInfoUpdate;
PWelsRCMBInitFunc pfWelsRcMbInit;
PWelsRCMBInfoUpdateFunc pfWelsRcMbInfoUpdate;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -2938,6 +2938,23 @@
return ENC_RETURN_SUCCESS;
}
+ //loop each layer to check if have skip frame when RC and frame skip enable
+ if (RC_OFF_MODE != pCtx->pSvcParam->iRCMode && true == pCtx->pSvcParam->bEnableFrameSkip) {
+ bool bSkipMustFlag = false;
+ for (int32_t i = 0; i< iSpatialNum; i++) {
+ pCtx->uiDependencyId = (uint8_t)(pSpatialIndexMap+i)->iDid;
+ pCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge(pCtx);
+ if (true == pCtx->pWelsSvcRc[pCtx->uiDependencyId].bSkipFlag) {
+ bSkipMustFlag = true;
+ }
+ }
+ if (true == bSkipMustFlag) {
+ pFbi->eOutputFrameType = videoFrameTypeSkip;
+ return ENC_RETURN_SUCCESS;
+ }
+ }
+
+
InitFrameCoding (pCtx, eFrameType);
iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[pSpatialIndexMap->iDid], pCtx->iCodingIndex,
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -711,6 +711,22 @@
}
}
+void WelsRcFrameDelayJudge(void* pCtx) {
+ sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
+ SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
+ SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
+ SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
+
+ int32_t iSentBits = WELS_ROUND(pDLayerParam->iSpatialBitrate / pDLayerParamInternal->fOutputFrameRate);
+
+ pWelsSvcRc->bSkipFlag = false;
+ if (pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip) {
+ pWelsSvcRc->bSkipFlag = true;
+ pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
+ pWelsSvcRc->iBufferFullnessSkip = WELS_MAX(pWelsSvcRc->iBufferFullnessSkip, 0);
+ }
+}
+
void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
const int32_t kiOutputBits = WELS_DIV_ROUND(pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
@@ -862,8 +878,8 @@
#endif
- if (pEncCtx->pSvcParam->bEnableFrameSkip &&
- pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iSpatialLayerNum - 1) {
+ if (pEncCtx->pSvcParam->bEnableFrameSkip /*&&
+ pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iSpatialLayerNum - 1*/) {
RcVBufferCalculationSkip (pEncCtx);
}
@@ -976,6 +992,7 @@
switch (iModule) {
case WELS_RC_DISABLE:
pRcf->pfWelsRcPictureInit = WelsRcPictureInitDisable;
+ pRcf->pfWelsRcPicDelayJudge = NULL;
pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateDisable;
pRcf->pfWelsRcMbInit = WelsRcMbInitDisable;
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable;
@@ -983,6 +1000,7 @@
case WELS_RC_GOM:
default:
pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom;
+ pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudge;
pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateGom;
pRcf->pfWelsRcMbInit = WelsRcMbInitGom;
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateGom;
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -623,10 +623,11 @@
WelsLog (m_pEncContext, WELS_LOG_INFO, "ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, sEncodingParam.iInputCsp= 0x%x\n",
sEncodingParam.iInputCsp);
WelsLog (m_pEncContext, WELS_LOG_INFO,
- "coding_param->iPicWidth= %d;coding_param->iPicHeight= %d;coding_param->iTargetBitrate= %d;coding_param->iRCMode= %d;coding_param->iPaddingFlag= %d;coding_param->iTemporalLayerNum= %d;coding_param->iSpatialLayerNum= %d;coding_param->fFrameRate= %.6ff;coding_param->iInputCsp= %d;coding_param->uiIntraPeriod= %d;coding_param->bEnableSpsPpsIdAddition = %d;coding_param->bPrefixNalAddingCtrl = %d;coding_param->bEnableDenoise= %d;coding_param->bEnableBackgroundDetection= %d;coding_param->bEnableAdaptiveQuant= %d;coding_param->bEnableAdaptiveQuant= %d;coding_param->bEnableLongTermReference= %d;coding_param->iLtrMarkPeriod= %d;\n",
+ "coding_param->iPicWidth= %d;coding_param->iPicHeight= %d;coding_param->iTargetBitrate= %d; coding_param->iMaxBitrate= %d; coding_param->iRCMode= %d;coding_param->iPaddingFlag= %d;coding_param->iTemporalLayerNum= %d;coding_param->iSpatialLayerNum= %d;coding_param->fFrameRate= %.6ff;coding_param->iInputCsp= %d;coding_param->uiIntraPeriod= %d;coding_param->bEnableSpsPpsIdAddition = %d;coding_param->bPrefixNalAddingCtrl = %d;coding_param->bEnableDenoise= %d;coding_param->bEnableBackgroundDetection= %d;coding_param->bEnableAdaptiveQuant= %d;coding_param->bEnableAdaptiveQuant= %d;coding_param->bEnableLongTermReference= %d;coding_param->iLtrMarkPeriod= %d;\n",
sEncodingParam.iPicWidth,
sEncodingParam.iPicHeight,
sEncodingParam.iTargetBitrate,
+ sEncodingParam.iMaxBitrate,
sEncodingParam.iRCMode,
sEncodingParam.iPaddingFlag,
sEncodingParam.iTemporalLayerNum,
@@ -646,11 +647,12 @@
while (i < sEncodingParam.iSpatialLayerNum) {
SSpatialLayerConfig* pSpatialCfg = &sEncodingParam.sSpatialLayers[i];
WelsLog (m_pEncContext, WELS_LOG_INFO,
- "coding_param->sSpatialLayers[%d]: .iVideoWidth= %d; .iVideoHeight= %d; .fFrameRate= %.6ff; .iSpatialBitrate= %d; .sSliceCfg.uiSliceMode= %d; .sSliceCfg.sSliceArgument.iSliceNum= %d; .sSliceCfg.sSliceArgument.uiSliceSizeConstraint= %d;\n",
+ "coding_param->sSpatialLayers[%d]: .iVideoWidth= %d; .iVideoHeight= %d; .fFrameRate= %.6ff; .iSpatialBitrate= %d; .iMaxSpatialBitrate= %d; .sSliceCfg.uiSliceMode= %d; .sSliceCfg.sSliceArgument.iSliceNum= %d; .sSliceCfg.sSliceArgument.uiSliceSizeConstraint= %d;\n",
i, pSpatialCfg->iVideoWidth,
pSpatialCfg->iVideoHeight,
pSpatialCfg->fFrameRate,
pSpatialCfg->iSpatialBitrate,
+ pSpatialCfg->iMaxSpatialBitrate,
pSpatialCfg->sSliceCfg.uiSliceMode,
pSpatialCfg->sSliceCfg.sSliceArgument.uiSliceNum,
pSpatialCfg->sSliceCfg.sSliceArgument.uiSliceSizeConstraint
--- a/testbin/layer2.cfg
+++ b/testbin/layer2.cfg
@@ -13,6 +13,7 @@
InitialQP 24 # Quantization parameters for base quality layer
#================================ RATE CONTROL ===============================
SpatialBitrate 600 # Unit: kbps, controled by DisableRC also
+MaxSpatialBitrate 800 # Unit: kbps, max bitrate for current layer
#============================== MultiSlice Slice Argument ==============================
# for S/M Slice(s) mode settings
SliceMode 0 # 0: sigle slice mode; >0: multiple slices mode, see below;
--- a/testbin/layer2_arbitrary_res.cfg
+++ b/testbin/layer2_arbitrary_res.cfg
@@ -14,6 +14,7 @@
InitialQP 24 # Quantization parameters for base quality layer
#================================ RATE CONTROL ===============================
SpatialBitrate 600 # Unit: kbps, controled by DisableRC also
+MaxSpatialBitrate 800 # Unit: kbps, max bitrate for current layer
#============================== MultiSlice Slice Argument ==============================
# for S/M Slice(s) mode settings
SliceMode 0 # 0: sigle slice mode; >0: multiple slices mode, see below;
--- a/testbin/layer2_vd.cfg
+++ b/testbin/layer2_vd.cfg
@@ -14,6 +14,7 @@
InitialQP 24 # Quantization parameters for base quality layer
#================================ RATE CONTROL ===============================
SpatialBitrate 600 # Unit: kbps, controled by DisableRC also
+MaxSpatialBitrate 800 # Unit: kbps, max bitrate for current layer
#============================== MultiSlice Slice Argument ==============================
# for S/M Slice(s) mode settings
SliceMode 0 # 0: sigle slice mode; >0: multiple slices mode, see below;
--- a/testbin/layer2_vd_rc.cfg
+++ b/testbin/layer2_vd_rc.cfg
@@ -14,6 +14,7 @@
InitialQP 24 # Quantization parameters for base quality layer
#================================ RATE CONTROL ===============================
SpatialBitrate 600 # Unit: kbps, controled by DisableRC also
+MaxSpatialBitrate 800 # Unit: kbps, max bitrate for current layer
#============================== MultiSlice Slice Argument ==============================
# for S/M Slice(s) mode settings
SliceMode 0 # 0: sigle slice mode; >0: multiple slices mode, see below;
--- a/testbin/welsenc.cfg
+++ b/testbin/welsenc.cfg
@@ -31,6 +31,7 @@
#============================== RATE CONTROL ==============================
RCMode 0 # 0: quality mode; 1: bitrate mode; 2: bitrate limited mode; -1: rc off mode
TargetBitrate 5000 # Unit: kbps, controled by EnableRC also
+MaxOverallBitrate 6000 # Unit: kbps, max bitrate overall
EnableFrameSkip 1 #Enable Frame Skip
#============================== DENOISE CONTROL ==============================
--- a/testbin/welsenc_arbitrary_res.cfg
+++ b/testbin/welsenc_arbitrary_res.cfg
@@ -32,6 +32,7 @@
#============================== RATE CONTROL ==============================
RCMode 0 # 0: quality mode; 1: bitrate mode; 2: bitrate limited mode; -1: rc off mode
TargetBitrate 5000 # Unit: kbps, controled by EnableRC also
+MaxOverallBitrate 6000 # Unit: kbps, max bitrate overall
#============================== DENOISE CONTROL ==============================
EnableDenoise 0 # Enable Denoise (1: enable, 0: disable)
--- a/testbin/welsenc_ios.cfg
+++ b/testbin/welsenc_ios.cfg
@@ -32,6 +32,7 @@
#============================== RATE CONTROL ==============================
RCMode 0 # 0: quality mode; 1: bitrate mode; 2: bitrate limited mode; -1: rc off mode
TargetBitrate 5000 # Unit: kbps, controled by EnableRC also
+MaxOverallBitrate 6000 # Unit: kbps, max bitrate overall
EnableFrameSkip 1 #Enable Frame Skip
#============================== DENOISE CONTROL ==============================
--- a/testbin/welsenc_vd_1d.cfg
+++ b/testbin/welsenc_vd_1d.cfg
@@ -32,6 +32,7 @@
#============================== RATE CONTROL ==============================
RCMode 0 # 0: quality mode; 1: bitrate mode; 2: bitrate limited mode; -1: rc off mode
TargetBitrate 5000 # Unit: kbps, controled by EnableRC also
+MaxOverallBitrate 6000 # Unit: kbps, max bitrate overall
#============================== DENOISE CONTROL ==============================
EnableDenoise 0 # Enable Denoise (1: enable, 0: disable)
--- a/testbin/welsenc_vd_rc.cfg
+++ b/testbin/welsenc_vd_rc.cfg
@@ -32,6 +32,7 @@
#============================== RATE CONTROL ==============================
RCMode 0 # 0: quality mode; 1: bitrate mode; 2: bitrate limited mode; -1: rc off mode
TargetBitrate 600 # Unit: kbps, controled by EnableRC also
+MaxOverallBitrate 800 # Unit: kbps, max bitrate overall
#============================== DENOISE CONTROL ==============================
EnableDenoise 1 # Enable Denoise (1: enable, 0: disable)