Rate control refine to fit MAX bitrate requirement

This commit is contained in:
lyao2 2014-12-05 12:09:08 +08:00
parent ea93f3943e
commit c01606c28a
7 changed files with 5819 additions and 5681 deletions

View File

@ -169,7 +169,14 @@ typedef struct TagWelsEncCtx {
// Rate control routine
SWelsSvcRc* pWelsSvcRc;
bool bCheckWindowStatusRefreshFlag;
int64_t iCheckWindowStartTs;
int64_t iCheckWindowCurrentTs;
int32_t iCheckWindowInterval;
int32_t iCheckWindowIntervalShift;
bool bCheckWindowShiftResetFlag;
int32_t iSkipFrameFlag; //_GOM_RC_
int32_t iContinualSkipFrames;
int32_t iGlobalQp; // global qp
// VAA

View File

@ -119,10 +119,18 @@ enum {
#define SMOOTH_FACTOR_MIN_VALUE 2 // *INT_MULTIPLY
//#define VGOP_BITS_MIN_RATIO 0.8
//skip and padding
#define TIME_CHECK_WINDOW 5000 // ms
#define SKIP_RATIO 50 // *INT_MULTIPLY
#define LAST_FRAME_PREDICT_WEIGHT 0.5
#define PADDING_BUFFER_RATIO 50 // *INT_MULTIPLY
#define PADDING_THRESHOLD 5 //*INT_MULTIPLY
enum {
EVEN_TIME_WINDOW =0,
ODD_TIME_WINDOW =1,
TIME_WINDOW_TOTAL =2
};
typedef struct TagRCSlicing {
int32_t iComplexityIndexSlice;
int32_t iCalculatedQpSlice;
@ -152,7 +160,7 @@ int32_t iFrameCmplxMean;
typedef struct TagWelsRc {
int32_t iRcVaryPercentage;
int32_t iRcVaryRatio;
int32_t iRcVaryRatio;
int32_t iInitialQp; //initial qp
int32_t iBitRate;
@ -160,6 +168,7 @@ int32_t iPreviousBitrate;
int32_t iPreviousGopSize;
double fFrameRate;
int64_t iBitsPerFrame; // *INT_MULTIPLY
int64_t iMaxBitsPerFrame; // *INT_MULTIPLY
double dPreviousFps;
// bits allocation and status
@ -185,7 +194,7 @@ int32_t iMinFrameQp;
int32_t iMaxFrameQp;
int32_t iNumberMbFrame;
int32_t iNumberMbGom;
int32_t iSliceNum;
int32_t iSliceNum;
int32_t iGomSize;
int32_t iSkipFrameNum;
@ -201,15 +210,18 @@ int32_t iMinQp;
int32_t iMaxQp;
//int32_t delta_adaptive_qp;
int32_t iSkipBufferRatio;
int32_t iQStep; // *INT_MULTIPLY
int32_t iFrameDeltaQpUpper;
int32_t iFrameDeltaQpLower;
int32_t iLastCalculatedQScale;
//for skip frame and padding
int32_t iBufferSizeSkip;
int32_t iBufferFullnessSkip;
int32_t iBufferMaxBRFullness[TIME_WINDOW_TOTAL];//0: EVEN_TIME_WINDOW; 1: ODD_TIME_WINDOW
int32_t iPredFrameBit;
bool bNeedShiftWindowCheck[TIME_WINDOW_TOTAL];
int32_t iBufferSizePadding;
int32_t iBufferFullnessPadding;
int32_t iPaddingSize;
@ -244,6 +256,10 @@ PWelsRCMBInitFunc pfWelsRcMbInit;
PWelsRCMBInfoUpdateFunc pfWelsRcMbInfoUpdate;
} SWelsRcFunc;
bool CheckFrameSkipBasedMaxbr (void* pCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
const uint32_t uiTimeStamp);
void UpdateBufferWhenFrameSkipped(void* pCtx, int32_t iSpatialNum);
void UpdateMaxBrCheckWindowStatus(void* pCtx, int32_t iSpatialNum, const long long uiTimeStamp);
void RcTraceFrameBits (void* pEncCtx, long long uiTimeStamp);
void WelsRcInitModule (void* pCtx, RC_MODES iRcMode);
void WelsRcFreeMemory (void* pCtx);

View File

@ -3035,29 +3035,6 @@ int32_t GetSubSequenceId (sWelsEncCtx* pCtx, EVideoFrameType eFrameType) {
return iSubSeqId;
}
//loop each layer to check if have skip frame when RC and frame skip enable (maxbr>0)
bool CheckFrameSkipBasedMaxbr (sWelsEncCtx* pCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
const long long uiTimeStamp) {
SSpatialPicIndex* pSpatialIndexMap = &pCtx->sSpatialIndexMap[0];
bool bSkipMustFlag = false;
if (pCtx->pSvcParam->bEnableFrameSkip) {
if ((RC_QUALITY_MODE == pCtx->pSvcParam->iRCMode) || (RC_BITRATE_MODE == pCtx->pSvcParam->iRCMode)) {
for (int32_t i = 0; i < iSpatialNum; i++) {
if (UNSPECIFIED_BIT_RATE == pCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate) {
break;
}
pCtx->uiDependencyId = (uint8_t) (pSpatialIndexMap + i)->iDid;
pCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pCtx, eFrameType, uiTimeStamp);
if (true == pCtx->pWelsSvcRc[pCtx->uiDependencyId].bSkipFlag) {
bSkipMustFlag = true;
break;
}
}
}
}
return bSkipMustFlag;
}
/*!
* \brief core svc encoding process
*
@ -3108,29 +3085,37 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
pFbi->uiTimeStamp = pSrcPic->uiTimeStamp;
// perform csc/denoise/downsample/padding, generate spatial layers
iSpatialNum = pCtx->pVpp->BuildSpatialPicList (pCtx, pSrcPic);
if (pCtx->pSvcParam->bEnableFrameSkip) {
UpdateMaxBrCheckWindowStatus(pCtx, iSpatialNum, pSrcPic->uiTimeStamp);
}
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 = %lld, Frame type =%d",
pSrcPic->uiTimeStamp, pFbi->eFrameType);
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
return ENC_RETURN_SUCCESS;
}
eFrameType = DecideFrameType (pCtx, iSpatialNum);
if (eFrameType == videoFrameTypeSkip) {
UpdateBufferWhenFrameSkipped(pCtx, iSpatialNum);
pFbi->eFrameType = eFrameType;
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, Frame type =%d",
pSrcPic->uiTimeStamp, pFbi->eFrameType);
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
return ENC_RETURN_SUCCESS;
}
//loop each layer to check if have skip frame when RC and frame skip enable
if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType, pSrcPic->uiTimeStamp)) {
if (CheckFrameSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType, (uint32_t)pSrcPic->uiTimeStamp)) {
pFbi->eFrameType = videoFrameTypeSkip;
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, Frame type =%d",
pSrcPic->uiTimeStamp, pFbi->eFrameType);
WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
return ENC_RETURN_SUCCESS;
}
pCtx->iContinualSkipFrames = 0;
InitFrameCoding (pCtx, eFrameType);
iCurTid = GetTemporalLevel (&pSvcParam->sDependencyLayers[pSpatialIndexMap->iDid], pCtx->iCodingIndex,

View File

@ -247,6 +247,8 @@ void RcUpdateBitrateFps (sWelsEncCtx* pEncCtx) {
if (pWelsSvcRc->iBitsPerFrame > REMAIN_BITS_TH)
pWelsSvcRc->iRemainingBits = (int32_t) (pWelsSvcRc->iRemainingBits * input_iBitsPerFrame / pWelsSvcRc->iBitsPerFrame);
pWelsSvcRc->iBitsPerFrame = input_iBitsPerFrame;
pWelsSvcRc->iMaxBitsPerFrame = WELS_DIV_ROUND64 ((pDLayerParam->iMaxSpatialBitrate) * INT_MULTIPLY,
pDLayerParamInternal->fInputFrameRate);
}
@ -288,6 +290,9 @@ void RcInitRefreshParameter (sWelsEncCtx* pEncCtx) {
}
pWelsSvcRc->iBufferFullnessSkip = 0;
pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW] = 0;
pWelsSvcRc->iBufferMaxBRFullness[ODD_TIME_WINDOW] = 0;
pWelsSvcRc->iPredFrameBit = 0;
pWelsSvcRc->iBufferFullnessPadding = 0;
pWelsSvcRc->iGopIndexInVGop = 0;
@ -682,9 +687,14 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc;
const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
const int32_t kiOutputMaxBits = WELS_DIV_ROUND (pWelsSvcRc->iMaxBitsPerFrame, 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);
pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW] += (pWelsSvcRc->iFrameDqBits - kiOutputMaxBits);
pWelsSvcRc->iBufferMaxBRFullness[ODD_TIME_WINDOW] += (pWelsSvcRc->iFrameDqBits - kiOutputMaxBits);
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %d, bits in Max bitrate buffer = %d",
pWelsSvcRc->iBufferFullnessSkip,pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW]);
//condition 2: VGOP bits constraint
int32_t iVGopBitsPred = 0;
for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++)
@ -697,16 +707,6 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
&& pWelsSvcRc->iAverageFrameQp > pWelsSvcRc->iSkipQpValue)
|| (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) {
pEncCtx->iSkipFrameFlag = 1;
pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
}
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
if (pEncCtx->iSkipFrameFlag == 1) {
pWelsSvcRc->iRemainingBits += kiOutputBits;
pWelsSvcRc->iSkipFrameNum++;
pWelsSvcRc->iSkipFrameInVGop++;
}
}
@ -716,19 +716,144 @@ void WelsRcFrameDelayJudge (void* pCtx, EVideoFrameType eFrameType, long long ui
SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
int32_t iSentBits = WELS_ROUND (pDLayerParam->iSpatialBitrate / pDLayerParamInternal->fOutputFrameRate);
const int32_t iSentBits = WELS_ROUND (pDLayerParam->iSpatialBitrate / pDLayerParamInternal->fOutputFrameRate);
const int32_t kiOutputMaxBits = WELS_DIV_ROUND (pWelsSvcRc->iMaxBitsPerFrame, INT_MULTIPLY);
//estimate allowed continual skipped frames in the sequence
const int32_t iPredSkipFramesTarBr = (WELS_DIV_ROUND(pWelsSvcRc->iBufferFullnessSkip, iSentBits) + 1) >> 1;
const int32_t iPredSkipFramesMaxBr = (WELS_MAX(WELS_DIV_ROUND(pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW], kiOutputMaxBits), 0) + 1) >> 1;
//calculate the remaining bits in TIME_CHECK_WINDOW
const int32_t iAvailableBitsInTimeWindow = WELS_DIV_ROUND ((TIME_CHECK_WINDOW - pEncCtx->iCheckWindowInterval)*
pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId].iMaxSpatialBitrate, 1000);
const int32_t iAvailableBitsInShiftTimeWindow = WELS_DIV_ROUND ((TIME_CHECK_WINDOW - pEncCtx->iCheckWindowIntervalShift)*
pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId].iMaxSpatialBitrate, 1000);
bool bJudgeMaxBRbSkip[TIME_WINDOW_TOTAL];//0: EVEN_TIME_WINDOW; 1: ODD_TIME_WINDOW
/* 4 cases for frame skipping
1:skipping when buffer size larger than target threshold and current continual skip frames is allowed
2:skipping when MaxBr buffer size + predict frame size - remaining bits in time window < 0 and current continual skip frames is allowed
3:if in last ODD_TIME_WINDOW the MAX Br is overflowed, make more strict skipping conditions
4:such as case 3 in the other window
*/
bool bJudgeBufferFullSkip = (pEncCtx->iContinualSkipFrames <= iPredSkipFramesTarBr) && (pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip);
bool bJudgeMaxBRbufferFullSkip = (pEncCtx->iContinualSkipFrames <= iPredSkipFramesMaxBr) && (pEncCtx->iCheckWindowInterval > TIME_CHECK_WINDOW / 2)
&& (pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW] + pWelsSvcRc->iPredFrameBit - iAvailableBitsInTimeWindow > 0);
bJudgeMaxBRbSkip[EVEN_TIME_WINDOW] = (pEncCtx->iCheckWindowInterval > TIME_CHECK_WINDOW / 2) && (pWelsSvcRc->bNeedShiftWindowCheck[EVEN_TIME_WINDOW])
&& (pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW] + pWelsSvcRc->iPredFrameBit - iAvailableBitsInTimeWindow + kiOutputMaxBits > 0);
bJudgeMaxBRbSkip[ODD_TIME_WINDOW] = (pEncCtx->iCheckWindowIntervalShift > TIME_CHECK_WINDOW / 2) && (pWelsSvcRc->bNeedShiftWindowCheck[ODD_TIME_WINDOW])
&& (pWelsSvcRc->iBufferMaxBRFullness[ODD_TIME_WINDOW] + pWelsSvcRc->iPredFrameBit - iAvailableBitsInShiftTimeWindow + kiOutputMaxBits > 0);
pWelsSvcRc->bSkipFlag = false;
if (pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip) {
if (bJudgeBufferFullSkip || bJudgeMaxBRbufferFullSkip || bJudgeMaxBRbSkip[EVEN_TIME_WINDOW] || bJudgeMaxBRbSkip[ODD_TIME_WINDOW]) {
pWelsSvcRc->bSkipFlag = true;
pWelsSvcRc->iSkipFrameNum++;
pWelsSvcRc->iSkipFrameInVGop++;
pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip);
pWelsSvcRc->iRemainingBits += iSentBits;
pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW] -= kiOutputMaxBits;
pWelsSvcRc->iBufferMaxBRFullness[ODD_TIME_WINDOW] -= kiOutputMaxBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %d, bits in Max bitrate buffer = %d, Predict skip frames = %d and %d",
pWelsSvcRc->iBufferFullnessSkip, pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW], iPredSkipFramesTarBr, iPredSkipFramesMaxBr);
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
}
}
//loop each layer to check if have skip frame when RC and frame skip enable (maxbr>0)
bool CheckFrameSkipBasedMaxbr (void* pCtx, int32_t iSpatialNum, EVideoFrameType eFrameType,
const uint32_t uiTimeStamp) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SSpatialPicIndex* pSpatialIndexMap = &pEncCtx->sSpatialIndexMap[0];
bool bSkipMustFlag = false;
if (pEncCtx->pSvcParam->bEnableFrameSkip) {
if ((RC_QUALITY_MODE == pEncCtx->pSvcParam->iRCMode) || (RC_BITRATE_MODE == pEncCtx->pSvcParam->iRCMode)) {
for (int32_t i = 0; i < iSpatialNum; i++) {
if (UNSPECIFIED_BIT_RATE == pEncCtx->pSvcParam->sSpatialLayers[i].iMaxSpatialBitrate) {
break;
}
pEncCtx->uiDependencyId = (uint8_t) (pSpatialIndexMap + i)->iDid;
pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pEncCtx, eFrameType, uiTimeStamp);
if (true == pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].bSkipFlag) {
bSkipMustFlag = true;
pEncCtx->iContinualSkipFrames++;
break;
}
}
}
}
return bSkipMustFlag;
}
void UpdateBufferWhenFrameSkipped(void* pCtx, int32_t iSpatialNum) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SSpatialPicIndex* pSpatialIndexMap = &pEncCtx->sSpatialIndexMap[0];
for (int32_t i = 0; i < iSpatialNum; i++) {
int32_t iCurDid = (pSpatialIndexMap + i)->iDid;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[iCurDid];
const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
const int32_t kiOutputMaxBits = WELS_DIV_ROUND (pWelsSvcRc->iMaxBitsPerFrame, INT_MULTIPLY);
pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits;
pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW] -= kiOutputMaxBits;
pWelsSvcRc->iBufferMaxBRFullness[ODD_TIME_WINDOW] -= kiOutputMaxBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %d, bits in Max bitrate buffer = %d",
pWelsSvcRc->iBufferFullnessSkip,pWelsSvcRc->iBufferMaxBRFullness[EVEN_TIME_WINDOW]);
pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0);
pWelsSvcRc->iRemainingBits += kiOutputBits;
pWelsSvcRc->iSkipFrameNum++;
pWelsSvcRc->iSkipFrameInVGop++;
}
pEncCtx->iContinualSkipFrames++;
}
void UpdateMaxBrCheckWindowStatus(void* pCtx, int32_t iSpatialNum, const long long uiTimeStamp) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SSpatialPicIndex* pSpatialIndexMap = &pEncCtx->sSpatialIndexMap[0];
if(pEncCtx->bCheckWindowStatusRefreshFlag) {
pEncCtx->iCheckWindowCurrentTs = uiTimeStamp;
} else {
pEncCtx->iCheckWindowCurrentTs = pEncCtx->iCheckWindowStartTs = uiTimeStamp;
pEncCtx->bCheckWindowStatusRefreshFlag = true;
}
pEncCtx->iCheckWindowInterval = pEncCtx->iCheckWindowCurrentTs - pEncCtx->iCheckWindowStartTs;
if(pEncCtx->iCheckWindowInterval >= (TIME_CHECK_WINDOW >> 1) && !pEncCtx->bCheckWindowShiftResetFlag) {
pEncCtx->bCheckWindowShiftResetFlag = true;
for (int32_t i = 0; i < iSpatialNum; i++) {
int32_t iCurDid = (pSpatialIndexMap + i)->iDid;
if (pEncCtx->pWelsSvcRc[iCurDid].iBufferMaxBRFullness[ODD_TIME_WINDOW] > 0 && pEncCtx->pWelsSvcRc[iCurDid].iBufferMaxBRFullness[ODD_TIME_WINDOW] != pEncCtx->pWelsSvcRc[iCurDid].iBufferMaxBRFullness[0]) {
pEncCtx->pWelsSvcRc[iCurDid].bNeedShiftWindowCheck[EVEN_TIME_WINDOW] = true;
} else {
pEncCtx->pWelsSvcRc[iCurDid].bNeedShiftWindowCheck[EVEN_TIME_WINDOW] = false;
}
pEncCtx->pWelsSvcRc[iCurDid].iBufferMaxBRFullness[ODD_TIME_WINDOW] = 0;
}
}
pEncCtx->iCheckWindowIntervalShift = pEncCtx->iCheckWindowInterval >= (TIME_CHECK_WINDOW >> 1) ?
pEncCtx->iCheckWindowInterval - (TIME_CHECK_WINDOW >> 1) : pEncCtx->iCheckWindowInterval + (TIME_CHECK_WINDOW >> 1);
if(pEncCtx->iCheckWindowInterval >= TIME_CHECK_WINDOW || pEncCtx->iCheckWindowInterval == 0) {
pEncCtx->iCheckWindowStartTs = pEncCtx->iCheckWindowCurrentTs;
pEncCtx->iCheckWindowInterval = 0;
pEncCtx->bCheckWindowShiftResetFlag = false;
for (int32_t i = 0; i < iSpatialNum; i++) {
int32_t iCurDid = (pSpatialIndexMap + i)->iDid;
if (pEncCtx->pWelsSvcRc[iCurDid].iBufferMaxBRFullness[EVEN_TIME_WINDOW] > 0) {
pEncCtx->pWelsSvcRc[iCurDid].bNeedShiftWindowCheck[ODD_TIME_WINDOW] = true;
} else {
pEncCtx->pWelsSvcRc[iCurDid].bNeedShiftWindowCheck[ODD_TIME_WINDOW] = false;
}
pEncCtx->pWelsSvcRc[iCurDid].iBufferMaxBRFullness[EVEN_TIME_WINDOW] = 0;
}
}
return;
}
void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY);
@ -749,6 +874,11 @@ void RcTraceFrameBits (void* pCtx, long long uiTimeStamp) {
sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx;
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
if (pWelsSvcRc->iPredFrameBit != 0)
pWelsSvcRc->iPredFrameBit = LAST_FRAME_PREDICT_WEIGHT * pWelsSvcRc->iFrameDqBits + (1 - LAST_FRAME_PREDICT_WEIGHT) * pWelsSvcRc->iPredFrameBit;
else
pWelsSvcRc->iPredFrameBit = pWelsSvcRc->iFrameDqBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
"[Rc] Frame timestamp = %lld, 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",

File diff suppressed because one or more lines are too long