2. RTP协议基础
RTP(Real-time Transport Protocol)是实时音视频传输的基石。它并不负责可靠传输,而是把“时间”和“来源”这两类信息显式地写进报文头部,让接收端能够重建播放节奏、识别丢包、区分多路媒体流。理解 RTP 报文结构,是后续做抖动缓冲、丢包隐藏、带宽估计和同步优化的前提。
一、RTP报文结构总览
一个 RTP 报文由固定头部、可选的 CSRC 列表、可选的扩展头部以及载荷(Payload)组成。固定头部最小 12 字节,字段排列紧凑,每个字段都服务于实时传输的某个具体需求。
二、头部字段逐项解析
固定头部中的每个字段都有明确的语义,下面按顺序说明。
- V(Version,2bit):RTP 版本号,当前标准为 2。版本不匹配通常意味着协议栈实现错误或中间设备篡改。
- P(Padding,1bit):置 1 表示报文末尾有填充字节,最后一个字节给出填充长度。加密算法常要求块对齐,因此需要填充。
- X(Extension,1bit):置 1 表示固定头部之后存在扩展头部,用于承载传输层无关的附加信息,如 abs-send-time、transport-cc 等。
- CC(CSRC Count,4bit):CSRC 列表中的条目数量,取值 0~15。
- M(Marker,1bit):标记位。视频中通常表示一帧的最后一个包;音频中可表示静音后的第一个包或话轮开始。
- PT(Payload Type,7bit):载荷类型,标识编码格式与采样率等参数。动态 PT 通过 SDP 协商,静态 PT 有固定含义,如 0 为 PCMU、8 为 PCMA。
- 序列号(16bit):每发送一个 RTP 包递增 1,接收端据此检测丢包、乱序和重复包。初始值应随机,避免明文猜测攻击。
- 时间戳(32bit):反映载荷第一个字节的采样时刻,单位由采样率决定。同一帧的多个包共享相同时间戳,接收端据此做播放调度和音视频同步。
- SSRC(32bit):同步源标识,唯一标识一路媒体流。同一会话中不同 SSRC 代表不同发送源,接收端据此区分流并维护独立的状态机。
- CSRC 列表:贡献源标识列表,用于混音器场景。混音器将自己的 SSRC 作为同步源,把原始发言者的 SSRC 填入 CSRC,接收端可据此显示“谁在说话”。
三、序列号与时间戳的协同工作
序列号和时间戳是 RTP 最核心的两个字段,它们分别解决“包是否连续”和“何时播放”两个问题。下面用一个典型场景说明。
发送端(视频 30fps,每帧 3 个 RTP 包):
帧 1:seq=100, ts=90000, M=0
帧 1:seq=101, ts=90000, M=0
帧 1:seq=102, ts=90000, M=1 ← 帧结束标记
帧 2:seq=103, ts=93000, M=0 ← 时间戳增加 3000(90000/30)
帧 2:seq=104, ts=93000, M=0
帧 2:seq=105, ts=93000, M=1
接收端观察:
- seq 从 101 跳到 103 → 检测到 seq=102 丢失
- 同一 ts 的多个包共享时间戳 → 可重组为一帧
- M=1 表示该帧最后一个包 → 可触发解码
- ts 差值 3000 → 帧间隔 33.3ms,用于抖动计算
接收端通常维护一个抖动缓冲区,根据序列号重排乱序包,根据时间戳计算网络抖动,再决定播放时刻。如果序列号出现空洞,可以请求重传(如 RTX)或做丢包隐藏;如果时间戳跳跃异常,则可能意味着发送端时钟漂移或帧率突变。
四、SSRC 与 CSRC 的典型应用场景
SSRC 和 CSRC 的区别常被混淆。简单说:SSRC 标识“这包是谁发的”,CSRC 标识“这包里的内容原本来自谁”。
| 场景 | SSRC | CSRC | 接收端行为 |
|---|---|---|---|
| 一对一通话 | 发送端唯一标识 | 通常为空 | 直接按 SSRC 建立流状态 |
| 多人混音 | 混音器标识 | 原始发言者列表 | 按 CSRC 显示发言者,按 SSRC 收流 |
| 视频转发 | 转发器标识 | 通常为空 | 按 SSRC 区分不同转发流 |
| Simulcast | 每层独立 SSRC | 为空 | 按 SSRC 选择订阅层 |
提示:SSRC 冲突是常见故障。当两个发送端随机生成相同 SSRC 时,接收端会把两路流混为一谈,表现为画面错乱或音频断续。排查时可抓包查看 SSRC 是否重复,必要时通过 RTCP BYE 或重新协商更换 SSRC。
五、常见误区与复盘
在实际优化中,以下几个误区值得注意。
- 误区一:把序列号当作可靠传输序号。RTP 序列号只用于检测,不保证重传。需要可靠性时应叠加 RTX、NACK 或 SCTP 等机制。
- 误区二:忽略时间戳的随机初始值。时间戳初始值应随机,否则可能被用于推断媒体内容或进行攻击。同时,接收端不能假设时间戳从 0 开始。
- 误区三:认为 CSRC 一定存在。CSRC 只在混音场景出现,普通点对点流中 CC=0,解析时不能越界读取。
- 误区四:用 PT 判断编码格式而不看 SDP。动态 PT 的含义由 SDP 协商决定,同一 PT 值在不同会话中可能对应不同编码。
排障建议:遇到花屏、卡顿或音画不同步时,优先抓包检查 RTP 头部的 seq、ts、SSRC 和 M 位。确认序列号是否连续、时间戳是否单调递增、SSRC 是否稳定、M 位是否符合帧边界。多数实时传输问题都能从这几个字段中找到线索。
掌握 RTP 报文结构后,后续的抖动缓冲、丢包重传、带宽估计和音视频同步才有坚实的分析基础。建议在实验环境中用 Wireshark 抓取一段 RTP 流,逐字段对照观察,形成直观认识。