一、NAL全称Network Abstract Layer, 即网络抽象层。
在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。
一段h.264的码流通常是由多个GOP组成的,GOP内一般包含1sps+1pps+1sei+1I帧+若干p帧(加上B帧一共有6种单元结构)。
二、结构单元介绍
1、sps(序列参数集)
(1)序列参数集。SPS中保存了一组编码视频序列(Coded video sequence)的全局参数,所谓的编码视频序列即原始视频的一帧一帧的像素数据经过编码之后的结构组成的序列。而每一帧的编码后数据所依赖的参数保存于图像参数集中
(2)里面包含宏块编码方式、图像大小尺寸、宏块个数,播放器通过这些参数,调用播放器里面的对应算法去解码
2、pps(图像参数集)
(1)H.264中另一重要的参数集合为图像参数集Picture Paramater Set(PPS)
3、SEI
(1)也是一些图像的额外信息,帮助播放器解析压缩图像
4、I帧、P帧、B帧
(1)I帧是关键,丢了I帧当前sequence就废了,每个sequence有且只有1个I帧
(2)帧内编码帧 ,I帧表示关键帧,你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成(因为包含完整画面),I帧大,说明本身压缩比不高,图像数据更完整,则P帧可以越小,反之I帧越小则P帧会越大
(3)P帧:前向预测编码帧。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)
(4)B帧:双向预测内插编码帧。B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别
三、实战分析一帧(I帧)
下面分析一个I帧的数据(其实不止I帧,这里包含了sps、pps、I帧,因为通常情况下,这三货是哐哐很快地一起编码过来的,就保存在一起了,判断是sps即可认为是I帧):
1、分隔符
红色框框的,H.264在编码的时候,生成一个序列时,序列中每个单元前面就会加上00 00 00 01作为分隔符
2、分隔符后第一个字节(绿色框框的)
分隔符后面紧跟着的第一个字节就是用来判断是什么类型的单元,详情如下:
1)第1位禁止位,值为1表示语法出错
2)第2~3位为参考级别
3)第4~8为是nal单元类型(比如是0x67(取5位00111表示sps)
NAL 单元中的 RBSP 数据结构的类型,Nal 单元类型码,如下所示:
Nal_ref_type |
内容 |
0 |
未指定 |
1 |
不分区,非IDR图像的片 |
2 |
片分区A |
3 |
片分区B |
4 |
片分区C |
5 |
IDR图像中的片 |
6 |
辅助增强信息 (SEI) |
7 |
SPS 序列参数集 |
8 |
PPS 图像参数集 |
9 |
访问单元分隔符AUD |
10 |
序列结束 |
11 |
流结尾 |
12 |
填充数据 |
13 |
序列参数集扩展 |
14....18 |
保留 |
19 |
未分割的辅助编码图像的编码条带 |
20...23 |
保留 |
24...31 |
未指定 |
其中1~12由H.264使用,24~31由H.264以外的应用使用。只需要记得常用的sps、pps、I帧、p帧对应的数值就好。
3、绿色框框后面紧跟着的就是该结构单元的实际数据了,0x27后面的即为sps的实际内容,0x28后面即为pps的内容,0x25后面才真真正正的I帧的数据(也有人把这三合在一起叫I帧)。