RTP
RTP 头部结构详解 (RTP Header Format)
为了方便记忆,首先给出一张标准的 RTP 头部位图(32 bits 宽):
text
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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Contributing Source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1. 基础控制字段 (Byte 0)
-
Version (V, 2 bits): [Bit 0-1]
- 协议版本号。当前标准版本为 2。
-
Padding (P, 1 bit): [Bit 2]
- 含义:若置为 1,说明 RTP 包末尾包含额外的填充字节(Payload 之后)。
- 作用:主要用于加密算法(如 DES、AES)需要固定块大小,或 DMA 传输要求字节对齐(如 64 字节对齐)的场景。
- 规则 :填充区域的最后一个字节记录了填充的总字节数(包括它自己)。
-
Extension (X, 1 bit): [Bit 3] (原文未提及,补充以保证完整性)
- 若置为 1,则 RTP 头后会跟一个扩展头,用于承载实验性或特定应用的扩展信息。
-
CSRC Count (CC, 4 bits): [Bit 4-7]
- 含义:贡献源列表(CSRC)的计数。
- 场景:
- 点对点(P2P)/ 简单推流:值为 0(这也是最常见的情况)。
- 混音/电话会议:值为混音器(Mixer)之前的说话人数目。随后会在头部附带这些人的 ID(每个 ID 占 4 字节),方便接收端显示"谁在说话"。
2. 负载与序号 (Byte 1-3)
-
Marker (M, 1 bit): [Bit 8]
- 含义:标记位,具体语义由应用层配置文档(Profile)定义。
- 典型应用:
- 视频:表示一帧图像的结束(Frame Boundary)。如果一帧图像太大被拆分成多个 RTP 包,只有最后一个包的 M 位置 1。
- 音频:表示一段谈话(Talk Spurt)的开始,用于静音抑制后的重新同步。
-
Payload Type (PT, 7 bits): [Bit 9-15]
- 含义:有效载荷类型,即"给数据包贴的内容标签"。范围 0~127。
- 分类 (根据 RFC 3551):
- 静态类型 (0-95):历史遗留的标准类型(如 PCMU=0, PCMA=8, JPEG=26)。
- 动态类型 (96-127) :当前最常用 。用于 H.264、H.265 (HEVC)、Opus 等。具体对应的编码格式需在 SDP (Session Description Protocol) 中协商定义(例如:
rtpmap:96 H264/90000)。
-
Sequence Number (16 bits): [Bit 16-31]
- 机制:每发送一个 RTP 包,该值 +1。
- 作用:
- 丢包检测:接收端发现序号不连续,即知丢包。
- 乱序重排:UDP 不保证顺序,接收端通过序号将包重新按序排列。
- 安全性 :初始值设为随机数,以防御已知明文攻击(Known-plaintext attack)。
3. 时间与同步 (Byte 4-11)
-
Timestamp (32 bits):
-
含义 :反映该 RTP 包中第一个字节的采样时刻。
-
核心作用:
-
同步回放:让 Receiver 知道在什么时间点播放这段数据,恢复数据原本的时间间隔。
-
抗抖动:配合 Jitter Buffer 计算网络抖动。
-
注意 :属于同一视频帧的所有 RTP 包,时间戳是相同的(因为它们是同时采样的),但序列号是递增的。
-
-
SSRC (Synchronization Source Identifier, 32 bits):
- 含义:同步源标识符,用于区分不同的媒体流。
- 特点:随机生成,但在同一个 RTP 会话中必须唯一。
RTCP
总的来说RTCP的结构就是一个包头加上想发送的类型
RTCP的类型
| 名字 | 全称 | PT 值 | 谁来发? | 作用 |
|---|---|---|---|---|
| SR | Sender Report | 200 | 发送端 (你) | "我发了多少包,现在的绝对时间是几点。" (用于音画同步) |
| RR | Receiver Report | 201 | 接收端 (VLC) | "我收到了多少,丢包率是多少。" (用于拥塞控制) |
| SDES | Source Description | 202 | 双方都发 | "我的名字叫 Camera01。" (类似于备注名) |
| BYE | Goodbye | 203 | 双方都发 | "挂断了,再见。" (结束会话) |
| APP | Application | 204 | 自定义 | 开发者自己定义的私有协议数据。 |
RTCP的包头
A. 第 1 个字节 (Bit 0-7)
- V (Version, 2 bits) :版本号。
- 固定值:2 (
10二进制)。和 RTP 一模一样。 - 如果抓包看到不是 2,说明包坏了或者不是 RTCP。
- P (Padding, 1 bit) :填充位。
- 通常为 0。
- 如果为 1,表示这个 RTCP 包的末尾有一些填充字节(用于对齐),最后一个字节记录了填充长度。逻辑和 RTP 的 P 位完全一致。
- RC (Report Count, 5 bits) :报告计数(有时也叫 SC - Source Count)。
- 含义:这个包后面跟了几个"接收报告块"?
- 你的场景(纯推流) :因为你是摄像头(Sender),你只发不收,所以你没有"接收报告"要汇报给别人。填 0。
- 注:如果是 SDES 包,这里表示包含几个人的信息。
B. 第 2 个字节 (Bit 8-15)
- PT (Payload Type, 8 bits) :包类型。
- 这是区分你是 SR 还是 RR 的关键 ID。
- 200 (SR) :发送端报告(Sender Report)。你主要用这个。
- 201 (RR):接收端报告(Receiver Report)。
- 202 (SDES):源描述(Source Description)。
- 203 (BYE):再见。
C. 第 3-4 个字节 (Bit 16-31)
- Length (16 bits) :包长度。
-
⚠️ 超级大坑!必看!
-
它的单位不是字节 ,而是 32-bit 字(4字节)。
-
而且,它记录的值是 (总长度 / 4) - 1。
-
计算公式:
-
包括头部吗? 包括!
-
例子 :
一个标准的 SR 包(不带接收报告块)总长 28 字节 。
计算:。
减一:。
所以这里你应该填 6 (
0x0006),而不是 28。
SDP
SDP (Session Description Protocol) 是媒体流的 "名片" 或 "说明书"。
在你的 RTSP/RTP 项目中,SDP 并不负责传输数据(那是 RTP 的事),也不负责控制播放(那是 RTSP 的事)。它的唯一作用是告诉播放器(客户端)这一路流的详细配置信息。
如果没有 SDP,播放器收到你的 RTP 包后会一脸懵逼:"这是 H.264 还是 H.265?分辨率多少?帧率多少?我该用哪个解码器?"
1. SDP 在哪里出现?
当你用 VLC 打开一个 RTSP 地址 rtsp://192.168.1.100/live 时,交互流程如下:
- OPTIONS: 问服务器支持什么指令。
- DESCRIBE : 客户端问:"请给我看看你的说明书(SDP)。"
- 200 OK (含 SDP): 服务器把一段文本(SDP)发回给客户端。
- SETUP: 客户端看了说明书,决定建立连接。
- PLAY: 开始传 RTP 包。
结论:SDP 是在正式传视频之前,双方协商格式用的。
2. SDP 里到底写了什么?(核心字段解析)
SDP 是一堆看起来像乱码的键值对文本。对于 H.264 推流 项目,最重要的只有 m行 和 a行。
看一个标准的 H.264 SDP 范例:
text
v=0
o=- 123456 123456 IN IP4 192.168.1.100
s=My RK3576 Stream
c=IN IP4 0.0.0.0
t=0 0
m=video 0 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;sprop-parameter-sets=Z0LgH5Z8C...,aM48gA==;
a=control:track0
关键字段解读:
-
m=video 0 RTP/AVP 96(Media Line) -
video: 这是一路视频。
-
0: 端口号(在 RTSP 中通常填 0,因为端口在 SETUP 步骤才确定)。
-
RTP/AVP: 使用 RTP 协议。
-
96 : 重点! 这就是我们之前说的 Payload Type。这里定义了 96 代表这路流。
-
a=rtpmap:96 H264/90000(Attribute Mapping) -
翻译官 :这句话告诉播放器,"刚才上面写的数字 96,代表 H.264 编码,时钟频率是 90000Hz"。
-
如果没有这一行,播放器看到 RTP 包头的 96 就不认识了。
-
a=fmtp:96 ...(Format Parameters) -
最硬核的地方 :这里面通常藏着 SPS 和 PPS(H.264 的关键参数集)。
-
sprop-parameter-sets=Z0LgH5...,aM48...: 这是一串 Base64 编码。 -
作用 :有了这个,播放器不用等待下一个 I 帧 ,甚至不需要收到流里的 SPS/PPS NALU,立刻就能初始化解码器出图。这就是"秒开"的关键。