shithub: openh264

Download patch

ref: 3904c025cb70d418b55ff8778fc7bcfd296ac4f8
parent: e4b373a8000914f6326f094951e40cc9218c833c
author: lyao2 <lyao2@LYAO2-WS01.cisco.com>
date: Mon Sep 29 11:41:03 EDT 2014

add debug info for RC max bitrate control test

--- a/codec/encoder/core/inc/rc.h
+++ b/codec/encoder/core/inc/rc.h
@@ -122,7 +122,7 @@
 #define SKIP_RATIO  50 // *INT_MULTIPLY
 #define PADDING_BUFFER_RATIO 50 // *INT_MULTIPLY
 #define PADDING_THRESHOLD    5 //*INT_MULTIPLY
- 
+
 typedef struct TagRCSlicing {
 int32_t   iComplexityIndexSlice;
 int32_t   iCalculatedQpSlice;
@@ -137,7 +137,7 @@
 int32_t   iGomTargetBits;
 //int32_t   gom_coded_mb;
 } SRCSlicing;
- 
+
 typedef struct TagRCTemporal {
 int32_t   iMinBitsTl;
 int32_t   iMaxBitsTl;
@@ -147,13 +147,13 @@
 int64_t   iLinearCmplx; // *INT_MULTIPLY
 int32_t   iPFrameNum;
 int32_t   iFrameCmplxMean;
- 
+
 } SRCTemporal;
- 
+
 typedef struct TagWelsRc {
 int32_t   iRcVaryPercentage;
 int32_t    iRcVaryRatio;
- 
+
 int32_t   iInitialQp; //initial qp
 int32_t   iBitRate;
 int32_t   iPreviousBitrate;
@@ -161,31 +161,33 @@
 double    fFrameRate;
 int32_t   iBitsPerFrame; // *INT_MULTIPLY
 double    dPreviousFps;
- 
+
 // 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;
 int32_t   iIntraMbCount;
- 
+
 int8_t    iTlOfFrames[VGOP_SIZE];
 int32_t   iRemainingWeights;
 int32_t   iFrameDqBits;
- 
+
 double*    pGomComplexity;
 int32_t*   pGomForegroundBlockNum;
 int32_t*   pCurrentFrameGomSad;
 int32_t*   pGomCost;
- 
+
 int32_t   iAverageFrameQp;
+int32_t   iMinFrameQp;
+int32_t   iMaxFrameQp;
 int32_t   iNumberMbFrame;
 int32_t   iNumberMbGom;
 int32_t	iSliceNum;
 int32_t   iGomSize;
- 
+
 int32_t   iSkipFrameNum;
 int32_t   iFrameCodedInVGop;
 int32_t   iSkipFrameInVGop;
@@ -238,9 +240,9 @@
 PWelsRCMBInfoUpdateFunc			pfWelsRcMbInfoUpdate;
 } SWelsRcFunc;
 
+void RcTraceFrameBits (void* pEncCtx, long long uiTimeStamp);
 void WelsRcInitModule (void* pCtx, RC_MODES iRcMode);
 void WelsRcFreeMemory (void* pCtx);
 
 }
 #endif //RC_H
- 
\ No newline at end of file
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -167,6 +167,12 @@
                  pSpatialLayer->iSpatialBitrate);
         return ENC_RETURN_INVALIDINPUT;
       }
+      if (pSpatialLayer->iMaxSpatialBitrate < pSpatialLayer->iSpatialBitrate * 1.1f) {
+        WelsLog (pLogCtx, WELS_LOG_WARNING,
+          "MaxSpatialBitrate (%d) should set be larger than 1.1 times of SpatialBitrate (%d)",
+          pSpatialLayer->iMaxSpatialBitrate, pSpatialLayer->iSpatialBitrate);
+ //       pSpatialLayer->iSpatialBitrate = (int32_t) (pSpatialLayer->iMaxSpatialBitrate/1.1f);
+      }
     }
     if (iTotalBitrate > pCfg->iTargetBitrate) {
       WelsLog (pLogCtx, WELS_LOG_ERROR,
@@ -3032,6 +3038,7 @@
   if (iSpatialNum < 1) {	// skip due to temporal layer settings (different frame rate)
     ++ pCtx->iCodingIndex;
     pFbi->eFrameType = videoFrameTypeSkip;
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] Frame timestamp = %8d, skip one frame",pSrcPic->uiTimeStamp);
     return ENC_RETURN_SUCCESS;
   }
 
@@ -3038,6 +3045,7 @@
   eFrameType = DecideFrameType (pCtx, iSpatialNum);
   if (eFrameType == videoFrameTypeSkip) {
     pFbi->eFrameType = eFrameType;
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] Frame timestamp = %8d, skip one frame",pSrcPic->uiTimeStamp);
     return ENC_RETURN_SUCCESS;
   }
 
@@ -3044,6 +3052,7 @@
   //loop each layer to check if have skip frame when RC and frame skip enable
   if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType, (uint32_t)pSrcPic->uiTimeStamp)) {
     pFbi->eFrameType = videoFrameTypeSkip;
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] Frame timestamp = %8d, skip one frame",pSrcPic->uiTimeStamp);
     return ENC_RETURN_SUCCESS;
   }
 
@@ -3427,6 +3436,7 @@
     }
 
     pCtx->pFuncList->pfRc.pfWelsRcPictureInfoUpdate (pCtx, iLayerSize);
+    RcTraceFrameBits (pCtx,pSrcPic->uiTimeStamp);
     pCtx->pDecPic->iFrameAverageQp = pCtx->pWelsSvcRc->iAverageFrameQp;
 
     //update scc related
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -575,6 +575,8 @@
   const int32_t kiGlobalQp			= pEncCtx->iGlobalQp;
 
   pWelsSvcRc->iAverageFrameQp = 0;
+  pWelsSvcRc->iMinFrameQp = 51;;
+  pWelsSvcRc->iMaxFrameQp = 0;
   for (int32_t i = 0; i < kiSliceNum; ++i) {
     pSOverRc->iComplexityIndexSlice	= 0;
     pSOverRc->iCalculatedQpSlice		= kiGlobalQp;
@@ -699,6 +701,7 @@
   const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
   //condition 1: whole pBuffer fullness
   pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
+  WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
   //condition 2: VGOP bits constraint
   int32_t iVGopBitsPred = 0;
   for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++)
@@ -712,14 +715,13 @@
       || (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) {
     pEncCtx->iSkipFrameFlag = 1;
     pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits;
-    WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "skip one frame");
+    WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
   }
 
-  if (pWelsSvcRc->iBufferFullnessSkip < 0)
-    pWelsSvcRc->iBufferFullnessSkip = 0;
+  pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
 
   if (pEncCtx->iSkipFrameFlag == 1) {
-    pWelsSvcRc->iRemainingBits +=  WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
+    pWelsSvcRc->iRemainingBits +=  kiOutputBits;
     pWelsSvcRc->iSkipFrameNum++;
     pWelsSvcRc->iSkipFrameInVGop++;
   }
@@ -739,6 +741,7 @@
     pWelsSvcRc->iSkipFrameNum++;
     pWelsSvcRc->iSkipFrameInVGop++;
     pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
+    WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
     pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
   }
 }
@@ -759,14 +762,17 @@
 }
 
 
-void RcTraceFrameBits (sWelsEncCtx* pEncCtx) {
+void RcTraceFrameBits (void* pCtx, long long uiTimeStamp) {
+  sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
   SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
 
   WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
-           "[Rc] encoding_qp%d, qp = %3d, index = %8d, iTid = %1d, used = %8d, target = %8d, remaingbits = %8d",
-           pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp, pEncCtx->iFrameIndex, pEncCtx->uiTemporalId,
-           pWelsSvcRc->iFrameDqBits,
-           pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits);
+    "[Rc] Frame timestamp = %8d, Frame type =%d, encoding_qp%d, average qp = %3d, max qp = %3d, min qp = %3d, index = %8d,\
+    iTid = %1d, used = %8d, bitsperframe = %8d, target = %8d, remaingbits = %8d, skipbuffersize = %8d",
+    (uint32_t)uiTimeStamp,pEncCtx->eSliceType, pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp,pWelsSvcRc->iMaxFrameQp,pWelsSvcRc->iMinFrameQp,
+    pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits,WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY),
+    pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits, pWelsSvcRc->iBufferSizeSkip);
+
 }
 
 void RcUpdatePictureQpBits (sWelsEncCtx* pEncCtx, int32_t iCodedBits) {
@@ -891,8 +897,6 @@
   }
   pWelsSvcRc->iRemainingBits -= pWelsSvcRc->iFrameDqBits;
 
-  RcTraceFrameBits (pEncCtx);
-
   if (pEncCtx->pSvcParam->bEnableFrameSkip /*&&
       pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iSpatialLayerNum - 1*/) {
     RcVBufferCalculationSkip (pEncCtx);
@@ -945,13 +949,15 @@
   SRCSlicing* pSOverRc				= &pWelsSvcRc->pSlicingOverRc[iSliceId];
   const int32_t kiComplexityIndex	= pSOverRc->iComplexityIndexSlice;
 
-  int32_t cur_mb_bits = BsGetBitsPos (bs) - pSOverRc->iBsPosSlice;
-  pSOverRc->iFrameBitsSlice += cur_mb_bits;
-  pSOverRc->iGomBitsSlice += cur_mb_bits;
+  int32_t iCurMbBits = BsGetBitsPos (bs) - pSOverRc->iBsPosSlice;
+  pSOverRc->iFrameBitsSlice += iCurMbBits;
+  pSOverRc->iGomBitsSlice += iCurMbBits;
 
   pWelsSvcRc->pGomCost[kiComplexityIndex] += iCostLuma;
 
-  if (cur_mb_bits > 0) {
+  pWelsSvcRc->iMinFrameQp = WELS_MIN(pWelsSvcRc->iMinFrameQp,pCurMb->uiLumaQp);
+  pWelsSvcRc->iMaxFrameQp = WELS_MAX(pWelsSvcRc->iMaxFrameQp,pCurMb->uiLumaQp);
+  if (iCurMbBits > 0) {
     pSOverRc->iTotalQpSlice += pCurMb->uiLumaQp;
     pSOverRc->iTotalMbSlice++;
   }