将视频装入 RTP 的正确姿势,就像打包易碎品——分步骤、标序号、贴时间,确保接收方能完整拼回原样!以下是通俗步骤:
一、RTP 基础:快递盒的“标准包装”
每个 RTP 包像一个小快递盒,包含 头部信息 和 视频数据载荷:
[ RTP头部 | 视频数据 ]
RTP 头部关键字段:
- 序号(Sequence Number) :给每个包编号(1,2,3...),防乱序或丢包检测。
- 时间戳(Timestamp) :标记数据采集时间,确保音视频同步。
- 负载类型(Payload Type) :说明视频编码格式(如 H.264=96,VP8=100)。
- 同步源(SSRC) :唯一标识流来源(如摄像头设备ID)。
二、视频分片:大件拆成小包裹
视频帧(尤其关键帧)可能很大,需拆成多个 RTP 包发送:
1. 编码后的数据分块:
-
H.264/H.265:按 NAL 单元(NALU)拆分,每个 NALU 包含头部和视频数据。
[ NALU头 | 视频数据 ] -
VP8/VP9:按帧分块,通常一帧一包(若小)或分片。
2. RTP 分片规则:
-
单包模式:小 NALU 直接装入一个 RTP 包。
[RTP头 | NALU头 | 视频数据] -
分片模式(FU-A) :大 NALU 拆成多个 RTP 包,每包加 分片头。
[RTP头 | FU指示头 | FU分片头 | 视频分片]-
分片头字段:
S(Start):标记分片起始包(1表示开始)。E(End):标记分片结束包(1表示结束)。Type:原始 NALU 类型(如 H.264 的 IDR 帧类型)。
-
三、H.264 分片示例
假设一个 IDR 帧的 NALU 太大,需拆成 3 个 RTP 包:
包1:[RTP头 | FU指示头 | S=1,E=0 | 分片1数据]
包2:[RTP头 | FU指示头 | S=0,E=0 | 分片2数据]
包3:[RTP头 | FU指示头 | S=0,E=1 | 分片3数据]
接收方根据 S/E 标记和序号重组完整 NALU。
四、时间戳的“心跳规则”
-
增量计算:
-
时间戳按 采样率 递增。例如:
- 视频帧率 30fps → 时间戳增量 = 90000 / 30 = 3000(RTP 时钟通常 90kHz)。
- 第一帧时间戳 = 0,第二帧 = 3000,第三帧 = 6000,依此类推。
-
-
音频同步:若同时传音频,音频和视频时间戳需基于同一时钟基准。
五、实战注意事项
-
MTU 限制:
- 确保单个 RTP 包不超过网络 MTU(通常 ≤ 1400 字节),否则分片。
-
序号连续:
- 序号逐个 +1,接收方检测不连续可触发重传或纠错。
-
关键帧标记:
- 在 RTP 扩展头或负载中标记关键帧(I帧),便于丢包后快速恢复。
-
与 RTCP 配合:
- 定期发送 RTCP 报告(如每秒一次),反馈丢包率和延迟,动态调整编码。
六、工具推荐
-
FFmpeg:一键生成 RTP 流
ffmpeg -i input.mp4 -c:v libx264 -f rtp rtp://192.168.1.100:5004 -
Wireshark:抓包分析 RTP 结构,验证分片和时间戳。
总结口诀
“视频分片像拆箱,RTP包按序号装。
时间戳记同步用,负载类型标格式。
关键帧要打标记,分片头尾标清楚。
配合RTCP调网络,实时传输稳如狗!”