commit
7a29b1f55a
@ -252,13 +252,8 @@ int32_t ParamBaseTranscode (const SEncParamBase& pCodingParam, const bool kbEnab
|
|||||||
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
|
SUsedPicRect.iWidth = ((iPicWidth >> 1) << 1);
|
||||||
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
|
SUsedPicRect.iHeight = ((iPicHeight >> 1) << 1);
|
||||||
|
|
||||||
bEnableRc = kbEnableRc;
|
bEnableRc = kbEnableRc;
|
||||||
if (pCodingParam.iRCMode != RC_MODE0 && pCodingParam.iRCMode != RC_MODE1)
|
iRCMode = pCodingParam.iRCMode; // rc mode
|
||||||
iRCMode = RC_MODE1;
|
|
||||||
else
|
|
||||||
iRCMode = pCodingParam.iRCMode; // rc mode
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int8_t iIdxSpatial = 0;
|
int8_t iIdxSpatial = 0;
|
||||||
uint8_t uiProfileIdc = PRO_BASELINE;
|
uint8_t uiProfileIdc = PRO_BASELINE;
|
||||||
@ -332,10 +327,7 @@ int32_t ParamTranscode (const SEncParamExt& pCodingParam) {
|
|||||||
|
|
||||||
/* Rate Control */
|
/* Rate Control */
|
||||||
bEnableRc = pCodingParam.bEnableRc;
|
bEnableRc = pCodingParam.bEnableRc;
|
||||||
if (pCodingParam.iRCMode != RC_MODE0 && pCodingParam.iRCMode != RC_MODE1)
|
iRCMode = pCodingParam.iRCMode; // rc mode
|
||||||
iRCMode = RC_MODE1;
|
|
||||||
else
|
|
||||||
iRCMode = pCodingParam.iRCMode; // rc mode
|
|
||||||
iPaddingFlag = pCodingParam.iPaddingFlag;
|
iPaddingFlag = pCodingParam.iPaddingFlag;
|
||||||
|
|
||||||
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
|
iTargetBitrate = pCodingParam.iTargetBitrate; // target bitrate
|
||||||
|
@ -56,10 +56,17 @@ namespace WelsSVCEnc {
|
|||||||
#define WELS_RC_GOM 1
|
#define WELS_RC_GOM 1
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RC_MODE0, //Quality mode
|
RC_QUALITY_MODE, //Quality mode
|
||||||
RC_MODE1, //Bitrate mode
|
RC_BITRATE_MODE, //Bitrate mode
|
||||||
|
RC_LOW_BW_MODE, //bitrate limited mode
|
||||||
} RC_MODES;
|
} RC_MODES;
|
||||||
|
|
||||||
|
enum{
|
||||||
|
BITS_NORMAL,
|
||||||
|
BITS_LIMITED,
|
||||||
|
BITS_EXCEEDED,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
//virtual gop size
|
//virtual gop size
|
||||||
VGOP_SIZE = 8,
|
VGOP_SIZE = 8,
|
||||||
@ -67,6 +74,7 @@ enum {
|
|||||||
//qp information
|
//qp information
|
||||||
GOM_MIN_QP_MODE = 12,
|
GOM_MIN_QP_MODE = 12,
|
||||||
GOM_MAX_QP_MODE = 36,
|
GOM_MAX_QP_MODE = 36,
|
||||||
|
MAX_LOW_BR_QP = 42,
|
||||||
MIN_IDR_QP = 26,
|
MIN_IDR_QP = 26,
|
||||||
MAX_IDR_QP = 32,
|
MAX_IDR_QP = 32,
|
||||||
DELTA_QP = 2,
|
DELTA_QP = 2,
|
||||||
@ -160,6 +168,7 @@ typedef struct TagWelsRc {
|
|||||||
// bits allocation and status
|
// bits allocation and status
|
||||||
int32_t iRemainingBits;
|
int32_t iRemainingBits;
|
||||||
int32_t iTargetBits;
|
int32_t iTargetBits;
|
||||||
|
int32_t iCurrentBitsLevel;//0:normal; 1:limited; 2:exceeded.
|
||||||
|
|
||||||
int32_t iIdrNum;
|
int32_t iIdrNum;
|
||||||
int32_t iIntraComplexity;
|
int32_t iIntraComplexity;
|
||||||
@ -170,14 +179,14 @@ typedef struct TagWelsRc {
|
|||||||
int32_t iFrameDqBits;
|
int32_t iFrameDqBits;
|
||||||
|
|
||||||
double* pGomComplexity;
|
double* pGomComplexity;
|
||||||
int32_t* pGomForegroundBlockNum;
|
int32_t* pGomForegroundBlockNum;
|
||||||
int32_t* pCurrentFrameGomSad;
|
int32_t* pCurrentFrameGomSad;
|
||||||
int32_t* pGomCost;
|
int32_t* pGomCost;
|
||||||
|
|
||||||
int32_t iAverageFrameQp;
|
int32_t iAverageFrameQp;
|
||||||
int32_t iNumberMbFrame;
|
int32_t iNumberMbFrame;
|
||||||
int32_t iNumberMbGom;
|
int32_t iNumberMbGom;
|
||||||
int32_t iSliceNum;
|
int32_t iSliceNum;
|
||||||
int32_t iGomSize;
|
int32_t iGomSize;
|
||||||
|
|
||||||
int32_t iSkipFrameNum;
|
int32_t iSkipFrameNum;
|
||||||
|
@ -429,7 +429,38 @@ void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) {
|
|||||||
|
|
||||||
if (0 == pTOverRc->iPFrameNum) {
|
if (0 == pTOverRc->iPFrameNum) {
|
||||||
iLumaQp = pWelsSvcRc->iInitialQp;
|
iLumaQp = pWelsSvcRc->iInitialQp;
|
||||||
} else {
|
}
|
||||||
|
else if (pWelsSvcRc->iCurrentBitsLevel==BITS_EXCEEDED)
|
||||||
|
{
|
||||||
|
iLumaQp = MAX_LOW_BR_QP;
|
||||||
|
//limit QP
|
||||||
|
int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1;
|
||||||
|
if (iLastIdxCodecInVGop < 0)
|
||||||
|
iLastIdxCodecInVGop += VGOP_SIZE;
|
||||||
|
int32_t iTlLast = pWelsSvcRc->iTlOfFrames[iLastIdxCodecInVGop];
|
||||||
|
int32_t iDeltaQpTemporal = iTl - iTlLast;
|
||||||
|
if (0 == iTlLast && iTl > 0)
|
||||||
|
iDeltaQpTemporal += 3;
|
||||||
|
else if (0 == iTl && iTlLast > 0)
|
||||||
|
iDeltaQpTemporal -= 3;
|
||||||
|
|
||||||
|
iLumaQp = WELS_CLIP3 (iLumaQp,
|
||||||
|
pWelsSvcRc->iLastCalculatedQScale - pWelsSvcRc->iFrameDeltaQpLower + iDeltaQpTemporal,
|
||||||
|
pWelsSvcRc->iLastCalculatedQScale + pWelsSvcRc->iFrameDeltaQpUpper + iDeltaQpTemporal);
|
||||||
|
iLumaQp = WELS_CLIP3 (iLumaQp, GOM_MIN_QP_MODE, MAX_LOW_BR_QP);
|
||||||
|
|
||||||
|
pWelsSvcRc->dQStep = RcConvertQp2QStep (iLumaQp);
|
||||||
|
pWelsSvcRc->iLastCalculatedQScale = iLumaQp;
|
||||||
|
|
||||||
|
if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
|
||||||
|
iLumaQp = (int32_t)(iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
|
||||||
|
}
|
||||||
|
|
||||||
|
pEncCtx->iGlobalQp = iLumaQp;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
double dCmplxRatio = (double)pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity / pTOverRc->iFrameCmplxMean;
|
double dCmplxRatio = (double)pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity / pTOverRc->iFrameCmplxMean;
|
||||||
dCmplxRatio = WELS_CLIP3 (dCmplxRatio, 1.0 - FRAME_CMPLX_RATIO_RANGE, 1.0 + FRAME_CMPLX_RATIO_RANGE);
|
dCmplxRatio = WELS_CLIP3 (dCmplxRatio, 1.0 - FRAME_CMPLX_RATIO_RANGE, 1.0 + FRAME_CMPLX_RATIO_RANGE);
|
||||||
|
|
||||||
@ -459,8 +490,11 @@ void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) {
|
|||||||
#ifndef _NOT_USE_AQ_FOR_TEST_
|
#ifndef _NOT_USE_AQ_FOR_TEST_
|
||||||
if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
|
if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
|
||||||
|
|
||||||
iLumaQp = (int32_t)WELS_CLIP3 (iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp,
|
iLumaQp = (int32_t)(iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
|
||||||
pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
|
|
||||||
|
if (pEncCtx->pSvcParam->iRCMode!=RC_LOW_BW_MODE)
|
||||||
|
iLumaQp = (int32_t)WELS_CLIP3 (iLumaQp,pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
pEncCtx->iGlobalQp = iLumaQp;
|
pEncCtx->iGlobalQp = iLumaQp;
|
||||||
@ -489,12 +523,22 @@ void RcInitSliceInformation (sWelsEncCtx* pEncCtx) {
|
|||||||
void RcDecideTargetBits (sWelsEncCtx* pEncCtx) {
|
void RcDecideTargetBits (sWelsEncCtx* pEncCtx) {
|
||||||
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
|
SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
|
||||||
SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId];
|
SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId];
|
||||||
|
|
||||||
|
pWelsSvcRc->iCurrentBitsLevel = BITS_NORMAL;
|
||||||
//allocate bits
|
//allocate bits
|
||||||
if (pEncCtx->eSliceType == I_SLICE) {
|
if (pEncCtx->eSliceType == I_SLICE) {
|
||||||
pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->dBitsPerFrame * IDR_BITRATE_RATIO);
|
pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->dBitsPerFrame * IDR_BITRATE_RATIO);
|
||||||
} else {
|
} else {
|
||||||
pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->iRemainingBits * pTOverRc->dTlayerWeight /
|
pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->iRemainingBits * pTOverRc->dTlayerWeight /
|
||||||
pWelsSvcRc->dRemainingWeights);
|
pWelsSvcRc->dRemainingWeights);
|
||||||
|
if ((pWelsSvcRc->iTargetBits <= 0) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE))
|
||||||
|
{
|
||||||
|
pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED;
|
||||||
|
}
|
||||||
|
else if ((pWelsSvcRc->iTargetBits <= pTOverRc->iMinBitsTl) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE))
|
||||||
|
{
|
||||||
|
pWelsSvcRc->iCurrentBitsLevel = BITS_LIMITED;
|
||||||
|
}
|
||||||
pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, pTOverRc->iMinBitsTl, pTOverRc->iMaxBitsTl);
|
pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, pTOverRc->iMinBitsTl, pTOverRc->iMaxBitsTl);
|
||||||
}
|
}
|
||||||
pWelsSvcRc->dRemainingWeights -= pTOverRc->dTlayerWeight;
|
pWelsSvcRc->dRemainingWeights -= pTOverRc->dTlayerWeight;
|
||||||
@ -617,7 +661,8 @@ void RcCalculateGomQp (sWelsEncCtx* pEncCtx, SMB* pCurMb, int32_t iSliceId) {
|
|||||||
|
|
||||||
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice,
|
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice,
|
||||||
pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame);
|
pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame);
|
||||||
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
|
if (!(pEncCtx->pSvcParam->iRCMode==RC_LOW_BW_MODE))
|
||||||
|
pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
|
||||||
|
|
||||||
pSOverRc->iGomBitsSlice = 0;
|
pSOverRc->iGomBitsSlice = 0;
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ int32_t CWelsPreProcess::AnalyzeSpatialPic (sWelsEncCtx* pCtx, const int32_t kiD
|
|||||||
{
|
{
|
||||||
SPicture* pLastPic = m_pLastSpatialPicture[kiDidx][0];
|
SPicture* pLastPic = m_pLastSpatialPicture[kiDidx][0];
|
||||||
bool bCalculateSQDiff = ((pLastPic->pData[0] == pRefPic->pData[0]) && bNeededMbAq);
|
bool bCalculateSQDiff = ((pLastPic->pData[0] == pRefPic->pData[0]) && bNeededMbAq);
|
||||||
bool bCalculateVar = (pSvcParam->iRCMode == RC_MODE1 && pCtx->eSliceType == I_SLICE);
|
bool bCalculateVar = (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE);
|
||||||
|
|
||||||
VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, bCalculateSQDiff, bCalculateVar, bCalculateBGD);
|
VaaCalculation (pCtx->pVaa, pCurPic, pRefPic, bCalculateSQDiff, bCalculateVar, bCalculateBGD);
|
||||||
}
|
}
|
||||||
@ -839,11 +839,11 @@ void CWelsPreProcess::AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCu
|
|||||||
SWelsSvcRc* SWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId];
|
SWelsSvcRc* SWelsSvcRc = &pCtx->pWelsSvcRc[kiDependencyId];
|
||||||
int32_t iComplexityAnalysisMode = 0;
|
int32_t iComplexityAnalysisMode = 0;
|
||||||
|
|
||||||
if (pSvcParam->iRCMode == RC_MODE0 && pCtx->eSliceType == P_SLICE) {
|
if (pSvcParam->iRCMode == RC_QUALITY_MODE && pCtx->eSliceType == P_SLICE) {
|
||||||
iComplexityAnalysisMode = FRAME_SAD;
|
iComplexityAnalysisMode = FRAME_SAD;
|
||||||
} else if (pSvcParam->iRCMode == RC_MODE1 && pCtx->eSliceType == P_SLICE) {
|
} else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == P_SLICE) {
|
||||||
iComplexityAnalysisMode = GOM_SAD;
|
iComplexityAnalysisMode = GOM_SAD;
|
||||||
} else if (pSvcParam->iRCMode == RC_MODE1 && pCtx->eSliceType == I_SLICE) {
|
} else if (pSvcParam->iRCMode >= RC_BITRATE_MODE && pCtx->eSliceType == I_SLICE) {
|
||||||
iComplexityAnalysisMode = GOM_VAR;
|
iComplexityAnalysisMode = GOM_VAR;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
@ -903,7 +903,7 @@ int CWelsH264SVCEncoder::SetOption (ENCODER_OPTION eOptionId, void* pOption) {
|
|||||||
WelsEncoderApplyBitRate (m_pEncContext->pSvcParam,pInfo->iLayer);
|
WelsEncoderApplyBitRate (m_pEncContext->pSvcParam,pInfo->iLayer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENCODER_OPTION_RC_MODE: { // 0:quality mode;1:bit-rate mode
|
case ENCODER_OPTION_RC_MODE: { // 0:quality mode;1:bit-rate mode;2:bitrate limited mode
|
||||||
int32_t iValue = * ((int32_t*)pOption);
|
int32_t iValue = * ((int32_t*)pOption);
|
||||||
m_pEncContext->pSvcParam->iRCMode = iValue;
|
m_pEncContext->pSvcParam->iRCMode = iValue;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user