分类: C/C++
2021-10-12 10:15:14
当我们把摄像头采集画面直接写入到文件中时,我们会发现没一会文件已经非常大了。这导致很不适合保存和传输,所以需要编码,把画面数据进行压缩。视频编码标准有很多,而我们这里讲的是H.264编码。其他请看:视频编码标准汇总及比较。
制订H.264的主要目标有两个:
(1)视频编码层(VCL,全称:Video Coding Layer):得到高的视频压缩比。
(2)网络提取层(NAL,全称:Network Abstraction Layer):具有良好的网络亲和性,即可适用于各种传输网络。而NAL则是以NALU(NAL Unit)为单元来支持编码数据在基于包交换技术网络中传输的。
一张张画面通过以H.264编码标准的编码器(如x264)编码后,输出一段包含N个NALU的数据,每个NALU之间通过起始码来分隔,如图:
在网络传输(如RTMP)或者一些容器中(如FLV),通常会把NALU整合到视频区域的数据中。如下图的flv格式:
所以这篇文章主要学习NALU的基本知识,学会如何去分析一段NALU数据。
NALU(NAL Unit,NAL 单元)的组成部分如下图。其中,f(0)占1bit,u(2)占2bit,u(5)占5bit,文中如有出现类似描述符请看。
从上图可以看出来,当前NAL单元属于什么样的类型,这取决于RBSP具体是什么样的类型,而RBSP的类型是根据nal_unit_type的值来定义的。
①当nal_unit_type为1~5时:RBSP为切片类型(有5种切片类型);整个NAL单元类型为VCL NAL单元,VCL是上面说的视频编码层,里面有编码后画面数据。
②当nal_unit_type为其他时:RBSP为序列参数集类型、图像参数集类型等等;整个NAL单元类型为非VCL NAL单元。
具体的nal_unit_type所对应的RBSP类型如下表所示:
nal_unit_type | NAL 单元和 RBSP 语法结构的内容 |
---|---|
0 | 未指定 |
1 |
一个非IDR图像的编码条带 slice_layer_without_partitioning_rbsp( ) |
2 |
编码条带数据分割块A slice_data_partition_a_layer_rbsp( ) |
3 |
编码条带数据分割块B slice_data_partition_b_layer_rbsp( ) |
4 |
编码条带数据分割块C slice_data_partition_c_layer_rbsp( ) |
5 |
IDR图像的编码条带 slice_layer_without_partitioning_rbsp( ) |
6 |
辅助增强信息 (SEI) sei_rbsp( ) |
7 |
序列参数集(SPS) seq_parameter_set_rbsp( ) |
8 |
图像参数集(PPS) pic_parameter_set_rbsp( ) |
9 |
访问单元分隔符 access_unit_delimiter_rbsp( ) |
10 |
序列结尾 end_of_seq_rbsp( ) |
11 |
流结尾 end_of_stream_rbsp( ) |
12 |
填充数据 filler_data_rbsp( ) |
13 |
序列参数集扩展 seq_parameter_set_extension_rbsp( ) |
14…18 | 保留 |
19 |
未分割的辅助编码图像的编码条带 slice_layer_without_partitioning_rbsp( ) |
20…23 | 保留 |
24…31 | 未指定 |
SPS全称 Sequence parameter set(序列参数集),当nal_unit_type=7时,RBSP就是SPS类型,也可以说NAL单元为SPS的NAL单元。SPS主要包含的是针对一连续编码视频序列的参数,如帧数、图像尺寸等;详见下表 序列参数集RBSP 语法:
上面中的主要参数的含义:
下面为从一个只放h.264视频编码文件的一段(SPS):
点击(此处)折叠或打开
PPS全称picture parameter set(图像参数集),当nal_unit_type=8时,RBSP就是PPS类型,也可以说NAL单元为SPS的NAL单元。一个序列中某一幅图像或者某几幅图像,其参数如标识符pic_parameter_set_id、可选的seq_parameter_set_id、熵编码模式选择标识、片组数目、初始量化参数和去方块滤波系数调整标识等;详见下表 图像参数集RBSP 语法: