H.264 码流结构
从码流功能的角度可以分为两层:视频编码层(VCL)和网络抽象层(NAL)。
VCL层
VIdeo Coding Layer, 视频数据编码层,表示被压缩编码后的视频数据序列。
NAL层
Network Abstraction Layer, 视频数据网络抽像层。负责以网络所要求的恰当的方式对 VCL 数据进行打包和传送。VCL数据将被封装到一个个的NALU中。
NALU Header
- forbidden_zero_bit 在网络传输中发生错误时,会被置为 1,告诉接收方丢掉该单元;否则为 0。
- nal_ref_idc 用于表示当前NALU的重要性,值越大,越重要。 解码器在解码处理不过来的时候,可以丢掉重要性为 0 的 NALU。
- nal_unit_type 表示 NALU 数据的类型
NALU Payload
SODB
String Of Data Bits,称原始数据比特流,就是最原始的编码/压缩得到的VCL数据。
RBSP
Raw Byte Sequence Payload,又称原始字节序列载荷。在SODB的后面填加了结尾比特:一个bit“1”若干比特“0”,以便网络传输或存储时进行字节对齐。
RBSP = SODB + RBSP Trailing Bits(RBSP尾部补齐字节)
引入 RBSP Trailing Bits 做 8 位字节补齐。
EBSP
Encapsulated Byte Sequence Payload,称为扩展字节序列载荷。和 RBSP 关系如下:
EBSP = RBSP插入防竞争字节(0x03)
防止竞争字节(0x03):H264会在NALU前插入StartCode的字节串(三字节或四字节,0x000001或0x00000001)来分割NALU。于是问题来了,如果RBSP中也包括了StartCode,就无法找到NALU的起始和结束,于是就引入了防止竞争字节(0x03):
编码时,扫描 RBSP,如果遇到连续两个0x00字节,就在后面添加防止竞争字节(0x03);解码时,同样扫描 EBSP,进行逆向操作即可。
这样RBSP中就不会存在StartCode了,解码器就能正确找到NALU的边界。
如果RBSP包含了0x000003,同样会插入0x03,变成0x00000303。解码时也能还原出正确的数据。
总结
以一幅图总结 NALU 这段内容: