1. SODB
视频编码器生成的压缩数据比特流片段称为SODB(String Of Data Bits),SODB为最高位有效的存储形式,即字节内的比特按照从左到右、从高到低的顺序排列。
2. RBSP
在SODB后添加RBSP尾(rbsp_trailing_bits)就生成了原始字节序列载荷(Raw Byte Sequence Payload, RBSP),RBSP尾由称为RBSP停止比特的一个比特1和其后的零个或多个比特0组成。由SODB生成RBSP的过程为:
- RBSP的第一字节直接取SODB最左端的8比特,第二字节取SODB接下来的8比特,以此类推,直到SODB中所剩的内容不足8比特(包括0)为止。
- RBSP的下一字节首先包含SODB的最后几比特,然后添加比特1(RBSP停止比特)。如果该字节包含的比特数小于8,在后面添加0直到该字节包含8比特。
- 最后可能会加入若干16比特的语法元素cabac_zero_word作为填充比特,其值为0x0000。
3. NALU流
NALU流由NALU头和NALU载荷组成。
RBSP不能直接作为NALU载荷,因为在字节流应用环境中0x000001为NALU的起始码,0x000000为结束码。因此为了避免NALU载荷中的字节流片段与NALU的起始码、结束码冲突,需要对RBSP字节流做如下冲突避免处理:
0x000000 ----------> 0x00000300 (0x000000为结束码)
0x000001 ----------> 0x00000301 (0x000001为起始码)
0x000002 ----------> 0x00000302 (0x000002为预留码)
0x000003 ----------> 0x00000303
注意,当RBSP数据的最后一字节等于0x00时(这种情况只会在RBSP的末尾是cabac_zero_word时出现),字节0x03会被加入数据的末尾。
经过冲突避免后的RBSP可以直接作为NALU的载荷信息,在其前增加NALU头就生成了NALU流。
4. 字节流
字节流应用将NALU流作为有序的字节流或比特流进行传输、处理,这就要求对NALU的边界进行标识以保证解码端可以对NALU进行识别。
NALU流生成字节流的过程如下:
- 在每个NALU前面插入3字节的起始码start_code_prefix_one_3bytes,其对应的值为0x000001。
- 如果NALU的类型为VPS_NUT、SPS_NUT、PPS_NUT,或者解码顺序为一个AU的第一个NALU,则在起始码前再插入zero_byte,其对应的值为0x00。
- 在视频流的首个NALU的起始码(可能包含zero_byte)前插入leading_zero_8bits,其对应的值为0x00。
- 根据需要可在每个NALU后增加trailing_zero_8bits,其对应的值为0x00,作为填充数据。