共计 6578 个字符,预计需要花费 17 分钟才能阅读完成。
视频编码的目标是为了压缩原始视频,压缩的次要思路是从空间、工夫、编码、视觉等几个次要角度去除冗余信息。因为 H.264 杰出的数据压缩比率和视频品质,成为以后市场上最为风行的编解码规范。而 H.265 是在 H.264 的根底上,保障雷同视频品质的同时,视频流的码率还能够缩小 50%。随着 H.265 编码格局越来越风行,本文将次要介绍 H.265 的编码原理,以下是 H.265 的编码框架流程图。
01 编码构造
H.265 在编码构造上分为 视频编码层(VCL)和 网络提取层(NAL)。
- VCL:Video Coding Layer,次要包含视频压缩引擎和图像分块的语法定义,原始视频在 VCL 层,被编码成视频数据。简略版本的编码过程如下:
- 将每一帧的图像分块,将块信息增加到码流中;
- 对单元块进行预测编码,帧内预测生成残差,帧间预测进行静止预计和静止弥补;
- 对残差进行变换,对变换系数进行量化、扫描。
- 对量化后的变换系数、静止信息、预测信息等进行熵编码,造成压缩的视频码流输入。
- NAL:Network Abstraction Layer,次要定义数据的封装格局,把 VCL 产生的视频数据封装成一个个 NAL 单元的数据包,适配不同的网络环境并传输。
02 分块
从编码程序和构造上讲,H.265 首先将一个视频划分成若干个序列,一个序列划分成若干个 图像组(GOP),每一个 GOP 代表一组间断的视频帧。H.265 在对图像做预测编码和变换编码时,会先对图像进行划分,划分形式是四叉树。在划分四叉树时,会将整个视频帧划分成若干个正方形的 编码树块(CTB),CTB 能够持续划分成 编码块(CB),CB 还能够划分为 预测块(PB)和 变换块(TB)。因而,H.265 对视频的构造划分如下图所示:
同一地位处的一个亮度 CB 和两个色度 CB,加上一些相应的语法元素,组成一个编码单元(CU)。CU 是决定进行帧内预测、帧间预测、Skip/Merge 模式的单元。
同一地位处的一个亮度 CTB 和两个色度 CTB,加上一些相应的语法元素,和蕴含的 CU,组成一个编码树单元(CTU)。CTU 相当于 H.264 中的宏块,区别是 CTU 的尺寸是由编码器制订,最大能够反对到 64×64,最小能够反对到 16×16。而宏块的大小固定为 16×16。
一个 CTU 在进行编码时,依照深度优先的程序进行 CU 编码,像数据结构中的四叉树一样,一个大的方块代表父节点,外面有四个小方块别离代表四个子节点。
03 预测
视频的实质是由一系列间断的视频帧组成,在单个视频帧外部和多个视频帧之间都存在大量的冗余。从空间的角度看,单个视频帧外部的像素点之间的像素值相差很小。从工夫的角度看,两个间断的视频帧之间也有很多雷同的像素点。预测编码就是基于图像统计个性进行数据压缩的一种办法,利用了图像在工夫和空间上的相关性,通过曾经重建的像素数据预测以后正在编码的像素。
3.1 帧内预测
帧内预测是指用于预测的像素和以后正在编码的像素 都在 同一个视频帧内,并且个别都在邻近的区域内。因为邻近的像素之间有很强的相关性,像素值个别都十分靠近,产生渐变的概率十分小,差值都是 0 或者十分小的数。所以,帧内预测编码后传输的是预测值和实在值之间的差值,即 0 左近的值,叫做 预测误差 或残差,这样就用较少的比特传输,达到压缩的成果。
H.265 帧内预测编码以块为单位,应用相邻曾经重建的块的重建值对正在编码的块进行预测。预测重量分为亮度和色度两个,对应的预测块别离是亮度预测块和色度预测块。为了适应高清视频的内容特色,进步预测精度,H.265 采纳了更加丰盛的预测块尺寸和预测模式。
H.265 亮度预测块的尺寸在 4 * 4 到 32*32 之间,所有尺寸的预测块都有 35 种预测模式,这些预测模式能够分为 3 类:立体(Planar)模式、直流(DC)模式和角度(Angular)模式。
- Planar 模式:亮度模式 0,实用于像素值变换迟缓的区域,例如像素突变的场景。对预测块中的每个像素都应用不同的预测值。预测值等于:该像素在程度和垂直两个方向线性插值的平均值。
- DC 模式:亮度模式 1,实用于图像的大面积平坦区域,该模式对预测块中的所有像素都应用雷同的预测值。
- 如果预测块是正方形,预测值等于右边和上边的参考像素的平均值;
- 如果预测块是长方形,预测值等于长的那一边的平均值;
- 角度模式:亮度模式 2~34,总共 33 个预测方向,其中模式 10 是程度方向,模式 26 是垂直方向。角度模式每个像素的预测值都是从对应预测方向前曾经重建的像素集的样值进行程度或垂直方向偏移角度预测。
因为黑白视频中,雷同地位的色度信号和亮度信号的特色相似,因而色度预测块和亮度预测块的预测模式也相似。H.265 中色度预测块的预测模式有 Planar 模式、垂直模式、程度模式、DC 模式和导出模式 5 种:
- Planar 模式:色度模式 0,和亮度模式 0 一样。
- 垂直模式:色度模式 1,和亮度模式 26 一样。
- 程度模式:色度模式 2,和亮度模式 10 一样。
- DC 模式:色度模式 3,和亮度模式 1 一样。
- 导出模式:色度模式 4,采纳和对应亮度预测块雷同的预测模式。如果对应的亮度预测块模式是 0、1、10、26 中的一种,则替换为模式 34。
3.2 帧间预测
帧间预测是指用于预测的像素和以后正在编码的像素不在同一个视频帧内,然而个别在相邻或左近的地位。个别状况下,帧间预测编码的压缩成果要比帧内预测好,次要起因是视频帧之间的相关性十分强。如果视频帧中的静止物体变动速度很慢,那么视频帧之间的像素差值也就很小,工夫冗余度就十分大。
帧间预测评估静止物体静止情况的办法是 静止预计 ,它的次要思维就是对预测块从参考帧的给定范畴中搜寻匹配块,计算匹配块和预测块之间的绝对位移,该绝对位移就是静止矢量。失去静止矢量后,须要对预测修改,也就是 静止弥补。将静止矢量输出到静止弥补模块,” 弥补 ” 参考帧,即可失去以后编码帧的预测帧。预测帧和以后帧的差,就是帧间预测误差。
如果帧间预测只用到了前一帧图像,就称为前向帧间预测或单向预测。该预测帧也就是 P 帧,P 帧能够参考后面的 I 帧或者 P 帧。
如果帧间预测不仅用到了前一帧图像预测以后块,还用到了后一帧图像,那么就是双向预测。该预测帧也就是 B 帧,B 帧能够参考后面的 I 帧或 P 帧和前面的 P 帧。
因为 P 帧须要参考后面的 I 帧或 P 帧,而 B 帧须要参考后面 I 帧或 P 帧和前面的 P 帧,如果在一个视频流中,先到了 B 帧,而依赖的 I 帧、P 帧还没有到,那么该 B 帧还不能立刻解码,那么应该怎么保障播放程序呢?其实,在视频编码时,会生成 PTS 和 DTS。通常状况下,编码器在生成一个 I 帧后,会向后跳过几个帧,用后面的 I 帧作为参考帧对 P 帧编码,I 帧和 P 帧之间的帧被编码为 B 帧。推流的视频帧程序在编码的时候就曾经依照 I 帧、P 帧、B 帧的依赖程序编好了,收到数据后间接解码即可。所以,不可能先收到 B 帧,再收到依赖的 I 帧和 P 帧。
- PTS:Presentation Time Stamp,显示工夫戳,通知播放器在什么工夫显示这一帧。
- DTS:Decoding Time Stamp,解码工夫戳,通知播放器在什么工夫解码这一帧。
04 变换
变换编码是指将图像中的空间域信号映射变换到频域(频率域),而后对生成的变换系数编码。因为在空间域中,数据之间的相关性比拟大,通过预测编码后的残差变动较小,存在大量的数据冗余,在图像中亮度值变动迟缓的平坦区域特地显著。而变换为频域后,会将空间域扩散散布的残差数据转换成集中散布,能够升高相关性,缩小数据冗余,从而达到去除空间冗余的目标。
在 H.265 中,一个编码块(CB)能够通过四叉树划分成若干个预测块(PB)和变换块(TB)。因为从 CB 到 TB 之间的四叉树划分次要是为了残差的变换运算,因而这种四叉树又称为 残差四叉树(RQT)。如下图所示,就是一个 RQT 划分实例,将一个 32*32 的残差 CB 划分成 13 个不同大小的 TB。
每个 TB 的大小有四种,别离是从 4*4、8*8、16*16、32*32,每个 TB 都对应一个 整数变换系数矩阵 。大尺寸的 TB 实用于图像亮度值变动迟缓的平坦区域,小尺寸的 TB 实用于图像亮度值变动激烈的简单区域。所有尺寸都能够应用 离散余弦变换(DCT)变换 。 另外,对于 4*4 的帧内预测亮度残差块,还能够应用离散正弦变换(DST)。
因为帧内预测编码是基于右边和上边曾经编码块的数据,因而预测块间隔已编码块越近,相关性越强,预测误差越小;间隔已编码块越远,相关性越小,预测误差越大。预测误差的这种数据分布特色和 DST 的正弦基函数 sin 十分类似,起始点最小,而后逐步变大。然而因为 DST 计算量比 DCT 大,须要减少更多的变换类型标识,因而 DST 仅用于 4* 4 的帧内预测亮度残差块。
05 量化
因为变换编码只是将图像数据从空间域矩阵转换为频域的变换系数矩阵,矩阵的系数个数和数据量都没有缩小。要想压缩数据,还须要对频域中的统计特色进行量化和熵编码。
常见的量化办法能够分为 ** 标量量化(SQ)和矢量量化(VQ)** 两类:
- 标量量化:将图像中的数据划分成若干个区间,而后在每个区间用一个 值代表这个区间内所有样点的取值。
- 矢量量化:将图像中的数据划分成若干个区间,而后在每个区间用一个 代表矢量 代表这个区间的所有矢量取值。
因为矢量量化引入了多个像素之间的关联,并且应用了概率的办法,个别压缩率比标量量化高。然而因为其计算复杂度高,所以目前宽泛应用的量化办法是标量量化。
量化的压缩率取决于划分的区间大小,即量化步长。量化步长越大,示意量化越粗,对应的视频码率越低,失真越大;量化步长越小,示意量化越细,对应的视频码率越高,失真越小。
H.265 量化时是以 ** 变换单元(TU)为 根本单位 , 解决对象包含 TU 中的亮度重量和色度重量。H.265 采纳了非线性标量量化,通过量化参数(QP)** 管制每个编码块的量化步长,QP 和量化步长的关系近似呈指数关系。QP 是个整数,亮度重量的 QP 值范畴是 0~51,色度重量的亮度 QP 值范畴是 0~45。QP 值在 0~29 范畴时,亮度重量和色度重量的量化步长相等,从 QP=30 开始,两者开始产生差别。QP 和量化步长的关系如下图所示:
编码端的 量化过程 能够简略了解为是每个 DCT 变换系数除以量化步长 失去量化值。在解码端对应的 反量化过程 就是 量化值乘以量化步长 失去 DCT 变化系数值。
06 熵编码
熵编码是指在编码过程中按熵原理不失落任何信息的编码。量化是一种有损的压缩形式,而熵编码是用更紧凑的形式标记和原数据之间的映射关系,属于无损压缩。常见的熵编码有香农(Shannon)编码、哈夫曼(Huffman)编码、算术(Arithmetic)编码、游程编码等。
6.1 哈夫曼编码
哈夫曼编码是一种变长编码,即不同字符的编码长度是变动的。该编码利用字符呈现的概率结构哈夫曼二叉树,指标是让呈现概率大的字符编码时用短码(间隔根节点近),概率小的字符编码时用长码(间隔根节点远),从而让均匀码字长度最短。
码字:字符通过哈夫曼编码后失去的编码。
例:字符 A、B、C、D、E、F 对应的呈现的概率别离是 0.32、0.22、0.18、0.16、0.08、0.04。哈夫曼树的结构过程如下:
- 抉择概率最小的 E、F 作为叶子节点,计算 E、F 的概率和作为它们父节点;
- 将父节点的值与剩下的 A、B、C、D 概率值排序,再抉择最小的两个树求和;
- 反复以上过程;
最终结构进去的哈夫曼二叉树如下图所示:
左节点的门路为 0,右节点的门路为 1,求得 A、B、C、D、E、F 的编码后果:
均匀码字长度 = 0.32*2 + 0.22*2 + 0.18*2 + 0.16*3 + 0.08*4 + 0.04*4 = 2.4bit
6.2 算术编码
尽管哈夫曼编码在实践上能够获得最佳编码后果,然而在理论编码中,因为计算机解决的最小数据单位是 1bit,对于蕴含小数点的码字长度只能依照整数解决,所以理论编码成果往往略逊于实践编码成果。在图像压缩畛域,通常应用算术编码代替哈夫曼编码。不过,算术编码的实践根底和哈夫曼编码是统一的,都是概率大的字符用短码,概率小的字符用长码。
算术编码分为固定模式算术编码、自适应算术编码(AAC)、二进制算术编码、自适应二进制算术编码(CABAC)等,H.265 中应用了 CABAC。此处将只介绍固定模式算术编码流程:
- 统计输出的符号序列中各个字符和呈现的概率;
- 依照概率分布,将 [0, 1) 区间划分成多个子区间,每个子区间代表一个字符,子区间的大小代表字符呈现的概率;所有子区间大小的和等于 1;假如该字符的区间范畴为 [L, H);
- 设置初始变量 low=0, high=1,一直读取符号序列中的每个字符,找到该字符对应的区间范畴 [L, H),更新 low 和 high 的值:
- low = low + (high – low) * L
- high = low + (high – low) * H
- 遍历完符号序列后,失去最终的 low 和 high,转换二进制模式输入失去编码数据;
例:输出符号序列是 ADBCD,统计各个字符呈现的概率:
- 遍历第一个字符 A 时,low = 0, high = 1, L = 0, H = 0.2
- low = low + (high – low) * L = 0
- high = low + (high – low) * H = 0.2
- 遍历第二个字符 D 时,low = 0, high = 0.2, L = 0.6, H = 1
- low = low + (high – low) * L = 0.12(注:此处计算的 low 不代入上面计算 high 值的公式中)
- high = low + (high – low) * H = 0.2
- 遍历第三个字符 B 时,low = 0.12,high = 0.2,L = 0.2,H = 0.4
- low = low + (high – low) * L = 0.136
- high = low + (high – low) * H = 0.152
- 遍历第四个字符 C 时,low = 0.136,high = 0.152,L = 0.4,H = 0.6
- low = low + (high – low) * L = 0.1424
- high = low + (high – low) * H = 0.1456
- 遍历第五个字符 D 时,low = 0.1424,high = 0.1456,L = 0.6,H = 1
- low = low + (high – low) * L = 0.14432
- high = low + (high – low) * H = 0.1456
失去最初的 [low, high) 区间是[0.14432, 0.1456),在这个区间内取任意值转二进制后都是对 “ADBCD” 的算术编码。对应的编码流程能够简化到上面这张图中:
07 环路滤波
因为 H.265 采纳分块编码,在图像反量化、反变换重建的时候,会存在一些失真效应,例如 块效应、振铃效应 。为了解决这些问题,H.265 采纳了 环路滤波 技术,其中包含 去方块滤波(DBF)和样点自适应弥补(SAO)。
DBF 作用于边界像素,用于 解决块效应。块效应是指一些相邻编码块边界处的灰度值存在显著的不连续性,产生块效应次要有两个起因:
- 编码器对残差的 DCT 变换和量化是基于块的,疏忽了块与块之间的相关性,导致块之间的解决不统一;
- 帧间预测静止弥补块的不齐全匹配,存在误差;而编码时的预测参考帧通常来自这些重建图像,导致待预测图像失真;
DBF 针对边界类型采纳强滤波、弱滤波或者不解决,边界类型的断定是由边界像素梯度阈值和边界块的量化参数决定的。DBF 解决时,先对整个图像的垂直边缘进行程度滤波,而后对程度边缘进行垂直滤波。滤波过程实际上就是对像素值进行修改的过程,让方块看起来不那么显著。H.264 中也存在 DBF 技术,然而利用于 4*4 大小的解决块,而 H.265 中利用于 8*8 大小的解决块。
SAO 是 H.265 新引入的对重建图像的误差弥补机制,用于 改善振铃效应。振铃效应是指图像的灰度值激烈变动产生的震荡,产生振铃效应次要起因是 DCT 变换后高频信息失落。SAO 的原理就是通过对重构曲线的波峰像素增加负值弥补,波谷增加正值弥补,从而减小高频信息的失真。和 DBF 只作用于边界像素不同,SAO 作用于块中所有的像素。
08 小结
本文从 H.265 整体编码流程的角度,介绍了 H.265 编码波及到的分块、预测、变换、量化、编码、环路滤波等技术点。通过理解这些编码原理,为咱们后续进一步学习音视频开发技术奠定扎实的根底。
———- END ———-
举荐浏览【技术加油站】系列:
小程序启动性能优化实际
百度工程师教你玩转设计模式(单例模式)
百度程序员 Android 开发小技巧
Chrome Devtools 调试小技巧
人工智能超大规模预训练模型浅谈