H264详解之打包形式

1. 一些概念

SODB (String Of Data Bits), RBSP (Raw Byte Sequence Payload)的概念见H264标准。关于EBSP (Encapsulated Byte Sequence Payload),并不是H264标准里面的概念,而是H264参考模型jm代码里面使用的缩略语 (见nal.c)


在H264标准里描述了2种stream format:NAL unit stream和byte stream. 其中NAL unit stream是基本的形式,byte stream是在NAL unit stream基础上加了start code以及填充0而来,是一种非强制的形式。应用可以基于NAL unit stream创建不同于byte stream的流形式,比如:size NAL size NAL ... size NAL。


2. NAL unit stream

NAL unit stream是一系列NAL unit构成。如何切割NAL,不属于标准范围。下表是NAL unit的结构:

H264详解之打包形式_第1张图片

RBSP由SODB和stop bit以及一些0组成。如果SODB为空,则RBSP也为空 (有些NAL只有header)



3. Byte stream

指Annex B描述的方法,通过start code prefix进行NAL的同步。

第一次同步,需要进行字节同步,只要解码器检测到连续31个0和1个1的bit串,就认为后面的bit是一个NAL的第一个bit。如果byte边界无需检测,也可以直接搜索0x000001的字节串。虽然这样也能同步上NAL,但是可能那个NAL是解不了的(sps/pps/au的第一个nal是以0x00000001的字节串开头的,第一次同步搜索0x00000001,而不是0x000001,更有效率)


为了防止同步出错,需要对RBSP进行处理:

1. 防止RBSP内部出现连续31个0

2. 防止出现0x000001的字节串


考虑下面这些字串:

1. 80 00 00 00   // 出现了31个连续0

2. 80 00 00 01   // 出现了start_code_prefix

如果这样处理(插入一个x):

1. 80 00 00 00 -> 80 00 00 x 00

2. 80 00 00 01 -> 80 00 00 x 01

那么, 增加额外的一个规则 00 00 x -> 00 00 x x:

3. 80 00 00 x   -> 80 00 00 x x


x取多少呢?显然x=0或者x=1是不行的。取x=2呢?按理也可以防止同步出错啊,spec为什么取得是3?


按照spec,RBSP变成EBSP需要经过如下处理:

0x000000, 0x000001, 0x000002, 0x000003分别变成0x00000300, 0x00000301, 0x00000302, 0x00000303


NAL不能以0x00结尾,所以cabac_zero_words后面增加一个0x03 (实际上每个cabac_zero_word,包括最后一个cabac_zero_word, 后面都插入一个0x03: emulation_prevention_three_byte (7.4.2.10))



列出完整的byte stream形式下的NAL结构:

 H264详解之打包形式_第2张图片


其中NAL header + EBSP就是NAL unit stream里面的NAL unit



你可能感兴趣的:(H264)