当前位置: 首页 > news >正文

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

一、核心功能

ProbeBitrateEstimator 是 WebRTC 中用于估计网络带宽的探测器类,其主要功能是通过分析探测包(probe packets)的发送和接收情况,来估算当前网络的可用带宽。它在拥塞控制中起到关键作用,帮助确定合适的发送速率。

二、核心算法原理

算法基于发送和接收探测包的时间间隔和数据量来计算带宽:

  1. 将属于同一探测簇(cluster)的包进行聚合统计

  2. 计算发送端速率:(总数据量 - 最后一个包大小) / (最后发送时间 - 最先发送时间)

  3. 计算接收端速率:(总数据量 - 第一个包大小) / (最后接收时间 - 最先接收时间)

  4. 取两个速率的最小值作为初步估计

  5. 如果接收速率远小于发送速率,则应用目标利用率系数进行调整

三、关键数据结构

struct AggregatedCluster {int num_probes = 0;                      // 探测包数量Timestamp first_send = Timestamp::PlusInfinity();    // 最早发送时间Timestamp last_send = Timestamp::MinusInfinity();    // 最晚发送时间Timestamp first_receive = Timestamp::PlusInfinity(); // 最早接收时间Timestamp last_receive = Timestamp::MinusInfinity(); // 最晚接收时间DataSize size_last_send = DataSize::Zero();          // 最后发送包大小DataSize size_first_receive = DataSize::Zero();      // 最先接收包大小DataSize size_total = DataSize::Zero();              // 总数据量
};

四、核心方法详解

HandleProbeAndEstimateBitrate

absl::optional<DataRate> HandleProbeAndEstimateBitrate(const PacketResult& packet_feedback) {int cluster_id = packet_feedback.sent_packet.pacing_info.probe_cluster_id;// 确认是探测包RTC_DCHECK_NE(cluster_id, PacedPacketInfo::kNotAProbe);// 清理过时的簇数据EraseOldClusters(packet_feedback.receive_time);// 获取或创建对应簇ID的聚合数据AggregatedCluster* cluster = &clusters_[cluster_id];// 更新聚合统计信息(时间窗口和数据量)if (packet_feedback.sent_packet.send_time < cluster->first_send) {cluster->first_send = packet_feedback.sent_packet.send_time;}// ... 更多统计更新代码// 检查是否收到足够多的探测包反馈int min_probes = packet_feedback.sent_packet.pacing_info.probe_cluster_min_probes * kMinReceivedProbesRatio;DataSize min_size = DataSize::Bytes(packet_feedback.sent_packet.pacing_info.probe_cluster_min_bytes) * kMinReceivedBytesRatio;if (cluster->num_probes < min_probes || cluster->size_total < min_size)return absl::nullopt;// 计算发送和接收时间间隔TimeDelta send_interval = cluster->last_send - cluster->first_send;TimeDelta receive_interval = cluster->last_receive - cluster->first_receive;// 验证时间间隔有效性if (send_interval <= TimeDelta::Zero() || send_interval > kMaxProbeInterval ||receive_interval <= TimeDelta::Zero() || receive_interval > kMaxProbeInterval) {// 记录失败事件并返回空值return absl::nullopt;}// 计算发送速率(排除最后一个包)DataSize send_size = cluster->size_total - cluster->size_last_send;DataRate send_rate = send_size / send_interval;// 计算接收速率(排除第一个包)DataSize receive_size = cluster->size_total - cluster->size_first_receive;DataRate receive_rate = receive_size / receive_interval;// 验证接收/发送比率double ratio = receive_rate / send_rate;if (ratio > kMaxValidRatio) {// 比率过高,记录失败事件return absl::nullopt;}// 计算最终估计速率DataRate res = std::min(send_rate, receive_rate);// 如果接收速率显著低于发送速率,应用目标利用率系数if (receive_rate < kMinRatioForUnsaturatedLink * send_rate) {res = kTargetUtilizationFraction * receive_rate;}// 记录成功事件并返回估计值estimated_data_rate_ = res;return estimated_data_rate_;
}

EraseOldClusters

void EraseOldClusters(Timestamp timestamp) {// 清理超过最大历史时间的簇数据for (auto it = clusters_.begin(); it != clusters_.end();) {if (it->second.last_receive + kMaxClusterHistory < timestamp) {it = clusters_.erase(it);} else {++it;}}
}

五、设计亮点

  1. 时间窗口管理:自动清理过期数据,防止内存无限增长

  2. 有效性验证:通过多种条件(最小包数、最小数据量、时间间隔、速率比率)确保估计结果的可靠性

  3. 排除边界包:在计算速率时排除第一个和最后一个包,减少边界效应的影响

  4. 事件日志记录:详细记录探测成功和失败的情况,便于调试和分析

  5. 保守估计策略:当接收速率远低于发送速率时,采用目标利用率系数,避免过度乐观估计

六、典型工作流程

  1. 发送端发送一组探测包(属于同一探测簇)

  2. 接收端收到包后发送反馈

  3. 对每个反馈包调用HandleProbeAndEstimateBitrate

  4. 方法内部聚合同一簇的包统计信息

  5. 当收到足够多的反馈时,计算带宽估计值

  6. 通过FetchAndResetLastEstimatedBitrate获取估计结果

  7. 定期清理过时的簇数据

ProbeBitrateEstimator 在 WebRTC 中是实现网络带宽主动探测的核心组件。它通过分析专门发送的探测数据包的发送和接收情况,估算当前网络的实际可用带宽。该类聚合同一探测簇的包统计信息,计算发送端和接收端速率,并采用保守策略(如目标利用率系数)确保估计结果可靠。其输出为拥塞控制算法提供关键输入,用于动态调整媒体流的发送速率,避免网络过载的同时最大化带宽利用率,是 WebRTC 实现自适应码率控制和保证音视频传输质量的重要基础模块。

http://www.dtcms.com/a/393827.html

相关文章:

  • 在OpenHarmony上适配图形显示【4】——rk3568_4.0r_mesa3d适配
  • 嵌入式(3)——RTC实时时钟
  • 内核模块组成和裁剪参考表
  • 140-understanding_the_armv8.x_and_armv9.x_extensions_guide
  • 【序列晋升】40 Spring Data R2DBC 轻量异步架构下的数据访问最佳实践
  • TGRS | 视觉语言模型 | 语言感知领域泛化实现高光谱跨场景分类, 代码开源!
  • Oracle / MySQL / MariaDB / SQL Server 常用连接与基础查询(Linux操作系统上)
  • 将 Jupyter Notebook 转换为 PDF
  • torchvision 编译安装 nano
  • 华为昇腾 910 到 950 系列 NPU 深度解析
  • 设计模式---门面模式
  • SQL Server从入门到项目实践(超值版)读书笔记 26
  • Datawhale学习笔记——深度语义匹配模型DSSM详解、实战与FAQ
  • 一文了解瑞萨MCU常用的芯片封装类型
  • LeetCode:44.二叉搜索树中第K小的元素
  • 初学者如何系统性地学习Linux?
  • LeetCode:43.验证二叉搜索树
  • [学习log] OT/ICS工业控制系统渗透测试
  • 六边形箱图 (Hexbin Plot):使用 Matplotlib 处理大规模散点数据
  • LinuxC++项目开发日志——基于正倒排索引的boost搜索引擎(2——Parser解析html模块)
  • 电脑能ping开发板,开发板不能ping电脑的解决方法:
  • git 覆盖:检出特定分支的文件到当前分支
  • CentOS 8.5.2.111部署Zabbix6.0
  • 【Elasticsearch面试精讲 Day 20】集群监控与性能评估
  • hive调优系列-3.HQL语法和运行参数层面
  • 计算机网络学习(三、数据链路层)
  • Refresh keys changed: [] 2023.0.3.3 问题排查
  • 高并发内存池(二):三层缓存的整体框架设计
  • Android音视频编解码全流程之Extractor
  • 基于 @antv/x6 实现流程图