详解RTP协议之H264封包细节(1)

0.引言
为了更好理解本篇文章 , 可以先阅读前面几篇文章 , 文章列表如下:
详细解析RTSP框架和数据包分析(1)
手把手搭建RTSP流媒体服务器
RTP协议
HLS实战之Wireshark抓包分析
HTTP实战之Wireshark抓包分析
1.RTP封包H264简述
RTP第一个特点就是利于低延迟音视频数据的传输 , 另?个特点是它允许通过其它协议接收端和发送端协商?视频数据的封装和编解码格式 , 就是能够更好的适应其它应用层协议 , 这样固定头的playload type字段就?较灵活适配各种协议 。 RTP可以传输很多种音视频数据类型 。 参考如下链接地址:
界面如下:
详解RTP协议之H264封包细节(1)文章插图
在数据封装是 , 上面一层是H264NALU , 再用RTP打包 , RTP使用UDP或TCP去发送数据 。 UDP每个包有大小限制 , 如MTU一般是1500 , sendto一般不能发送超过1500 , 而RTMP一般大小是1434左右(RTP header + RTP payload) 。 这就涉及到打包和拆包的原理和方法 。
其中RTP打包H264的详细方法 , 可以参考文档RFC6184 。 如下界面:
详解RTP协议之H264封包细节(1)文章插图
2.封包详解
很早之前的文章有写过H264的内部结构 , H.264标准协议定义了两种不同的类型 , ?种是视频编码层VCL(Video Coding Layer),? 种是网络抽象层 NAL (Network Abstraction Layer) 。 其中前者就是编码器吐出来的原始编码数据 , 没有考虑传输和存储 。 后者就是为了展现H.264的?络亲和性 , 对VCL输出的slice片数据进行了封装为NALUs(NAL Units) , 然后再封装为RTP包进?传输 。
NALU的基本格式是NALU Header+NALU Data , 其头部由一个字节组成 , 如下图所示:
详解RTP协议之H264封包细节(1)文章插图
2.1 NALU Header描述
NALU Header的头部解释 , 有如下表格:
详解RTP协议之H264封包细节(1)文章插图
2.2 NALU Type描述
NALU_Type由0-31组成 , 每个type值表示不同的含义 。 如下表格:
由于时间戳的问题 , 就有了24-29?种类型 。
详解RTP协议之H264封包细节(1)文章插图
详解RTP协议之H264封包细节(1)文章插图
详解RTP协议之H264封包细节(1)文章插图
2.3 NALU 封包和拆包方法
?个NALU的??是不?样的 , 如果是?视频数据的SPS PPS才??个字节 , 对于IDR帧 , 则有可能??KB 。 同一个NALU拆分成多个RTP包进行发送 。 一般NALU(去掉startcodec , RTP传输的时候不传输startcode)的大小 。 SPS一般是25字节左右 , PPS一般是5字节左右 , SEI帧是600字节左右 , 1080P的I帧是200K字节左右 , 一个RTP包发送不完一个I帧 , 那就需要同一个NALU拆分成多个RTP包进行发送 。 这样NALU打包的方式就有以下几种:
(1)?个RTP包承载?个NALU , 一种就是nalu size(主要是payload部分) < rtp size , 就是1:1发送 。 就是nalu只有一个字节 , 也会rtp包发送 。 一般很小帧才使用 , 如pps , B帧等 。
(2)?个?的NALU切分成多个RTP , 一种就是nalu size大于rtp size , 那就是1:N发送 。 大多数还是使用FU-A模式 。 要分成起始 , 中间过程 , 结束值 。
(3)多个NALU合并到?个RTP 。
注意:一个RTP包也可以发送多个NALU , 如sps、pps、SEI帧一起发送 。 一般一个NALU对应的就是一帧数据 , 也有可能是多个NALU对应一帧数据 。 很多时候为了简化程序 , sps、pps、SEI帧还是独立地发送数据 。 组合起来发送(可能就需要缓存) , 还是很少
2.4 工程应用中封包方式
发送端 , 对于发送端组RTP包 , 尽可能找简单的打包?式 。
接收端 , 对于接收端则需要适配各种发送端的打包?式 , 因为?法决定输?源的打包?式 。 这?先分享下打包?式 , ?较简单 , 打包的时候最好不要搞得这么复杂 。 打包的方式如下:
(1)当NALU的?度<=1400(rtp payload size)的则采?的是单?NALU打包到单?的RTP包中 。 就是上面所描述的一对一 。
(2)当于NALU的?度>1400的则采?了FU-A的?式进?了打包 , 发送端就是把?个?的NALU进?了切分 , 最后接收端则进?了合并 , 把多个RTP包合并成?个完整的NALU即可
注意:这里说NALU的?度?于1400字节就要进?FU-A切? , 是因为底层MTU??值固定为1500 , 从传输效率讲 , 这??1400作为切分条件 。
在实际的工程项目中 , 在视频监控领域摄像头通过RTP 传输码流的打包?式基本都是FU-A , 这种打包?案简单容易实现 , ?满?需要 。 Wireshark抓包如下图所示: