aimd的全称是Additive Increase Multiplicative Decrease,意思是:加性增加,乘性减少。AimdRateControl是一种码率控制实现,当未检测到over-use时,基于加性的码率增加,当检测到over-use时,基于乘性的比特率减少。当认为可用带宽有变化或未知时,我们将切换到“慢启动模式”,成倍增加。
   AimdRateControl码率控制模块有三种状态:kRcHold,kRcIncrease和kRcDecrease 。“kRcIncrease”是未检测到拥塞的状态;“kRcDecrease”是检测到拥塞的状态,“kRcHold”是等待累积队列耗尽后进入“增加”状态的状态,状态迁移过程取决于基于延迟的码率控制输出的网络状态,网络状态有三种:kRcHold,kBwOverusing和kBwUnderusing,码率控制的状态机如下:

状态Hold
   保持原码率,且状态继续保持Hold
状态kRcIncrease
   如果测量的吞吐量与估计值相差太远,则重置link_capacity估计值。因此,我们可以假设我们的目标速率与链接容量相当接近,并使用加性增加;如果我们没有对link_capacity的估计,可以使用更快的乘型增加。
码率加性算法因子:
加性因子计算为当前码率下平均码率ave_bitrate,
               ave_bitrate=avg_packet_size/(rtt+100)
其中avg_packet_size表示包平均字节大小,是在1/30秒时间间隔内在当前码率下,按单包最大1200字节计算的平均单包字节大小;rtt加100ms表示接近over-use的延时是时间,按最糟糕的情况计算ave_bitrate,然后与4000取最大。
ave_bitrate代码实现如下:

double AimdRateControl::GetNearMaxIncreaseRateBpsPerSecond() const {const TimeDelta kFrameInterval = TimeDelta::seconds(1) / 30;//1/30秒的时间间隔DataSize frame_size = current_bitrate_ * kFrameInterval;//间隔内当前码率下的字节数const DataSize kPacketSize = DataSize::bytes(1200);//按最大1200字节包计算double packets_per_frame = std::ceil(frame_size / kPacketSize);//间隔内平均包个数,为浮点型DataSize avg_packet_size = frame_size / packets_per_frame;//每个包平均字节个数TimeDelta response_time = rtt_ + TimeDelta::ms(100);//rtt+100按最坏情况计算响应时间if (in_experiment_)response_time = response_time * 2;double increase_rate_bps_per_second =//计算平均码率(avg_packet_size / response_time).bps<double>();double kMinIncreaseRateBpsPerSecond = 4000;return std::max(kMinIncreaseRateBpsPerSecond, increase_rate_bps_per_second);//与4000取两者最大
}

码率乘性算法因子:
               alpha=alphamin(timeDelta,1)
其中alpha初始值为1.08,timeDelta为本次码率控制器更新码率时间与上一次更新码率时间的差,则乘性后的码率为max(curbitrate*alpha,curbitrate+1000)。代码如下:

DataRate AimdRateControl::MultiplicativeRateIncrease(Timestamp at_time,Timestamp last_time,DataRate current_bitrate) const {double alpha = 1.08;//默认乘性因子1.08if (last_time.IsFinite()) {auto time_since_last_update = at_time - last_time;//相邻两次码率控制器更新码率时间差alpha = pow(alpha, std::min(time_since_last_update.seconds<double>(), 1.0));//计算乘性因子}DataRate multiplicative_increase =std::max(current_bitrate * (alpha - 1.0), DataRate::bps(1000));return multiplicative_increase;
}

状态kRcDecrease
   如果网络处于over-use状态,需要减少码率,从ack计算的码率降低原来的85%,如果码率还是比码率控制器估计的码率大,则码率降低为链路容量link_capacity估计值的85%。

case kRcDecrease:// TODO(srte): Remove when |estimate_bounded_backoff_| has been validated.if (network_estimate_ && capacity_deviation_ratio_threshold_ &&!estimate_bounded_backoff_) {estimated_throughput = std::max(estimated_throughput,network_estimate_->link_capacity_lower);}if (estimated_throughput > low_throughput_threshold_) {//low_throughput_threshold_=0// 将比特率设置为略低于测量吞吐量的值,以消除任何自引起的延迟。new_bitrate = estimated_throughput * beta_;if (new_bitrate > current_bitrate_) {// 当过度使用时,避免增加速率。if (link_capacity_.has_estimate()) {new_bitrate = beta_ * link_capacity_.estimate();}}if (estimate_bounded_backoff_ && network_estimate_) {new_bitrate = std::max(new_bitrate, network_estimate_->link_capacity_lower * beta_);}} else {new_bitrate = estimated_throughput;if (link_capacity_.has_estimate()) {new_bitrate = std::max(new_bitrate, link_capacity_.estimate());}new_bitrate = std::min(new_bitrate, low_throughput_threshold_.Get());}new_bitrate = std::min(new_bitrate, current_bitrate_);if (bitrate_is_initialized_ && estimated_throughput < current_bitrate_) {constexpr double kDegradationFactor = 0.9;if (smoothing_experiment_ &&new_bitrate < kDegradationFactor * beta_ * current_bitrate_) {// If bitrate decreases more than a normal back off after overuse, it// indicates a real network degradation. We do not let such a decrease// to determine the bandwidth estimation period.last_decrease_ = absl::nullopt;} else {last_decrease_ = current_bitrate_ - new_bitrate;}}if (estimated_throughput < link_capacity_.LowerBound()) {// The current throughput is far from the estimated link capacity. Clear// the estimate to allow an immediate update in OnOveruseDetected.link_capacity_.Reset();}

更新link_capacity估计值
根据ack测量的吞吐量更新链路容量估计值,初始时将测量的码率赋予链路容量,
      estimate_kbps_ = (1 - alpha) * estimate_kbps_.value() + alpha * sample_kbps;
其中estimate_kbps_为链路容量,alpha为计算因子alpha=0.05,sample_kbps为计算的码率(探测码率,或ack码率)

void LinkCapacityEstimator::Update(DataRate capacity_sample, double alpha) {double sample_kbps = capacity_sample.kbps();if (!estimate_kbps_.has_value()) {estimate_kbps_ = sample_kbps;} else {estimate_kbps_ = (1 - alpha) * estimate_kbps_.value() + alpha * sample_kbps;}const double norm = std::max(estimate_kbps_.value(), 1.0);double error_kbps = estimate_kbps_.value() - sample_kbps;deviation_kbps_ =(1 - alpha) * deviation_kbps_ + alpha * error_kbps * error_kbps / norm;// 估计链路容量估计的方差,并将方差与链路容量估计进行归一化。// 0.4 ~= 14 kbit/s at 500 kbit/s// 2.5f ~= 35 kbit/s at 500 kbit/sdeviation_kbps_ = rtc::SafeClamp(deviation_kbps_, 0.4f, 2.5f);
}

webrtc中GCC拥塞控制模块之码率控制器AimdRateControl相关推荐

  1. WebRTC GCC拥塞控制算法详解

    1.WebRTC版本 m74 2.GCC的概念 GCC全称Google Congest Control,所谓拥塞控制,就是控制数据发送的速率避免网络的拥塞.可以对比TCP的拥塞控制算法,由于WebRT ...

  2. WebRTC GCC 拥塞控制算法(TFB-GCC)

    目录 一. 前言 二. TFB-GCC原理 1. 接收端记录并反馈收包情况 (1)transport-wide sequence nunmber (2)RTCP RTPFB TW 报文 2. 发送端结 ...

  3. WebRTC GCC 拥塞控制算法(REMB-GCC)

    目录 一. 前言 二. REMB-GCC算法原理 1. 接收端基于延时梯度的带宽预估 (1)Arrival-time filter (2)Overuse Detector (3)Adaptive th ...

  4. WebRTC 基于GCC的拥塞控制(下)

    本文在文章[1]的基础上,从源代码实现角度对WebRTC的GCC算法进行分析.主要内容包括: RTCP RR的数据源.报文构造和接收,接收端基于数据包到达延迟的码率估计,发送端码率的计算以及生效于目标 ...

  5. OBS直播时编码器、码率控制器、分辨率帧率是什么以及如何向第三方推流

    内容摘要:OBS直播时编码器.码率控制器.分辨率.帧率到底是什么,以及OBS向第三方直播平推流时,要注意什么. 图:OBS直播时输出界面参数设定 OBS编码器 1. 软编:x264 使用CPU进行编码 ...

  6. WebRTC中的拥塞控制 一

    对于基于内容分享的Internet应用来说, 拥塞控制都是其无法回避的问题,     而实时多媒体应用的拥塞控制, 相比于其他应用而言, 更具有挑战性.      原因在于: 1.  媒体数据对于 p ...

  7. rtsp 分辨率信息_SDP在RTSP、国标GB28181、WebRTC中的实践

    ​问题背景: 无论你是用微信进行视频电话还是开Zoom视频会议,按照OSI网络七层参考模型,我们进行这些活动之前一般都要先建立一组会话.在建立会话的过程中,我们需要描述下会话的一些信息,描述这种会话能 ...

  8. 取rtsp流数据_SDP在RTSP、国标GB28181、WebRTC中的实践

    问题背景: 无论你是用微信进行视频电话还是开Zoom视频会议,按照OSI网络七层参考模型,我们进行这些活动之前一般都要先建立一组会话.在建立会话的过程中,我们需要描述下会话的一些信息,描述这种会话能力 ...

  9. WebRTC[1]-WebRTC中h264解码过程的源码分析

    目录 前言 正文 <WebRTC工作原理精讲>系列-总览_liuzhen007的专栏-CSDN博客_webrtc 原理前言欢迎大家订阅Data-Mining 的<WebRTC工作原理 ...

  10. WebRTC中的SDP

    SDP简介 在WebRTC的通信过程中,SDP是其中重要的协议.SDP(Session Description Protocol)全称是会话描述协议.主要用于两个会话实体之间的媒体协商.WebRTC引 ...

最新文章

  1. 改名之后的Java EE,现在有什么新进展?
  2. lr_save_string lr_eval_string使用介绍
  3. 生产环境elasticsearch5.0.1和6.3.2集群的部署配置详解
  4. JS实现Echarts的图表保存为图片功能
  5. 服务器用户配置文件在哪里找,管理远程桌面服务的用户配置文件
  6. LeetCode-1两数之和
  7. hibernate4中主要的配置文件配置
  8. Python零基础入门(二)——Python中常见的数据结构[学习笔记]
  9. python---之suplot里面的twinx()函数
  10. 【Java_基础】java中static与final关键字的区别
  11. 如何快速的开发直播App
  12. DbgView不能显示OutputDebugString的输出内容
  13. 服务器无法定位到现有系统分区,真正解决win7 “安装程序无法定位现有系统分区,也无法创建新的系统分区”的方法...
  14. 向前的快捷键_快速提高逼格的电脑快捷键你懂多少?
  15. duang~NBA资讯小程序
  16. 关于前端后台管理系统总结
  17. 判断字母是元音、辅音、半元音
  18. 【环境配置】gazebo搭建仿真机器人研究动态障碍物算法
  19. 暴力字典密码破解之crypt
  20. 开设生物医学工程的高校(按区域划分)

热门文章

  1. SAP中多层扩展有效地bom
  2. 定时器的用法以及pwm的调速
  3. linux模拟手柄输入,Steam 输入手柄模拟最佳实践
  4. vba字典重复key_VBA字典技术整理
  5. office2019卸载组件_禁止电脑随意安装和卸载软件,用这个方法就够了
  6. Kettle5.4调用Redis
  7. STM32CubeMX HAL库+STM32F407+uCOS-III移植
  8. python图像拉伸_python处理图像
  9. 谷歌SEO之如何使用Ahrefs工具选择关键词(2022更新教程)
  10. 【Cinema 4D】物体路径跟随动画