H.264 的 NAL 单元及码流结构

NAL 简介

NAL 全称 Network Abstract Layer, 即网络抽象层。在H.264/AVC 视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)网络抽象层面(NAL),其中,前者负责有效表示视频数据的内容,而后者负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。NAL 单元是 NAL 的基本语法结构,它包含一个字节的头信息和一系列来自 VCL 的称为原始字节序列荷载(RBSP)的字节流。

NAL单元是 NAL 的基本语法结构,它包含一个字节的头信息和一系列来自 VCL 的称为原始字节序列载荷(RBSP)的字节流。头信息中包含着一个可否丢弃的指示标记,标识着该 NAL 单元的丢弃能否引起错误扩散,一般,如果 NAL 单元中的信息不用于构建参考图像,则认为可以将其丢弃;最后包含的是 NAL 单元的类型信息,暗示着其内含有效载荷的内容。在 RBSP 的最后包含一个 比特 1 若干比特 0,以便字节对齐。

H.264 的编码视频序列包括一系列的 NAL 单元,每个 NAL 单元包含一个 RBSP。编码片(包括数据分割片 IDR 片)和序列 RBSP 结束符被定义为 VCL NAL 单元,其余为 NAL 单元。

典型的 RBSP 单元序列。每个单元都按独立的 NAL 单元传送。NAL单元的类型如下表所示

NAL Type Description VCL
0 未规定 N/A
1 非 DIR 图像中不采用数据划分 Slice Yes
2 非 DIR 图像中 A 类数据划分 Slice Yes
3 非 DIR 图像中 B 类数据划分 Slice Yes
4 非 DIR 图像中 C 类数据划分 Slice Yes
5 IDR 图像的 Slice,Coded Video Sequence 的 Access Unit Yes
6 补充增强信息(SEI) NO
7 序列参数集(SPS) NO
8 图像参数集(PPS) NO
9 分割符(Access Unit Delimiter) NO
10 序列结束符(End of Sequence) NO
11 流结束符(End of Stream) NO
12 填充数据(Filler) NO
13 保留 N/A
14 未规定 N/A

H.264 码流结构

H.264 的码流结构如下图所示:

H.264码流结构

Annexb格式: NALU数据+起始码,如果 NALU 对应的 Slice 为一帧的开始,则用 4 字节表示,即 0x00000001;否则用 3 字节表示,0x000001

解惑:一个字节是由几个16进制的位组成?

两个16进制数!

一个字节八个比特,就是八个二进制位

四个二进制数最大表示为15,就是一个16进制数,所以八位可以表示成两个16进制的数!

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 单元传输过程中作为参考使用,在这些数据 NAL 单元的片头中,通过语法元素 pic_parameter_set_id 设置它们所使用的图像参数集编号;而相应的每个图像参数集中,通过语法元素 seq_paramter_set_id 设置他们使用的序列参数集编号。