openh264 帧级码率控制源码分析

openh264 码率控制结构

关于 openh264 码率控制整体结构,可以参考:openh264 码率控制原理框架。

openh264 帧级码率控制介绍

  1. 函数关系图:从图可以看出,帧级码控的核心函数就是WelsRcPictureInitGomWelsRcPictureInfoUpdateGom函数。
    在这里插入图片描述

帧级码率控制核心函数介绍

  1. WelsRcPictureInitGom函数
  • 功能:负责设置编码周期的初始参数,包括码率、帧率、量化参数等,以确保视频编码过程中码率的稳定性和视频质量的一致性。通过调整这些参数,编码器可以在保持视频质量的同时,控制输出视频的比特率。
  • 原理过程
  • 函数声明:
    • WelsRcPictureInitGom 是函数的名称,用于初始化编码周期的率控制参数。
    • 参数 pEncCtx 是指向编码器上下文的指针。
    • 参数 uiTimeStamp 是当前帧的时间戳。
  • 局部变量声明:
    • pWelsSvcRc 指向当前依赖层的率控制结构体。
    • kiSliceNum 是当前编码层最大切片数量。
  • 连续跳帧计数器重置:
    • pWelsSvcRc->iContinualSkipFrames 重置为0,这可能用于跟踪连续跳过的帧数。
  • IDR帧的特殊处理:
    • 如果编码类型是I帧(关键帧),并且IDR帧计数器 iIdrNum 为0(表示编码器刚初始化),则调用 RcInitRefreshParameter 来初始化刷新参数。
  • 码率和帧率更新判断:
    • 如果需要,调用 RcJudgeBitrateFpsUpdate 判断并使用 RcUpdateBitrateFps 更新码率和帧率。
  • 时间层0的特殊处理:
    • 如果时间ID为0,则调用 RcUpdateTemporalZero 更新时间层0的参数。
  • 基于时间戳的码率决定:
    • 如果RC模式是时间戳模式,则调用 RcDecideTargetBitsTimestamp 根据时间戳决定目标比特数,并更新最后的时间戳。
    • 如果不是时间戳模式,则调用 RcDecideTargetBits 决定目标比特数。
  • 全局优化移动平均量化参数(GOM QP)的启用与禁用:
    • 如果切片数大于1,或者在码率模式下且编码类型为I帧,则禁用GOM QP。
    • 否则,启用GOM QP。
  • 全局量化参数计算:
    • 根据帧类型(I帧或非I帧),调用 RcCalculateIdrQpRcCalculatePictureQp 计算全局量化参数。
  • 切片信息初始化:
    • 调用 RcInitSliceInformation 初始化切片信息。
  • GOM参数初始化:
    • 调用 RcInitGomParameters 初始化GOM参数。
  • 源码
void  WelsRcPictureInitGom (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {SWelsSvcRc* pWelsSvcRc           = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];const int32_t kiSliceNum         = pEncCtx->pCurDqLayer->iMaxSliceNum;pWelsSvcRc->iContinualSkipFrames = 0;if (pEncCtx->eSliceType == I_SLICE) {if (0 == pWelsSvcRc->iIdrNum) { //iIdrNum == 0 means encoder has been initialedRcInitRefreshParameter (pEncCtx);}}if (RcJudgeBitrateFpsUpdate (pEncCtx)) {RcUpdateBitrateFps (pEncCtx);}if (pEncCtx->uiTemporalId == 0) {RcUpdateTemporalZero (pEncCtx);}if (pEncCtx->pSvcParam->iRCMode == RC_TIMESTAMP_MODE) {RcDecideTargetBitsTimestamp (pEncCtx);pWelsSvcRc->uiLastTimeStamp = uiTimeStamp;} else {RcDecideTargetBits (pEncCtx);}//turn off GOM QP when slicenum is larger 1if ((kiSliceNum > 1) || ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE)&& (pEncCtx->eSliceType == I_SLICE))) {pWelsSvcRc->bEnableGomQp = false;} elsepWelsSvcRc->bEnableGomQp = true;//decide globe_qpif (pEncCtx->eSliceType == I_SLICE) {RcCalculateIdrQp (pEncCtx);} else {RcCalculatePictureQp (pEncCtx);}RcInitSliceInformation (pEncCtx);RcInitGomParameters (pEncCtx);
} 
  1. WelsRcPictureInfoUpdateGom函数
  • 功能:负责在编码一帧后更新相关的率控制参数。通过这些更新,编码器可以动态调整编码参数,以确保在达到目标码率的同时,尽可能保持视频质量。此外,跳帧和填充的计算有助于在编码过程中进一步控制码率和视频文件的大小。
  • 原理过程
  • 函数声明:
    • WelsRcPictureInfoUpdateGom 是函数的名称,用于更新编码周期中帧的信息。
    • 参数 pEncCtx 是指向编码器上下文的指针。
    • 参数 iLayerSize 是当前编码层的大小,以字节为单位。
  • 局部变量声明:
    • pWelsSvcRc 指向当前依赖层的率控制结构体。
    • iCodedBits 是编码后帧的比特数,通过对 iLayerSize 左移3位(相当于乘以8)计算得出。
  • 更新编码后的量化参数和比特数:
    • 调用 RcUpdatePictureQpBits 函数,使用 pEncCtx 和 iCodedBits 更新编码帧的量化参数和比特数。
  • 更新帧复杂度:
    • 如果编码类型是P帧(前向预测帧),调用 RcUpdateFrameComplexity 更新帧的复杂度。
    • 如果编码类型是I帧(关键帧),调用 RcUpdateIntraComplexity 更新帧的复杂度。
  • 更新剩余比特数:
    • pWelsSvcRc->iRemainingBits 减去当前帧的比特数 pWelsSvcRc->iFrameDqBits,更新剩余的比特数。
  • 跳帧判断:
    • 如果启用了帧跳过功能(bEnableFrameSkip 为真),并且当前依赖层是最后一个空间层,则调用 RcVBufferCalculationSkip 函数进行跳帧计算。
  • 填充判断:
    • 如果设置了填充标志(iPaddingFlag),调用 RcVBufferCalculationPadding 函数进行填充计算。
  • 更新编码帧计数器:
    • pWelsSvcRc->iFrameCodedInVGop 增加1,表示在当前视频组(Video Group of Pictures, VGop)中又编码了一帧。
  • 源码
void  WelsRcPictureInfoUpdateGom (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;if (pEncCtx->pSvcParam->bEnableFrameSkip /*&&pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iSpatialLayerNum - 1*/) {RcVBufferCalculationSkip (pEncCtx);}if (pEncCtx->pSvcParam->iPaddingFlag)RcVBufferCalculationPadding (pEncCtx);pWelsSvcRc->iFrameCodedInVGop++;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DAB-DETR

论文地址&#xff1a; https://arxiv.org/pdf/2201.12329 文章通过前人的经验得出&#xff0c;导致 DETR 训练速度慢的原因很大可能是因为 decoder 中 cross attention 这个模块&#xff0c;由上面的对比可以看出其与 self attention 的区别主要就在于query的不同。文章猜想两个…

【Python办公自动化之Word】

python办公⾃动化之-Word python-docx库 文章目录 python办公⾃动化之-Word1、安装python-docx库2、⽂档的结构说明3、基本操作语法3.1 打开⽂档3.2加⼊不同等级的标题3.3 添加⽂本3.4 设置字号插曲1&#xff1a;实战演示3.5 设置中⽂字体3.6 设置斜体3.7 设置粗体3.8⾸⾏缩进…

H3C防火墙抓包(图形化)

一.报文捕获 &#xff0c;然后通过wireshark查看报文 二.报文示踪 &#xff0c; 输入源目等信息&#xff0c; 查看报文的详情

mongodb 集群安装

整体架构图&#xff1a; 1. 配置域名 Server1&#xff1a; OS version: CentOS Linux release 8.5.2111 hostnamectl --static set-hostname mongo01 vi /etc/sysconfig/network # Created by anaconda hostnamemong01 echo "192.168.88.20 mong1 mongo01.com mongo…

返回给前端数据的封装

返回格式如下&#xff1a; { "code": 200/400, "msg": "成功"/"失败", "total": n, "data": [ {}&#xff0c;{}]} 1.在common中新增Result 类&#xff0c;代码如下 package com.xxx0523.common; import lombo…

酸性设计震撼登场,让你眼前一亮!

说起酸性&#xff08;ACID&#xff09;&#xff0c;你会想到什么&#xff1f;”我们通常会想到酸味&#xff0c;酸设计的视觉魅力是通过图形、颜色、排版给人复古、迷幻、黑暗、叛逆的感觉&#xff0c;反复几何图形和高饱和的颜色&#xff0c;使设计非常时尚&#xff0c;非常适…

css实现多行文本的展开收起

背景 在我们写需求时可能会遇到类似于这样的多行文本展开与收起的场景&#xff1a; 那么&#xff0c;如何通过纯css实现这样的效果呢&#xff1f; 实现的难点 &#xff08;1&#xff09;位于多行文本右下角的 展开收起按钮。 &#xff08;2&#xff09;展开和收起两种状态的…

Spatio-temporal Relation Modeling for Few-shot Action Recognition

标题&#xff1a;少样本动作识别的时空关系建模 源文链接&#xff1a;Thatipelli_Spatio-Temporal_Relation_Modeling_for_Few-Shot_Action_Recognition_CVPR_2022_paper.pdf (thecvf.com)https://openaccess.thecvf.com/content/CVPR2022/papers/Thatipelli_Spatio-Temporal_…

Pikachu靶场--RCE

参考借鉴 pikachu-RCE_pikachu rce-CSDN博客 Pikachu靶场-RCE远程命令/代码执行漏洞-CSDN博客 命令执行/代码执行/RCE&#xff08;CTF教程&#xff0c;Web安全渗透入门&#xff09;_bilibili exec"ping" 输入IP地址查看页面反应 可以在IP地址的后面拼接我们想要执行…

6.2 事件的创建,修改和删除

6.2.1 事件的概述 事件(Event)是在指定时刻才被执行的过程式数据库对象。 事件通过MySQL中一个很有特色的功能模块——事件调度器(Event Scheduler)进行监视&#xff0c;并确定其是否需要被调用。 MySQL的事件调度器可以精确到每秒钟执行一个任务&#xff0c;比操作系统的计…

CCF推荐会议必投攻略:这些顶级会议投完直通录取大门

CCF推荐会议必投攻略&#xff1a;这些顶级会议投完直通录取大门&#xff01; 会议之眼 快讯 CCF介绍 CCF&#xff08;China Computer Federation&#xff09;即中国计算机学会&#xff0c;前身是中国电子学会计算机专业委员会&#xff0c;成立于1962年。这是由从事计算机及相…

MicroPython+ESP32 C3+ST7735S LCD屏 WIFI联网显示实时时间

案例地址&#xff1a;https://gitee.com/whltaoin_admin/MP_ESP32_ST7735S- 展示效果 ESP32LCD屏 WIFI联网并显示实时时间 TFT LCD模块参数介绍 名称&#xff1a;1.8 128*160 RGB_TFT驱动芯片&#xff1a;ST7735S ESP32 C3 参数介绍&#xff08;经典款&#xff09; 外观及…

Linux系统ubuntu20.04 无人机PX4 开发环境搭建(失败率很低)

Linux系统ubuntu20.04 无人机PX4 开发环境搭建 PX4固件下载开发环境搭建MAVROS安装安装地面站QGC PX4固件下载 PX4的源码处于GitHub&#xff0c;因为众所周知的原因git clone经常失败&#xff0c;此处从Gitee获取PX4源码和依赖模块。 git clone https://gitee.com/voima/PX4-…

基 CanMV 的 C 开发环境搭建(Linux,Ubuntu篇)

不论是使用 CanMV 提供的基于 C 语言和 FreeRTOS 的应用开发方式开发应用程序或是编译 CanMV 固件&#xff0c;都需要搭建基于 CanMV 的 C 开发环境&#xff0c;用于编译 CanMV 源码。 1. 开发环境搭建说明 CanMV 提供了基于 C 语言和 FreeRTOS 的应用开发…

傅里叶级数在不连续点会怎么样???

文章目录 一、前言背景二、用狄利克雷核表达傅里叶级数三、狄利克雷核与狄拉克函数四、傅里叶级数在不连续点的表示五、吉伯斯现象的解释六、总结参考资料 一、前言背景 笔者最近在撸《信号与系统》&#xff0c;写下此博客用作记录和分享学习笔记。由于是笔者为电子爱好者&…

ENVI实战—一文搞定非监督分类

实验1&#xff1a;使用isodata法分类 目的&#xff1a;学会使用isodata法开展非监督分类 过程&#xff1a; ①导入影像&#xff1a;打开ENVI&#xff0c;按照“文件→打开为→光学传感器→ESA→Sentinel-2”的顺序&#xff0c;打开实验1下载的哨兵2号数据。 图1 ②区域裁剪…

一文简述AI自动化漏洞修复实践

2024年&#xff0c;人工智能&#xff08;AI&#xff09;技术正以其前所未有的速度和影响力&#xff0c;革新着网络安全领域。AI在自动化漏洞修复方面的应用&#xff0c;标志着我们迈入了一个全新的网络安全时代。近日&#xff0c;在中国电信组织的一场技术交流会上&#xff0c;…

鸿蒙开发通信与连接:【@ohos.rpc (RPC通信)】

RPC通信 本模块提供进程间通信能力&#xff0c;包括设备内的进程间通信&#xff08;IPC&#xff09;和设备间的进程间通信&#xff08;RPC&#xff09;&#xff0c;前者基于Binder驱动&#xff0c;后者基于软总线驱动。 说明&#xff1a; 本模块首批接口从API version 7开始支…

番外篇 | 基于改进YOLOv5的安全帽佩戴检测 | 重参数化结构RepVGG + 空间对象注意力机制RCS-OSA模块

前言:Hello大家好,我是小哥谈。RCS-YOLO是一种目标检测算法,它是基于YOLOv3算法的改进版本。通过查看RCS-YOLO的整体架构可知,其中包括RCS-OSA模块。RCS-OSA模块在模型中用于堆叠RCS模块,以确保特征的复用并加强不同层之间的信息流动。本文针对安全帽佩戴的检测就是基于RC…

Vue 的 axios二次封装

&#xff08;以下的接口地址链接换成自己的写&#xff01;&#xff01;&#xff01;&#xff09; 首先在项目中src的目录下创建一个api的文件夹&#xff0c;在api的文件下在穿件两个文件用于二次封装 别忘了先安装axios&#xff1a;&#xff08;在根目录下安装axios&#xff0…