欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > openh264 帧级码率控制原理:RcCalculatePictureQp 函数

openh264 帧级码率控制原理:RcCalculatePictureQp 函数

2024/10/24 5:21:17 来源:https://blog.csdn.net/yanceyxin/article/details/139864180  浏览:    关键词:openh264 帧级码率控制原理:RcCalculatePictureQp 函数

RcCalculatePictureQp 函数

函数功能

在码控中,当eSliceType为P_SLICE时 计算 P 帧的帧级量化参数QP 值。

函数原理过程

  • 初始化各类变量;
  • 计算帧复杂度iFrameComplexity,如果iUsageType是SCREEN_CONTENT_REAL_TIME,重复赋值帧复杂度iFrameComplexity;
  • 如果iPFrameNum 等于 0;
    • 第一个 P 帧,则iLumaQp等于iInitialQp;
  • 如果iCurrentBitsLevel等于BITS_EXCEEDED;
    • iLumaQp等于iLastCalculatedQScale加上 一个常量;
    • 声明并计算一个变量iLastIdxCodecInVGop,它代表在视频组(Video Group of Pictures, VGop)中最后一个编码帧的索引。这里通过从iFrameCodedInVGop减去1来得到;
    • 如果iLastIdxCodecInVGop 小于 0,就通过加上VGOP_SIZE(视频组的大小)来调整;
    • 声明并计算一个变量iTlLast,它是根据iLastIdxCodecInVGop索引在iTlOfFrames数组中的时间层ID;
    • 计算时间层量化参数差iDeltaQpTemporal,它是当前时间层iTl与上一个时间层iTlLast的差值;
    • 如果上一个时间层是0(表示基础层),而当前时间层大于0(表示增强层),则增加iDeltaQpTemporal的值;
    • 如果当前时间层是0,而上一个时间层大于0,那么减少iDeltaQpTemporal的值;
  • 否则,
    • 调用WELS_DIV_ROUND64函数根据帧复杂度iFrameComplexity和帧复杂度均值iFrameCmplxMean计算复杂度变化率iCmplxRatio;
    • 调用WELS_CLIP3函数限制复杂度变化率iCmplxRatio值;
    • 调用WELS_DIV_ROUND函数根据iLinearCmplx、iCmplxRatio、iTargetBits计算量化步长iQStep;
    • 调用RcConvertQStep2Qp函数将量化步长iQStep转化为量化参数iLumaQp;
    • 声明并计算一个变量iLastIdxCodecInVGop,它代表在视频组(Video Group of Pictures, VGop)中最后一个编码帧的索引。这里通过从iFrameCodedInVGop减去1来得到;
    • 如果iLastIdxCodecInVGop 小于 0,就通过加上VGOP_SIZE(视频组的大小)来调整;
    • 声明并计算一个变量iTlLast,它是根据iLastIdxCodecInVGop索引在iTlOfFrames数组中的时间层ID;
    • 计算时间层量化参数差iDeltaQpTemporal,它是当前时间层iTl与上一个时间层iTlLast的差值;
    • 如果上一个时间层是0(表示基础层),而当前时间层大于0(表示增强层),则增加iDeltaQpTemporal的值;
    • 如果当前时间层是0,而上一个时间层大于0,那么减少iDeltaQpTemporal的值;
  • 根据iLastCalculatedQScale、iFrameDeltaQpLower、iDeltaQpTemporal、iMinQp、iMaxQp计算出量化参数最大值iMaxFrameQp和最小值iMinFrameQp;
  • 根据最大值iMaxFrameQp和最小值iMinFrameQp,限制亮度 qp 值iLumaQp;
  • 如果开启自适应量化;
    • 调用WELS_DIV_ROUND函数根据iAverMotionTextureIndexToDeltaQp重新计算出亮度 qp 值iLumaQp;
    • 根据最大值iMaxFrameQp和最小值iMinFrameQp,限制亮度 qp 值iLumaQp;
  • 调用RcConvertQp2QStep函数将亮度 qp 值iLumaQp转为量化步长iQStep;
  • 将亮度 qp 值iLumaQp赋值给iLastCalculatedQScale和帧级 qp 值iGlobalQp。

函数原理图

在这里插入图片描述

函数源码

void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) {SWelsSvcRc* pWelsSvcRc        = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];int32_t iTl                   = pEncCtx->uiTemporalId;SRCTemporal* pTOverRc         = &pWelsSvcRc->pTemporalOverRc[iTl];int32_t iLumaQp = 0;int32_t iDeltaQpTemporal = 0;int64_t iFrameComplexity = pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity;if (pEncCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) {SVAAFrameInfoExt* pVaa = static_cast<SVAAFrameInfoExt*> (pEncCtx->pVaa);iFrameComplexity = pVaa->sComplexityScreenParam.iFrameComplexity;}if (0 == pTOverRc->iPFrameNum) {iLumaQp = pWelsSvcRc->iInitialQp;} else if (pWelsSvcRc->iCurrentBitsLevel == BITS_EXCEEDED) {iLumaQp = pWelsSvcRc->iLastCalculatedQScale + DELTA_QP_BGD_THD;
//limit QPint32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1;if (iLastIdxCodecInVGop < 0)iLastIdxCodecInVGop += VGOP_SIZE;int32_t iTlLast = pWelsSvcRc->iTlOfFrames[iLastIdxCodecInVGop];iDeltaQpTemporal = iTl - iTlLast;if (0 == iTlLast && iTl > 0)iDeltaQpTemporal += 1;else if (0 == iTl && iTlLast > 0)iDeltaQpTemporal -= 1;} else {int64_t iCmplxRatio = WELS_DIV_ROUND64 (iFrameComplexity * INT_MULTIPLY,pTOverRc->iFrameCmplxMean);iCmplxRatio = WELS_CLIP3 (iCmplxRatio, INT_MULTIPLY - FRAME_CMPLX_RATIO_RANGE, INT_MULTIPLY + FRAME_CMPLX_RATIO_RANGE);pWelsSvcRc->iQStep = WELS_DIV_ROUND ((pTOverRc->iLinearCmplx * iCmplxRatio), (pWelsSvcRc->iTargetBits * INT_MULTIPLY));iLumaQp = RcConvertQStep2Qp (pWelsSvcRc->iQStep);WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"iCmplxRatio = %d,frameComplexity = %" PRId64 ",iFrameCmplxMean = %" PRId64 ",iQStep = %d,iLumaQp = %d", (int)iCmplxRatio,iFrameComplexity, pTOverRc->iFrameCmplxMean, pWelsSvcRc->iQStep, iLumaQp);
//limit QPint32_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 += 1;else if (0 == iTl && iTlLast > 0)iDeltaQpTemporal -= 1;}pWelsSvcRc->iMinFrameQp =  WELS_CLIP3 (pWelsSvcRc->iLastCalculatedQScale - pWelsSvcRc->iFrameDeltaQpLower +iDeltaQpTemporal, pTOverRc->iMinQp, pTOverRc->iMaxQp) ;pWelsSvcRc->iMaxFrameQp =  WELS_CLIP3 (pWelsSvcRc->iLastCalculatedQScale + pWelsSvcRc->iFrameDeltaQpUpper +iDeltaQpTemporal, pTOverRc->iMinQp, pTOverRc->iMaxQp);iLumaQp = WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinFrameQp, pWelsSvcRc->iMaxFrameQp);if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {iLumaQp =  WELS_DIV_ROUND (iLumaQp * INT_MULTIPLY - pEncCtx->pVaa->sAdaptiveQuantParam.iAverMotionTextureIndexToDeltaQp,INT_MULTIPLY);iLumaQp = WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinFrameQp, pWelsSvcRc->iMaxFrameQp);}pWelsSvcRc->iQStep = RcConvertQp2QStep (iLumaQp);pWelsSvcRc->iLastCalculatedQScale = iLumaQp;pEncCtx->iGlobalQp = iLumaQp;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com