参考标准文档:7.3和7.4节
一、NAL Unit结构
- NAL Unit:
- NAL Unit = NAL Header + NAL Body
- NAL Header:一个字节,包括:
- forbidden_zero_bit:规定必须为0禁止位,1 bit;
- nal_ref_idc:第2和3位,主要表示NAL的优先级。当该值为正时,表示当前NAL Unit中包含了SPS、PPS和作为参考帧的Slice等重要数据,2bit
- nal_unit_type:5bit,表示NAL Unit的类型,包括VCL层和非VCL层的多种数据类型。常见的nal_unit_type取值有:7表示SPS,8表示PPS,5表示IDR帧,1表示非IDR帧等
二、NAL Unit的有效负载数据及其封装
在NAL Header之后,NAL Unit的其余部分,即NAL Body包含了有效负载数据的封装。从NAL Body到实际的语法元素的码流自外向内共3层封装:
第一层:EBSP——扩展字节序列载荷
EBSP全称为Extended Byte String Payload,等同于NAL Body的数据本身。在EBSP中包含了一个特殊的字节0x03,表示防止竞争校验字节:
- emulation_prevention_three_byte:设置该值的目的是为了防止NAL Body内部出现于NAL Unit起始码0x 00 00 01或0x 00 00 00 01冲突。
- 当内部的连续4字节数据出现了下列情况时:
0x 00 00 00
0x 00 00 01
0x 00 00 02
0x 00 00 03 - 在两个0字节之后会插入值为3的一个字节,形成下列情况:
0x 00 00 03 00
0x 00 00 03 01
0x 00 00 03 02
0x 00 00 03 03 - 在进行解析时需要将附加的03字节去掉,得到RBSP数据。
第二层:RBSP——原始字节序列载荷
- RBSP全称为Raw Byte Sequence Payload
- 相当于NAL Body去掉03字节之后的数据,是对原始的语法元素码流进一步处理后产生的数据
- 相比于原始的语法元素码流,RBSP在末尾添加了rbsp_trailing_bits()部分,其主要目的是字节对齐
- 每个rbsp_trailing_bits()包括一个1bit和若干个0bit,0bit的个数不定,以实现字节的对齐。
例如: xxx 11010000 //后面的10000是为了对齐,如果不对齐会导致后面所有的都存在对齐问题(编码之后的数据并不是字节对齐的)
第三层:SODB——数据字节流
- SODB全称为String Of Data Bits
- 表示H.264的语法元素编码完成后的实际的原始二进制码流。SODB通常不能保证字节对齐,所以需要逐层向上封装