H.264亦称为H.264/AVC(先进视频编码),由MPEG和ITU合作制定的视频编码标准。从原理上讲,H.264仍旧秉承传统混合编码架构,但由于在编码细节引入和诸多改进,将许多一直停留在纸上的技术如可变尺寸块的运动补偿、多参考帧预测等付诸实践,使编码效率得到了显著的提高,同时也大大增加了编解码器的复杂度和运算量。是由ITU-T视频编码专家组(VCEG)和ISO/IEC动态图像专家组(MPEG)联合组成的联合视频组(JVT,Joint Video Team)提出的高度压缩数字视频编解码器标准。对应的标准文档是ISO 14496-10.这个标准通常被称之为H.264/AVC(或者AVC/H.264或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC)而明确的说明它两方面的开发者。
H.264分为2层:
视频编码层 (VCL: Video Coding Layer): 进行视频编解码,包括运动补偿预测,变换编码和熵编码等功能;
网络提取层 (NAL: Network Abstraction Layer): 用于采用适当的格式对VCL视频数据进行封装打包
VCL需要打包成NAL,才能用于传输或存储.
分层的目的:
(1) 可以定义VCL视频压缩处理与NAL网络传输机制的接口,这样允许视频编码层VCL的设计可以在不同的处理器平台进行移植,而与NAL层的数据封装格式无关;
(2) VCL和NAL都被设计成工作于不同的传输环境,异构的网络环境并不需要对VCL比特流进行重构和重编码。
NAL单元(NAL Unit, NALU)是NAL的基本语法结构,由1字节的头,3个定长的字段和一个字节数不定的编码段组成.
NALU Header(8bit) = 禁止位(1bit) + 重要性指示位(2bit) + NALU类型(5bit)
NALU类型:1~12由H.264使用,24~31由H.264以外的应用使用。
重要性指示:标志该NAL单元用于重建时的重要性,值越大,越重要。
禁止位:网络发现NAL单元有比特错误时可设置该比特为1,以便接收方丢掉该单元
注: NALU 类型
如果NALU对应的Slice为一帧的开始,则用4字节表示,即0x00000001;否则用3字节表示,0x000001
以0x000001分割之后就是NAL头,格式应为:0AAB BBBB
解析如下:
(1)第1位禁止位,值为1表示语法出错
(2)第2~3位为参考级别
(3)第4~8为是nal单元类型(详见3.1)
AA用于表示该NAL是否可以丢弃(有无被其后的NAL参考):
0——表示没有参考作用,可丢弃,如B slice、SEI等,
非零——包括01b、10b、11b——表示该NAL不可丢弃,如SPS、PPS、I Slice、P Slice等。
常用的NAL头的取值如:
0x67: SPS 0x68: PPS 0x65: IDR 0x61: non-IDR Slice 0x01: B Slice 0x06: SEI 0x09: AU Delimiter
注:判断是否为I帧方法为:
(NALU类型 & 0001 1111) = 5 即 NALU类型 & 31 = 5
由于NAL的语法中没有给出长度信息,实际的传输、存储系统需要增加额外的头实现各个NAL单元的定界。
其中,AVI文件和MPEG TS广播流采取的是字节流的语法格式,即在NAL单元之前增加0x00000001的同步码,则从AVI文件或MPEG TS PES包中读出的一个H.264视频帧以下面的形式存在:
00 00 00 01 06 ... 00 00 00 01 67 ... 00 00 00 01 68 ... 00 00 00 01 65 ... SEI信息 SPS PPS IDR Slice
而对于MP4文件,NAL单元之前没有同步码,却有若干字节的长度码,来表示NAL单元的长度,这个长度码所占用的字节数由MP4文件头给出;此外,从MP4读出来的视频帧不包含PPS和SPS,这些信息位于MP4的文件头中,解析器必须在打开文件的时候就获取它们。从MP4文件读出的一个H.264帧往往是下面的形式(假设长度码为2字节):
00 19 06 [... 25 字节...] 24 aa 65 [... 9386 字节...] SEI信息 IDR Slice
[1] h264 NAL头解析 http://blog.csdn.net/occupy8/article/details/9042139
[2] H264(NAL简介与I帧判断) http://blog.csdn.net/jefry_xdz/article/details/8461343