RTP 头扩展 · 每个包捎带的元数据

标准 RTP 头就那几个字段,但拥塞控制、音视频同步、分流都需要更多信息——靠头扩展捎带。这一章讲清头扩展的机制(URI 经 SDP 协商成本地 ID)、one-byte/two-byte 格式,以及几个关键扩展:transport-cc 序号、abs-send-time、mid。

作者 David更新于 第 34 篇(共 112 篇)

RTP 头扩展 · 每个包捎带的元数据

上一章说 RTP 标准头就 SSRC、序号、时间戳等固定几个字段。但实时通信需要更多每包元数据——发送的绝对时间(给带宽估计用)、这个包属于哪条媒体(给分流用)、音量、视频朝向……这些靠 RTP 头扩展(header extensions) 捎带。别小看它:WebRTC 的拥塞控制和同步都离不开它。

机制:URI ⟷ 本地 ID

头扩展是一套可扩展机制:每种扩展由一个 URI 标识(如 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time),但塞进 RTP 包时用一个紧凑的本地 ID(1~14 或更大的数字)代表它。URI 和 ID 的映射,在 SDP 里协商:

a=extmap:2 http://www.webrtc.org/.../abs-send-time
a=extmap:3 http://www.ietf.org/id/.../transport-wide-cc-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid

头扩展的启用是协商出来的——双方用 a=extmap: 约定「ID 2 代表 abs-send-time」,之后每个 RTP 包里那个 2 号扩展,收端就知道怎么解读。 这和编解码器 payload type 的协商一个道理:用一个小数字代表一个长 URI,省字节。ModuleRtpRtcpImpl2 上有 RegisterSendRtpHeaderExtension / DeregisterSendRtpHeaderExtension 之类的接口来登记这些映射。没协商上的扩展不会被发送 / 解析——扩展是「双方都同意才用」。

格式上,RTP 扩展有 one-byte(ID 1-14,每个扩展 ≤16 字节)和 two-byte(ID 更多、数据更长)两种编码。WebRTC 按需选用,对读者而言知道「有这两种、按空间自动选」即可。

几个关键扩展

头扩展种类不少,但有几个是 WebRTC 的命脉:

扩展捎带什么给谁用
transport-wide-cc 序号一个跨所有流的全局发送序号Transport-CC 拥塞控制(第 5 部分)
abs-send-time包发送的绝对时间带宽估计(算单向延迟变化)
mid这个包属于哪条 m-lineBUNDLE 分流
audio-level音频音量会议里的「谁在说话」
video-orientation视频旋转角度手机横竖屏正确显示
playout-delay期望的播放延迟范围低延迟 / 同步场景

最重要的两个,是 transport-cc 序号和 mid。

  • transport-cc 序号是 WebRTC 现代拥塞控制的基石:它给每一个发出的包(跨所有流)打一个连续的全局序号,接收端记录每个序号包的到达时间,通过 RTCP 反馈报回发送端;发送端据此精确掌握「哪些包到了、什么时候到的、延迟怎么变」,这是 GCC 带宽估计的输入。没有它,现代 WebRTC 的拥塞控制无从谈起。
  • mid 让接收端在 BUNDLE(多流挤一条传输)时,靠包里的 mid 就能知道它属于哪条 m-line / 收发器,从而正确分流——比单靠 SSRC 更稳健(SSRC 可能在信令到达前就先收到包)。

一个包的真实样子

综合上一章和这一章,一个真实的 WebRTC RTP 包大致是:

[RTP 固定头: PT | seq | timestamp | SSRC]
[头扩展: transport-cc 序号=1234 | abs-send-time=... | mid=0]
[负载: SRTP 加密的编码媒体数据]

固定头给出「哪条流、第几个包、什么时刻」,头扩展给出「拥塞控制与分流的元数据」,负载是加密的媒体。小小一个包,信息密度极高——这是几十年实时传输经验的结晶。

小结与下一章

RTP 头扩展给每个包捎带标准头之外的元数据。机制是 URI ⟷ 本地 ID,经 SDP a=extmap 协商(one-byte / two-byte 两种编码)。最关键的两个:transport-cc 序号(全局发送序号 + 接收端记到达时间,是现代拥塞控制的基石)和 mid(BUNDLE 下的可靠分流);还有 abs-send-time、audio-level、video-orientation 等。

一个包要标明用哪种编解码器,靠 PayloadType 字段——而这个数字怎么分配,竟有不少讲究(范围、冲突、BUNDLE)。下一章讲。👉 Payload Type 分配。

参考资料

  • [1] libwebrtc 源码.modules/rtp_rtcp/source/rtp_header_extensions.h、rtp_header_extension_map.h、rtp_rtcp_impl2.h(注册扩展)。
  • [2] IETF RFC 8285「A General Mechanism for RTP Header Extensions」。
  • [3] IETF「transport-wide-cc」草案、RFC 内的 abs-send-time / mid 扩展定义。

本页目录