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

RcCalculateIdrQp函数

功能

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

原理过程

  • 初始化变量:
    • dBpp:初始化为0,用来存储比特率每像素(bits per pixel)的值。
    • i:一个整型循环变量。
  • 注释说明:
    • 提供了不同分辨率和帧率下的目标比特率每像素值(bpp)和对应的量化参数(QP)示例。
  • 定义数组:
    • dBppArray:一个二维数组,存储不同分辨率下的比特率每像素值的阈值。
    • dInitialQPArray:一个二维数组,存储不同分辨率下对应的初始量化参数。
    • iQpRangeArray:一个二维数组,存储量化参数的范围。
  • 计算帧复杂度:
    • 根据编码参数的用途类型(iUsageType),可能使用不同的方法来计算帧复杂度(iFrameComplexity)。
  • 获取编码器的比特率控制和空间层配置:
    • pWelsSvcRc:指向比特率控制结构体的指针。
    • pDLayerParam:指向空间层配置的指针。
    • pDLayerParamInternal:指向空间层内部配置的指针。
  • 计算比特率每像素值(dBpp):
    • 如果输出帧率、视频宽度和高度都大于0,则根据空间层的比特率、输出帧率、视频宽度和高度计算dBpp。
    • 如果上述条件不满足,则将dBpp设置为0.1,这可能是一个默认值或者最小值。
  • 分辨率与索引关联:
    • 根据视频的分辨率(宽度乘以高度)来设置iBppIndex。这个索引将用于选择适当的比特率每像素(bpp)阈值和初始量化参数。
    • iBppIndex为0时,对应90p视频(160x90像素)。
    • iBppIndex为1时,对应180p视频(320x180像素)。
    • iBppIndex为2时,对应360p视频(640x360像素)。
    • 如果分辨率大于360p,则iBppIndex默认为3。
  • 搜索合适的bpp阈值:
    • 使用一个循环来搜索dBppArray中不超过当前dBpp值的最大阈值。循环中的i变量从0开始,直到找到合适的阈值或达到数组的最后一个元素。
  • 确定量化参数范围:
    • 根据找到的阈值索引i和iBppIndex,从iQpRangeArray中获取量化参数的最大值iMaxQp和最小值iMinQp。
  • 量化参数范围的调整:
    • 使用WELS_CLIP3函数来确保iMinQp和iMaxQp在编码器设定的最小量化参数pWelsSvcRc->iMinQp和最大量化参数pWelsSvcRc->iMaxQp之间。
  • 检查是否为第一个IDR帧:
    • 如果pWelsSvcRc->iIdrNum等于0,表示当前正在处理的是序列的第一个IDR帧。
  • 设置第一个IDR帧的初始量化参数:
    • 对于第一个IDR帧,使用dInitialQPArray数组中对应iBppIndex和索引i的值作为初始量化参数iInitialQp。
  • 处理非第一个IDR帧:
    • 如果当前IDR帧不是序列中的第一个IDR帧,则根据前一个IDR帧的复杂度来计算量化参数。
  • 调整内部分块复杂度:
    • 如果iNumberMbFrame(帧的宏块数)不等于iIntraMbCount(帧内的内部分块数),则重新计算iIntraComplexity,即内部分块的复杂度。
  • 计算复杂度比率:
    • 使用WELS_DIV_ROUND64函数计算iFrameComplexity(当前帧的复杂度)与iIntraComplxMean(平均内部分块复杂度)的比率iCmplxRatio,并且乘以一个常数INT_MULTIPLY。
  • 限制复杂度比率的范围:
    • 使用WELS_CLIP3函数将iCmplxRatio限制在INT_MULTIPLY - FRAME_CMPLX_RATIO_RANGE和INT_MULTIPLY + FRAME_CMPLX_RATIO_RANGE之间。
  • 计算量化步长:
    • 根据iIntraComplexity、iCmplxRatio和目标比特数iTargetBits计算量化步长iQStep,使用WELS_DIV_ROUND函数。
  • 将量化步长转换为量化参数:
    • 使用RcConvertQStep2Qp函数将量化步长iQStep转换为量化参数iInitialQp。
  • 限制初始量化参数:
    • pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, iMinQp, iMaxQp);
    • 使用WELS_CLIP3函数确保iInitialQp(初始量化参数)在预定义的最小量化参数iMinQp和最大量化参数iMaxQp之间。这是为了确保量化参数不会超出设定的范围。
  • 设置全局量化参数:
    • pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp;
    • 将初始量化参数赋值给编码上下文pEncCtx中的全局量化参数iGlobalQp。这个全局参数会被编码过程中的其他部分使用。
  • 转换量化参数为量化步长:
    • pWelsSvcRc->iQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp);
    • 将量化参数转换为量化步长iQStep。量化步长是比特率控制算法中的一个中间参数,用于进一步的计算。
  • 记录最后计算的量化参数:
    • pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp;
    • 将当前的全局量化参数保存为最后计算的量化参数iLastCalculatedQScale。用于跟踪和调整编码过程中的量化参数。
  • 设置帧的最小和最大量化参数:
    • pWelsSvcRc->iMinFrameQp = WELS_CLIP3 (pEncCtx->iGlobalQp - DELTA_QP_BGD_THD, iMinQp, iMaxQp);
    • pWelsSvcRc->iMaxFrameQp = WELS_CLIP3 (pEncCtx->iGlobalQp + DELTA_QP_BGD_THD, iMinQp, iMaxQp);
    • 分别计算帧的最小量化参数iMinFrameQp和最大量化参数iMaxFrameQp。它们是基于全局量化参数iGlobalQp减去或加上一个阈值DELTA_QP_BGD_THD来计算的,然后使用WELS_CLIP3函数确保结果在iMinQp和iMaxQp的范围内。

原理流程图

在这里插入图片描述

源码

void RcCalculateIdrQp (sWelsEncCtx* pEncCtx) {
  double dBpp = 0;
  int32_t i;

//64k@6fps for 90p:     bpp 0.74    QP:24
//192k@12fps for 180p:  bpp 0.28    QP:26
//512k@24fps for 360p:  bpp 0.09    QP:30
//1500k@30fps for 720p: bpp 0.05    QP:32
  double dBppArray[4][3] = {{0.5, 0.75, 1.0}, {0.2, 0.3, 0.4}, {0.05, 0.09, 0.13}, {0.03, 0.06, 0.1}};
  int32_t dInitialQPArray[4][4] = {{28, 26, 24, 22}, {30, 28, 26, 24}, {32, 30, 28, 26}, {34, 32, 30, 28}};
  int32_t iBppIndex = 0;
  int32_t iQpRangeArray[4][2] = {{37, 25}, {36, 24}, {35, 23}, {34, 22}};
  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;
  }
  SWelsSvcRc* pWelsSvcRc                = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
  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 *
           pDLayerParam->iVideoHeight);
  else
    dBpp = 0.1;
//Area*2
  if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 28800) // 90p video:160*90
    iBppIndex = 0;
  else if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 115200) // 180p video:320*180
    iBppIndex = 1;
  else if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 460800) // 360p video:640*360
    iBppIndex = 2;
  else
    iBppIndex = 3;

//Search
  for (i = 0; i < 3; i++) {
    if (dBpp <= dBppArray[iBppIndex][i])
      break;
  }
  int32_t iMaxQp = iQpRangeArray[i][0];
  int32_t iMinQp = iQpRangeArray[i][1];
  iMinQp = WELS_CLIP3 (iMinQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
  iMaxQp = WELS_CLIP3 (iMaxQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
  if (0 == pWelsSvcRc->iIdrNum) { //the first IDR frame
    pWelsSvcRc->iInitialQp = dInitialQPArray[iBppIndex][i];
  } else {

    //obtain the idr qp using previous idr complexity
    if (pWelsSvcRc->iNumberMbFrame != pWelsSvcRc->iIntraMbCount) {
      pWelsSvcRc->iIntraComplexity = pWelsSvcRc->iIntraComplexity * pWelsSvcRc->iNumberMbFrame /
                                     pWelsSvcRc->iIntraMbCount;
    }

    int64_t iCmplxRatio = WELS_DIV_ROUND64 (iFrameComplexity * INT_MULTIPLY,
                                            pWelsSvcRc->iIntraComplxMean);
    iCmplxRatio = WELS_CLIP3 (iCmplxRatio, INT_MULTIPLY - FRAME_CMPLX_RATIO_RANGE, INT_MULTIPLY + FRAME_CMPLX_RATIO_RANGE);
    pWelsSvcRc->iQStep = WELS_DIV_ROUND ((pWelsSvcRc->iIntraComplexity * iCmplxRatio),
                                         (pWelsSvcRc->iTargetBits * INT_MULTIPLY));
    pWelsSvcRc->iInitialQp = RcConvertQStep2Qp (pWelsSvcRc->iQStep);
  }

  pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, iMinQp, iMaxQp);
  pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp;
  pWelsSvcRc->iQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp);
  pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp;
  pWelsSvcRc->iMinFrameQp = WELS_CLIP3 (pEncCtx->iGlobalQp - DELTA_QP_BGD_THD, iMinQp, iMaxQp);
  pWelsSvcRc->iMaxFrameQp = WELS_CLIP3 (pEncCtx->iGlobalQp + DELTA_QP_BGD_THD, iMinQp, iMaxQp);

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/728070.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

nginx的正向代理

目录 1 正向代理 1.1 使用正向代理的作用 1.2 Nginx正向代理实战 1.2.1 下载对应版本的nginx&#xff08;源码编译&#xff09; 1.2.2 下载 https 代理模块 1.2.3 使用https代理模块对源代码修改 1.2.4 源码安装 1.2.5 编写systemd 服务单元 1.2.6 修改nginx的主配置文件 1.2.…

虚拟现实环境下的远程教育和智能评估系统(十一)

视频帧画面知识点区域划分 知识点区域精确分割技术: 在深度学习检测模型结果基础上使用基于交并比&#xff08;IoU&#xff09;阈值的目标合并算法&#xff0c;合并过度重合目标区域面积&#xff0c;实现知识点区域精确分割 多模态知识点内容匹配策略: 图像&#xff1a;利用…

【人工智能,机器学习,统计学习,科学表征】开源商用与研发合作

个体工户linjing-lab托管在Github&#xff0c;现公开招募商用与合作人员&#xff0c;目标人群分为以下几个方向&#xff1a; 数学、信息科学、计算机专业的大学高年级学生&#xff0c;熟悉C和面向对象模型&#xff0c;擅长Pybind11编译算子到Python环境。26岁以下的大学本科毕…

PDF文档翻译软件哪个好?分享5款快速翻译的工具

世界各地的交流日益密切&#xff0c;文档翻译服务因此变得不可或缺。 无论是企业间的跨国商务合同&#xff0c;还是学术领域的专业研究论文&#xff0c;准确无误地将文档内容翻译成目标语言&#xff0c;对于保障信息的清晰传达和正确理解极为关键。 在这样的背景下&#xff0…

今日分享:中国石油年金系统交互、视觉设计和vue开发

金融系统交互及UI设计时&#xff0c;需注意简洁明了、色彩合理、字体统一、交互易用、安全感和用户控制。确保用户快速理解、安全操作并提升体验。

JavaScript:at()方法遇到的问题并解决

目录 第一章 前言 第二章 使用at方法 第三章 分析原因并解决问题 第一章 前言 最近上线了一个项目&#xff0c;测试过程中并没有什么问题&#xff0c;但是上线后使用的用户多了&#xff0c;结果出现了这么一个问题&#xff1a;.at方法对低版本手机的浏览器不兼容问题&#x…

英伟达中国特供芯片降价背后:巨头与市场的较量

英伟达&#xff0c;这家曾经在人工智能芯片领域独领风骚的巨头&#xff0c;近期在中国市场遭遇了一些挑战。为了应对来自华为等中国本土企业的竞争&#xff0c;英伟达不得不采取降价策略&#xff0c;调整其专为中国市场打造的H20芯片价格&#xff0c;甚至低于华为的同类产品。这…

STM32 串口通讯

使用STM32的串口通讯&#xff0c;接收串口助手的数据&#xff0c;并且将接收到的数据返回串口&#xff0c;重定义printf功能。 配置引脚信息 由于每次新建工程都需要配置信息&#xff0c;比较麻烦&#xff0c;好在STM32CubeIDE提供了导入.ioc文件的功能&#xff0c;可以帮我们…

Flutter【组件】按钮

简介 flutter 按钮组件。提供一种封装按钮组件的思路&#xff0c;并不支持过多的自定义属性。根据使用场景及设计规范进行封装&#xff0c;使用起来比较方便。 github地址&#xff1a;https://github.com/ThinkerJack/jac_uikit pub地址&#xff1a;https://pub.dev/package…

Faiss:加速大规模数据相似性搜索的利器

在机器学习和数据挖掘领域&#xff0c;相似性搜索是一项基本且重要的任务&#xff0c;它涉及到在大型数据集中找到与特定对象最相似的对象。Faiss是一个由Facebook AI Research开发的库&#xff0c;专门用于高效地进行相似性搜索和聚类&#xff0c;它之所以重要&#xff0c;是因…

uni-app的uni-list列表组件高效使用举例 (仿知乎日报实现)

目录 前言 uni-list组件介绍 基本使用 高级配置与自定义 仿知乎日报实现 知乎的api接口 后台服务实现 知乎日报首页 轮播图界面实现 客户端接口实现 uni-list列表使用 插入日期分割线 下滑分页的实现 完整页面代码 其他资源 前言 在移动应用开发领域&#xff0…

2024年【N1叉车司机】作业考试题库及N1叉车司机实操考试视频

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年N1叉车司机作业考试题库为正在备考N1叉车司机操作证的学员准备的理论考试专题&#xff0c;每个月更新的N1叉车司机实操考试视频祝您顺利通过N1叉车司机考试。 1、【多选题】《中华人民共和国特种设备安全法》第…

JavaWeb之JSON、AJAX

JSON 什么是JSON&#xff1a;JSON: JavaScript Object Notation JS对象简谱 , 是一种轻量级的数据交换格式(JavaScript提供) 特点 [{"name":"周珍珍", "age":18},{"name":"李淑文","age":20}]数据是以键值对形式…

[Ansible详解]

Ansible 1.主机组清单设置 #组 #父组与子组[组名] [组名]ip ipip ip[组名 : vars] [组名2]ansible_user=用户 …

如何在linux中下载R或者更新R

一、问题阐述 package ‘Seurat’ was built under R version 4.3.3Loading required package: SeuratObject Error: This is R 4.0.4, package ‘SeuratObject’ needs > 4.1.0 当你在rstudio中出现这样的报错时&#xff0c;意味着你需要更新你的R 的版本了。 二、解决方…

【机器学习】与【深度学习】的前沿探索——【GPT-4】的创新应用

gpt4o年费&#xff1a;一年600&#xff0c; 友友们&#xff0c;一起拼单呀&#xff0c;两人就是300&#xff0c;三个人就是200&#xff0c;以此类推&#xff0c; 我已经开通年费gpt4o&#xff0c;开通时长是 从2024年6月20日到2025年7月16日 有没有一起的呀&#xff0c;有需要的…

在SQL中使用explode函数展开数组的详细指南

目录 简介示例1&#xff1a;简单数组展开示例2&#xff1a;展开嵌套数组示例3&#xff1a;与其他函数结合使用处理结构体数组示例&#xff1a;展开包含结构体的数组示例2&#xff1a;展开嵌套结构体数组 总结 简介 在处理SQL中的数组数据时&#xff0c;explode函数非常有用。它…

VScode中js关闭烦人的ts检查

类似如下的代码在vscode 会报错&#xff0c;我们可以在前面添加忽略检查或者错误&#xff0c;如下&#xff1a; 但是&#xff01;&#xff01;&#xff01;这太不优雅了&#xff01;&#xff01;&#xff01;&#xff0c;js代码命名没有问题&#xff0c;错在ts上面&#xff0c;…

window安装miniconda

下载 https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/ 安装 双击安装 配置环境变量 添加&#xff1a;PYTHONUSERBASE你的安装路径 添加Path&#xff1a; cmd执行&#xff1a; python -m site将USER_SITE添加进Path 还需要将如下添加进环境变量 D:\Miniconda…

C++学习/复习16---优先级队列/仿函数/反向迭代器

一、优先队列与堆 1.1概念 1.2第k个元素 仿函数&#xff1a; **仿函数&#xff08;Functor&#xff09;是一种通过重载operator()运算符的类或结构体&#xff0c;调用使得对象可以像函数一样被**。在C编程中&#xff0c;仿函数不仅增添了编程的灵活性和功能的强大性&#xff…