【WebRTC】QoS 拥塞控制 GCC 理论 Sender Side BWE 或 REMB

news2024/11/15 7:52:12

介绍

Sender Side Bandwidth Estimation 发送方带宽预估。Sender Side BWE 是新方案,利用的是 RTCP 中的 TransportCC 协议。

Receiver Estimated Maximum Bitrate 接收端预估最大码率。REMB 是旧方案,利用的是 RTCP 中的 REMB 协议。

背景

WebRTC 中的拥塞控制算法有三种:GCC、BBR、PCC。GCC 是 WebRTC 的默认算法,GCC 包含基于 丢包 和 延迟 两种情况的算法。以下所有内容都是 GCC 中的。

拥塞控制的源码在:目录 src/modules/congestion_controller/ 下

GCC 全称 Google Congestion Control。

GCC 由于新旧版本兼容原因 有三种 实现的方式。

  1. 根据 丢包 情况计算带宽。
  2. 根据 延迟 情况在 接收端 计算带宽。旧方案,使用卡尔曼滤波器。
  3. 根据 延迟 情况在 发送端 计算带宽。新方案,使用最小二乘法作线性回归。

为什么要切换方案

也就是新的比旧的好在哪?

Google 给的官方解释是:> https://groups.google.com/g/discuss-webrtc/c/ZyKcu3E9XgA/m/hF0saddeLgAJ

  1. 所有决策逻辑都在一端们会让测试新算法变得简单。
  2. 发送端知道自己发送的数据流是什么类型,可以在发送普通视频和做屏幕广播时选择不同的算法。

当然更实际的好处是:新的方案在应对峰值流量的能力上比旧的好。

基于 丢包 的拥塞控制

基本思想:丢包率小,提高码率;丢包率大,降低码率;丢包率适中,不进行调整。

A s ( t k ) = { A s ( t k − 1 ) ( 1 − 0.5 f l ( t k ) ) f l ( t k ) > 0.1 1.05 ( A s ( t k − 1 ) ) f l ( t k ) < 0.02 A s ( t k − 1 ) o t h e r w i s e A_s(t_k) = \begin{cases} A_s(t_{k-1})(1-0.5f_l(t_k))&f_l(t_k)>0.1\\ 1.05(A_s(t_{k-1}))&f_l(t_k)<0.02\\ A_s(t_{k-1})&otherwise\\ \end{cases} As(tk)=As(tk1)(10.5fl(tk))1.05(As(tk1))As(tk1)fl(tk)>0.1fl(tk)<0.02otherwise

A s ( t k ) A_s(t_k) As(tk) 即为 t k t_k tk 时刻的带宽估计值, f l ( t k ) f_l(t_k) fl(tk) 即为 t k t_k tk 时刻的丢包率。

基于 延迟 的拥塞控制

最小二乘法求线性回归方程

基本思想:以时间为x轴,延迟梯度为y轴。对其中的点做一元线性拟合求斜率。斜率越大说明网络越拥塞。

一元线性方程: y = a x + b y = ax + b y=ax+b

求线性回归方程系数a: a = ∑ i = 1 n ( x i − x ˉ ) ( y i − y ˉ ) ∑ i = 1 n ( x i − x ˉ ) 2 a=\frac{\sum_{i=1}^{n}{(x_i-\bar{x})(y_i-\bar{y})}}{\sum_{i=1}^{n}{(x_i-\bar{x})^{2}}} a=i=1n(xixˉ)2i=1n(xixˉ)(yiyˉ)

关键技术

InterArrival 到达间隔

一帧视频往往是由多个 RTP 包发送的,所以首先将 RTP 的数据按照 5ms 分组,之后对相邻的两组数据包进行计算。

5ms 是 GCC 草案中提出的:The Pacer sends a group of packets to the network every burst_time interval. RECOMMENDED value for burst_time is 5 ms.

请添加图片描述

理论上,WebRTC 是按照包组为单位进行计算的。但为理解的方便,后面将包组统一理解为一个数据包。

计算内容包括:

  1. 发送时刻差: △ t i m e s t a m p = T 2 − T 1 △timestamp = T_2-T_1 timestamp=T2T1
  2. 接收时刻差: △ a r r i v a l = t 2 − t 1 △arrival = t_2-t_1 arrival=t2t1
  3. 数据包大小差: △ s i z e = G 2 − G 1 △size = G_2-G_1 size=G2G1 虽然很多博文里都提到计算数据包大小差,但实际后面都没有用到。

TrendlineEstimator 趋势线预估

通过上述的三个值,可以计算:

一个包的延迟: d e l a y i = △ a r r i v a l − △ t i m e s t a m p delay_i = △arrival - △timestamp delayi=arrivaltimestamp

每个包累计的延迟: a c c d e l a y i = ∑ d e l a y 0 + d e l a y 1 + . . . + d e l a y i acc_{delay_i} = \sum delay_0 + delay_1 + ... + delay_i accdelayi=delay0+delay1+...+delayi

WebRTC 中对累计的延迟做了平滑处理,也就是取了之前的累计延迟的 90%,取了当前包累计延迟的 10% ,从而减少了变化幅度。 s m o d e l a y i = α ∗ s m o d e l a y i − 1 + ( 1 − α ) ∗ a c c d e l a y i smo_{delay_i} = α * smo_{delay_{i-1}} + (1-α) * acc_{delay_i} smodelayi=αsmodelayi1+(1α)accdelayi 这里 α = 0.9 α = 0.9 α=0.9

现在有了平滑后的延迟梯度,有了每个包的到达时间。那么时间为 x 轴,延迟梯度为 y 轴。

  • 如果随着时间的变化 延迟梯度增加,也就是 y = a x + b y = ax + b y=ax+b 这条线的斜率 a > 0 a > 0 a>0,说明网络情况差。
  • 如果随着时间的变化 延迟梯度保持不变,也就是 y = a x + b y = ax + b y=ax+b 这条线的斜率 a = 0 a = 0 a=0,说明网络稳定。
  • 如果随着时间的变化 延迟梯度减小,也就是 y = a x + b y = ax + b y=ax+b 这条线的斜率 a < 0 a < 0 a<0,说明网络情况在好转。

WebRTC 中使用最小二乘算法计算出了 a a a 的值。具体计算过程,并不建议深入阅读,可能会把自己绕进去。

阿里云(WebRTC 拥塞控制 | Trendline 滤波器) 个人觉得算法这部分将的比别的好 https://developer.aliyun.com/article/781509

剩余的公式如下,最好别看:

剩余计算公式:

对 包的累计延迟 和 包的平滑延迟 求平均:

x i = ∑ d e l a y 0 + d e l a y 1 + . . . + d e l a y i i x_i = \frac{\sum delay_0 + delay_1 + ... + delay_i}{i} xi=idelay0+delay1+...+delayi y i = ∑ s m o d e l a y 0 + s m o d e l a y 1 + . . . + s m o d e l a y i i y_i = \frac{\sum smo_{delay_0} + smo_{delay_1} + ... + smo_{delay_i}}{i} yi=ismodelay0+smodelay1+...+smodelayi

每个包组的传输时间为: t r a n s i = t i − f i r s t _ a r r i v a l i trans_i = t_i - first\_arrival_i transi=tifirst_arrivali

趋势斜率分子: n u m e r a t o r i = ∑ k = 0 i ( t r a n s k − x k ) ∗ ( s m o d e l a y k − y k ) numerator_i = \sum\limits_{k=0}^i(trans_k - x_k) * (smo_{delay_k} - y_k) numeratori=k=0i(transkxk)(smodelaykyk)

趋势斜率分母: d e n o i n a t o r i = ∑ k = 0 i ( t r a n s k − x k ) 2 denoinator_i = \sum\limits_{k=0}^i(trans_k - x_k)^2 denoinatori=k=0i(transkxk)2

趋势斜率为: t r e n d l i n e i = n u m e r a t o r i d e n o i n a t o r i trendline_i = \frac{numerator_i}{denoinator_i} trendlinei=denoinatorinumeratori

Overuse Detector 过载检测器

上述步骤已经计算出斜率 a a a ,过载检测器就会利用 a a a 与 阈值 γ γ γ 进行比较,从而决策当前网络所处状态。

由于实际计算出的 a a a 非常小,所以 WebRTC 对其进行了放大,会用 a ∗ 包 组 数 量 ∗ 增 益 系 数 a * 包组数量 * 增益系数 a

而 阈值 也是需要动态计算的,阈值计算公式: γ i = γ i − 1 + Δ t i ∗ k i ∗ ( ∣ m i ∣ − γ i − 1 ) γ_i = γ_{i-1} + Δt_i * k_i * (|m_i| - γ_{i-1}) γi=γi1+Δtiki(miγi1)

Δ t i Δt_i Δti 表示 距离上一次更新阈值的时间。 k i k_i ki 表示 一个系数。 m i m_i mi 表示 上面说的被放大后的 a a a

k i k_i ki 的取值规则如下: k i = { k d = 0.039 ∣ m i ∣ < γ i − 1 k u = 0.0087 o t h e r w i s e k_i = \begin{cases} k_d=0.039&|m_i|<γ_{i-1}\\ k_u=0.0087&otherwise\\ \end{cases} ki={kd=0.039ku=0.0087mi<γi1otherwise k d k_d kd k u k_u ku 分别决定阈值增加以及减小的速度。

WebRTC 将当前网络所处状态分为三个。

  • overuse: m ( t i ) > γ ( t i ) m(ti) > γ(ti) m(ti)>γ(ti) 并且持续时间超过 100ms
  • underuse: m ( t i ) < − γ ( t i ) m(ti) < -γ(ti) m(ti)<γ(ti) 并且持续时间超过 100ms
  • normal: − γ ( t i ) < m ( t i ) < γ ( t i ) -γ(ti) < m(ti) < γ(ti) γ(ti)<m(ti)<γ(ti)

在这里插入图片描述

AIMD Rate Controller 码率控制器

AIMD 的全称是 Additive Increase Multiplicative Decrease,意思是:和式增加,积式减少。直白点就是:增加的时候用加法,减少的时候用乘法。增加的时候慢一点,降低的时候快一点。

但是,AIMD 是 TCP 底层的码率调节概念,WebRTC 没有完全照搬,而是有自己一套算法。

该模块同样也维护了一个状态机:码流控制状态机。

保存当前码流改变的状态:Decrease 正在降低码率,Hold 正在保持码率,Increase 正在增加码率。

请添加图片描述

计算出当前网络状态后,根据码流控制器状态机,按照 和式增加,积式减少 的原则,估算出下一时刻发送端应该发送码流的大小。

A r ( t i ) = { α A r ( t i − 1 ) α = 1.08   σ = I n c r e a s e β R r ( t i ) β = 0.85   σ = D e c r e a s e A r ( t i − 1 ) σ = H o l d A_r(t_i) = \begin{cases} αA_r(t_{i-1})&α = 1.08 \ σ=Increase\\ βR_r(t_i)&β=0.85 \ σ=Decrease\\ A_r(t_{i-1})&σ=Hold\\ \end{cases} Ar(ti)=αAr(ti1)βRr(ti)Ar(ti1)α=1.08 σ=Increaseβ=0.85 σ=Decreaseσ=Hold

当前是 Increase 状态,如果吞吐量 R r R_r Rr 和 链路容量(历史吞吐量的指数平滑)相差较大,则对当前码率(上次更新的码率)使用乘性增加;如果相差较小,则使用加性增加。

当前是 Decrease 状态,直接将当前吞吐量 R r R_r Rr * 0.85 作为新码率,如果该码率可能仍大于上一个调整后的码率,则使用链路容量 R r R_r Rr * 0.85 作为新码率。

据此,得到基于延时预估出来的码率。

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

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

相关文章

C++自动定义的成员函数

C自动提供了下面这些成员函数&#xff1a; 默认构造函数&#xff0c;如果没有定义构造函数默认析构函数&#xff0c;如果没有定义复制构造函数&#xff0c;如果没有定义赋值运算符&#xff0c;如果没有定义地址运算符&#xff0c;如果没有定义 另有移动构造函数和移动赋值运算…

业余时间可以做什么副业,什么副业可以赚钱

大家好&#xff0c;我是蝶衣王的小编 现在的年轻人大多是过着朝九晚五的社畜生活&#xff0c;但是朝九晚五就意味着工资可能不是很高&#xff0c;生活压力会比较大&#xff0c;很多人就会想能不能利用业余时间做一些副业呢​&#xff1f;答案当然是可以的 那么&#xff0c;什…

售前工程师工作内幕揭秘:面试实战技巧

售前工程师工作内幕揭秘&#xff1a;面试实战技巧前言一、售前面试问题&#xff0c;基本就下面这些二、售前工程师岗位普遍误区三、售前工程师核心技能四、面试中&#xff0c;主动出击&#xff0c;才是王道五、对行业的了解是做好售前的基础前言 看到网上很多关于售前工程师面…

git分支上的tag

在发布一个版本时&#xff0c;我们通常先在版本库中打一个标签&#xff0c;这样&#xff0c;就唯一确定了打标签时刻的版本。将来无论什么时候&#xff0c;取某个标签的版本&#xff0c;就是把那个打标签的时刻的历史版本取出来。所以&#xff0c;标签也是版本库的一个快照。在…

Spring的创建与使用

⭐️前言⭐️ 在了解了Spring的核心与设计思想以后,下边就是Spring的具体使用&#xff0c;这篇文章主要介绍Spring项目的创建和Bean对象的存放与取出。 &#x1f349;博客主页&#xff1a; &#x1f341;【如风暖阳】&#x1f341; &#x1f349;精品Java专栏【JavaSE】、【备…

Kong(二)通过案例快速了解使用

一 Kong安装目录结构的说明 后续看看里面有啥 /usr/local/bin --> kong命令的路径/etc/kong/ --> kong默认会寻找配置文件/usr/local/kong --> Kong的日志 -->/usr/local/kong/logs/usr/local/lib/lua/5.1/usr/local/lib/…

[附源码]Python计算机毕业设计Django人事系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【Leetcode】拿捏链表(五)——138. 复制带随机指针的链表

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 138. 复制带随机指针的链表 138. 复制带随机指针的链表 138. 复制带随…

MySQL8.0 OCP最新版1Z0-908认证考试题库整理-005

原题 Choose four.A newly deployed replication master database has a 10/90 read to write ratio.The complete dataset is currently 28G but will never fluctuate beyond -10%.The database storage system consists of two locally attached PCI- E Enterprise grade di…

单纯形法的补充与代码实现

线性规划中&#xff0c;我们介绍了三种求解算法——单纯形法、对偶理论和内点法。传送门&#xff1a;线性规划之单纯形法 线性规划的对偶理论 线性规划之内点法其中单纯形法要建立在标准型上&#xff0c;并且开始迭代要求有一个基本可行解。如果系数矩阵A规模较大&#xff0c;有…

阿里云OSS依赖无法导入的问题

版本背景&#xff1a;springboot:2.4.12&#xff0c;spring-cloud:2020.0.1 在使用阿里云对象存储OSS服务时候&#xff0c;根据官方参考文档&#xff1a;aliyun-spring-boot/aliyun-spring-boot-samples/aliyun-oss-spring-boot-sample at master alibaba/aliyun-spring-boot…

第十五章 图的BFS与拓扑序列

图的BFS与拓扑序列一、图的BFS1、思路2、模板&#xff08;1&#xff09;问题&#xff08;2&#xff09;代码模板&#xff08;3&#xff09;代码解析二、拓扑序列引入&#xff1a;1、什么是拓扑序列&#xff1f;2、模板&#xff1a;&#xff08;1&#xff09;问题&#xff1a;&a…

一张图搞懂微服务架构设计

前言 当前&#xff0c;微服务架构在很多公司都已经落地实施了&#xff0c;下面用一张图简要概述下微服务架构设计中常用组件。不能说已经使用微服务好几年了&#xff0c;结果对微服务架构没有一个整体的认知&#xff0c;一个只懂搬砖的程序员不是一个好码农! 流量入口Nginx 在…

Awesome Uplift Modeling【如何学习因果推断、因果机器学习和Uplift建模?All in here】

Awesome-Uplift-Model How to Apply Causal ML to Real Scene Modeling&#xff1f;How to learn Causal ML&#xff1f; Github项目地址&#xff1a;&#x1f449;https://github.com/JackHCC/Awesome-Uplift-Model&#x1f448; &#x1f449;https://github.com/JackHCC/…

汇编原理理论知识复习

书上重点内容 本篇博客整理老师课上强调的重点理论知识&#xff0c;以便复习备考&#xff0c;如有错误欢迎指正。 这门课主要讲CPU芯片与其他芯片&#xff08;内存芯片和I/O接口芯片&#xff09;之间交互。 一条指令的执行过程&#xff1a;取指&#xff08;从主存取到CPU寄…

(五)Vue之data与el的两种写法

文章目录el的两种写法data的两种写法Vue学习目录 上一篇&#xff1a;&#xff08;四&#xff09;Vue之数据绑定 容器&#xff1a; <div id"root"><h1>hello,{{name}}</h1></div>el的两种写法 (1).new Vue时候配置el属性。 new Vue({el:#r…

【C语言航路】第六站:指针初阶

目录 一、指针是什么 二、指针和指针类型 1.指针类型的意义 2.指针-整数 3.指针解引用 三、野指针 1.野指针的成因 &#xff08;1&#xff09;指针未初始化 &#xff08;2&#xff09;指针越界访问 &#xff08;3&#xff09;指针指向的空间释放 2.如何规避野指针 &a…

伸手运动想象训练与伸手抓取想象的关系

本研究旨在确定为期4周的目标导向性伸手&#xff08;抓取任务&#xff09;的运动想象训练&#xff08;MIT&#xff09;是否会以相同的方式影响伸手&#xff08;MIR&#xff09;和抓取&#xff08;MIG&#xff09;运动想象的皮质活动。试验过程中&#xff0c;我们在健康的年轻参…

基于未知环境下四旋飞行器运动规划应用研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

QT QDoubleSpinBox 浮点计数器控件(使用详解)

本文详细的介绍了QDoubleSpinBox控件的各种操作&#xff0c;例如&#xff1a;新建界面、获取数值、设置前后缀、设置最大/小值、设置显示精度、关联信号槽、优化信号、关联控件、文件源码、样式表等等操作。 本文是QT控件使用详解的第十五篇 QT QDoubleSpinBox 浮点计数器控件(…