h265 的分层结构
分层结构的目的
○ 网络类型多种多样,不同的网络环境具有不同的特性,压缩视频在其中进行传输必然会受到影响;比如不同网络的 MTU 有所不同;
○ 不同的应用场景对视频有不同的需求,视频业务会喜用不同的传输协议;
分层的重要性
○ 经过熵编码,码流中的二进制符号不再简单地对应实际数值,严重时当个符号的丢失或错误会导致后续数据无法正确解码;
○ 在网络上优化传输这种高度复杂的压缩视频流时,必须对码流进行深入分析或解码才能清楚不同数据的重要程度;但对码流进行深入分析甚至解码的计算复杂度太高,无法得到通用网络设备的支持。
VCL 与 NAL
○ H.265/HEVC也采用了视频编码层(Video Coding Layer, VCL)和网络适配层(Network Abstract Layer, NAL)的双层架构,以适应不同的网络环境和视频应用 。网络适配层的主要任务是对视频压缩后的数据进行划分和封装,并进行必要的标识,使其可以很好地适应复杂多变的网络环境。
NAL的作用机制
○ 一系列图像组成的原视频视频经过压缩编码 (VCL),接着根据压缩视频比特流的内容特性将其划分成多个数据段,对每个数据段进行封装并标识,就生成了 NALU,内容特性信息存放在 NALU 头信息中。
NAL 与 MTU
○ NAL的大小不一定与网络的MTU(MaximumTransmission Unit,最大传输单元)大小一致,因此网络分组与NALU 就产生几种组合形 式: 一个网络分组包含一个NALU ; 一个网络分组包含多个NALU,即多个NALU合并到一个网络分组;多个网络分组包含一个NALU,即一个NALU被分割到多个网 络分组。
○ 网络传输过程中,网络设备可以直接通过 NALU 的头信息获取 NALU 承载视频数据的内容特性,在此基础 上优化视频流的传输。
h265 图像类型
- 所有的压缩视频数据都被封装到不同的 NALU 的载荷部分,NALU 除了承载 VPS、SPS、PPS 等信息,主要承载视频片 Slice 的压缩数据;
- 承载视频片压缩数据的 NALU 称为 VCLU(VCL NALU),承载其他信息的 NALU 被称为 non-VCLU(non-VCL NALU);
- 随机介入点 IRAP
○ 从 IRAP (Intra Random Access Point)开始,后续视频流可独立正确解码,无须参考 IRAP 前面的视频信息,IRAP 后的第一幅解码图像被称为 IRAP 图像;
○ 根据播放和解码顺序,有可以将其他图像分为前置(Leading)图像、后置(Trailing)图像;其中前置图像又可以分为 RADL 图像和 RASL图像;
○ h265 规定了3 种 IRAP 图像:IDR 图像、CRA 图像、BLA 图像;
○ IRAP 图像把视频流分成多个相对对立 的区域,每个区域被称为 CVS(Coded Video Sequence),CVS 定义为两个相邻 IRAP 图像(且 NoRas1OutputFlag=1)之间的这段视频流; - TSA/STSA
○ h265 的新增图像类型,用来标识时域子层切换点;
网络适配层单元 NALU
- 每个 NALU 包含两部分:NALU 头(Header)和 NALU 载荷(Payload);
- SODB
○ 视频编码过程中输出包含不同内容的压缩数据比特流片段,这些比特流片段称为 SODB(String Of Data Bits);SODB 为最高为有效的存储形式,即字节内的比特按照从左到右、从高到低的顺序排列; - RBSP
○ 在SODB(String Of Data Bits)后添加RBSP尾(rbsp trailing_bits)就生成了原始字节序列载荷(Raw Byte Sequence Payload,RBSP);RBSP尾由称为RBSP停止比特的 1 个比特和其后的0个或多个比特0组成。RBSP即为整数字节化的SODB , RBSP的数据类型即为SODB 的数据类型。 - EBSP
○ 在H265中,为了避免字节流片段和NALU的启起码及结束码发生冲突,需要对RBSP的字节流进行冲突处理 0x3,即EBSP为扩展字节序列载荷(Encapsulated Byte Sequence Payload),经过处理后的RBSP才可以直接作为NALU的负载信息,才可以进行磁盘保存和网络传输。
○ 因此实际最后的 NALU = Header + EBSP;
- NALU 语法
NALU Header
- 与h264相比,h265固定两字节的header,表征NALU的内容特征;
- 由定长的四部分组成:forbidden_zero_bit、nal_unit_type、nuh_layer_id、nuh_temporal_id_plus1;
○ forbidden_zero_bit占 1 比特,值应设置成 0,防止与 MPEG-2 系统的起始位冲突;
○ nal_unit_type占 6 比特,标识当前 NALU 载荷信息的内容特性,称为 NALU 类型;
○ nuh_layer_id占 6 比特,当前版本取值 0,未来可能勇于可分级视频或3D视频
○ nuh_temporal_id_plus1占 3 比特,时域标识,该值减 1表示 NALU 所在时域层的标识号 TemporalId不能为 0 ;
帧类型解析
-
与h264的 & 01f不同,h265判断方式为:
○ int type = (code & 0x7E ) >> 1;// 0x7E的二进制的后8位是 0111 1110
-
VPS:00 00 00 01 40 01 的nuh_unit_type的值为 32
○ 40 & 0x7E = (二进制)01000000 & 01111110 = 01000000
○ 01000000 >> 1 = 00100000
○ (转十进制)00100000 = 2^5 = 32
-
SPS:00 00 00 01 42 01 的nuh_unit_type的值为 33
○ 42 & 0x7E = (二进制)01000010 & 01111110 = 01000010
○ 01000010 >> 1 = 00100001
○ (转十进制) 00100001 = 2^0 + 2^5 = 33
-
PPS:00 00 00 01 44 01 的nuh_unit_type的值为 34
○ 44 & 0x7E = (二进制)01000100 & 01111110 = 01000100
○ 01000100 >> 1 = 00100010
○ (转十进制)00100010 = 2^1 + 2^5 = 34
-
SEI:00 00 00 01 4E 01 的nuh_unit_type的值为 39
○ 4E & 0x7E = (二进制)01001110 & 0111110 = 01001110
○ 01001110 >> 1 = 00100111
○ (转十进制) 00100111 = 2^0+2^1+2^2+2^5 = 1+2+4+32 = 39
-
IDR:00 00 00 01 26 01 的nuh_unit_type的值为 19
-
被参考图像(P帧或者B帧):00 00 00 01 02 01 的nuh_unit_type的值为 1
接入单元
○ h264 引入了接入单元(Access Unit, AU)的概念,定义为多个按解码顺序排列的 NALU,这些 NALU 解码正好生成一个图像;
○ AU 可以看成是压缩视频比特流的基本单位,压缩视频流由多个按顺序排列的 AU 组成。
参考
- 新一代高效视频编码H.265HEVC原理、标准与实现 [万帅,杨付正 编著] 2014年版.
- T-REC-H.265-202108-I.