说明:我们参考黄金圈学习法(什么是黄金圈法则?->模型 黄金圈法则,本文使用:why-what)来学习音H264视频编码。本系列文章侧重于理解视频编码的知识体系和实践方法,理论方面会更多地讲清楚 音视频中概念的起源以及各个概念的联系。知其然,知其所以然。同时更强调知识系统的建立。
针对本文,我们主要讲研究 H.264数据压缩的流程及其相关概念。 H.264数据压缩的目的只有一个,压缩压缩再压缩,减少视频数据大小的同时尽可能地保证图像质量。所以在学习H.264数据压缩前 我们先要理解:虽然这个流程中涉及的概念、方法颇多,但是所有的方法和流程都是为了这个目的:压缩。
1 H.264数据压缩流程解读
H.264是的数据压缩流程主要总结为以下几个关键步骤:宏块划分和子块划分-> 帧分组-> 帧预测-> 整数离散余弦变换(DCT)-> CABAC压缩。具体展开说明如下。
1.1 划分宏块 && 划分子块
宏块(macro block):可以这样理解,视频帧被送到H264 编码器的缓冲中时,编码器为每一幅图片划分宏块。H264 编码默认是使用 16X16 像素大小的区域作为一个宏块(H265使用的是64X64像素大小的区域),视频中的一帧图像划分成宏块的效果如下:
同时在上图中我们实际上还可以在 16X16 像素的宏块上更划分出更小的子块。子块的大小可以是 8X16、 16X8、 8X8、 4X8、 8X4、 4X4非常灵活。而再次划分成子块的目的就是用很小的数据去记录这个数据。宏块划分好后,就可以对H264编码器缓存中的所有图片进行分组了。
宏块和子块划分使得视频编码可以更加精确地对视频内容进行分析和处理,实现更高效的数据压缩。视频帧被划分为大小为16x16像素的宏块,这些宏块可以进一步划分为更小的块,如8x8、8x4、4x8等,以适应图像内容的复杂性。
1.2 帧分组
帧分组(GOP结构)是在帧内预测和帧间预测之前进行定义的。在视频编码的流程中,帧分组的设置是初始步骤之一,它决定了视频帧的组织和编码顺序。帧分组主要目的是为了减少数据冗余。其中视频数据冗余主要分两类:
- 时间上的数据冗余,这需要使用帧间预测压缩,占比更大(因为即使摄像头每秒抓取30帧,这30帧数据多数情况下都是相关联的。也有可能不止30帧的的数据,可能几十帧的数据都是关联特别密切的。而对于关联特别密切的帧,我们只需要保存一个关键帧(I帧)的数据,其它帧(B帧和P帧)都可以通过这一帧再按某种规则 预测出来,所以说视频数据在时间上的冗余是最多的)。
- 空间上的数据冗余,这需要使用帧内预测压缩,占比相对较小。
H264的帧分组执行步骤:
- 每次取出两幅相邻的帧进行宏块比较,计算两帧的相似度。
- 量化后达到相似:如果有差别的像素只有10%以内的点,亮度差值变化不超过2%,而色度差值的变化只有1%以内,我们认为这样的图可以分到一组。
当分组结束后,就开始解决帧预测压缩的问题了。
1.3 帧预测压缩
该部分主要包括帧内预测和帧间预测。其中帧内预测是对静态图像帧进行压缩,通过9种不同的模式预测每个宏块的像素值,然后计算出与原始图像的残差值。而帧间预测(运动估计和运动补偿):对于P帧和B帧,通过运动估计找出与前一帧或双帧之间的运动向量,然后进行运动补偿预测,生成预测图像,并计算出与当前帧的残差。
注意:帧内预测和帧间预测的顺序取决于编码帧的类型和编码策略。在实际的视频编码器实现中,这些步骤是编码流程的一部分,由编码器自动处理。不一定非得谁先处理。
1.3.1 帧内预测
帧内预测压缩:解决的是空域数据冗余问题。 空域冗余数据是指颜色、光亮等,主要针对人眼不敏感的信息,编码通过对其进行删除来压缩。帧内预测使用的原理就是人眼对图象都有一个识别度,对低频的亮度很敏感,对高频的亮度不太敏感(可以理解为 一个宏块16X16大小,H264中通过最上层16个像素和 最左侧16个像素来预测其他数据,这样原本需要16*16=256的像素表示信息可以转换为 16+16-1=31个像素来表示信息)。
1.3.2 帧间预测(运动估计和运动补偿)
帧间预测压缩(运动估计与补偿):解决的是时域数据冗余问题。 视频中按照时间顺序线性排列的多帧画面,帧画面间相关性很强,所以帧与帧之间会有许多的可以删除的数据。经过压缩后会分为 I帧、P帧、B帧 3种类型(说明:运动估计与补偿原理: H264编码器首先按顺序从缓冲区头部取出两帧视频数据,然后进行宏块扫描。当发现其中一幅图片中有 物体时,就在另一幅图的邻近位置(搜索窗口中)进行搜索。如果此时在另一幅图中找到该物体,那么 就可以计算出物体的运动矢量了。下面这幅图就是搜索后的台球移动的位置)。
对于P帧和B帧,通过运动估计找出与前一帧或双帧之间的运动向量,然后进行运动补偿预测,生成预测图像,并计算出与当前帧的残差。
1.4 整数离散余弦变换(DCT,Discrete Cosine Transform)
该步骤主要是对预测残差进行DCT变换,将空间上的相关性转换为频域上无关的数据,然后进行量化。DCT主要运用于数据或图像的压缩,将空间上的相关性变为频域上无关的数据然后进行量化(说明:DCT变换能够把图像更重要的信息聚集在一块,对于那些不重要的频域区域和系数就能够直接裁剪掉)。
总结:帧数据压缩的顺序是 先进行 帧间和帧内压缩,之后对残差数据进行DCT变换,去掉数据的相关性,进一步压缩数据。如下所示:
1.5 CABAC压缩
CABAC压缩是一种无损压缩技术,属于熵编码的一种方法。CABAC在压缩编码时是给高频数据定义成短码,给低频数据定义成长码。该方式比VLC方式要高效。使用CABAC(Context-Adaptive Binary Arithmetic Coding)熵编码方法对量化后的系数进行进一步压缩,提高压缩效率。这里将前面4步处理得到的数据使用编码算法编码为最终的码流。最终经过压缩后的帧分为:I帧,P帧和B帧。CABAC无损压缩方法执行后得到视频码流。
2 数据压缩流程中相关概念
2.1 时间和空间上的数据冗余
空间上的数据冗余和时间上的数据冗余是视频压缩中的两个基本概念,它们分别描述了视频帧内部和视频帧之间的重复信息。
空间上的数据冗余(Spatial Redundancy)解读:
- 指的是在单个视频帧内部,相邻像素之间存在相似性或相关性,导致的数据重复。由于自然图像的连续性,相邻像素往往具有相似的亮度或颜色值。
- 空间冗余的典型例子包括大面积的单色区域、渐变或缓慢变化的纹理区域。
- 视频压缩算法通过空间预测、变换编码(如DCT)等技术减少空间冗余,将图像从空间域转换到频率域,集中能量到少数几个系数上,从而达到压缩的目的。
时间上的数据冗余(Temporal Redundancy)解读:
- 指的是在视频序列的连续帧之间存在的相似性,即连续帧中的相同物体或场景在视觉上没有显著变化。
- 时间冗余通常出现在摄像机静止不动或场景中物体运动缓慢的情况下,后续帧与前一帧相比只有小部分区域发生变化。
- 视频压缩算法通过帧间预测、运动估计和运动补偿等技术减少时间冗余,利用前后帧的相关性来预测和编码帧间差异,而不是对每一帧进行完整编码。
2.2 残差数据及相关概念解读
在H.264视频压缩中,残差数据(Residual Data)是指原始视频帧与预测帧之间的差异。同时要想更深入的了解残差数据,需要对以下概念有所了解,如下所示:
-
预测帧:在视频编码过程中,会使用帧内预测(Intra Prediction)或帧间预测(Inter Prediction)来生成预测帧。帧内预测基于当前帧的像素信息,而帧间预测则基于先前或后续帧的运动补偿信息。
-
原始帧:指的是视频序列中实际捕获的原始图像帧。
-
残差计算:通过从原始帧中减去预测帧,计算得到残差数据。残差数据表示了预测帧与原始帧之间的差异。
有了以上这些概念的基础,我们可以进一步理解残差数据的特点:
-
残差数据通常具有较高的空间随机性,因为预测帧已经去除了大部分的冗余信息。这种随机性使得残差数据适合通过变换和量化进一步压缩。
-
残差数据经过整数离散余弦变换(Integer Discrete Cosine Transform, IDCT)和量化处理后,可以显著减少数据量。变换将残差的二维空间信息转换为频率信息,量化则减少这些系数的精度,去除人眼不易察觉的细节。
编码残差数据的目的是进一步减少视频数据的比特率,同时尽量保持图像质量。同时残差数据的有效压缩对于H.264编码效率至关重要,因为它直接影响到编码后视频的质量和所需的存储或传输带宽。
2.3 熵编码相关概念及扩展解读
熵编码是一种无损数据压缩技术,基于信息熵的概念,旨在用尽可能少的位数表示数据。熵编码的核心思想是为更可能出现的符号分配更少的比特,而为不常出现的符号分配更多的比特。这样,期望的存储空间或传输带宽就会减少,因为整个数据集的平均比特率会降低。
熵编码通常用于文本和一些特定类型的数据压缩,它可以显著提高压缩效率,特别是当数据具有明显的非均匀概率分布时。在视频压缩编码中,与视频压缩关系最紧密的熵编码方法主要有以下几种:
- 霍夫曼编码(Huffman Coding):霍夫曼编码是许多视频压缩标准(如JPEG、MPEG系列)中使用的一种基本熵编码技术。它通过基于符号出现频率构建的霍夫曼树来为每个符号分配一个变长编码。
- 算术编码(Arithmetic Coding):算术编码在一些视频压缩标准中(如JPEG-LS、JPEG 2000)被采用。它使用一个分数区间来表示输入数据的概率分布,通常能够提供比霍夫曼编码更好的压缩效率。
- 基于上下文的自适应二进制算术编码(CABAC):CABAC是H.264/AVC和H.265/HEVC视频压缩标准中使用的熵编码方法。它结合了算术编码和上下文自适应的概念,能够根据上下文信息动态调整编码的概率模型,从而实现更高效的编码。
- 可变长度编码(Variable Length Coding, VLC):VLC是一个通用术语,用于描述包括霍夫曼编码在内的为符号分配变长码的编码方法。在视频压缩中,VLC通常指代用于表示变换系数等的编码方式。
在视频压缩中,熵编码是最后的编码步骤,用于对帧内预测和帧间预测后的残差数据进行编码。残差数据是原始数据和预测数据之间的差异,通常具有更少的能量和更不均匀的概率分布。通过熵编码,可以进一步减少这些残差数据的比特率,从而达到压缩视频数据的目的。