Merge pull request #1396 from lyao2/rc_trace2
add debug info for RC max bitrate control test
This commit is contained in:
commit
6b1630cc90
@ -122,7 +122,7 @@ enum {
|
||||
#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 iGomBitsSlice;
|
||||
int32_t iGomTargetBits;
|
||||
//int32_t gom_coded_mb;
|
||||
} SRCSlicing;
|
||||
|
||||
|
||||
typedef struct TagRCTemporal {
|
||||
int32_t iMinBitsTl;
|
||||
int32_t iMaxBitsTl;
|
||||
@ -147,13 +147,13 @@ int32_t iGopBitsDq;
|
||||
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 @@ int32_t iPreviousGopSize;
|
||||
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 @@ PWelsRCMBInitFunc pfWelsRcMbInit;
|
||||
PWelsRCMBInfoUpdateFunc pfWelsRcMbInfoUpdate;
|
||||
} SWelsRcFunc;
|
||||
|
||||
void RcTraceFrameBits (void* pEncCtx, long long uiTimeStamp);
|
||||
void WelsRcInitModule (void* pCtx, RC_MODES iRcMode);
|
||||
void WelsRcFreeMemory (void* pCtx);
|
||||
|
||||
}
|
||||
#endif //RC_H
|
||||
|
@ -167,6 +167,12 @@ int32_t ParamValidation (SLogContext* pLogCtx, SWelsSvcCodingParam* pCfg) {
|
||||
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,18 +3038,21 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//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 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
||||
}
|
||||
|
||||
pCtx->pFuncList->pfRc.pfWelsRcPictureInfoUpdate (pCtx, iLayerSize);
|
||||
RcTraceFrameBits (pCtx,pSrcPic->uiTimeStamp);
|
||||
pCtx->pDecPic->iFrameAverageQp = pCtx->pWelsSvcRc->iAverageFrameQp;
|
||||
|
||||
//update scc related
|
||||
|
@ -575,6 +575,8 @@ void RcInitGomParameters (sWelsEncCtx* pEncCtx) {
|
||||
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 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
|
||||
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 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
|
||||
|| (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 @@ void WelsRcFrameDelayJudge (void* pCtx, EVideoFrameType eFrameType, long long ui
|
||||
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 RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
|
||||
}
|
||||
|
||||
|
||||
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 @@ void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t iLayerSize) {
|
||||
}
|
||||
pWelsSvcRc->iRemainingBits -= pWelsSvcRc->iFrameDqBits;
|
||||
|
||||
RcTraceFrameBits (pEncCtx);
|
||||
|
||||
if (pEncCtx->pSvcParam->bEnableFrameSkip /*&&
|
||||
pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iSpatialLayerNum - 1*/) {
|
||||
RcVBufferCalculationSkip (pEncCtx);
|
||||
@ -945,13 +949,15 @@ void WelsRcMbInfoUpdateGom (void* pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice*
|
||||
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++;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user