ref: 7a29b1f55a4b03948ec70820dead1de963cb1952
parent: d81dbeaa2e24cf7ad7154203145105463bdcc788
parent: 071254748fe93e6df8023e8c388bf4d53ab6f598
author: Licai Guo <licaguo@cisco.com>
date: Fri Mar 21 05:15:18 EDT 2014
Merge pull request #549 from lyao2/rc_tune RC LOWBR mode merge
--- a/codec/encoder/core/inc/param_svc.h
+++ b/codec/encoder/core/inc/param_svc.h
@@ -252,14 +252,9 @@
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
- bEnableRc = kbEnableRc;
- if (pCodingParam.iRCMode != RC_MODE0 && pCodingParam.iRCMode != RC_MODE1)
- iRCMode = RC_MODE1;
- else
- iRCMode = pCodingParam.iRCMode; // rc mode
+ bEnableRc = kbEnableRc;
+ iRCMode = pCodingParam.iRCMode; // rc mode
-
-
int8_t iIdxSpatial = 0;
uint8_t uiProfileIdc = PRO_BASELINE;
@@ -332,10 +327,7 @@
/* Rate Control */
bEnableRc = pCodingParam.bEnableRc;
- if (pCodingParam.iRCMode != RC_MODE0 && pCodingParam.iRCMode != RC_MODE1)
- iRCMode = RC_MODE1;
- else
- iRCMode = pCodingParam.iRCMode; // rc mode
+ iRCMode = pCodingParam.iRCMode; // rc mode
iPaddingFlag = pCodingParam.iPaddingFlag;
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
--- a/codec/encoder/core/inc/rc.h
+++ b/codec/encoder/core/inc/rc.h
@@ -56,10 +56,17 @@
#define WELS_RC_GOM 1
typedef enum {
- RC_MODE0, //Quality mode
- RC_MODE1, //Bitrate mode
+ RC_QUALITY_MODE, //Quality mode
+ RC_BITRATE_MODE, //Bitrate mode
+ RC_LOW_BW_MODE, //bitrate limited mode
} RC_MODES;
+enum{
+ BITS_NORMAL,
+ BITS_LIMITED,
+ BITS_EXCEEDED,
+};
+
enum {
//virtual gop size
VGOP_SIZE = 8,
@@ -67,6 +74,7 @@
//qp information
GOM_MIN_QP_MODE = 12,
GOM_MAX_QP_MODE = 36,
+ MAX_LOW_BR_QP = 42,
MIN_IDR_QP = 26,
MAX_IDR_QP = 32,
DELTA_QP = 2,
@@ -160,6 +168,7 @@
// bits allocation and status
int32_t iRemainingBits;
int32_t iTargetBits;
+ int32_t iCurrentBitsLevel;//0:normal; 1:limited; 2:exceeded.
int32_t iIdrNum;
int32_t iIntraComplexity;
@@ -170,7 +179,7 @@
int32_t iFrameDqBits;
double* pGomComplexity;
- int32_t* pGomForegroundBlockNum;
+ int32_t* pGomForegroundBlockNum;
int32_t* pCurrentFrameGomSad;
int32_t* pGomCost;
@@ -177,7 +186,7 @@
int32_t iAverageFrameQp;
int32_t iNumberMbFrame;
int32_t iNumberMbGom;
- int32_t iSliceNum;
+ int32_t iSliceNum;
int32_t iGomSize;
int32_t iSkipFrameNum;
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -429,7 +429,38 @@
if (0 == pTOverRc->iPFrameNum) {
iLumaQp = pWelsSvcRc->iInitialQp;
- } else {
+ }
+ else if (pWelsSvcRc->iCurrentBitsLevel==BITS_EXCEEDED)
+ {
+ iLumaQp = MAX_LOW_BR_QP;
+ //limit QP
+ int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1;
+ if (iLastIdxCodecInVGop < 0)
+ iLastIdxCodecInVGop += VGOP_SIZE;
+ int32_t iTlLast = pWelsSvcRc->iTlOfFrames[iLastIdxCodecInVGop];
+ int32_t iDeltaQpTemporal = iTl - iTlLast;
+ if (0 == iTlLast && iTl > 0)
+ iDeltaQpTemporal += 3;
+ else if (0 == iTl && iTlLast > 0)
+ iDeltaQpTemporal -= 3;
+
+ iLumaQp = WELS_CLIP3 (iLumaQp,
+ pWelsSvcRc->iLastCalculatedQScale - pWelsSvcRc->iFrameDeltaQpLower + iDeltaQpTemporal,
+ pWelsSvcRc->iLastCalculatedQScale + pWelsSvcRc->iFrameDeltaQpUpper + iDeltaQpTemporal);
+ iLumaQp = WELS_CLIP3 (iLumaQp, GOM_MIN_QP_MODE, MAX_LOW_BR_QP);
+
+ pWelsSvcRc->dQStep = RcConvertQp2QStep (iLumaQp);
+ pWelsSvcRc->iLastCalculatedQScale = iLumaQp;
+
+ if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
+ iLumaQp = (int32_t)(iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
+ }
+
+ pEncCtx->iGlobalQp = iLumaQp;
+
+ return;
+ }
+ else {
double dCmplxRatio = (double)pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity / pTOverRc->iFrameCmplxMean;
dCmplxRatio = WELS_CLIP3 (dCmplxRatio, 1.0 - FRAME_CMPLX_RATIO_RANGE, 1.0 + FRAME_CMPLX_RATIO_RANGE);
@@ -459,8 +490,11 @@
#ifndef _NOT_USE_AQ_FOR_TEST_
if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
- iLumaQp = (int32_t)WELS_CLIP3 (iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp,
- pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
+ iLumaQp = (int32_t)(iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
+
+ if (pEncCtx->pSvcParam->iRCMode!=RC_LOW_BW_MODE)
+ iLumaQp = (int32_t)WELS_CLIP3 (iLumaQp,pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
+
}
#endif
pEncCtx->iGlobalQp = iLumaQp;
@@ -489,6 +523,8 @@
void RcDecideTargetBits (sWelsEncCtx* pEncCtx) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId];
+
+ pWelsSvcRc->iCurrentBitsLevel = BITS_NORMAL;
//allocate bits
if (pEncCtx->eSliceType == I_SLICE) {
pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->dBitsPerFrame * IDR_BITRATE_RATIO);
@@ -495,6 +531,14 @@
} else {
pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->iRemainingBits * pTOverRc->dTlayerWeight /
pWelsSvcRc->dRemainingWeights);
+ if ((pWelsSvcRc->iTargetBits <= 0) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE))
+ {
+ pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED;
+ }
+ else if ((pWelsSvcRc->iTargetBits <= pTOverRc->iMinBitsTl) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE))
+ {
+ pWelsSvcRc->iCurrentBitsLevel = BITS_LIMITED;
+ }
pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, pTOverRc->iMinBitsTl, pTOverRc->iMaxBitsTl);
}
pWelsSvcRc->dRemainingWeights -= pTOverRc->dTlayerWeight;
@@ -617,7 +661,8 @@
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice,
pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame);
- pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
+ if (!(pEncCtx->pSvcParam->iRCMode==RC_LOW_BW_MODE))
+ pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
pSOverRc->iGomBitsSlice = 0;
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -346,7 +346,7 @@
{
SPicture* pLastPic = m_pLastSpatialPicture[kiDidx][0];
bool bCalculateSQDiff = ((pLastPic->pData[0] == pRefPic->pData[0]) && bNeededMbAq);
- bool bCalculateVar = (pSvcParam->iRCMode == RC_MODE1 && pCtx->eSliceType == I_SLICE);
+ bool bCalculateVar = (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE);
VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, bCalculateSQDiff, bCalculateVar, bCalculateBGD);
}
@@ -839,11 +839,11 @@
SWelsSvcRc* SWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId];
int32_t iComplexityAnalysisMode = 0;
- if (pSvcParam->iRCMode == RC_MODE0 && pCtx->eSliceType == P_SLICE) {
+ if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) {
iComplexityAnalysisMode = FRAME_SAD;
- } else if (pSvcParam->iRCMode == RC_MODE1 && pCtx->eSliceType == P_SLICE) {
+ } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) {
iComplexityAnalysisMode = GOM_SAD;
- } else if (pSvcParam->iRCMode == RC_MODE1 && pCtx->eSliceType == I_SLICE) {
+ } else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) {
iComplexityAnalysisMode = GOM_VAR;
} else {
return;
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -903,7 +903,7 @@
WelsEncoderApplyBitRate (m_pEncContext->pSvcParam,pInfo->iLayer);
}
break;
- case ENCODER_OPTION_RC_MODE: { // 0:quality mode;1:bit-rate mode
+ case ENCODER_OPTION_RC_MODE: { // 0:quality mode;1:bit-rate mode;2:bitrate limited mode
int32_t iValue = * ((int32_t*)pOption);
m_pEncContext->pSvcParam->iRCMode = iValue;
}