shithub: openh264

Download patch

ref: 071254748fe93e6df8023e8c388bf4d53ab6f598
parent: 4bc881c3aebb361fe9db888af16efa945b6c570a
author: lyao2 <lyao2@LYAO2-WS01.cisco.com>
date: Thu Mar 20 09:13:32 EDT 2014

avoid QP sudden fluctates

--- a/codec/encoder/core/inc/rc.h
+++ b/codec/encoder/core/inc/rc.h
@@ -56,9 +56,9 @@
 #define    WELS_RC_GOM            1
 
 typedef enum {
-  RC_MODE0,	//Quality mode
-  RC_MODE1,   //Bitrate mode
-  RC_MODE_LOWBR, //bitrate limited mode
+  RC_QUALITY_MODE,	//Quality mode
+  RC_BITRATE_MODE,   //Bitrate mode
+  RC_LOW_BW_MODE, //bitrate limited mode
 } RC_MODES;
 
 enum{
@@ -74,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,
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -432,7 +432,23 @@
   }
   else if (pWelsSvcRc->iCurrentBitsLevel==BITS_EXCEEDED)
   {
-	iLumaQp = 42;
+	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;
 
@@ -476,7 +492,7 @@
 
 	iLumaQp = (int32_t)(iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
 
-	if (pEncCtx->pSvcParam->iRCMode!=RC_MODE_LOWBR)
+	if (pEncCtx->pSvcParam->iRCMode!=RC_LOW_BW_MODE)
 	  iLumaQp = (int32_t)WELS_CLIP3 (iLumaQp,pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
 
   }
@@ -515,11 +531,11 @@
   } else {
     pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->iRemainingBits * pTOverRc->dTlayerWeight /
                                          pWelsSvcRc->dRemainingWeights);
-	if ((pWelsSvcRc->iTargetBits <= 0) && (pEncCtx->pSvcParam->iRCMode == RC_MODE_LOWBR))
+	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_MODE_LOWBR))
+	else if ((pWelsSvcRc->iTargetBits <= pTOverRc->iMinBitsTl) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE))
 	{
 		pWelsSvcRc->iCurrentBitsLevel = BITS_LIMITED;
 	}
@@ -645,8 +661,8 @@
 
   pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice,
                                  pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame);
-  if (!(pEncCtx->pSvcParam->iRCMode==RC_MODE_LOWBR))
-  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);
   }
@@ -831,11 +831,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;