H.264基本概念总结之Slice与NALU
date
Mar 16, 2022
slug
2022-03-16-h264-slice-nalu
status
Published
tags
H.264
音视频
type
Post
AI summary
summary
本文总结了H.264视频编解码技术中的Slice、NALU等概念。
VCL与NAL
VCL:Video Coding Layer,视频编码层。
NAL :Network Abstraction Layer, 即网络抽象层。
在 H.264/AVC 视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL, Video Coding Layer)和网络抽象层面(NAL, Network Abstract Layer)。其中,前者负责有效表示视频数据的内容;而后者则负责格式化数据并提供头信息,以保证数据适合各种信道和存储介质上的传输。
- 简单地说,所谓的VCL就是图像帧经过H.264算法进行视频编码后所产生的编码图像数据,所以在后面的NALU中所封装的数据包含有两种类型,VCL和non-VCL,VCL表示的就是图像编码数据,non-VCL则是非图像压缩数据;
- 而所谓的NAL则是把H.264图像编码所产生字节流,进行合理和标准化的封装,以方便保存在存储介质上,或者通过网络等方式传输出去后,能够被播放端正确的解析、读取、解码、回放显示出来。
Frame与Slice
每一个Frame在编码的时候分为一个或者多个Slice进行编码,而每个Slice内部又可以包含有多个宏块。H.264进行编码的时候就是以宏块为单位进行编码的。
具体而言,Frame与Slice之间的关系在实践中可能是:
- 一个Frame只有一个Slice,这个Frame中所包含的宏块都在同一个Slice中进行编码;
- 每个Frame中包含有N个Slice,每个Slice包含有固定的M个宏块,M和N均为整数。每个Slice经过编码后产生的字节流的大小根据这个Slice中图像的运动和细节表现而变化,可能差异较大。
- 每个Frame中包含有N个Slice,每个Slice中包含的宏块数量不定,但是经过编码后各个Slice缩成的编码字节流大小基本一致。
NALU
NAL:Network Abstraction Layer。
NALU:Network Abstraction Layer Unit。
NALU是H.264编码产生数据进行保存和传输的基本单元,各个Slice编码后产生的数据使用NALU进行打包封装。实际上一个.h264文件就是有连续的很多个NALU组成。
- 当然并非所有的NALU中封装的都是Slice的编码数据。
一个标准的NALU总是包含有3个部分:start code(3个或者4个字节),nalu header(1个字节),nalu paylodf(不定长)。
每个NALU都固定的以0x00 0x00 0x01或者0x00 0x00 0x00 0x01开头,这个0x00 0x00 0x01或者0x00 0x00 0x00 0x01序列就是所谓的start code。
每个NALU开头的start code后面紧跟的那个字节就是nalu header。nalu header中包含有3个域:
- forbidden_zero_bit(1bit):H.264规范中要求该位应该设置为0。
- nal_ref_idc(2bit):nalu的重要性指示位,标志该NALU的重要性。值越大,表示该NALU越重要,解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU。
- nal_unit_type(5bit):用于表示这个NALU结构体中Payload部分包含的数据类型是什么。
nal unit type=6表示这个NALU中包含的是SEI信息。
nal unit type=7表示这个NALU中包含的是SPS信息。
nal unit type=8表示这个NALU中包含的是PPS信息。
- 以上三种类型的相关信息整理在H.264基本概念总结之SPS,PPS,SEI中。
H.264对一帧图像进行编码后所产生的的图像压缩数据(实际上也就是所谓的VCL数据)则保存在nal unit type=1-5这五种类型的NALU中。
- 其他nal unit type=5,就表示当前的这个NALU中封装的是IDR帧的数据。