WebRTC Pacer
Abstract |
WebRTC Pacer 发送节奏控制 |
Authors |
Walter Fan |
Status |
v1.0 |
Updated |
2026-03-20 |
概述
Pacer(发送节奏控制器)是 WebRTC 拥塞控制中的关键组件。 它的核心作用是**将突发的编码输出平滑为均匀的发送速率**,避免网络瞬时拥塞。
没有 Pacer 的话,编码器输出一个关键帧(可能 50KB+)会一次性将所有 RTP 包发送出去, 造成网络突发拥塞和丢包。Pacer 则将这些包排入队列,按照目标比特率匀速发送。
编码器输出(突发) Pacer 输出(平滑)
┃█████████████┃ ┃██ ██ ██ ██ ██ ██ ██┃
┃ ┃ ┃ ┃
┃ ████ ┃ ┃██ ██ ██ ██ ┃
┃ ██ ██ ┃ ──► ┃██ ██ ██ ██ ┃
┃██ ██ ┃ ┃██ ██ ██ ██ ┃
━━━━━━━━━━━━━━━ 时间 ━━━━━━━━━━━━━━━━━━━━━━ 时间
在 WebRTC 中的位置
编码器 → RTP 打包 → Pacer 队列 → SRTP 加密 → ICE/UDP 发送
↑
GCC 带宽估计 → 设定发送速率
核心类
PacingController
PacingController 实现了 Leaky Bucket(漏桶)算法,是 Pacer 的核心逻辑:
维护一个按优先级排序的包队列
按照设定的发送速率(pacing rate)释放包
处理不同类型包的优先级调度
关键方法:
class PacingController {
public:
// 将包加入发送队列
void EnqueuePacket(std::unique_ptr<RtpPacketToSend> packet);
// 处理定时器触发,发送到期的包
void ProcessPackets();
// 设置发送速率(由 GCC 算法决定)
void SetPacingRates(DataRate pacing_rate, DataRate padding_rate);
// 设置是否允许探测式发送
void SetProbingEnabled(bool enabled);
// 暂停/恢复发送
void Pause();
void Resume();
};
RtpPacketPacer
TaskQueuePacedSender (旧版中为 RtpPacketPacer) 是 Pacer 的外层封装,
负责定时器调度和实际的包发送:
主要调用链:
TaskQueuePacedSender::EnqueuePackets()
→ PacingController::EnqueuePacket()
TaskQueuePacedSender::MaybeProcessPackets() (定时器触发)
→ PacingController::ProcessPackets()
→ PacketRouter::SendPacket()
→ ModuleRtpRtcpImpl::TrySendPacket()
包类型与优先级
Pacer 按照包类型分配不同的发送优先级:
static constexpr size_t kNumMediaTypes = 5;
enum class RtpPacketMediaType : size_t {
kAudio, // 音频包 (最高优先级)
kVideo, // 视频包
kRetransmission, // 重传包 (响应 NACK)
kForwardErrorCorrection, // FEC 包
kPadding = kNumMediaTypes - 1, // 填充包 (最低优先级)
};
发送优先级从高到低:
优先级 |
类型 |
说明 |
|---|---|---|
1 |
Audio |
音频包始终最高优先级,确保语音流畅 |
2 |
Retransmission |
NACK 重传包需要快速发送以降低恢复延迟 |
3 |
Video |
正常视频包 |
4 |
FEC |
前向纠错冗余包 |
5 |
Padding |
填充包,用于维持带宽估计探测 |
发送速率控制
Pacer 的发送速率由 GCC(Google Congestion Control)算法决定:
GCC 估计可用带宽
│
▼
设定 pacing_rate = estimated_bitrate × multiplier (通常 2.5x)
│
▼
Pacer 按照 pacing_rate 匀速发送队列中的包
│
▼
如果队列为空且带宽有富余 → 发送 padding 包以探测更高带宽
关键参数:
Pacing rate:通常是目标比特率的 2.5 倍(允许突发恢复,同时不过度占用带宽)
Padding rate:当没有媒体数据时的填充发送速率,用于保持带宽估计准确
Max queue time:队列中包的最大等待时间(默认 2 秒),超过则丢弃
// 典型配置
pacer->SetPacingRates(
DataRate::KilobitsPerSec(2500), // pacing rate: 2.5 Mbps
DataRate::KilobitsPerSec(200)); // padding rate: 200 kbps
Probe 探测
Pacer 还负责带宽探测(Probing)。在连接初期或带宽变化时, GCC 会要求 Pacer 以特定速率发送探测包来估算可用带宽:
连接建立
│
▼
Probe Cluster 1: 以 900 kbps 发送 5 个包
│
▼
Probe Cluster 2: 以 1800 kbps 发送 5 个包
│
▼
根据接收端反馈(TWCC)计算实际可用带宽
│
▼
进入正常 GCC 速率控制
探测包优先使用排队中的媒体包,只在媒体包不足时才补充 padding。
与 GCC 的协作
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Encoder │ │ Pacer │ │ Network │
│ │ │ │ │ │
│ 输出 RTP 包 ──────► 排队 + 调度 ──────► 发送 │
│ │ │ ↑ │ │ │
└─────────────┘ │ 设定速率 │ └──────┬──────┘
│ ↑ │ │
└─────┼────────┘ │
│ │
┌─────┴────────┐ ┌──────▼──────┐
│ GCC │ │ Receiver │
│ │◄────│ TWCC/REMB │
│ 估计可用带宽 │ │ 反馈 │
└──────────────┘ └─────────────┘
参考资料
WebRTC 源码:
modules/pacing/目录