带宽探测 · 主动试探能不能更快
光被动测量,涨得太慢——通话开始或网络变好时,得主动发探测包快速试探可用带宽。这一章读 goog_cc 的 ProbeController:探测怎么用成串的包测出瞬时吞吐、padding 与 RTX 两种探测手段,以及探测为什么能让码率快速爬坡。
带宽探测 · 主动试探能不能更快
延迟based的 AIMD 加性增很稳,但也很慢——小步慢涨,要好久才能爬到高带宽。通话刚开始(从零起步)或网络突然变好时,慢涨意味着画质半天上不来。所以 GoogCC 还有一招主动的:带宽探测(probing),由 goog_cc/probe_controller.h 的 ProbeController 负责。
思路:成串发包,看它们怎么到
探测 = 故意在短时间内发一串(cluster)包,看它们到达接收端时被“压”成什么样,从而直接测出瞬时可用带宽。 原理:如果你以 5 Mbps 的速率发一串包,而链路只有 3 Mbps,这串包会在瓶颈处排队、被拉开间隔——到达端一算它们的到达速率,就知道「实际只能跑 3 Mbps」。反之若它们几乎原速到达,说明链路至少有 5 Mbps,可以放心涨上去。
这比 AIMD 慢慢试快得多:AIMD 要很多个 RTT 一点点涨,探测一串包、一个来回就能测出「能不能到 5 Mbps」,让码率直接跳上去。代价是探测包本身占带宽(万一链路不够,这串包还加重了瞬时拥塞),所以要用得克制——只在该探测的时机探。
什么时候探测
ProbeController 决定何时发探测,典型时机:
- 通话启动 —— 从一个初始猜测(如 300 kbps)快速爬坡到真实带宽。没有探测,新通话的画质要好几秒才能起来;有探测,一两秒就能冲上去。
- 码率被降后网络恢复 —— 之前因拥塞降了码率,现在延迟 / 丢包都好转,探测一下「是不是能涨回去了」,避免长期被压在低码率。
- 达到当前估计上限 —— AIMD 已经涨到当前估计的天花板,探测「天花板之上还有没有空间」。
探测包哪来:padding 与 RTX
探测要发「额外的包」,这些包哪来?PT 分配那章提过,g3doc/rtp.md 讲了两种手段:
探测让码率快速爬坡
有了探测,码率曲线的形状就好看多了:
探测负责“快速跳到大致水平”,AIMD 负责“精细微调”——一个粗调快、一个细调稳,配合起来,码率既能快速起来、又能稳定收敛。这是 GoogCC 用户体验好的一大原因:视频通话接通没几秒画质就清晰了,靠的正是探测的快速爬坡。
小结与下一章
带宽探测主动发一串包、测它们的到达速率,直接测出瞬时可用带宽——比 AIMD 慢涨快得多。ProbeController 在通话启动、码率恢复、触及上限等时机探测。探测包用 padding(浪费、量大)或 RTX(重发旧包,兼修丢包,更优)。探测快速跳档 + AIMD 精细微调,让码率又快又稳地贴住网络容量。
估计出了目标码率,但包不能一股脑猛发——那会造成瞬时拥塞。得平滑地、按节奏吐出去,这是 pacing 的活。下一章。👉 Pacing 平滑发包。
参考资料
- [1] libwebrtc 源码.
modules/congestion_controller/goog_cc/probe_controller.h、probe_bitrate_estimator.h。 - [2] libwebrtc 源码.
g3doc/rtp.md(padding / RTX 探测对比)。 - [3] IETF「GoogCC」draft —— probing 部分。