4. 媒体封装与传输基础

RTSP 本身只负责“会话控制”,真正承载音视频数据的是 RTP。理解 RTSP 推流链路,必须先弄清两件事:一是音视频被压缩成什么格式(H.264/H.265、AAC、G.711),二是这些压缩后的数据如何被切成 RTP 包并打上时间戳、序列号、SSRC 与负载类型。本节把这两层关系串起来,为后续调优建立参数坐标系。

一、核心原理:编码格式决定打包方式

编码格式决定了码流的“形状”,而 RTP 打包必须适配这个形状。H.264/H.265 属于视频编码,输出的是 NAL 单元(H.265 为 NALU 的扩展结构),一个 NALU 可能远大于网络 MTU,因此需要分片;AAC 属于音频编码,输出的是 AU(Access Unit),通常一个 AU 可以放进一个 RTP 包;G.711 是窄带语音编码,码率固定 64 kbps,打包最简单,常用于对讲和低延迟场景。

  • H.264:NAL 单元类型包括 SPS、PPS、IDR、非 IDR 片等。RTP 打包遵循 RFC 6184,常用模式为 Single NAL Unit、STAP-A、FU-A。
  • H.265:结构类似但 NAL 头为 2 字节,RTP 打包遵循 RFC 7798,分片类型为 FU,AP 用于聚合。
  • AAC:RTP 打包遵循 RFC 3640,需要携带 AU-headers-length 与 AU-header,用于描述每个 AU 的大小和索引。
  • G.711:RTP 打包遵循 RFC 3551,PCMA/PCMU 负载类型分别为 8 和 0,每个包通常承载 20 ms 采样。
关键结论:编码格式不是“内容”,而是“打包契约”。RTP 包中的负载类型(PT)就是告诉接收端“这段负载该用什么解码器、按什么规则解析”。

二、RTP 打包规则:分片、聚合与边界

RTP 包由固定头和负载组成。固定头包含序列号(16 位)、时间戳(32 位)、SSRC(32 位)、负载类型(7 位)等字段。对于视频,最大的挑战是 MTU。以太网 MTU 通常为 1500 字节,减去 IP 头 20 字节、UDP 头 8 字节、RTP 头 12 字节,实际可用负载约 1460 字节。因此一个大的 IDR 帧必须被切成多个 FU-A 包。

RTP 固定头(12 字节):
 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|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

打包时要注意三个边界:帧边界、NALU 边界和 MTU 边界。FU-A 分片时,只有最后一个分片将 Marker 位置 1,表示一帧结束;STAP-A 用于把多个小 NALU 聚合到一个 RTP 包,减少包头开销。音频侧,AAC 的 AU-header 需要正确描述每个 AU 的长度,否则接收端无法切分。

三、时间戳、序列号、SSRC 与负载类型

这四个字段是 RTP 的“身份系统”,也是排障时最常看的参数。

字段作用调优关注点
序列号 Sequence Number标识 RTP 包顺序,每发一个包加 1丢包检测、乱序判断、重传策略
时间戳 Timestamp标识采样时刻,视频通常为 90 kHz,音频为采样率音视频同步、抖动缓冲、帧率稳定性
SSRC标识一个 RTP 流源,同一会话中唯一多路流区分、冲突检测、统计归属
负载类型 PT标识编码格式与打包规则动态 PT 协商、SDP 描述一致性

时间戳的增量决定了播放节奏。例如 H.264 在 90 kHz 时钟下,25 fps 每帧时间戳增量为 90000/25 = 3600。如果时间戳增量忽大忽小,接收端就会看到卡顿或加速。序列号则用于检测丢包,若接收端发现序列号跳跃,就会触发 NACK 或 PLI 请求关键帧。

SSRC 冲突是隐蔽故障:当两个推流端使用相同 SSRC 时,接收端会把两路流混在一起,表现为画面花屏、声音断续。排查时可在 SDP 和 RTP 统计中核对 SSRC 值。

四、案例与场景:一次推流参数配置

假设我们要推送一路 1080p25 的 H.264 视频和一路 AAC 音频。SDP 中会这样描述:

m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=42e01f

m=audio 0 RTP/AVP 97
a=rtpmap:97 MPEG4-GENERIC/44100/2
a=fmtp:97 streamtype=5;profile-level-id=1;mode=AAC-hbr;
        sizelength=13;indexlength=3;indexdeltalength=3;config=1210

这里 PT=96 对应 H.264,时钟 90000;PT=97 对应 AAC,时钟 44100。视频打包模式为 1,表示允许 FU-A 分片。音频使用 AAC-hbr 模式,AU-header 长度由 sizelength 等参数决定。若把 PT 写错,接收端会用错误解码器解析,直接黑屏或爆音。

五、误区与复盘

  • 误区一:只看编码格式,不看打包模式。同样是 H.264,packetization-mode=0 与 1 的兼容性差异很大,很多老设备只支持模式 0。
  • 误区二:时间戳用系统时间。RTP 时间戳必须基于采样时钟,不能用墙上时间,否则音视频同步会漂移。
  • 误区三:忽略 Marker 位。视频帧结束未置 Marker,接收端可能一直等后续分片,造成延迟累积。
  • 误区四:SSRC 随机但未校验。多路推流时应确保 SSRC 唯一,并在接收端做冲突检测。

复盘时建议按“编码格式 → 打包模式 → PT 映射 → 时间戳基准 → 序列号连续性 → SSRC 唯一性”的顺序逐项核对。这六个检查点覆盖了媒体封装与传输的基础链路,也是后续调优的起点。

媒体封装与 RTP 传输基础关系图 视频编码 H.264 / H.265 NAL 单元 / 分片 SPS / PPS / IDR 音频编码 AAC / G.711 AU / 采样帧 PCMA / PCMU RTP 打包规则 H.264: Single / STAP-A / FU-A H.265: FU / AP AAC: AU-header + AU G.711: 20ms 采样直打包 MTU 边界 ≈ 1460 字节 Marker 位标记帧结束 序列号 +1 / 时间戳按采样时钟 SSRC 唯一 / PT 映射编码 RTP 固定头字段 序列号 (16 bit) 时间戳 (32 bit) SSRC (32 bit) 负载类型 PT (7 bit) Marker / 版本 / 填充 调优检查顺序 1. 编码格式 2. 打包模式 3. PT 映射 4. 时间戳基准 5. 序列号连续 6. SSRC 时间戳增量示例:H.264 90kHz,25fps → 每帧 +3600;AAC 44100Hz,1024 采样 → 每帧 +1024