1.H264的格式
a video coding layer (VCL) and a network abstraction layer (NAL)
一个网络层,一个视频层,网络层肯定是用于互联网传输,视频层就是视频数据了。
2.RTP格式
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 |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
PT:代表支持的音视频格式的编号;sequence number:代表序列号,可以用来确定是否丢包
那么h264在RTP的哪个部分,是怎么存放的呢?
根据rfc协议和wireshark软件观察,前12个字节为RTP头部,csrc为H264的数据部分
现在越来越觉得还是看标准文件和研究原始数据才是王道,google的效率不一定高,而且学到的东西很少!
那么H264数据又是如何存储的了?
根据观察H264由于数据比较大,都是分成多个rtp包发过来的,那么如何把它们组合在一起了?
协议应该会标示哪些是h264的开始,哪些是h264的结尾,继续看rfc寻找答案。
h264前面1个字节,会标注h264是否分包,type类型根据下表就可以查找h264是否被分包
比如:如果h264被分包了,那么如何知道分包什么时候开始什么时候结束呢?
接着的1个字节将告诉你,s表示开始标志位,e标示结束标志位。
h264的数据已经获取到了,接下来,我们要考虑如何获取视频的宽度和高度来用ffmpeg初始化视频了?
那么我们是从rtsp中还是h264本身的数据中寻找这两个参数呢?
经过观察发现rtsp中并没有提供这两个参数,那么h264中是否会提供这两个参数呢?
很有可能!因为h264中有两个关键的数据sps(Sequence parameter set序列参数集),pps(Picture parameter set图片参数集),看这两个参数的名字,就觉得有可能,那么继续研究h264的itu文档,寻找答案。
那么,接下来,我们首先要从h264的nal头中找到哪些数据是sps,哪些数据是pps
h264用第一个字节作为nal头,详细请看下表
nal_unit_type |
NAL类型 |
C |
0 |
未使用 |
|
1 |
不分区、非IDR的片 |
2,3,4 |
2 |
片分区A |
2 |
3 |
片分区B |
3 |
4 |
版分区C |
4 |
5 |
IDR图像中的片 |
2,3 |
6 |
补充增强信息单元(SEI) |
5 |
7 |
序列参数集 |
0 |
8 |
图像参数集 |
1 |
9 |
分界符 |
6 |
10 |
序列结束 |
7 |
11 |
码流结束 |
8 |
12 |
填充 |
9 |
13..23 |
保留 |
|
24..31 |
不保留 |
|
根据观察,发现sps中,有这两个参数 pic_width_inmbs_minus1, pic_height_in_map_units_minus1,会不会代表视频的长宽呢?