拥塞控制总览 · GoogCC 与该发多快
该发多快?发太快网络堵、太慢浪费。WebRTC 的答案是 GoogCC——一个跑在发送端的拥塞控制器。这一章讲清它的双控制器结构(延迟based + 丢包based 取小)、以 Transport-CC 反馈为输入、产出目标码率的闭环,以及 GoogCcNetworkController 这个总成。
拥塞控制总览 · GoogCC 与该发多快
第 4 部分反复逼近一个问题:到底该发多快? 这是实时通信最难、也最能拉开体验差距的部分——估准了,烂网也能流畅;估错了,好网也卡成 PPT。WebRTC 的答案是一套叫 GoogCC(Google Congestion Control) 的算法,在 modules/congestion_controller/goog_cc/。第 5 部分就拆解它。
目标:贴着网络容量发
拥塞控制要解的,是一个动态平衡:
两个信号,两个控制器
GoogCC 用两种信号判断拥塞,对应两个控制器——这是它的核心结构:
GoogCC 同时跑「延迟based」和「丢包based」两个带宽估计,取两者的较小值。
- 延迟based(delay-based) —— 看包的延迟趋势。延迟在涨,说明网络缓冲区在排队、拥塞将至——在丢包之前就预警。这是主控制器,反应快、灵敏。
- 丢包based(loss-based) —— 看丢包率。丢包多,说明已经发过量了。它更滞后(丢包是拥塞的结果而非先兆),但更确凿,作为兜底。
取小:两个估计谁更保守听谁的——延迟说“该降”就降,哪怕还没丢包。为什么要两个?因为单靠丢包太迟(等丢包就晚了),单靠延迟在某些网络(如有主动丢包的链路)不够。两者结合,既能提前反应,又有丢包兜底。这是 GoogCC 相比早期「只看丢包」算法的关键进步。
总成:GoogCcNetworkController
把这些拼在一起的,是 GoogCcNetworkController(modules/congestion_controller/goog_cc/goog_cc_network_control.h),它实现 NetworkControllerInterface。看它持有的成员,整个第 5 部分的地图就出来了:
// goog_cc_network_control.h(节选成员)
std::unique_ptr<DelayBasedBwe> delay_based_bwe_; // 延迟based 估计
// LossBasedBweV2 // 丢包based 估计
const std::unique_ptr<ProbeController> probe_controller_; // 主动探测
congestion_window_pushback_controller_; // 拥塞窗口
// acknowledged_bitrate_estimator // 实际吞吐估计
NetworkControlUpdate OnTransportPacketsFeedback(...); // 吃反馈,吐决策| 成员 | 干什么 | 本教程 |
|---|---|---|
DelayBasedBwe | 延迟趋势估带宽(含 trendline + over-use) | 下一章 |
LossBasedBweV2 | 丢包估带宽 | 第 5 部分 |
ProbeController | 主动发探测包试探更高带宽 | 第 5 部分 |
CongestionWindow... | 限制在途数据量 | 第 5 部分 |
| acknowledged bitrate | 估实际到达的吞吐 | 第 5 部分 |
核心入口是 OnTransportPacketsFeedback——它吃 Transport-CC 反馈(每个包何时到的),吐出 NetworkControlUpdate(新的目标码率、pacing 速率等决策)。一次反馈进来,一轮估计与决策产出,闭环就此转动。
在哪运行
呼应反馈那章:GoogCC 跑在发送端(它信息最全——同时知道发送时间和反馈来的到达时间)。它是可替换的——PeerConnectionFactoryDependencies 的 network_controller_factory 就是换拥塞控制算法的口子。GoogCC 是默认实现,但你能塞自己的。它归 RtpTransportControllerSend(第 9 部分)调度。
小结与下一章
GoogCC(modules/congestion_controller/goog_cc/)是 WebRTC 的拥塞控制,目标是让发送速率贴着看不见、时刻变的网络带宽。它用两个信号:延迟based(主控,看延迟趋势,丢包前预警)+ 丢包based(兜底,看丢包),取较小值。总成 GoogCcNetworkController 持有 DelayBasedBwe、LossBasedBweV2、ProbeController、拥塞窗口等,核心入口 OnTransportPacketsFeedback(吃反馈吐决策)。跑在发送端,可替换。
主控制器是延迟based——它怎么从一堆包的到达时间里,看出「延迟在涨、拥塞将至」?下一章深入 trendline 与 over-use detector。👉 延迟based 带宽估计。
参考资料
- [1] libwebrtc 源码.
modules/congestion_controller/goog_cc/goog_cc_network_control.h/.cc(GoogCcNetworkController、OnTransportPacketsFeedback)。 - [2] libwebrtc 源码.
api/transport/network_control.h(NetworkControllerInterface)。 - [3] Holmer et al.「A Google Congestion Control Algorithm for Real-Time Communication」(IETF draft)。