webrtc 服务器 webrtc服务器需要多少带宽
其实webrtc 服务器的问题并不复杂,但是又很多的朋友都不太了解webrtc服务器需要多少带宽,因此呢,今天小编就来为大家分享webrtc 服务器的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
WebRTC 服务器要干些什么
WebRTC的服务器大体分为信令服务器和媒体服务器
WebRTC信令服务器是主要功能是为 WebRTC通讯搭建一个了解彼此能力的通道,交换信息,同步改动.
而媒体服务器就是用来交换媒体,包括对媒体数据的加解密,编解码,带宽和速率控制等功能
不同的 RTP Toplogies对服务器有不同的要求
WebRTC或者说多媒体通信一般有如下的几种拓扑结构:
如果是两个人之间的端到端(P2P)的通信,信令服务器的功能很简单
而由于是点对点的通信,媒体服务器也就不需要了。
如果是 SFU(Selective Forward Unit),那么它的信令服务器除了上述的 SDP媒体参数协商, ICE连接地址交换,还有参加 RTP会话的参加者信息的同步。
多个人之间的会议系统,信令控制会麻烦很多,除了上述两个基本功能之外,还要有
在 RFC4575中有这样的定义
Multiple Control Unit多点控制单元相比 SFU,它有着对于媒体流的 Mix和 translate功能,可以很好地适配传统的通信设备,在实际应用中,一般我们会以 SFU为主, MCU为辅,共同形成一个服务器集群。
在 WebRTC服务器上,我们一般会维护如下的领域对象
领域对象的具体内容从略,一般有如下的 Command或 Event
应用层的事件大约可以分为 5类
具体的有
在一个视频会议中,大家都在向会议室中发布自己的音视频流,也订阅他人的音视频媒体流,所以服务器,特别是 SFU需要维护这样一个 pub-sub发布者和订阅者之间的关系
webrtc和websocket的区别
按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP是应用层的协议。在这三者之间,SPDY和WebSocket都是与HTTP相关的协议,而TCP是HTTP底层的协议。
WebSocket则提供使用一个TCP连接进行双向通讯的机制,包括网络协议和API,以取代网页和服务器采用HTTP轮询进行双向通讯的机制。
本质上来说,WebSocket是不限于HTTP协议的,但是由于现存大量的HTTP基础设施,代理,过滤,身份认证等等,WebSocket借用HTTP和HTTPS的端口。
由于使用HTTP的端口,因此TCP连接建立后的握手消息是基于HTTP的,由服务器判断这是一个HTTP协议,还是WebSocket协议。 WebSocket连接除了建立和关闭时的握手,数据传输和HTTP没丁点关系了。
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)由帧的数据包大小算出
由此可见,我们只需要知道当前帧的长度,发送时间,接收时间以及前一帧的状态,就可以计算出网络使用情况。
接下来具体看一下代码:
[cpp] view
plaincopy
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);
}
[cpp] view
plaincopy
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_;
}
关于webrtc 服务器到此分享完毕,希望能帮助到您。