webrtc中的带宽自适应算法
webrtc中的带宽自适应算法分为两种:
1, 发端带宽控制, 原理是由rtcp中的丢包统计来动态的增加或减少带宽,在减少带宽时使用TFRC算法来增加平滑度。
2, 收端带宽估算, 原理是并由收到rtp数据,估出带宽; 用卡尔曼滤波,对每一帧的发送时间和接收时间进行分析, 从而得出网络带宽利用情况,修正估出的带宽。
两种算法相辅相成, 收端将估算的带宽发送给发端, 发端结合收到的带宽以及丢包率,调整发送的带宽。
下面具体分析两种算法:
2, 接收端带宽估算算法分析
结合文档http://tools.ietf.org/html/draft-alvestrand-rtcweb-congestion-02以及源码webrtc/modules/remote_bitrate_estimator/overuse_detector.cc进行分析
带宽估算模型: d(i) = dL(i) / c + w(i) d(i)两帧数据的网络传输时间差,dL(i)两帧数据的大小差, c为网络传输能力, w(i)是我们关注的重点, 它主要由三个因素决定:发送速率, 网络路由能力, 以及网络传输能力。w(i)符合高斯分布, 有如下结论:当w(i)增加是,占用过多带宽(over-using);当w(i)减少时,占用较少带宽(under-using);为0时,用到恰好的带宽。所以,只要我们能计算出w(i),即能判断目前的网络使用情况,从而增加或减少发送的速率。
算法原理:即应用kalman-filters
theta_hat(i) = [1/C_hat(i) m_hat(i)]^T // i时间点的状态由C, m共同表示,theta_hat(i)即此时的估算值
z(i) = d(i) - h_bar(i)^T * theta_hat(i-1) //d(i)为测试值,可以很容易计算出, 后面的可以认为是d(i-1)的估算值, 因此z(i)就是d(i)的偏差,即residual
theta_hat(i) = theta_hat(i-1) + z(i) * k_bar(i) //好了,这个就是我们要的结果,关键是k值的选取,下面两个公式即是取k值的,具体推导见后继博文。
E(i-1) * h_bar(i)
k_bar(i) = --------------------------------------------
var_v_hat + h_bar(i)^T * E(i-1) * h_bar(i)
E(i) = (I - K_bar(i) * h_bar(i)^T) * E(i-1) + Q(i) // h_bar(i)由帧的数据包大小算出
由此可见,我们只需要知道当前帧的长度,发送时间,接收时间以及前一帧的状态,就可以计算出网络使用情况。
接下来具体看一下代码:
- void OveruseDetector::UpdateKalman(int64_t t_delta,
- double ts_delta,
- uint32_t frame_size,
- uint32_t prev_frame_size) {
- const double min_frame_period = UpdateMinFramePeriod(ts_delta);
- const double drift = CurrentDrift();
- // Compensate for drift
- const double t_ts_delta = t_delta - ts_delta / drift; //即d(i)
- double fs_delta = static_cast<double>(frame_size) - prev_frame_size;
- // Update the Kalman filter
- const double scale_factor = min_frame_period / (1000.0 / 30.0);
- E_[0][0] += process_noise_[0] * scale_factor;
- E_[1][1] += process_noise_[1] * scale_factor;
- if ((hypothesis_ == kBwOverusing && offset_ < prev_offset_) ||
- (hypothesis_ == kBwUnderusing && offset_ > prev_offset_)) {
- E_[1][1] += 10 * process_noise_[1] * scale_factor;
- }
- const double h[2] = {fs_delta, 1.0}; //即h_bar
- const double Eh[2] = {E_[0][0]*h[0] + E_[0][1]*h[1],
- E_[1][0]*h[0] + E_[1][1]*h[1]};
- const double residual = t_ts_delta - slope_*h[0] - offset_; //即z(i), slope为1/C
- const bool stable_state =
- (BWE_MIN(num_of_deltas_, 60) * fabsf(offset_) < threshold_);
- // We try to filter out very late frames. For instance periodic key
- // frames doesn't fit the Gaussian model well.
- if (fabsf(residual) < 3 * sqrt(var_noise_)) {
- UpdateNoiseEstimate(residual, min_frame_period, stable_state);
- } else {
- UpdateNoiseEstimate(3 * sqrt(var_noise_), min_frame_period, stable_state);
- }
- const double denom = var_noise_ + h[0]*Eh[0] + h[1]*Eh[1];
- const double K[2] = {Eh[0] / denom,
- Eh[1] / denom}; //即k_bar
- const double IKh[2][2] = {{1.0 - K[0]*h[0], -K[0]*h[1]},
- {-K[1]*h[0], 1.0 - K[1]*h[1]}};
- const double e00 = E_[0][0];
- const double e01 = E_[0][1];
- // Update state
- E_[0][0] = e00 * IKh[0][0] + E_[1][0] * IKh[0][1];
- E_[0][1] = e01 * IKh[0][0] + E_[1][1] * IKh[0][1];
- E_[1][0] = e00 * IKh[1][0] + E_[1][0] * IKh[1][1];
- E_[1][1] = e01 * IKh[1][0] + E_[1][1] * IKh[1][1];
- // Covariance matrix, must be positive semi-definite
- assert(E_[0][0] + E_[1][1] >= 0 &&
- E_[0][0] * E_[1][1] - E_[0][1] * E_[1][0] >= 0 &&
- E_[0][0] >= 0);
- slope_ = slope_ + K[0] * residual; //1/C
- prev_offset_ = offset_;
- offset_ = offset_ + K[1] * residual; //theta_hat(i)
- Detect(ts_delta);
- }
- BandwidthUsage OveruseDetector::Detect(double ts_delta) {
- if (num_of_deltas_ < 2) {
- return kBwNormal;
- }
- const double T = BWE_MIN(num_of_deltas_, 60) * offset_; //即gamma_1
- if (fabsf(T) > threshold_) {
- if (offset_ > 0) {
- if (time_over_using_ == -1) {
- // Initialize the timer. Assume that we've been
- // over-using half of the time since the previous
- // sample.
- time_over_using_ = ts_delta / 2;
- } else {
- // Increment timer
- time_over_using_ += ts_delta;
- }
- over_use_counter_++;
- if (time_over_using_ > kOverUsingTimeThreshold //kOverUsingTimeThreshold是gamma_2, gamama_3=1
- && over_use_counter_ > 1) {
- if (offset_ >= prev_offset_) {
- time_over_using_ = 0;
- over_use_counter_ = 0;
- hypothesis_ = kBwOverusing;
- }
- }
- } else {
- time_over_using_ = -1;
- over_use_counter_ = 0;
- hypothesis_ = kBwUnderusing;
- }
- } else {
- time_over_using_ = -1;
- over_use_counter_ = 0;
- hypothesis_ = kBwNormal;
- }
- return hypothesis_;
- }
参考文档:
- http://www.swarthmore.edu/NatSci/echeeve1/Ref/Kalman/ScalarKalman.html
- http://tools.ietf.org/html/draft-alvestrand-rtcweb-congestion-02
webrtc中的带宽自适应算法相关推荐
- WebRTC中AECM算法简介
1,算法介绍以及整体框架 1.1算法整体框架 AECM 属于 WebRTC 语音处理引擎(Voice Engine)的子模块,是为移动设备专门设计的回声消除处理模块,其内部有根据芯片类型进行汇编指令级 ...
- webrtc中的网络反馈与控制
转自编风网 http://befo.io/4206.html 一.引言 站在风口上,猪都能飞起来.雷布斯的这句名言,已经被大家传的家喻户晓了,说起当下站在风口上的猪,除了丁老板的未央猪,这头实实在在的 ...
- 【转载】 webrtc中的网络反馈与控制
原地址:http://www.befoio.com/4206.html 一.引言 站在风口上,猪都能飞起来.雷布斯的这句名言,已经被大家传的家喻户晓了,说起当下站在风口上的猪,除了丁老板的未央猪,这头 ...
- webrtc中的网络反馈与控制【转】
来自: http://befo.io/4206.html 一.引言 站在风口上,猪都能飞起来.雷布斯的这句名言,已经被大家传的家喻户晓了,说起当下站在风口上的猪,除了丁老板的未央猪,这头实实在在的猪, ...
- 音视频框架-webrtc中的网络反馈与控制
webrtc中的网络反馈与控制 引言 站在风口上,猪都能飞起来.雷布斯的这句名言,已经被大家传的家喻户晓了,说起当下站在风口上的猪,除了丁老板的未央猪,这头实实在在的猪,视频直播应该可以算一个.今年各 ...
- 弱网优化,GCC 动态带宽评估算法(内附详细公式)
通过上次的<RTC 系统音视频传输弱网对抗技术概览>,我们知道 RTC 的三大核心指标为实时性.清晰度.流畅度.在整个通话过程中核心表现达标,才能给用户一个基本的良好体验.关注[融云全球互 ...
- WebRTC中的拥塞控制 一
对于基于内容分享的Internet应用来说, 拥塞控制都是其无法回避的问题, 而实时多媒体应用的拥塞控制, 相比于其他应用而言, 更具有挑战性. 原因在于: 1. 媒体数据对于 p ...
- WebRTC 中 SDP 信息解析
TL;NR 更详细的 WebRTC SDP 解析请参考 https://tools.ietf.org/html/draft-ietf-rtcweb-sdp-14 0x00 前言 SDP (Sessio ...
- [4G5G专题-26]:架构-什么是部分带宽BWP, 不对称载波带宽、UE带宽自适应?
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:CSDN 目录 第1章 LTE系统的对称载波带宽 1.1 LTE的带宽 1.2 不同用户共享相同的 ...
最新文章
- ACM学习历程—HDU5586 Sum(动态规划)(BestCoder Round #64 (div.2) 1002)
- 小程序中textarea点击按钮事件
- NTP时间服务器介绍
- php解析url的三种方法举例
- VMware虚拟机中ubuntu的磁盘怎么扩容
- 设计模式学习笔记------简单工厂
- Paip.YXSHOP易想商场功能模块说明
- 关于快逸报表超链接的使用方式。
- 超浪漫-HTML5生日祝福网页制作 ❤粉色少女系列为你定制❤ HTML+CSS+JavaScript
- SIFT算法学习总结
- Talib macd函数探究
- CSS动画和JS动画对比
- 局域计算机网络,【计算机网络】局域网小知识点
- 台式计算机启动叫两声,电脑开机2声短报警什么情况
- Unity碰撞和碰撞检测
- 茅山煤矿轶事(三)--拖拉机
- 《Android Studio开发实战》学习(六)- 下拉框
- CSS--BEM风格介绍
- 【OpenCV-Python】教程:1-2 视频读取显示保存
- 大数据 | Spark on K8S 在有赞的实践
热门文章
- locust工具学习笔记(三)-Tasks属性、tag修饰符、TaskSet类
- python ppt 图片_python ppt转图片
- (28)Verilog实现倍频【方法三】
- 典型的计算机网络安全技术有哪些,网络安全(计算机网络安全技术有哪些)
- 陶哲轩实分析习题8.3.4
- 9*9数独——C++实现
- [附源码]Node.js计算机毕业设计大学生学科竞赛管理系统Express
- postgis——几何图形创建使用
- 几何光学基础(1):基本定律
- 蓝鸽服务器崩溃怎样从装系统,系统崩溃如何重装系统?