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++;
}