背景介绍
- BWE 带宽预估,参考 https://blog.csdn.net/CrystalShaw/article/details/82981183 的文章
– 丢包预测:丢包率反应带宽情况
– 延时预测: 组包延时,多个包的到达时间delta的趋势来判断带宽情况
– 从之前GCC拥塞的接收端计算带宽并发送remb 到接收端反馈Transport cc, 由发送端sender来收集来计算带宽
Transport cc
- transport wide cc 是属于feedback反馈机制的一种
PT=RTPFB 205
FMT=15 接收端构造TransportCC报文 rfc transport wide cc - 原理:接收端接收到rtp包后,存储sequence number(这里有翻转)和arrive timestamp,然后每隔一段时间计算出每个包的相对延时,通过transport wide cc 传输。接收端收到后通过一些算法计算延时情况,预估带宽。
janus-gateway的transport wide cc 作为接收端的使用
janus作为发送端没看到对transport cc 做处理。
- 第一步检测offer中的SDP信息中是否包含transport wide cc 信息:
janus_process_incoming_request(){
//offer
int transport_wide_cc_ext_id = janus_rtp_header_extension_get_id(jsep_sdp, JANUS_RTP_EXTMAP_TRANSPORT_WIDE_CC);
handle->stream->do_transport_wide_cc = transport_wide_cc_ext_id > 0 ? TRUE : FALSE;
handle->stream->transport_wide_cc_ext_id = transport_wide_cc_ext_id;
}
- Transport wide sequence numbers header extension
x所有的RTP包额外的增加一个头部扩展项,该扩展项用来表示发送序列号。通过SDP来协商是否打开该扩展项
a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
- Transport Feedback
接收方向媒体发送方定期发送反馈,提供有关接收到的数据包的信息以及它们之间的延迟。反馈信息通过RTCP-Transport-FB反馈给发送端。通过SDP来协商是否启用
a=rtcp-fb:100 transport-cc
- 在janus_ice_cb_nice_recv 接收到rtp包后形成status状态包
- 使用transport cc 后,发送端会在rtp包extension 中扩展 cc相关信息
/* 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ID | L=1 |transport-wide sequence number | zero padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
- 通过
janus_rtp_header_extension_parse_transport_wide_cc
获取transport_seq_num
,获取当前的时间为rtp包的到达时间。加入到stream->transport_wide_received_seq_nums
list中。
- 通过
janus_ice_outgoing_transport_wide_cc_feedback
函数来生成transport ccrtcp包发送。 这个函数由rtcp_source timer 默认一秒调用 - 排序transport_wide_received_seq_nums,计算丢失的包,
janus_rtcp_transport_wide_cc_feedback
生成rtcpbuf 通过janus_ice_relay_rtcp_internal
发送
transport wide cc RTCP协议
- 详细介绍 rfc
base sequence number: 当前包组第一个packet的nbumber
packet status count: 包组数量
reference time: 当前包组第一个packet的time
feedback packet count: 已发送的transport cc packet 数量 用于检测是rtcp否有丢失
Packet Status Symbols
计算出delta的大小,根据大小区分正常small delta 和large/negative packet
The status of a packet is described using a 2-bit symbol:
00 Packet not received
01 Packet received, small delta
10 Packet received, large or negative delta
11 [Reserved]
- janus中体现
packet chunk
- Run Length Chunk 连续相同状态
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T| S | Run Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
T = 0 1bit 表示run length chunk
S 2bit 参考Packet Status Symbols
Run Length 重复包数
- Status Vector Chunk
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T|S| Symbols |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
T = 1 1 bit A one identifies this as a status vector
S 0表示后面14bit只包含 00 Packet not received/01 Packet received, small delta两种状态最大共14个包
1表示后14字节包含正常的Packet Status Symbols,所以最大共7个包
具体代码实现可以参考 janus_rtcp_transport_wide_cc_feedback
函数
发送端的算法处理
可以参考这篇文章
- Packet Arrival Model
WebRTC根据数据包到达的时间延迟,通过到达时间滤波器,估算出网络延迟m(t)
Model the m(i+1) = m(i) + u(i), u(i) is the Gaussion statistic with the zero mean and variance q(i), q(i) is RECOMMANDED equal to 10^-3.
d(i) = m(i) + v(i), v(i) is zero mean white noise var_v = E{v(i)^2}.
z(i) = d(i) – m_hat(i), where m_hat(i) is the estimation of m(i).
m_hat(i) = m_hat(i-1) + z(i) * k(i)
k(i) = (e(i-1) + q(i))/(var_v_hat(i) + e(i-1) + q(i))
e(i) = (1-k(i))*(e(i-1)+q(i))
var_v_hat(i) = max(alpha*var_v_hat(i-1) + (1-alpha)*z(i)^2, 1)
alpha = (1-chi)^(30/1000*f_max), where f_max = max{1/(T(j) – T(j-1)} for j in i-K+1, … , i, chi is the filter coefficient,
typically choose as a number in [0.001, 0.1].
- Over-use Detector
The output of Arrival Time Filter is the delay estimation m(i).
m(i) is compared with the threshold del_var_th(i), An estimate above the threshold is considered as an indication of over-use,
but over-use will be signaled only if over-use has been detected for at least overuse_time_th milliseconds,
however, if m(i) less than m(i-1), overuse will not be signaled.
Similarly, the underuse is detected when m(i) less than -del_var_th(i).
If neigher overuse or underuse is detected, the detector will be in normal state.
del_var_th(i) = del_var_th(i) + (t(i)-t(i-1))*K(i)*(|m(i)| - del_var_th(i-1)),
where del_var_th(is) is RECOMMANDED to clamp to the range [6, 600].
- Rate Control
Delay Based Estimation
R_hat_delay(i) = 1/T * sum(L(j)) for j from 1 to N(i)
A_hat_delay(i) = A_hat_delay(i-1) + max(1000, alpha*expected_packet_size_bits) if under-use
A_hat_delay(i) = beta*R_hat_delay(i), beta is RECOMMANDED to 0.85 if over-use
Loss Based Estimation
Do nothing if loss between 2% ~ 10%
R_hat_loss(i) = R_hat(i-1)*(1 – 0.5*lossRate) if loss is more than 10%
R_hat_lss(i) = R_hat(i-1)*(1+0.08) if loss is less than 2%
Combined Rate Control
R_hat = min(R_hat_loss, A_hat_delay)
REMB : Receiver Estimated Maximum Bitrate,作为接收端
https://www.freehacker.cn/media/tcc-vs-gcc/ WebRTC-GCC两种实现方案对比