参考:
http://blog.csdn.net/EricBaner/article/details/3950810
http://wenku.baidu.com/view/ab19d6c79ec3d5bbfd0a7418.html
一、NAL简介
在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(NAL)。其中,前者负责有效表示视频数据的内容,而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。现实中的传输系统是多样化的,其可靠性,服务质量,封装方式等特征各不相同,NAL这一概念的提出提供了一个视频编码器和传输系统的友好接口,使得编码后的视频数据能够有效地在各种不同的网络环境中传输。
对于基于流的传输系统如H.320、MPEG等,需要按照解码顺序组织NAL单元,并为每个NAL单元增加若干比特字节对齐的前缀以形成字节流;对于RTP/UDP/IP系统,则可以直接将编码器输出的NAL单元作为RTP的有效载荷;而对于同时提供多个逻辑信道的传输系统,我们甚至可以根据重要性将不同类型的NAL单元在不同服务质量的信道中传输。
NAL单元是NAL的基本语法结构,它包含一个字节的头信息和一系列来自VCL的称为原始字节序列载荷(RBSP)的字节流。头信息中包含着一个可否丢弃的指示标记,标识着该NAL单元的丢弃能否引起错误扩散,一般,如果NAL单元中的信息不用于构建参考图像,则认为可以将其丢弃;最后包含的是NAL单元的类型信息,暗示着其内含有效载荷的内容。在RBSP的最后包含一个 比特1若干比特 0,以便字节对齐。
H.264 的编码视频序列包括一系列的 NAL 单元,每个 NAL 单元包含一个 RBSP。编码片(包括数据分割片 IDR 片)和序列 RBSP 结束符被定义为 VCL NAL 单元,其余为 NAL 单元。
典型的 RBSP 单元序列。每个单元都按独立的 NAL 单元传送。NAL单元的类型如下表所示。
H.264的码流结构如下图所示:
Annexb格式:NALU数据+起始码,如果 NALU 对应的 Slice 为一帧的开始,则用 4 字节表示,即 0x00000001;否则用 3 字节表示,0x000001。
RTP格式:NALU数据+RTP协议的RTP头数据。
NAL Header:forbidden_bit,nal_reference_bit(优先级),nal_unit_type(类型)。
脱壳操作:为了使 NALU 主体不包括起始码,在编码时每遇到两个字节(连续)的0,就插入一字节 0x03,以和起始码相区别。解码时,则将相应的 0x03 删除掉。
三、H.264解码
NAL 头信息的 nal_referrence_idc(NRI)用于在重建过程中标记一个 NAL 单元的重要性,值为 0 表示这个 NAL 单元没有用预测,因此可以被解码器抛弃而不会有错误扩散;值
高于 0 表示 NAL 单元要用于无漂移重构,且值越高,对此 NAL 单元丢失的影响越大。
NAL 头信息的隐藏比特位,在 H.264 编码器中默认为 0,当网络识别到单元中存在比特错误时,可将其置为 1。隐藏比特位主要用于适应不同种类的网络环境(比如有线无线相
结合的环境)。
NAL 单元解码的流程为:首先从 NAL 单元中提取出 RBSP 语法结构,然后按照下图所示的流程处理 RBSP 语法结构。输入的是 NAL 单元,输出结果是经过解码的当前图像的样值点。
NAL 单元中分别包含了序列参数集和图像参数集。图像参数集和序列参数集在其他NAL 单元传输过程中作为参考使用,在这些数据 NAL 单元的片头中,通过语法元素
pic_parameter_set_id 设置它们所使用的图像参数集编号;而相应的每个图像参数集中,通过语法元素 seq_paramter_set_id 设置他们使用的序列参数集编号。