H.264 NALUint 解析

接触过H.264视频编解码的朋友应该都知道NAL 单元这个概念。NAL的全称是 (Network Abstraction Layer) 网络抽象层。而这个NAL的主要作用是方便视频编码后数据的存储和网络传输而设计的一个额外的层。也就是说NAL是对编码数据的一种封装。说到这我们就有必要先来聊一下H.264的编码输出数据的定义了。

H.264 将最后呈现给我们的编码数据分为两层:
VCL: (Video Coding Layer) 视频编码层。即视频图像编码后输出的裸数据。不包含其他额外信息的纯视频图像编码后数据。
NAL: (Network Abstraction Layer) 网络抽象层。即对编码输出的VCL数据进行一次封装得到NAL Uint。

好,那么我们了解了这两个概念之后,我们就知道了。我们看到的H.264 码流其实就是一个各NAL Uint连接起来的序列。那我们就先来看一看 NAL Uint sequence的结构吧

NALUintSequence

大家一看可能会觉得奇怪。刚刚说的是VCL 和NAL 现在呢,这个图里面就完全没有 VCL呀。结果出来了一个 RBSP。那么RBSP是什么呢,它的全称是 (Raw Byte Sequence Payload)原始字节序列负载。
RBSP其实就是对视频编码数据进行对齐处理后的数据了。即在编码器输出数据后面添加一个 bit 的 ‘1’或者几个bit 的‘0’进而达到字节对齐的结果。

回过来说NAL Uint,那NAL Uint就是 NAL头 + BRSP 咯。
那么我们就来看看NAL Uint吧。NAL Uint的语法定义如下

nal_uint

从这个语法定义中可以很明确的知道NAL header中包含三个字段:
forbidden_zero_bit, nal_ref_indc, nal_uint_type 。共占一个字节
NALHeader

其中
forbidden_zero_bit: 恒等于0
nal_ref_idc: 指示当前NAL的优先级, 取值范围 0 — 3, 值越高表示当前NAL越重要。H.264中规定,如果当前NAL是属于参考帧,Sps或者pps。则nal_ref_idc 的值必须大于 0。别切 所有nal_uint_type 等于 6,9,10,11,12的NALUint的nal_ref_idc 应该等于0。
nal_unit_type: 指示当前NAL Uint中包含的RBSP 的类型。类型规定如下
nal_uint_type

其中type值 从1 到5称为VCL NAL。 其他的都称为非 VCL NAL。

好了,我们一个NAL Unit基本结构就是这样的了。
在这里还有一个问题需要明确一下。NAL Uint被用在网络传输。那么我们的做法都是把NAL Uint 各自独立的放入网络传输协议的分组中去发送的。如此,接收端在拆解开传输协议的分组后就能得到一个完整的NAL Uint了。但是,如我们是以NAL Uint放在硬盘中存储呢,又将会发生什么情况呢?
因为NAL header中没有特定的元素来自举自己是一个NAL Uint。将导致在读取过程中定位难的问题。
针对这个问题,其实H.264中有一个解决方案,然后这个方案也是现在大家都在使用的。就是在NAL Uint前面加上起始码:
0x000001。如果这个NAL Uint对应的Slice为一帧的开始,那么这个起始码就变成
0x00000001

所以我们在实际的工作中也经常会遇到起始码引起的问题,比如某些解码器就要求码流应该是带有起始码的。有些是不能包含起始码的,一定要看清楚这些规定。否则就会导致解码失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值