WebRTC Feedback
Abstract |
WebRTC Feedback |
Authors |
Walter Fan |
Status |
v1.0 |
Updated |
2026-03-20 |
简介
在 WebRTC 实时通信中,RTCP (Real-time Transport Control Protocol) 反馈机制是保障音视频质量的核心手段。 发送端需要根据接收端的反馈信息来调整编码策略、码率和重传行为,从而在不断变化的网络条件下维持尽可能好的用户体验。
RTCP 反馈消息定义在 RFC 4585 (Extended RTP Profile for RTCP-Based Feedback, RTP/AVPF) 中, 它扩展了原始的 RTP/AVP profile,允许接收端在不等待常规 RTCP 报告间隔的情况下,及时地向发送端反馈信息。
这些反馈消息按照功能分为三大类:
Transport layer FB messages (RTPFB, PT=205) — 传输层的反馈消息,关注 RTP 包的传输状态
Payload-specific FB messages (PSFB, PT=206) — 特定荷载的反馈消息,关注媒体编码层面的问题
Application layer FB messages (APPFB, PT=207) — 应用层的反馈消息,用于应用自定义的反馈
RTCP FB 通用包格式
所有 RTCP 反馈消息共享以下通用包格式:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P| FMT | PT | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of packet sender |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of media source |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Feedback Control Information (FCI) :
: :
Figure 3: Common Packet Format for Feedback Messages
各字段含义如下:
V (Version): 固定为 2
P (Padding): 填充标志位
FMT (Feedback Message Type): 反馈消息子类型,不同的 FMT 值代表不同的反馈消息
PT (Payload Type): 荷载类型,区分传输层、荷载特定和应用层反馈
length: 以 32-bit 字为单位的包长度(不含首个 32-bit 字)
SSRC of packet sender: 发送此 RTCP 反馈包的参与者的 SSRC
SSRC of media source: 被反馈的媒体源的 SSRC
FCI: 反馈控制信息,具体内容取决于 FMT 和 PT 的组合
PT 荷载类型有如下分类:
Name | Value | Brief Description
----------+-------+------------------------------------
RTPFB | 205 | Transport layer FB message
PSFB | 206 | Payload-specific FB message
APPFB | 207 | Application-specific FB message
传输层反馈消息 (Transport Layer FB)
传输层反馈消息 (PT=205, RTPFB) 关注的是 RTP 包在网络传输过程中的状态, 主要用于丢包通知和码率控制。
Generic NACK (FMT=1)
Generic NACK (Negative Acknowledgement) 是最基本的丢包反馈机制。 当接收端检测到 RTP 包丢失时,会发送 NACK 消息通知发送端进行重传。
NACK 的 FCI 格式如下:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PID | BLP |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PID (Packet ID, 16 bits): 丢失的 RTP 包的序列号。这是触发 NACK 的第一个丢失包。
BLP (Bitmask of Lost Packets, 16 bits): 位掩码,表示 PID 之后连续 16 个包的丢失情况。 BLP 的第 i 位 (i=0..15) 为 1 表示序列号为 PID+i+1 的包也丢失了。
因此,一个 NACK FCI 条目最多可以报告 17 个连续丢失的包(PID 本身加上 BLP 中的 16 个)。 一个 NACK 消息可以包含多个 FCI 条目,以报告不连续的丢包区间。
工作流程:
接收端维护一个 RTP 序列号的接收记录
当检测到序列号间隙(gap)时,等待一小段时间(通常为一个 RTT 的一部分)以应对乱序到达
如果等待超时后包仍未到达,发送 NACK 消息
发送端收到 NACK 后,从重传缓冲区(retransmission buffer)中取出对应的包进行重传
重传的包通常通过 RTX (Retransmission) 流发送,使用不同的 SSRC 和 PT
注意事项:
NACK 重传会引入额外的延迟(至少一个 RTT)
在高丢包率场景下,大量 NACK 和重传可能加剧拥塞
WebRTC 中通常对 NACK 重传次数有限制(如最多重传 10 次)
对于实时性要求极高的场景(如超低延迟直播),NACK 重传可能不适用
TMMBR/TMMBN (FMT=3/FMT=4)
TMMBR (Temporary Maximum Media Stream Bit Rate Request) 和 TMMBN (Temporary Maximum Media Stream Bit Rate Notification) 定义在 RFC 5104 中,用于接收端请求发送端临时限制媒体流的最大码率。
TMMBR (FMT=3) 的工作流程:
接收端根据自身的处理能力或下行带宽限制,计算出期望的最大码率
发送 TMMBR 消息给发送端,携带期望的最大码率值和 overhead 信息
发送端收到后,调整编码码率不超过请求的值
TMMBN (FMT=4) 是发送端对 TMMBR 的确认响应:
发送端收到一个或多个 TMMBR 后,选择最小的码率限制
发送 TMMBN 消息通知所有接收端当前生效的码率限制
TMMBR FCI 格式:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| MxTBR Exp | MxTBR Mantissa |Measured Overhead|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
MxTBR Exp (6 bits) 和 MxTBR Mantissa (17 bits): 共同表示最大码率, 计算公式为
MxTBR = MxTBR Mantissa * 2^MxTBR Exp(单位: bps)Measured Overhead (9 bits): 每个包的平均 overhead(IP/UDP/RTP 头部等)
Transport-wide CC Feedback (FMT=15)
Transport-wide Congestion Control (transport-cc) 是 Google 提出的一种传输层反馈机制, 定义在 draft-holmer-rmcat-transport-wide-cc-extensions 中。 它是 WebRTC 中 GCC (Google Congestion Control) 算法的核心组成部分。
与传统的基于 RTCP RR 的丢包率和 jitter 统计不同,transport-cc 提供了每个 RTP 包的精确到达时间信息, 使得发送端可以进行更精细的带宽估计。
核心思想:
发送端为每个 RTP 包分配一个 transport-wide sequence number(通过 RTP header extension 携带)
接收端记录每个包的到达时间
接收端定期(通常每 100ms)发送 transport-cc feedback 包,汇报一批包的接收状态和到达时间
RTP Header Extension 格式:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0xBE | 0xDE | length=1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ID | L=1 |transport-wide sequence number | padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
transport-wide sequence number 是一个 16-bit 的值,在所有媒体流(音频和视频)之间共享递增。
Feedback 包格式 (PT=205, FMT=15):
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P| FMT=15 | PT=205 | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of packet sender |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of media source |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| base sequence number | packet status count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| reference time | fb pkt. count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| packet chunk | packet chunk |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. .
. .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| recv delta | recv delta |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. .
. .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
关键字段说明:
base sequence number: 本次反馈覆盖的起始 transport-wide sequence number
packet status count: 本次反馈覆盖的包数量
reference time: 参考时间戳,以 64ms 为单位
fb pkt. count: 反馈包计数器,用于检测反馈包丢失
packet chunk: 使用 run-length 或 status vector 编码的包接收状态
recv delta: 相邻包到达时间的差值,以 250μs 为单位
Packet Status 编码:
每个包的状态用 1-bit 或 2-bit 表示:
00: 未收到 (not received)01: 收到,小 delta (received, small delta, 1 byte recv delta)10: 收到,大 delta (received, large or negative delta, 2 bytes recv delta)11: 保留
发送端如何使用 transport-cc feedback:
发送端收到 feedback 后,可以重建每个包的发送时间和到达时间序列, 然后使用 delay-based 算法(如 GCC 中的 Trendline Filter)来估计可用带宽:
计算相邻包的 inter-departure time(发送间隔)和 inter-arrival time(到达间隔)
计算 delay gradient:
delta = inter_arrival - inter_departure使用 Trendline Filter 对 delay gradient 序列进行线性回归
如果趋势线斜率为正,说明网络拥塞加剧,需要降低码率
如果趋势线斜率为零或负,说明网络状况良好,可以尝试提高码率
荷载特定反馈消息 (Payload-Specific FB)
荷载特定反馈消息 (PT=206, PSFB) 关注的是媒体编码层面的问题, 主要用于通知发送端视频解码出现了问题,需要采取相应的编码措施。
PLI — Picture Loss Indication (FMT=1)
PLI (Picture Loss Indication) 定义在 RFC 4585 中,用于通知发送端接收端的解码器丢失了一个或多个完整的视频帧, 导致解码器无法正确解码后续帧。
PLI 消息没有额外的 FCI 字段,它只是一个简单的信号:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P| FMT=1 | PT=206 | length=2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of packet sender |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of media source |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
触发条件:
接收端检测到一个或多个视频帧的 RTP 包丢失,且无法通过 NACK 重传恢复
解码器因为参考帧缺失而无法继续正确解码
长时间未收到关键帧,解码器状态不确定
发送端响应:
收到 PLI 后,编码器通常会生成一个关键帧(I-frame / IDR frame), 使接收端的解码器可以从该关键帧重新开始解码,无需依赖之前的参考帧。
注意事项:
关键帧通常比 P 帧大 5-10 倍,频繁的 PLI 会导致码率波动
WebRTC 中通常会对 PLI 请求进行节流(throttling),避免过于频繁地生成关键帧
Chrome/libwebrtc 中默认的 PLI 最小间隔约为 300ms
SLI — Slice Loss Indication (FMT=2)
SLI (Slice Loss Indication) 定义在 RFC 4585 中,提供比 PLI 更精细的丢失信息。 它可以指出具体丢失的是哪些 macroblock(宏块)区域,而不是笼统地报告整帧丢失。
SLI FCI 格式:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| First | Number | PictureID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
First (13 bits): 丢失区域中第一个宏块的地址(按光栅扫描顺序)
Number (13 bits): 连续丢失的宏块数量
PictureID (6 bits): 丢失宏块所属图片的时间参考(低 6 位)
使用场景:
SLI 在实际 WebRTC 实现中使用较少,因为:
现代视频编码器(如 VP8/VP9/AV1)不使用传统的 macroblock 概念
PLI 和 FIR 已经能满足大多数场景的需求
编码器通常不支持仅刷新部分区域的精细控制
RPSI — Reference Picture Selection Indication (FMT=3)
RPSI (Reference Picture Selection Indication) 定义在 RFC 4585 中, 用于接收端通知发送端某个特定的参考帧已经被正确解码, 发送端可以使用该帧作为后续编码的参考帧。
RPSI FCI 格式:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PB |0| Payload Type| Native RPSI bit string |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| defined per codec ... | Padding (0) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PB (8 bits): 填充位数
Payload Type (7 bits): 对应的 RTP payload type
Native RPSI bit string: 编解码器特定的参考帧标识信息
工作原理:
接收端成功解码某个帧后,发送 RPSI 告知发送端该帧可用作参考
发送端在编码后续帧时,选择该帧作为参考帧,而不是使用可能已丢失的最近帧
这样可以避免错误传播(error propagation),无需发送完整的关键帧
优势:
比 PLI/FIR 更高效,因为不需要生成完整的关键帧
可以在保持较低码率的同时恢复解码状态
局限:
需要编码器支持灵活的参考帧选择
在 WebRTC 中实际使用较少,VP8/VP9 更倾向于使用 PLI + 关键帧的方式
FIR — Full Intra Request (FMT=4)
FIR (Full Intra Request) 定义在 RFC 5104 中,用于请求发送端生成一个完整的关键帧。 与 PLI 不同,FIR 不仅仅是因为丢包,还可能是因为新的接收端加入(如 SFU 场景中新用户加入会议)。
FIR FCI 格式:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Seq nr. | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
SSRC (32 bits): 请求关键帧的媒体源 SSRC
Seq nr. (8 bits): 命令序列号,每次新的 FIR 请求递增,用于去重
FIR vs PLI 的区别:
特性 |
PLI |
FIR |
|---|---|---|
定义 |
RFC 4585 |
RFC 5104 |
触发原因 |
帧丢失导致解码失败 |
需要关键帧(不一定因为丢包) |
典型场景 |
丢包恢复 |
新用户加入、录制开始 |
FCI |
无 |
包含 SSRC 和序列号 |
语义 |
"我丢了帧,请帮忙" |
"请立即发送关键帧" |
REMB — Receiver Estimated Maximum Bitrate
REMB (Receiver Estimated Maximum Bitrate) 是 Google 提出的一种 RTCP 反馈消息, 用于接收端将其估计的最大可用带宽通知给发送端。REMB 使用 PSFB (PT=206) 的 Application layer FB (FMT=15)。
注解
REMB 已经逐渐被 transport-cc 取代。在较新的 WebRTC 实现中, 带宽估计主要在发送端完成(sender-side BWE),使用 transport-cc feedback。 但 REMB 在一些旧的实现和 SFU 中仍然被使用。
REMB 包格式:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P| FMT=15 | PT=206 | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of packet sender |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of media source (unused) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Unique identifier 'R' 'E' 'M' 'B' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Num SSRC | BR Exp | BR Mantissa |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC feedback |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ... |
Unique identifier: 固定为 ASCII 字符 "REMB"
Num SSRC (8 bits): 后续 SSRC 列表的数量
BR Exp (6 bits) 和 BR Mantissa (18 bits): 估计的最大码率, 计算公式为
bitrate = BR Mantissa * 2^BR Exp(单位: bps)SSRC feedback: 该估计适用的媒体流 SSRC 列表
工作流程:
接收端使用 REMB 算法(基于丢包率和延迟变化)估计可用带宽
将估计值通过 REMB 消息发送给发送端
发送端将 REMB 值作为码率上限的参考之一
在 SFU 场景中,SFU 可以汇总多个接收端的 REMB,取最小值转发给发送端
RTCP XR — Extended Reports
RTCP XR (Extended Reports) 定义在 RFC 3611 中,提供了比标准 RTCP SR/RR 更丰富的统计信息。 XR 使用 PT=207,包含一个或多个 report block,每个 block 有不同的 block type。
XR 通用格式:
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|reserved | PT=207 | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SSRC of packet sender |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: report blocks :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
常用的 XR Block Types:
BT |
名称 |
描述 |
|---|---|---|
1 |
Loss RLE Report Block |
使用 Run-Length Encoding 报告详细的丢包模式 |
2 |
Duplicate RLE Report Block |
报告重复包的模式 |
3 |
Packet Receipt Times Report Block |
报告每个包的接收时间 |
4 |
Receiver Reference Time Report Block |
接收端参考时间,类似 SR 中的 NTP 时间戳 |
5 |
DLRR Report Block |
Delay since Last Receiver Report,用于 RTT 计算 |
6 |
Statistics Summary Report Block |
汇总统计:丢包率、重复率、jitter 等 |
7 |
VoIP Metrics Report Block |
VoIP 质量指标:R-factor、MOS、burst/gap 统计等 |
VoIP Metrics Report Block (BT=7) 是最常用的 XR block 之一,包含以下关键指标:
Loss Rate: 丢包率
Discard Rate: 因为到达太晚而被丢弃的包的比率
Burst Density / Gap Density: 突发丢包和间隙丢包的密度
Burst Duration / Gap Duration: 突发和间隙的持续时间
Round Trip Delay: 往返延迟
End System Delay: 端系统延迟
R-factor: ITU-T G.107 E-model 中的 R 值,综合反映通话质量
MOS-LQ / MOS-CQ: Mean Opinion Score,主观质量评分
在 WebRTC 中,RTCP XR 主要用于 VoIP 质量监控和诊断,
Chrome 的 getStats() API 返回的部分统计数据就来源于 XR 报告。
反馈时机与频率控制
RTCP 带宽分配
根据 RFC 3550 的规定,RTCP 流量不应超过会话总带宽的 5%。 在这 5% 中,25% 分配给发送端报告(SR),75% 分配给接收端报告(RR 和反馈消息)。
然而,在 WebRTC 的实时交互场景中,这个限制可能导致反馈不够及时。 RFC 4585 (RTP/AVPF) 引入了 "Early RTCP" 机制,允许在以下条件下提前发送反馈:
Immediate feedback: 对于时间敏感的反馈(如 NACK、PLI),可以立即发送
Early feedback: 在常规 RTCP 间隔之前发送,但需要遵守最小间隔限制
Regular feedback: 按照常规 RTCP 间隔发送
Reduced-Size RTCP (RFC 5506)
传统的 RTCP 复合包(compound packet)要求每个 RTCP 包至少包含一个 SR 或 RR。 这在需要快速发送反馈时会增加不必要的开销。
RFC 5506 定义了 Reduced-Size RTCP,允许发送不包含 SR/RR 的单独反馈消息。 这对于 NACK、PLI 等需要快速响应的反馈特别有用。
在 WebRTC 的 SDP 协商中,通过以下属性启用 reduced-size RTCP:
a=rtcp-rsize
WebRTC 中几乎所有实现都支持并默认启用 reduced-size RTCP。
SDP 中的反馈能力协商
在 WebRTC 的 SDP offer/answer 交换中,通过 a=rtcp-fb 属性来协商支持的反馈类型。
格式为:
a=rtcp-fb:<payload type> <feedback type> [<feedback parameters>]
典型的 WebRTC SDP 中的反馈协商示例:
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 VP9/90000
a=rtcp-fb:97 goog-remb
a=rtcp-fb:97 transport-cc
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtpmap:98 H264/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
各 a=rtcp-fb 行的含义:
nack: 支持 Generic NACK (丢包重传)nack pli: 支持 PLI (Picture Loss Indication)ccm fir: 支持 FIR (Full Intra Request),ccm 表示 Codec Control Messages (RFC 5104)goog-remb: 支持 Google REMB (接收端带宽估计)transport-cc: 支持 Transport-wide Congestion Control
WebRTC 实现中的反馈处理
在 Chrome/libwebrtc 的实现中,各种反馈消息的处理流程如下:
NACK 处理流程
RtpVideoStreamReceiver检测到 RTP 序列号间隙通过
NackModule管理 NACK 请求的生成和去重NackModule维护一个 NACK 列表,等待一定时间后(基于 RTT)发送 NACKNACK 消息通过
RTCPSender发送发送端的
RTPSender收到 NACK 后,从RtpPacketHistory中查找并重传对应的包重传包通过 RTX (Retransmission) 通道发送,使用独立的 SSRC
PLI/FIR 处理流程
接收端检测到需要关键帧(解码失败、新用户加入等)
通过
RTCPSender发送 PLI 或 FIR 消息发送端的
VideoStreamEncoder收到关键帧请求编码器在下一帧编码时生成 IDR/关键帧
关键帧通过正常的 RTP 通道发送
Transport-CC 处理流程
发送端通过
TransportSequenceNumberAllocator为每个 RTP 包分配 transport-wide sequence number接收端的
RemoteEstimatorProxy收集包的到达时间定期(约 100ms)生成 transport-cc feedback 包并发送
发送端的
SendSideBandwidthEstimation接收 feedbackGoogCcNetworkController使用 feedback 数据运行 delay-based 和 loss-based 估计估计结果用于调整
BitrateAllocator的目标码率VideoStreamEncoder根据新的目标码率调整编码参数
反馈对质量的影响
RTCP 反馈机制是 WebRTC 自适应码率控制(Adaptive Bitrate Control)的基础。 各种反馈消息共同驱动以下质量适配决策:
反馈类型 |
触发的适配行为 |
对用户体验的影响 |
|---|---|---|
NACK |
丢包重传 |
减少视频花屏和卡顿,但增加延迟 |
PLI/FIR |
生成关键帧 |
快速恢复视频画面,但瞬间码率飙升 |
Transport-CC |
调整编码码率 |
平滑的码率适配,避免拥塞 |
REMB |
限制发送码率上限 |
防止接收端过载 |
RTCP XR |
质量监控和诊断 |
帮助定位和解决质量问题 |
典型的质量适配循环:
网络拥塞 → 丢包增加 → NACK 重传 + transport-cc 检测到延迟增加
→ GCC 降低目标码率 → 编码器降低码率/分辨率/帧率
→ 网络拥塞缓解 → transport-cc 检测到延迟减少
→ GCC 逐步提高目标码率 → 编码器提高码率/分辨率/帧率
这个反馈循环使得 WebRTC 能够在不断变化的网络条件下, 自动调整视频质量以维持最佳的用户体验。
反馈消息汇总表
消息类型 |
PT |
FMT |
RFC |
用途 |
|---|---|---|---|---|
Generic NACK |
205 |
1 |
RFC 4585 |
请求重传丢失的 RTP 包 |
TMMBR |
205 |
3 |
RFC 5104 |
请求临时限制最大码率 |
TMMBN |
205 |
4 |
RFC 5104 |
确认当前生效的码率限制 |
Transport-CC |
205 |
15 |
draft-holmer |
传输层拥塞控制反馈 |
PLI |
206 |
1 |
RFC 4585 |
通知图片丢失,请求关键帧 |
SLI |
206 |
2 |
RFC 4585 |
通知 slice 丢失 |
RPSI |
206 |
3 |
RFC 4585 |
参考帧选择指示 |
FIR |
206 |
4 |
RFC 5104 |
请求完整关键帧 |
REMB |
206 |
15 |
draft-alvestrand |
接收端估计的最大码率 |
参考
RFC4585: Extended RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback (RTP/AVPF)
RFC5104: Codec Control Messages in the RTP Audio-Visual Profile with Feedback (AVPF)
RFC5506: Support for Reduced-Size Real-Time Transport Control Protocol (RTCP): Opportunities and Consequences
RFC3611: RTP Control Protocol Extended Reports (RTCP XR)
draft-holmer-rmcat-transport-wide-cc-extensions: RTP Extensions for Transport-wide Congestion Control
draft-alvestrand-rmcat-remb: RTCP message for Receiver Estimated Maximum Bitrate
RFC3550: RTP: A Transport Protocol for Real-Time Applications