2.h264的nalu单元解析:sps、pps、sei的概念

  • Post author:
  • Post category:其他


一.VCL和NAL的关系:

1.H.264的功能分两层:

VCL(Video Codeing Layer):视频编码层,负责的是视频内容的处理,重点在编解码算法;

NAL(Network Abstraction Layer):网络抽象层,负责将编码后的数据以网络要求的格式进行打包和传输;

2.H.264编码过程中的三种不同数据格式:

(1)SODB(String of Data Bits)数据比特串:

最原始的编码数据,即VCL数据,没有任何附加数据;

(2)RBSP(Raw Byte Sequence Payload)原始字节序列载荷:

在SODB数据后面加了结尾比特(rbsp_trailing_bits),一个bit的”1″,若干比特的”0″,目的是为了字节对齐;

RBSP = SODB + rbsp_trailing_bits

(3)EBSP(Encapsulated Byte Sequence Packets)扩展字节序列载荷:

在 RBSP 数据的基础上添加了防止竞争的一个字节“0x03”;

原因是:

H264中NALU的起始码为0x000001或0x00000001,

同时H264规定,当检测到0x000000时也可以表示当前NALU的结束,

但是如果在NALU的内部出现了0x000001或0x00000001时该怎么办?

所以H264就提出了“防止竞争”这样一种机制,当编码器编完一个NALU时,

应该检测NALU内部是否出现了如下左侧的数据,如果检测到它们的存在,

编码器就在最后一个字节前,插入一个新字节“0x03”:

0x000000 –> 0x00000300

0x000001 –> 0x00000301

0x000002 –> 0x00000302

0x000003 –> 0x00000303

注:

NALU的头是0x000001或0x00000001,都按上面的方式处理,

对于0x000001就是在第2个字节后插入0x03,

对于0x00000001就是在第3个字节后插入0x03。

当解码器解码时,将0x03去掉即可,也称为脱壳操作。

注:在H264的文档中,并没有EBSP这一名词出现,但是在H264的官方参考软件JM里,却使用了EBSP。

EBSP = RBSP + “0x03”

(4)NALU(Network Abstraction Layer Units)网络抽象层:

每个NAL单元是一个一定语法元素的可变长字节字符串,包括一个字节的头信息(用来表示数据类型),

以及若干整数字节的原始字节序列负荷(RBSP)。

一个NAL单元可以携带一个编码片,I帧、P帧、B帧、一个序列参数集、或一个图像参数集。

H264采用NAL单元可以适用于多种网络,而且进一步提高其抗误码能力。

序列号的设置可以发现丢失的是哪一个VLC单元,

冗余编码图像使得基本编码图像丢失仍可得到较粗糙的图像。

NALU = NAL header(1 byte) + RBSP

二.NAL的相关概念:

一段H264的码流开始处的十六进制数据:

00 00 00 01 67 42 00 1f 9d a8 14 01 6e 9b 80 80
80 81 00 00 00 01 68 ce 3c 80 00 00 00 01 06 e5
01 d3 80 00 00 00 01 65 b8 00 00 03 03 27 5c 27
ff ff c3 d1 40 00 40 7b c9 c9 c9 c9 c9 c9 c9 c9
c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9
c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9 c9

1.如何判断帧类型(是I帧还是SPS或PPS):

官方文档如下:

表7-1-NAL单元类型码
nal_unit_type  	NAL单元和RBSP语法结构的内容  			
0  				未指定 							
1  				一个非 IDR 图像的编码条带
2  				编码条带数据分割块 A
3  				编码条带数据分割块 B
4 				编码条带数据分割块 C
5  				IDR 图像的编码条带
6  				辅助增强信息 (SEI)
7  				序列参数集
8  				图像参数集
9  				访问单元分隔符
10  			序列结尾
11  			流结尾
12  			填充数据
13  			序列参数集扩展
14..18  		保留 
19  			未分割的辅助编码图像的编码条带
20..23  		保留 
24..31  		未指定

我们看码流数据,用分隔符“00 00 00 01”分割后的下一个字节就是NAL单元类型码,其中:

bit7: 禁止位,值为1表示语法出错;

bit5-6: 为参考级别;

bit0-4: 是NAL的单元类型:

上边码流分隔符后依次是:0x67、0x68、0x65

0x67—0b0110 0111,bit0-4转为十进制是7,对应的是序列参数集

0x68—0b0110 1000,bit0-4转为十进制是8,对应的是图像参数集

0x65—0b0110 0101,bit0-4转为十进制是5,对应的是IDR图像的编码条带

所以判断NAL单元是否为I帧的方式可以为:(nal_unit_type & 0x1f) == 5

2.序列:

一般来说,编码器编出来的首帧数据是PPS,然后是SPS,接下来是I帧,P帧、B帧等;

一个序列 == 一个SPS + 1个PPS + 一个I帧 + 若干P帧 + 若干B帧

3.分隔符:

分割符就是一段H264码流数据中,用以区分NAL单元的标志,即0x000001或0x00000001,

当遇见这样的分割符,接下来的数据就是一个NAL单元的数据。

4.SPS(Sequence Paramater Set)序列参数集:

SPS中保存了一组视频编码序列(Codec Video Sequence)的全局参数,

序列中每一帧编码后的数据所依赖的参数保存于图像参数集中,

一般情况下SPS和PPS的NAL单元通常位与整个码流的起始位置,但是在某些特殊情况下,

在码流中间也可能出现这两种结构,主要的原因可能为:

*解码器需要在码流中间开始解码;

*编码器在编码的过程中改变了码流的参数(如图像的分辨率);

5.PPS(Picture Paramater Set)图像参数集:

PPS类似于SPS,在H264的码流中单独保存在一个NAL单元中,

只是PPS NAL Unit的nal_unit_type值为8,

而在封装格式中,PPS通常与SPS一起,保存在视频文件的文件头中。

6.SEI辅助增强信息

SEI是H264标准中一个重要的技术,主要起补充和增强的作用。

SEI没有图像数据信息,只是对图像数据信息或者视频流的补充,

有些内容可能对解码有帮助.

在这里插入图片描述
图1.码流中的序列

三.reference:

https://www.cnblogs.com/wainiwann/p/7477794.html



版权声明:本文为yanghangwww原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。