H.264码流结构
- 由多个NALU组成
- NALU
NAL:Network Abstraction Layer,网络抽象层面
NAL unit是NAL的基本语法结构,它包含一个字节的头信息(NAL header)和一系列来自VCL的原始数据字节流(RBSP)。
一个原始的H.264 NALU 开头必须是"00 00 00 01" 或"00 00 01"
- NALU header
为一个字节
由三部分组成forbidden_bit(1bit)H264定义此位必须是零,nal_reference_bit(2bits)(优先级,3最高),nal_unit_type(5bits)(类型)。
forbidden_bit:禁止位
nal_reference_bit:当前NAL的优先级,值越大,该NAL越重要
nal_unit_type :NAL类型
Start Code Prefix为3个字节. 但是,为了寻址方便,要求数据流在长度上对齐,因此H.264建议在Start Code Prefix前面加若干个0.
- RBSP
RBSP: Raw Byte Sequence Payload,原始字节序列载荷
由SODB和RBSP trailing bits构成的
- SODB
SODB:String Of Data Bits (原始数据比特流, 长度不一定是8的倍数,故需要补齐)
- RBSP trailing bits syntax
H.264码流的RBSP级别,是由SODB和RBSP trailing bits构成的
由于编码后的数据要精确到位(bit)组装起来,而码流又是以字节为单位的,这样就需要补齐到字节。
- 逻辑关系:
SODB + RBSP trailing bits = RBSP
NAL header(1 byte) + RBSP = NALU
Start Code Prefix(3 bytes) + NALU + Start Code Prefix(3 bytes) + NALU + ...+ = H.264BitsStream
NALU类型
- SEI
NALU type=6
SEI:Supplemental Enhancement Information,补充增强信息
属于码流范畴,它提供了向视频码流中加入额外信息的方法,是H.264/H.265这些视频压缩标准的特性之一
- SPS
SPS:Sequence Parameter Set,序列参数集
NAL uint_type=7
包括了一个图像序列的所有信息(包含的是针对一连续编码视频序列的参数,如标识符seq_parameter_set_id、帧数及POC的约束、参考帧数目、解码图像尺寸和帧场编码模式选择标识等)
- PPS
PPS:Picture Parameter Set,图像参数集
NAL uint_type=8
包括了一个图像所有片的信息(对应的是一个序列中某一副图像或者某几幅图像,参数如标识符pic_parameter_set_id、可选的seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等)
- SLICE
片
NAL uint_type=1-5
一帧视频图像可编码成一个或者多个片,每片包含整数个宏块,即每片至少一个宏块,最多时包含整个图像的宏块
- 宏块
宏块大小通常是:16*16像素
一个宏块 = 一个16*16的亮度像素 + 一个8×8Cb + 一个8×8Cr彩色像素块组成。
- 其他NALU type
量化参数(QP:quant param)
在H.264中,量化参数分3个级别给出:图像参数集(pps)、片头(slice_header)、宏块(mb)。
参数使用指数哥伦布码方式保存
1、图像参数集
pps.pic_init_qp_minus26:初始值,取值范围是-26, + 25
上图信息由Elecard StreamEye Tools的EsEye工具读取H264裸码流生成
2、片头
slice_header.slice_qp_delta:当前片所有宏块的量化参数初始值QPy
SliceQPy = 26 + pic_init_qp_minus26 + slice_qp_delta,取值范围是0, 51
3、宏块
- mb.mb_qp_delta:宏块量化参数偏移值, 取值范围是-26, + 25,指示的偏移是前后两个宏块之间的偏移
- 片中第一个宏块的QP = 26 + pic_init_qp_minus26 + slice_qp_delta
- 后续宏块的QP = (QPprev + mb_qp_delta + 52) % 52
4、一帧图像的统计
Exp-Golomb指数哥伦布码
指数哥伦布码(Exponential-Golomb)属于熵编码,属于无损编码
H.264中使用的是0阶指数哥伦布编码,编码方式如下:
以待编码码号code_num = 3为例:
第一步:将code_num +1, 即3+1 = 4
第二步:将4写为二进制的形式:100
第三步:计算100的比特个数为3,在100前面写(3-1)个0,得到编码码字:00100
0阶指数哥伦布码如下所示:
0 => 1 => 1
1 => 10 => 010
2 => 11 => 011
3 => 100 => 00100
4 => 101 => 00101
5 => 110 => 00110
6 => 111 => 00111
7 => 1000 => 0001000
8 => 1001 => 0001001
参考资料
- 软件:Elecard StreamEye Tools,解析H.264码流使用
- 新一代视频压缩码标准-H.264_AVC(第二版).毕厚杰,王健编著
- 从零了解H264结构
- 指数哥伦布码