一. 为什么实时音视频会“卡顿”?
在视频会议、语音通话、在线课堂或连麦直播中,我们经常会遇到这样的情况:画面突然卡住、出现马赛克,或者声音断断续续。造成这些问题的原因有很多,其中一个非常常见的原因就是网络丢包。
实时音视频通信与普通网页浏览、文件下载最大的不同,在于它对实时性有非常高的要求。用户可以接受视频画质短暂下降,却很难接受一句话隔几秒才传到对方耳朵里。
因此,在很多 RTC(Real-Time Communication,实时通信)场景中,音视频数据会通过 RTP(Real-time Transport Protocol,实时传输协议)进行传输,而 RTP 通常运行在 UDP 之上。
UDP 的优势很明显:协议机制相对简单,不需要像 TCP 那样先建立连接,也不会因为某个数据包迟迟没有到达,就阻塞后续数据的交付。因此,它非常适合强调低延迟的实时音视频业务。
但 UDP 也有一个天然缺陷:它不保证数据一定能够到达接收端,也不会自动帮应用重传丢失的数据包。
这会导致一个问题:
如果直接使用 TCP,虽然可以依靠确认、重传等机制提高可靠性,但 TCP 的队头阻塞等机制可能让后续数据等待前面的丢失数据恢复,从而增加时延;而如果只依赖 UDP,一旦网络中出现丢包,音视频数据又可能直接缺失。
因此,实时音视频系统通常不会简单地在“低延迟”和“可靠传输”之间二选一,而是在 RTP/RTCP 等机制的基础上,引入更加适合实时通信的抗丢包策略。
RTP 丢包重传,就是其中最常见的手段之一。
二. 什么是 RTP 丢包重传机制?
RTP 丢包重传机制,是指接收端发现某些 RTP 数据包丢失后,将丢包信息反馈给发送端,由发送端根据实际情况重新发送缺失数据包的一种丢包恢复机制。
它的核心思路并不是:“只要丢包,就不惜一切代价重新发送。”
而是:在数据仍然具有播放价值的前提下,有选择地、按需地重新发送丢失的数据包。
对于实时音视频来说,一个视频包如果已经错过了播放时间,即使后来成功重传到接收端,也可能已经没有意义。因此,RTP 重传必须同时考虑网络往返时延 RTT、媒体数据的重要程度、接收端缓冲时间以及当前网络状况等因素。
RFC 8834 对 WebRTC 中的 RTP 重传也特别强调:不应该对每一个 NACK 都进行盲目重传,而应判断丢失数据的重要性,以及重传包能否及时到达。
在实际 RTC 系统中,RTP 丢包重传通常会和 RTCP NACK 配合使用。
其中:
RTP 负责传输音视频媒体数据;
RTCP 负责传输与媒体传输状态相关的控制和反馈信息;
NACK(Negative Acknowledgement,负确认) 则可以用来告诉发送端:“某些 RTP 包我没有收到。”
如果双方还协商使用了 RTX(Retransmission),发送端还可以通过专门的 RTP 重传流重新封装并发送丢失数据。RFC 4588 就专门定义了 RTP 重传负载格式。
三. RTP 丢包重传

假设发送端连续发送了 4 个 RTP 数据包:
100 → 101 → 102 → 103
但由于网络波动,102 号数据包在传输过程中丢失,接收端实际上收到的是:
100 → 101 → 103
接下来,整个重传流程大致可以分成四步。
1. Sequence Number:接收端发现数据包缺失
每个 RTP 数据包的 Header 中,都包含一个 Sequence Number(序列号)。
发送端通常会让连续发送的数据包使用连续递增的序列号,因此接收端可以利用序列号判断 RTP 数据包的顺序,同时发现可能存在的数据缺失。
例如:
收到 100
收到 101
接下来却收到 103
接收端就会发现:
102 号数据包没有按预期到达。
不过,“没有按顺序到达”并不一定意味着它真的丢了。
因为网络中还可能发生乱序:102 只是走得比较慢,103 反而提前到达。
所以,一个成熟的接收端通常不会在发现 Sequence Number 出现缺口的一瞬间就立刻认定数据丢失,而是会结合一定的等待时间、乱序情况以及历史网络状态进行判断。
RFC 4588 也建议,接收端在发送重传请求之前,应考虑数据包乱序的可能性,可以设置适当的 reorder delay,避免因为正常乱序而产生不必要的重传。
2. 发现丢包后,通过 RTCP NACK 请求重传
当接收端判断 102 号数据包确实已经丢失后,就可以向发送端发送一个 RTCP NACK。
可以把 NACK 理解成接收端向发送端发送的一张“缺货清单”:
102 号 RTP 包没有收到,请尝试重新发送。
这里需要特别注意:
NACK 本身不是重传。
NACK 的作用只是告诉发送端哪些数据包可能丢失了。
至于发送端是否真的重传,还需要根据当前情况进一步判断。
在 WebRTC 中,接收端可以针对缺失的 RTP 包发送 Generic NACK;但标准同样不要求每一个丢失的数据包都必须发送 NACK。接收端需要考虑反馈成本以及数据包的重要性。
3. 发送端查找缓存,并决定是否重传
为什么发送端收到 NACK 后还能重新发送 102 号数据包?
因为发送端通常不会在 RTP 数据包发送出去后立刻把它彻底丢弃,而是会把最近发送的一部分数据暂时保存在重传缓存中。
当发送端收到:
NACK:102
就可以到缓存中查找对应的数据。
如果:
102 仍然存在于缓存中;
当前 RTT 足够低;
数据重新传过去仍然赶得上播放;
这个包具有足够的恢复价值;
发送端就可以进行重传。
如果已经太晚了,那么重传反而可能只会白白消耗带宽。
这正是 RTP 重传和普通“可靠传输”不同的地方:它更关注实时价值,而不是追求绝对意义上的“一个包都不能少”。
RFC 4588 也指出,重传机制实际上是在可靠性与时延之间进行权衡。
4. RTX 重传、Jitter Buffer 与数据重排序
如果发送端和接收端协商支持 RTX,发送端可以把需要重新发送的数据封装成新的 RTX RTP 包,再发送给接收端。
RFC 4588 定义的典型方式,是让原始 RTP 流和重传 RTP 流使用分离的流,从而避免破坏原始 RTP 的序列号空间和 RTCP 统计。
接收端收到重传包后,也不是立刻把数据直接播放出来。
因为网络数据到达的时间并不完全稳定。
例如接收端实际收到的顺序可能是:
100 → 101 → 103 → 104 → 重传的 102
这时,就需要 Jitter Buffer(抖动缓冲区)发挥作用。
Jitter Buffer 会在播放前短暂缓存一部分数据,对不同时间到达的数据包进行整理和排序,并尽量给迟到的包留出一定恢复时间。
因此,可以把整个 RTP 丢包重传流程概括为:
RTP 数据发送
↓
Sequence Number 出现缺口
↓
接收端判断发生丢包
↓
发送 RTCP NACK
↓
发送端查询重传缓存
↓
重新发送 RTP/RTX 数据
↓
接收端通过 Jitter Buffer 等机制整理数据
↓
继续解码和播放
整个过程追求的目标并不是“绝对不丢包”,而是:
在尽可能低的延迟下,把值得恢复、来得及恢复的数据找回来。
四. RTP 丢包重传与 FEC 的对比
RTP 丢包重传本质上属于一种基于反馈的 ARQ(Automatic Repeat reQuest,自动重传请求)思路。
但重传并不是 RTC 对抗丢包的唯一手段。
另一类非常重要的技术叫做:
FEC(Forward Error Correction,前向纠错)。
如果说 ARQ 的逻辑是:“发现丢了,再回来找。”
那么 FEC 的逻辑就是:“提前发送一些冗余信息,即使部分数据丢失,也有机会自己恢复。”
二者的主要区别如下。
| 对比维度 | ARQ / NACK 重传 | FEC |
|---|---|---|
| 基本思路 | 丢包发生后请求重新发送 | 提前加入冗余数据 |
| 是否依赖反馈 | 通常依赖接收端反馈 | 通常不需要等待重传反馈 |
| 对 RTT 的敏感度 | 较高 | 相对较低 |
| 带宽开销 | 发生重传时增加 | 无论是否丢包,都需要一定冗余带宽 |
| 优势 | 没有丢包时额外开销较小 | 无需等待一个 RTT,恢复速度快 |
| 局限 | RTT 太大时,重传可能来不及 | 会持续占用额外带宽 |
| 更适合 | RTT 较低、零星或突发丢包 | 高时延或需要快速恢复的场景 |
举一个简单的例子。
假设发送端需要发送:
A、B、C、D
使用 NACK 重传时,正常情况下只需要发送这四份数据。
如果 C 丢失:
接收端发现 C 不见了
→ 请求发送端重传
→ 发送端再发送 C。
而 FEC 可能在一开始就额外生成一份冗余数据 E:
A、B、C、D + E
如果 C 丢了,接收端可能利用 A、B、D、E 自行恢复缺失的数据,不需要等待发送端重新发送。
因此,两种方案实际上是在交换不同的成本:
NACK / ARQ 用“时间”换带宽。
FEC 用“带宽”换恢复时间。
为什么现代 RTC 往往“NACK + FEC”一起用?
真实网络环境远比理论模型复杂。
如果所有丢包都依靠 NACK:
在 RTT 较高的网络中,重传数据可能来不及赶上播放时间。
如果所有数据都使用大量 FEC:
即使网络状况很好,也需要持续发送冗余数据,会造成额外带宽消耗。
因此,在实际实时音视频系统中,更常见的做法并不是简单选择:
NACK 还是 FEC?
而是根据网络状况动态组合多种抗丢包机制。
例如:
网络情况较好、RTT 较低时,可以更多依赖 NACK / RTX 对少量丢包进行恢复;
网络条件恶化时,可以适当增加 FEC 等冗余保护;
如果网络已经严重拥塞,则还需要结合码率自适应、拥塞控制、分辨率调整等机制,而不是无限制地重传数据。
RFC 4588 也特别提醒:如果丢包本身是网络拥塞造成的,不加控制地继续发送重传数据,可能进一步加剧拥塞。
所以,从更完整的角度看,RTP 丢包重传只是 RTC 弱网对抗体系中的一环。
五. 总结:RTP 重传真正解决的不是“绝对可靠”
实时音视频通信一直面临一个核心问题:
既希望数据尽量完整,又希望延迟足够低。
UDP 为 RTC 提供了低延迟传输的基础,却不会主动保证数据可靠到达;RTP、RTCP NACK、RTX 等机制,则在此基础上提供了一种更加适合实时媒体的数据恢复方式。
整个 RTP 丢包重传过程可以概括为:
接收端利用 RTP Sequence Number 等信息发现丢包,通过 RTCP NACK 告诉发送端缺了哪些数据,发送端再根据缓存、RTT 和数据价值决定是否重新发送,接收端最终借助缓冲和重排序机制恢复媒体数据。
因此,RTP 丢包重传追求的并不是 数据必须全部送达,而是一种更加符合实时通信特性的策略:
该重传的快速重传,已经来不及的数据及时放弃。
而在现代 RTC 系统中,NACK / RTX 也通常不会孤立存在。它往往会与 FEC、Jitter Buffer、拥塞控制、自适应码率等机制共同工作,在实时性、可靠性、带宽和音视频质量之间寻找平衡。
这也是 RTC 弱网优化的核心逻辑之一。