ref: 5b5cc8434e06fda62fe5368dfe10a4a177a09030
parent: 993caea18c39fc8cbba890cd915f05219f5201e5
author: ruil2 <[email protected]>
date: Thu Jan 15 06:14:05 EST 2015
add rc function
--- a/codec/encoder/core/inc/rc.h
+++ b/codec/encoder/core/inc/rc.h
@@ -250,7 +250,7 @@
float fLatestFrameRate; // TODO: to complete later
} SWelsSvcRc;
-typedef void (*PWelsRCPictureInitFunc) (sWelsEncCtx* pCtx);
+typedef void (*PWelsRCPictureInitFunc) (sWelsEncCtx* pCtx,long long uiTimeStamp);
typedef void (*PWelsRCPictureDelayJudgeFunc) (sWelsEncCtx* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp);
typedef void (*PWelsRCPictureInfoUpdateFunc) (sWelsEncCtx* pCtx, int32_t iLayerSize);
typedef void (*PWelsRCMBInfoUpdateFunc) (sWelsEncCtx* pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice* pSlice);
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -3150,7 +3150,6 @@
pFbi->uiTimeStamp = pSrcPic->uiTimeStamp;
// perform csc/denoise/downsample/padding, generate spatial layers
iSpatialNum = pCtx->pVpp->BuildSpatialPicList (pCtx, pSrcPic);
-
if (pCtx->pFuncList->pfRc.pfWelsUpdateMaxBrWindowStatus) {
pCtx->pFuncList->pfRc.pfWelsUpdateMaxBrWindowStatus (pCtx, iSpatialNum, pSrcPic->uiTimeStamp);
}
@@ -3319,15 +3318,16 @@
#ifdef LONG_TERM_REF_DUMP
DumpRef (pCtx);
#endif
- if ((pSvcParam->iRCMode != RC_OFF_MODE))
+
+ if (pSvcParam->iRCMode != RC_OFF_MODE)
pCtx->pVpp->AnalyzePictureComplexity (pCtx, pCtx->pEncPic, ((pCtx->eSliceType == P_SLICE)
&& (pCtx->iNumRef0 > 0)) ? pCtx->pRefList0[0] : NULL,
- iCurDid, (pCtx->eSliceType == P_SLICE) && (pSvcParam->bEnableBackgroundDetection));
+ iCurDid, (pCtx->eSliceType == P_SLICE) && pSvcParam->bEnableBackgroundDetection);
WelsUpdateRefSyntax (pCtx, pCtx->iPOC,
eFrameType); //get reordering syntax used for writing slice header and transmit to encoder.
PrefetchReferencePicture (pCtx, eFrameType); // update reference picture for current pDq layer
- pCtx->pFuncList->pfRc.pfWelsRcPictureInit (pCtx);
+ pCtx->pFuncList->pfRc.pfWelsRcPictureInit (pCtx, pSrcPic->uiTimeStamp);
PreprocessSliceCoding (pCtx); // MUST be called after pfWelsRcPictureInit() and WelsInitCurrentLayer()
//TODO Complexity Calculation here for screen content
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -390,7 +390,8 @@
SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
if (pDLayerParamInternal->fOutputFrameRate > EPSN && pDLayerParam->iVideoWidth && pDLayerParam->iVideoHeight)
- dBpp = (double) (pDLayerParam->iSpatialBitrate) / (double) (pDLayerParamInternal->fOutputFrameRate * pDLayerParam->iVideoWidth *
+ dBpp = (double) (pDLayerParam->iSpatialBitrate) / (double) (pDLayerParamInternal->fOutputFrameRate *
+ pDLayerParam->iVideoWidth *
pDLayerParam->iVideoHeight);
else
dBpp = 0.1;
@@ -672,7 +673,8 @@
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice,
pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame);
- if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false)))
+ if (! (((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) || (pEncCtx->pSvcParam->iRCMode == RC_TIMESTAMP_MODE))
+ && (pEncCtx->pSvcParam->bEnableFrameSkip == false)))
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
pSOverRc->iGomBitsSlice = 0;
@@ -705,12 +707,12 @@
pEncCtx->iSkipFrameFlag = 1;
}
}
-
void WelsRcFrameDelayJudge (sWelsEncCtx* pEncCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
-
+ if (!pEncCtx->pSvcParam->bEnableFrameSkip)
+ return;
const int32_t iSentBits = WELS_ROUND (pDLayerParam->iSpatialBitrate / pDLayerParamInternal->fOutputFrameRate);
const int32_t kiOutputMaxBits = WELS_DIV_ROUND (pWelsSvcRc->iMaxBitsPerFrame, INT_MULTIPLY);
@@ -772,22 +774,22 @@
const uint32_t uiTimeStamp) {
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)|| (RC_TIMESTAMP_MODE == pEncCtx->pSvcParam->iRCMode)) {
+ if (!pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge)
+ return false;
+ 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;
- 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;
- }
- }
+ pEncCtx->pFuncList->pfRc.pfWelsRcPicDelayJudge (pEncCtx, eFrameType, uiTimeStamp);
+ if (true == pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].bSkipFlag) {
+ bSkipMustFlag = true;
+ pEncCtx->iContinualSkipFrames++;
+ break;
}
+
+
}
return bSkipMustFlag;
}
@@ -815,7 +817,6 @@
}
pEncCtx->iContinualSkipFrames++;
}
-
void UpdateMaxBrCheckWindowStatus (sWelsEncCtx* pEncCtx, int32_t iSpatialNum, const long long uiTimeStamp) {
SSpatialPicIndex* pSpatialIndexMap = &pEncCtx->sSpatialIndexMap[0];
if (pEncCtx->bCheckWindowStatusRefreshFlag) {
@@ -885,10 +886,9 @@
pWelsSvcRc->iPredFrameBit = pWelsSvcRc->iFrameDqBits;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
- "[Rc] Frame timestamp = %lld, Frame type =%d, dependency ID = %d, encoding_qp =%d, average qp = %3d, max qp = %3d, min qp = %3d, index = %8d,\
+ "[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",
- uiTimeStamp, pEncCtx->eSliceType, pEncCtx->uiDependencyId, pEncCtx->iGlobalQp, pWelsSvcRc->iAverageFrameQp,
- pWelsSvcRc->iMaxFrameQp,
+ uiTimeStamp, pEncCtx->eSliceType, pEncCtx->iGlobalQp, pWelsSvcRc->iAverageFrameQp, pWelsSvcRc->iMaxFrameQp,
pWelsSvcRc->iMinFrameQp,
pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits, WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame,
INT_MULTIPLY),
@@ -933,6 +933,8 @@
pWelsSvcRc->iIdrNum++;
if (pWelsSvcRc->iIdrNum > 255)
pWelsSvcRc->iIdrNum = 255;
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "RcUpdateIntraComplexity iFrameDqBits = %d,iQStep= %d,iIntraCmplx = %d",
+ pWelsSvcRc->iFrameDqBits, pWelsSvcRc->iQStep, pWelsSvcRc->iIntraComplexity);
}
void RcUpdateFrameComplexity (sWelsEncCtx* pEncCtx) {
@@ -956,6 +958,9 @@
pTOverRc->iPFrameNum++;
if (pTOverRc->iPFrameNum > 255)
pTOverRc->iPFrameNum = 255;
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
+ "RcUpdateFrameComplexity iFrameDqBits = %d,iQStep= %d,pTOverRc->iLinearCmplx = %lld", pWelsSvcRc->iFrameDqBits,
+ pWelsSvcRc->iQStep, pTOverRc->iLinearCmplx);
}
int32_t RcCalculateCascadingQp (struct TagWelsEncCtx* pEncCtx, int32_t iQp) {
@@ -971,7 +976,7 @@
return iTemporalQp;
}
-void WelsRcPictureInitGom (sWelsEncCtx* pEncCtx) {
+void WelsRcPictureInitGom (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
if (pEncCtx->eSliceType == I_SLICE) {
@@ -1001,8 +1006,6 @@
}
-
-
void WelsRcPictureInfoUpdateGom (sWelsEncCtx* pEncCtx, int32_t iLayerSize) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
int32_t iCodedBits = (iLayerSize << 3);
@@ -1074,7 +1077,7 @@
}
}
-void WelsRcPictureInitDisable (sWelsEncCtx* pEncCtx) {
+void WelsRcPictureInitDisable (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
const int32_t kiQp = pDLayerParam->iDLayerQp;
@@ -1114,7 +1117,7 @@
void WelsRcMbInfoUpdateDisable (sWelsEncCtx* pEncCtx, SMB* pCurMb, int32_t iCostLuma, SSlice* pSlice) {
}
-void WelRcPictureInitBufferBasedQp (sWelsEncCtx* pEncCtx) {
+void WelRcPictureInitBufferBasedQp (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
SVAAFrameInfo* pVaa = static_cast<SVAAFrameInfo*> (pEncCtx->pVaa);
int32_t iMinQp = MIN_SCREEN_QP;
@@ -1130,19 +1133,8 @@
pEncCtx->iGlobalQp += 2;
pEncCtx->iGlobalQp = WELS_CLIP3 (pEncCtx->iGlobalQp, iMinQp, MAX_SCREEN_QP);
}
-
-void InitRcModuleScc (sWelsEncCtx* pEncCtx) {
+void WelRcPictureInitScc (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
- pWelsSvcRc->iBaseQp = 30;
-
- pWelsSvcRc->iBufferFullnessSkip = 0;
- pWelsSvcRc->uiLastTimeStamp = 0;
-
- pWelsSvcRc->iCost2BitsIntra = INT_MULTIPLY;
- pWelsSvcRc->iAvgCost2Bits = INT_MULTIPLY;
-}
-void WelRcPictureInitScc (sWelsEncCtx* pEncCtx) {
- SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
SVAAFrameInfoExt* pVaa = static_cast<SVAAFrameInfoExt*> (pEncCtx->pVaa);
SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
@@ -1199,40 +1191,9 @@
}
pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, "WelRcPictureInitScc iLumaQp = %d\n", pEncCtx->iGlobalQp);
-
-}
-void WelsRcFrameDelayJudgeScc (sWelsEncCtx* pEncCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
- SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
- SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
-
- if (pDLayerConfig->iSpatialBitrate > pDLayerConfig->iMaxSpatialBitrate)
- pDLayerConfig->iSpatialBitrate = pDLayerConfig->iMaxSpatialBitrate;
-
- int32_t iBitRate = pDLayerConfig->iSpatialBitrate;
- int32_t iEncTimeInv = (pWelsSvcRc->uiLastTimeStamp == 0) ? 0 : (int32_t) (uiTimeStamp - pWelsSvcRc->uiLastTimeStamp);
- int32_t iSentBits = (int32_t) ((double)iBitRate * iEncTimeInv * (1.0E-3) + 0.5);
- iSentBits = WELS_MAX (iSentBits, 0);
-
- const int32_t iVbufferThRatio = (eFrameType == videoFrameTypeI
- || eFrameType == videoFrameTypeIDR) ? VIRTUAL_BUFFER_HIGH_TH : VIRTUAL_BUFFER_LOW_TH;
- const int32_t iVbufferTh = WELS_DIV_ROUND ((((int64_t)iBitRate) * iVbufferThRatio), INT_MULTIPLY);
-
- pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
- pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (0, pWelsSvcRc->iBufferFullnessSkip);
-
- pWelsSvcRc->bSkipFlag = true;
- if (pWelsSvcRc->iBufferFullnessSkip < iVbufferTh) {
- pWelsSvcRc->bSkipFlag = false;
- }
- if (pWelsSvcRc->bSkipFlag) {
- pWelsSvcRc->iSkipFrameNum++;
- WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO,
- "SCC iSkipFrameNum = %d,buffer = %d,threadhold = %d,bitrate = %d,timestamp=%lld\n", pWelsSvcRc->iSkipFrameNum,
- pWelsSvcRc->iBufferFullnessSkip, iVbufferTh, iBitRate, uiTimeStamp);
- }
pWelsSvcRc->uiLastTimeStamp = uiTimeStamp;
-}
+}
void WelsRcDropFrameUpdate (sWelsEncCtx* pEncCtx, uint32_t iDropSize) {
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
@@ -1243,7 +1204,7 @@
}
void WelsRcPictureInfoUpdateScc (sWelsEncCtx* pEncCtx, int32_t iNalSize) {
- SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0];
+ SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
int32_t iFrameBits = (iNalSize << 3);
pWelsSvcRc->iBufferFullnessSkip += iFrameBits;
@@ -1266,9 +1227,178 @@
pCurMb->uiChromaQp = g_kuiChromaQpTable[WELS_CLIP3 (pCurMb->uiLumaQp + pEncCtx->pPps->uiChromaQpIndexOffset, 0, 51)];
}
+void InitRcModuleTimeStamp (sWelsEncCtx* pEncCtx) {
+ SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
+ pWelsSvcRc->iBaseQp = 30;
+
+ pWelsSvcRc->iBufferFullnessSkip = 0;
+ pWelsSvcRc->uiLastTimeStamp = 0;
+
+ pWelsSvcRc->iCost2BitsIntra = INT_MULTIPLY;
+ pWelsSvcRc->iAvgCost2Bits = INT_MULTIPLY;
+ pWelsSvcRc->iSkipBufferRatio = SKIP_RATIO;
+}
+void WelsRcFrameDelayJudgeTimeStamp (sWelsEncCtx* pEncCtx, EVideoFrameType eFrameType, long long uiTimeStamp) {
+ SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
+ SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
+
+ if (pDLayerConfig->iSpatialBitrate > pDLayerConfig->iMaxSpatialBitrate)
+ pDLayerConfig->iSpatialBitrate = pDLayerConfig->iMaxSpatialBitrate;
+
+ int32_t iBitRate = pDLayerConfig->iSpatialBitrate;
+ int32_t iEncTimeInv = (pWelsSvcRc->uiLastTimeStamp == 0) ? 0 : (int32_t) (uiTimeStamp - pWelsSvcRc->uiLastTimeStamp);
+ int32_t iSentBits = (int32_t) ((double)iBitRate * iEncTimeInv * (1.0E-3) + 0.5);
+ iSentBits = WELS_MAX (iSentBits, 0);
+
+ //When bitrate is changed, pBuffer size should be updated
+ pWelsSvcRc->iBufferSizeSkip = WELS_DIV_ROUND (pDLayerConfig->iSpatialBitrate * pWelsSvcRc->iSkipBufferRatio,
+ INT_MULTIPLY);
+ pWelsSvcRc->iBufferSizePadding = WELS_DIV_ROUND (pDLayerConfig->iSpatialBitrate * PADDING_BUFFER_RATIO, INT_MULTIPLY);
+
+ pWelsSvcRc->iBufferFullnessSkip -= iSentBits;
+ pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (0, pWelsSvcRc->iBufferFullnessSkip);
+
+ if (pEncCtx->pSvcParam->bEnableFrameSkip) {
+ pWelsSvcRc->bSkipFlag = true;
+ if (pWelsSvcRc->iBufferFullnessSkip < pWelsSvcRc->iBufferSizeSkip) {
+ pWelsSvcRc->bSkipFlag = false;
+ }
+ if (pWelsSvcRc->bSkipFlag) {
+ pWelsSvcRc->iSkipFrameNum++;
+ pWelsSvcRc->uiLastTimeStamp = uiTimeStamp;
+ }
+ }
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
+ "WelsRcFrameDelayJudgeTimeStamp iSkipFrameNum = %d,buffer = %d,threadhold = %d,bitrate = %d,iSentBits = %d,lasttimestamp = %lld,timestamp=%lld\n",
+ pWelsSvcRc->iSkipFrameNum, pWelsSvcRc->iBufferFullnessSkip, pWelsSvcRc->iBufferSizeSkip, iBitRate, iSentBits,
+ pWelsSvcRc->uiLastTimeStamp, uiTimeStamp);
+}
+void WelsRcPictureInitGomTimeStamp (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
+ SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
+ SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId];
+ int32_t iLumaQp = pWelsSvcRc->iLastCalculatedQScale;
+ //decide one frame bits allocated
+ if (pEncCtx->eSliceType == I_SLICE) {
+ if (0 == pWelsSvcRc->iIdrNum) { //iIdrNum == 0 means encoder has been initialed
+ RcInitRefreshParameter (pEncCtx);
+ double dBpp = 0.05;
+ if ((pDLayerParam->fFrameRate > EPSN) && (pDLayerParam->iVideoWidth && pDLayerParam->iVideoHeight))
+ dBpp = (double) (pDLayerParam->iSpatialBitrate) / (double) (pDLayerParam->fFrameRate * pDLayerParam->iVideoWidth *
+ pDLayerParam->iVideoHeight);
+ pWelsSvcRc->iInitialQp = 50 - dBpp * 10 * 4;
+ pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP);
+
+ iLumaQp = pWelsSvcRc->iInitialQp;
+ pWelsSvcRc->iTargetBits = (double) (pDLayerParam->iSpatialBitrate) / (double) (pDLayerParam->fFrameRate) *
+ IDR_BITRATE_RATIO;
+
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
+ "[Rc] First IDR iSpatialBitrate = %d,iBufferFullnessSkip = %d,iTargetBits= %d,dBpp = %f,initQp = %d",
+ pDLayerParam->iSpatialBitrate, pWelsSvcRc->iBufferFullnessSkip, pWelsSvcRc->iTargetBits, dBpp,
+ pWelsSvcRc->iInitialQp);
+
+ } else {
+
+ int32_t iMaxTh = pWelsSvcRc->iBufferSizeSkip - pWelsSvcRc->iBufferFullnessSkip;
+ int32_t iMinTh = iMaxTh / 2;
+ pWelsSvcRc->iTargetBits = (double) (pDLayerParam->iSpatialBitrate) / (double) (pDLayerParam->fFrameRate) *
+ IDR_BITRATE_RATIO;
+ if (iMaxTh > 0) {
+ pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, iMinTh, iMaxTh);
+
+ pWelsSvcRc->iQStep = WELS_DIV_ROUND ((((int64_t)pWelsSvcRc->iIntraComplexity) *
+ pWelsSvcRc->iCost2BitsIntra), pWelsSvcRc->iTargetBits);
+ iLumaQp = RcConvertQStep2Qp (pWelsSvcRc->iQStep);
+
+ iLumaQp = WELS_CLIP3 (iLumaQp, pEncCtx->iGlobalQp - DELTA_QP_BGD_THD, pEncCtx->iGlobalQp + DELTA_QP_BGD_THD);
+
+ } else {
+ iLumaQp = pWelsSvcRc->iLastCalculatedQScale + DELTA_QP_BGD_THD;
+ }
+ iLumaQp = WELS_CLIP3 (iLumaQp, MIN_IDR_QP, MAX_IDR_QP);
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
+ "[Rc]I iLumaQp = %d,iQStep = %d,iTargetBits = %d,iBufferFullnessSkip =%d,iMaxTh=%d,iMinTh = %d,iFrameComplexity= %d",
+ iLumaQp, pWelsSvcRc->iQStep, pWelsSvcRc->iTargetBits, pWelsSvcRc->iBufferFullnessSkip, iMaxTh, iMinTh,
+ pWelsSvcRc->iIntraComplexity);
+
+ }
+
+ } else {
+ int32_t iTl = pEncCtx->uiTemporalId;
+ SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[iTl];
+ int32_t iMaxTh = pWelsSvcRc->iBufferSizeSkip - pWelsSvcRc->iBufferFullnessSkip;
+ int32_t iMinTh = iMaxTh / (iTl + 2);
+
+ SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
+ const int32_t kiGopSize = (1 << pDLayerParamInternal->iDecompositionStages);
+ int32_t iAverageFrameSize = (double) (pDLayerParam->iSpatialBitrate) / (double) (pDLayerParam->fFrameRate);
+ const int32_t kiGopBits = iAverageFrameSize * kiGopSize;
+ int64_t iCmplxRatio = WELS_DIV_ROUND64 (pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity * INT_MULTIPLY,
+ pTOverRc->iFrameCmplxMean);
+ iCmplxRatio = WELS_CLIP3 (iCmplxRatio, INT_MULTIPLY - FRAME_CMPLX_RATIO_RANGE, INT_MULTIPLY + FRAME_CMPLX_RATIO_RANGE);
+
+
+ pWelsSvcRc->iTargetBits = WELS_DIV_ROUND (pTOverRc->iTlayerWeight * kiGopBits, INT_MULTIPLY * 10 * 2);
+ if (iMaxTh > 0) {
+ pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, iMinTh, iMaxTh);
+ if (0 == pTOverRc->iPFrameNum)
+ iLumaQp = pWelsSvcRc->iInitialQp;
+ else {
+
+ pWelsSvcRc->iQStep = WELS_DIV_ROUND ((pTOverRc->iLinearCmplx * iCmplxRatio), (pWelsSvcRc->iTargetBits * INT_MULTIPLY));
+ iLumaQp = RcConvertQStep2Qp (pWelsSvcRc->iQStep);
+ iLumaQp = WELS_CLIP3 (iLumaQp, pEncCtx->iGlobalQp - DELTA_QP_BGD_THD, pEncCtx->iGlobalQp + DELTA_QP_BGD_THD);
+ }
+ } else {
+ iLumaQp = pWelsSvcRc->iLastCalculatedQScale + DELTA_QP_BGD_THD;
+ }
+
+ iLumaQp = WELS_CLIP3 (iLumaQp, GOM_MIN_QP_MODE, GOM_MAX_QP_MODE);
+
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
+ "[Rc]P iTl = %d,iLumaQp = %d,iQStep = %d,iTargetBits = %d,iBufferFullnessSkip =%d,iMaxTh=%d,iMinTh = %d,iFrameComplexity= %d,iCmplxRatio=%lld",
+ iTl, iLumaQp, pWelsSvcRc->iQStep, pWelsSvcRc->iTargetBits, pWelsSvcRc->iBufferFullnessSkip, iMaxTh, iMinTh,
+ pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity, iCmplxRatio);
+ }
+
+ pWelsSvcRc->iQStep = RcConvertQp2QStep (iLumaQp);
+ pWelsSvcRc->iLastCalculatedQScale = iLumaQp;
+ pEncCtx->iGlobalQp = iLumaQp;
+
+ RcInitSliceInformation (pEncCtx);
+ RcInitGomParameters (pEncCtx);
+ float fInstantFps = (uiTimeStamp - pWelsSvcRc->uiLastTimeStamp) > 0 ? (1000.0 / (uiTimeStamp -
+ pWelsSvcRc->uiLastTimeStamp)) : 0;
+ WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
+ "[Rc]pEncCtx->iGlobalQp= %d,uiTimeStamp = %lld,uiLastTimeStamp = %lld,InstantFps = %f,settingFps = %f",
+ pEncCtx->iGlobalQp, uiTimeStamp, pWelsSvcRc->uiLastTimeStamp,
+ fInstantFps, pDLayerParam->fFrameRate);
+ pWelsSvcRc->uiLastTimeStamp = uiTimeStamp;
+
+}
+
+void WelsRcPictureInfoUpdateGomTimeStamp (sWelsEncCtx* pEncCtx, int32_t iLayerSize) {
+ SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
+ int32_t iCodedBits = (iLayerSize << 3);
+
+ RcUpdatePictureQpBits (pEncCtx, iCodedBits);
+ if (pEncCtx->eSliceType == P_SLICE) {
+ RcUpdateFrameComplexity (pEncCtx);
+ } else {
+ RcUpdateIntraComplexity (pEncCtx);
+ }
+
+ pWelsSvcRc->iRemainingBits -= pWelsSvcRc->iFrameDqBits;
+ //condition 1: whole pBuffer fullness
+ pWelsSvcRc->iBufferFullnessSkip += pWelsSvcRc->iFrameDqBits;
+
+
+ if (pEncCtx->pSvcParam->iPaddingFlag)
+ RcVBufferCalculationPadding (pEncCtx);
+ pWelsSvcRc->iFrameCodedInVGop++;
+}
void WelsRcInitModule (sWelsEncCtx* pEncCtx, RC_MODES iRcMode) {
SWelsRcFunc* pRcf = &pEncCtx->pFuncList->pfRc;
-
switch (iRcMode) {
case RC_OFF_MODE:
pRcf->pfWelsRcPictureInit = WelsRcPictureInitDisable;
@@ -1303,19 +1433,21 @@
case RC_TIMESTAMP_MODE:
if (pEncCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {
pRcf->pfWelsRcPictureInit = WelRcPictureInitScc;
- pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudgeScc;
pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateScc;
pRcf->pfWelsRcMbInit = WelsRcMbInitScc;
pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable;
- pRcf->pfWelsCheckSkipBasedMaxbr = CheckFrameSkipBasedMaxbr;
- pRcf->pfWelsUpdateBufferWhenSkip = NULL;
- pRcf->pfWelsUpdateMaxBrWindowStatus = NULL;
- InitRcModuleScc (pEncCtx);
-
} else {
- WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "to be done in the future");
+ pRcf->pfWelsRcPictureInit = WelsRcPictureInitGomTimeStamp;
+ pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateGomTimeStamp;
+ pRcf->pfWelsRcMbInit = WelsRcMbInitGom;
+ pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateGom;
}
+ pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudgeTimeStamp;
+ pRcf->pfWelsCheckSkipBasedMaxbr = CheckFrameSkipBasedMaxbr;
+ pRcf->pfWelsUpdateBufferWhenSkip = NULL;
+ pRcf->pfWelsUpdateMaxBrWindowStatus = NULL;
+ InitRcModuleTimeStamp (pEncCtx);
break;
case RC_QUALITY_MODE:
default:
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -228,7 +228,6 @@
if (pSvcParam->bEnableBackgroundDetection) {
BackgroundDetection (pCtx->pVaa, pCurPic, pRefPic, bCalculateBGD && pRefPic->iPictureType != I_SLICE);
}
-
if (bNeededMbAq) {
AdaptiveQuantCalculation (pCtx->pVaa, pCurPic, pRefPic);
}
@@ -795,17 +794,20 @@
if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) {
iComplexityAnalysisMode = FRAME_SAD;
- } else if (((pSvcParam->iRCMode == RC_BITRATE_MODE)||(pSvcParam->iRCMode == RC_TIMESTAMP_MODE)) && pCtx->eSliceType == P_SLICE) {
+ } else if (((pSvcParam->iRCMode == RC_BITRATE_MODE) || (pSvcParam->iRCMode == RC_TIMESTAMP_MODE))
+ && pCtx->eSliceType == P_SLICE) {
iComplexityAnalysisMode = GOM_SAD;
- } else if (((pSvcParam->iRCMode == RC_BITRATE_MODE)||(pSvcParam->iRCMode == RC_TIMESTAMP_MODE)) && pCtx->eSliceType == I_SLICE) {
+ } else if (((pSvcParam->iRCMode == RC_BITRATE_MODE) || (pSvcParam->iRCMode == RC_TIMESTAMP_MODE))
+ && pCtx->eSliceType == I_SLICE) {
iComplexityAnalysisMode = GOM_VAR;
} else {
return;
}
+
sComplexityAnalysisParam->iComplexityAnalysisMode = iComplexityAnalysisMode;
sComplexityAnalysisParam->pCalcResult = & (pVaaInfo->sVaaCalcInfo);
sComplexityAnalysisParam->pBackgroundMbFlag = pVaaInfo->pVaaBackgroundMbFlag;
- if(pRefPicture)
+ if (pRefPicture)
SetRefMbType (pCtx, & (sComplexityAnalysisParam->uiRefMbType), pRefPicture->iPictureType);
sComplexityAnalysisParam->iCalcBgd = bCalculateBGD;
sComplexityAnalysisParam->iFrameComplexity = 0;
@@ -833,7 +835,7 @@
sSrcPixMap.sRect.iRectHeight = pCurPicture->iHeightInPixel;
sSrcPixMap.eFormat = VIDEO_FORMAT_I420;
- if(pRefPicture){
+ if (pRefPicture) {
sRefPixMap.pPixel[0] = pRefPicture->pData[0];
sRefPixMap.iSizeInBits = g_kiPixMapSizeInBits;
sRefPixMap.iStride[0] = pRefPicture->iLineSize[0];
--- a/codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp
+++ b/codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp
@@ -187,9 +187,7 @@
int32_t* pGomForegroundBlockNum = (int32_t*)m_sComplexityAnalysisParam.pGomForegroundBlockNum;
int32_t* pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity;
-
uint32_t uiGomSad = 0, uiFrameSad = 0;
-
InitGomSadFunc (m_pfGomSad, m_sComplexityAnalysisParam.iCalcBgd);
for (int32_t j = 0; j < iGomMbNum; j ++) {
@@ -212,11 +210,9 @@
iMbEndIndex = WELS_MIN (iMbEndIndex + iMbWidth , iGomMbEndIndex);
} while (--iGomMbRowNum);
-
pGomComplexity[j] = uiGomSad;
uiFrameSad += pGomComplexity[j];
}
-
m_sComplexityAnalysisParam.iFrameComplexity = uiFrameSad;
}
@@ -237,8 +233,8 @@
SVAACalcResult* pVaaCalcResults = m_sComplexityAnalysisParam.pCalcResult;
int32_t* pGomComplexity = (int32_t*)m_sComplexityAnalysisParam.pGomComplexity;
+ uint32_t uiFrameSad = 0;
-
uint32_t uiSampleSum = 0, uiSquareSum = 0;
for (int32_t j = 0; j < iGomMbNum; j ++) {
@@ -266,7 +262,9 @@
} while (--iGomMbRowNum);
pGomComplexity[j] = uiSquareSum - (uiSampleSum * uiSampleSum / iGomSampleNum);
+ uiFrameSad += pGomComplexity[j];
}
+ m_sComplexityAnalysisParam.iFrameComplexity = uiFrameSad;
}