webrtc弱网-IntervalBudget类源码分析与算法原理

一、核心功能

IntervalBudget 类用于基于时间窗口的带宽预算管理。它根据设定的目标比特率(kbps)和一个固定时间窗口(500ms),计算在该时间窗口内可用的字节数(即“预算”),并支持预算的增加(随时间累积)和使用(发送数据时消耗)。该类可用于拥塞控制、码率调整等场景中,确保数据发送速率不超过目标速率。


二、核心算法原理

  • 预算计算
    预算基于目标比特率和时间窗口(500ms)计算:
    max_bytes_in_budget_ = (kWindowMs * target_rate_kbps_) / 8
    即:最大预算 = (500ms × 目标速率kbps) / 8(转换为字节)

  • 预算累积(IncreaseBudget)
    根据时间差 delta_time_ms 计算应增加的预算字节数。

    • 若允许积累未使用预算(can_build_up_underuse_为true),则将剩余预算累加,但不超过最大值;

    • 否则,每个时间窗口的预算独立,不累积。

  • 预算消耗(UseBudget)
    每发送一定字节数,就从剩余预算中扣除,但不能低于 -max_bytes_in_budget_(允许一定程度超支)。


三、关键数据结构

成员变量类型说明
target_rate_kbps_int目标比特率,单位kbps
max_bytes_in_budget_int64_t时间窗口内的最大预算字节数
bytes_remaining_int64_t当前剩余预算字节数,可为负(表示超支)
can_build_up_underuse_bool是否允许未使用的预算累积到下一个周期

四、核心方法详解

1. 构造函数

IntervalBudget(int initial_target_rate_kbps, bool can_build_up_underuse): bytes_remaining_(0), can_build_up_underuse_(can_build_up_underuse) {set_target_rate_kbps(initial_target_rate_kbps);
}

2. set_target_rate_kbps

void IntervalBudget::set_target_rate_kbps(int target_rate_kbps) {target_rate_kbps_ = target_rate_kbps;max_bytes_in_budget_ = (kWindowMs * target_rate_kbps_) / 8;bytes_remaining_ = std::min(std::max(-max_bytes_in_budget_, bytes_remaining_),max_bytes_in_budget_);
}

功能:设置目标比特率,并重新计算最大预算,同时限制当前剩余预算在合理范围内。

3. IncreaseBudget

void IntervalBudget::IncreaseBudget(int64_t delta_time_ms) {int64_t bytes = target_rate_kbps_ * delta_time_ms / 8;if (bytes_remaining_ < 0 || can_build_up_underuse_) {bytes_remaining_ = std::min(bytes_remaining_ + bytes, max_bytes_in_budget_);} else {bytes_remaining_ = std::min(bytes, max_bytes_in_budget_);}
}

功能:根据时间差增加预算。若允许累积或之前超支,则累加;否则重置为本周期预算。

4. UseBudget

void IntervalBudget::UseBudget(size_t bytes) {bytes_remaining_ = std::max(bytes_remaining_ - static_cast<int>(bytes),-max_bytes_in_budget_);
}

功能:使用预算,扣除相应字节数,防止超支过多。

5. bytes_remaining

size_t IntervalBudget::bytes_remaining() const {return rtc::saturated_cast<size_t>(std::max<int64_t>(0, bytes_remaining_));
}

功能:返回非负的剩余预算(超支时返回0)。

6. budget_ratio

double IntervalBudget::budget_ratio() const {if (max_bytes_in_budget_ == 0)return 0.0;return static_cast<double>(bytes_remaining_) / max_bytes_in_budget_;
}

功能:返回当前预算比率(剩余预算 / 最大预算),用于判断当前负载情况。


五、设计亮点

  1. 支持两种预算模式

    • 可累积模式(can_build_up_underuse_ = true):允许未使用的预算累积到下一周期;

    • 非累积模式:每个周期预算独立,不累积。

  2. 防溢出与饱和处理

    • 使用 std::min / std::max 限制预算范围;

    • bytes_remaining() 返回非负值,避免负数引起误解。

  3. 灵活的预算调整

    • 支持动态调整目标码率,自动重新计算最大预算;

    • 支持负预算(超支),但限制在一定范围内。


六、典型工作流程

  1. 初始化 IntervalBudget,设置初始目标码率和是否允许累积;

  2. 每隔一段时间调用 IncreaseBudget(delta_time_ms) 增加预算;

  3. 发送数据时调用 UseBudget(bytes) 扣除预算;

  4. 通过 bytes_remaining() 或 budget_ratio() 查询当前预算状态;

  5. 可根据网络状态动态调用 set_target_rate_kbps() 调整目标码率。


注释精要

interval_budget.h

// 带宽预算管理器,基于时间窗口(500ms)和目标码率进行预算控制
class IntervalBudget {public:explicit IntervalBudget(int initial_target_rate_kbps);IntervalBudget(int initial_target_rate_kbps, bool can_build_up_underuse);void set_target_rate_kbps(int target_rate_kbps);  // 设置目标码率(kbps)void IncreaseBudget(int64_t delta_time_ms);  // 增加预算,delta_time_ms 为时间差(毫秒)void UseBudget(size_t bytes);                 // 使用预算,bytes 为使用的字节数size_t bytes_remaining() const;               // 获取当前剩余预算(非负)double budget_ratio() const;                  // 获取预算比率(剩余预算/最大预算)int target_rate_kbps() const;                 // 获取当前目标码率private:int target_rate_kbps_;        // 目标码率(kbps)int64_t max_bytes_in_budget_; // 最大预算字节数(500ms窗口)int64_t bytes_remaining_;     // 当前剩余预算字节数(可为负)bool can_build_up_underuse_;  // 是否允许未使用的预算累积
};

interval_budget.cc

void IntervalBudget::IncreaseBudget(int64_t delta_time_ms) {int64_t bytes = target_rate_kbps_ * delta_time_ms / 8; // 计算应增加的字节数if (bytes_remaining_ < 0 || can_build_up_underuse_) {// 若当前超支或允许累积,则累加预算(不超过最大值)bytes_remaining_ = std::min(bytes_remaining_ + bytes, max_bytes_in_budget_);} else {// 否则,本周期的预算不超过当前时间窗口内的最大值bytes_remaining_ = std::min(bytes, max_bytes_in_budget_);}
}

IntervalBudget类在WebRTC中负责基于时间窗口的带宽预算管理,用于控制数据发送速率不超过设定的目标比特率。它通过500ms时间窗口将目标码率转换为字节预算,随时间推移累积预算,发送数据时扣除相应字节数。该类支持两种模式:可累积未使用预算或每周期独立预算,为拥塞控制和码率自适应算法提供关键的发送速率状态信息,确保网络流量平稳且避免拥塞,是pacing模块和拥塞控制系统的重要组成部分。

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

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

相关文章

深度学习基本模块:RNN 循环神经网络

循环神经网络&#xff08;RNN&#xff09;是一种专门用于处理序列数据的神经网络架构。与处理空间数据的卷积神经网络&#xff08;Conv2D&#xff09;不同&#xff0c;RNN通过引入循环连接使网络具有"记忆"能力&#xff0c;能够利用之前的信息来影响当前的输出&#…

React18学习笔记(二) React的状态管理工具--Redux,案例--移动端外卖平台

文章目录一.Redux的基础用法1.示例:普通网页中的Redux计步器2.Redux管理数据的流程3.配套工具和环境准备3.1.配套工具3.2.环境准备4.示例:React项目中的Redux计步器思路步骤step1:创建子模块step2:导入子模块step3:注入store实例step4:React组件内使用store中的数据step5:在组件…

34.Socket编程(UDP)(上)

点分十进制字符串IP 转 32位网络序列IP 分析&#xff1a;1&#xff09;IP转成4字节 2&#xff09;4字节转成网络序列 思路&#xff1a; "192.168.1.1" 进行字符串划分&#xff0c;以 "." 为分割符&#xff0c;分割出"192"&#xff0c;&qu…

Redis的持久化工具包—RDB AOF

文章目录 前言 一、RDB 持久化&#xff08;快照持久化&#xff09; 1. 定义 2. RDB 触发机制 &#xff08;1&#xff09;手动触发 &#xff08;2&#xff09;自动触发 3. RDB 持久化流程 4. RDB 核心配置 5. RDB 优缺点 二、AOF 持久化&#xff08;日志持久化&#xff09; 1. 定…

【Web安全】XXL-JOB框架SRC高频漏洞分析总结

文章目录前言一、核心漏洞分类与技术细节二、漏洞关联利用与攻击路径三、版本演进与修复策略四、安全运维建议五、典型漏洞复现环境搭建六、总结前言 XXL-JOB是国内主流的开源分布式任务调度框架&#xff0c;由徐雪里开发维护&#xff0c;以轻量易用、高可用、适配分布式场景等…

Capacitor 打包后接口访问不到的排查经历

我最近在用 Quasar Capacitor 6 做一个 Android App&#xff0c;前端用的是 Vue3 Quasar&#xff0c;打包交给 Capacitor 去跑在手机的 WebView 里&#xff0c;后端是 FastAPI 提供接口。开发模式下一切顺利&#xff0c;浏览器里访问接口没有任何问题&#xff0c;我甚至觉得打…

【正点原子】Linux应用编程入门~概念及环境介绍

应用编程概念 应用编程&#xff08;也可称为系统编程&#xff09;与驱动编程、裸机编程有何不同&#xff1f;系统调用&#xff1b;何为库函数&#xff1b;应用程序的 main()函数&#xff1b;应用程序开发环境的介绍&#xff1b;系统调用 定义系统调用&#xff08;system call&a…

一、HTML 完全指南:从零开始构建网页

文章目录前言一、 HTML 结构认识 HTML 标签HTML 文件基本结构标签层次结构快速生成代码框架二、 HTML 常见标签详解2.1 注释标签2.2 标题标签 (h1 - h6)2.3 段落标签 (p)2.4 换行标签 (br)2.5 格式化标签2.6 图片标签 (img)2.7 超链接标签 (a)2.8 表格标签基本使用合并单元格2.…

基于POI-TL实现动态Word模板的数据填充:【散点图】特殊处理方案

基于POI-TL实现动态Word模板的数据填充:散点图特殊处理方案 在使用POI-TL进行Word模板动态数据填充时,图表生成是一个常见需求。最近在项目中使用POI-TL处理散点图时遇到了一个特殊问题,经过研究后找到了解决方案,特此记录分享。 问题背景 POI-TL作为一款优秀的Java Wor…

使用node-Express框架写一个学校宿舍管理系统练习项目-前后端分离

今天继续分享一个新的练习项目&#xff0c;是使用node做为后端语言&#xff0c;来写的一个前后端分离项目&#xff1a;学校宿舍管理系统。我们如果想掌握一门编程语言&#xff0c;就是需要大量的练习。所以当我们学习到了一些知识&#xff0c;自己想一下 可以拿学到的知识&…

Kafka 运维实战基本操作含命令与最佳实践

1. 基础概览与工具入口 Kafka 发行包的所有 CLI 工具均在 bin/ 目录下。任何工具不带参数运行都会显示所有可用选项。本文命令默认&#xff1a;--bootstrap-server localhost:9092&#xff1b;生产请替换为你的控制面或内网 VIP。 2. 主题管理&#xff08;创建 / 修改 / 删除 /…

贪心算法应用:航班起降问题详解

Java中的贪心算法应用&#xff1a;航班起降问题详解 贪心算法是一种在每一步选择中都采取当前状态下最优的选择&#xff0c;从而希望导致全局最优解的算法策略。在航班起降问题中&#xff0c;贪心算法可以有效地解决机场跑道调度问题&#xff0c;即如何安排航班的起降顺序以最大…

uniapp scroll-view 设置scrollTop无效

当我们使用 scroll-view的scroll-top的时候 默认想让它回到顶部&#xff0c;当我们设置值为0的时候会不生效&#xff0c;在实际运用过程中&#xff0c;发现设置了scroll-top无效&#xff0c;滚动条位置并没有发生变化&#xff0c;是因为微信小程序的官方框架处于性能考虑&#…

网络与通信

1.TCP协议与UDP协议TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;和 UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是 TCP/IP 协议族中两种核心的传输层协议&#xff0c;它们在数据传输方式、可靠性、适…

Node.js中package.json详解

1. name&#xff08;名称&#xff09; 如果你计划发布你的包&#xff0c;package.json 中最重要的字段是 name 和 version&#xff0c;因为它们是必需的。name 和 version 共同组成一个假定完全唯一的标识符。包的更改应伴随版本号的更新。如果你不打算发布包&#xff0c;那么…

代码随想录第14天| 翻转、对称与深度

226.翻转二叉树 &#xff08;优先掌握递归&#xff09; 题目链接/文章讲解/视频讲解&#xff1a;翻转二叉树 交换的是指针&#xff0c;而不是数值&#xff0c;如果用数值做交换&#xff0c;需要交换的节点下面无法很好的操作。 使用递归来实现&#xff0c;但要提前清除是什么顺…

DNS-Windows上使用DNS

DNS-Windows上使用DNS一、查看与修改DNS配置1.1、查看当前DNS服务器设置1.2、临时修改 DNS 服务器&#xff08;命令行&#xff09;二、DNS缓存相关操作2.1、查看DNS缓存内容2.2、 刷新 DNS 缓存&#xff08;清除过期记录&#xff09;三、测试域名解析&#xff08;nslookup 工具…

3dsMax 2026 .NET Core 8 转型下的Maxscript脚本开发:动态编译模块的重构策略与兼容性升级路径

3ds Max 长期以来一直提供出色的 .NET 集成,使 Maxscript 能够无缝利用任何 .NET 库的强大功能。部分开发者在工具中广泛使用了 .NET 功能。 之前,3ds Max 依赖于 .NET Framework 4.8 并且最近更新到了 4.8.1,用于 2025 版本的发布。然而,随着 3ds Max 2026 的推出,Autod…

golang 做webrtc开发核心

在Golang中进行WebRTC开发&#xff0c;核心在于理解WebRTC协议的工作原理以及如何利用Go生态中的库来实现关键功能。以下是Golang WebRTC开发的核心要点&#xff1a; WebRTC基础概念 了解ICE&#xff08;Interactive Connectivity Establishment&#xff09;协议用于NAT穿越掌握…

RabbitMQ 异步化抗洪实战

说明&#xff1a;本文仅展示架构思路与安全片段&#xff0c;所有敏感字段已用占位符&#xff1b;不含可直接复刻的生产细节。数据与接口均为演示/虚拟。0. 背景与目标长耗时/不确定接口&#xff08;如对接第三方机器人平台&#xff09;的同步阻塞&#xff0c;容易造成请求堆积与…