libaom
- 开放媒体联盟视频1(AV1)编解码器的框架基于一种混合视频编码结构,由几个主要的功能模块组成,如预测、变换、量化、熵编码和环路滤波。每个功能模块使用特定类型的视频编码技术处理输入数据,其输出被送入另一个功能模块或作为视频编解码器的最终输出。这些功能模块按照特定的设计连接在一起,协同工作以实现显著的数据压缩。
- libaom 是 AV1 视频编码格式的参考编码器,它在 AV1 的开发过程中也用于研究 。libaom 基于 libvpx,因此在功能、性能和使用方面与 libvpx 有许多共同点 。要安装支持 libaom-av1 的 FFmpeg,需要查看编译指南,并在编译 FFmpeg 时加上
--enable-libaom
选项 。
AV1的技术特点:
AV1的编码框架是一个高度模块化的系统,旨在通过各种编码技术实现高效的视频压缩。以下是AV1编码框架的主要组成部分及其功能:
块划分(Block Partitioning):
- 编码块划分:确定视频帧中编码单元的大小和形状,这影响编码的效率和质量。
- 变换块划分:确定应用变换操作的单元大小,通常与编码块不同。
帧内预测(Intra Prediction):
- 方向内预测:基于图像内容的方向性进行预测,适用于纹理区域。
- 非方向内预测:不依赖于特定方向的预测方法,适用于平坦区域。
- 递归内预测:一种高级的预测技术,可能涉及多步预测。
- 从亮度预测色度(Chroma from Luma, CfL):使用亮度信息来辅助色度的预测。
- 内预测模式信号:传输用于选择特定内预测模式的信息。
帧间预测(Inter Prediction):
- 引用帧系统:定义用于插值预测的参考帧,通常包括前向和后向帧。
- 运动向量预测:包括空间和时间上的运动向量预测,用于补偿视频中的运动。
- 插值预测模式信号:传输用于选择插值预测模式的信息。
- 运动补偿技术:包括平移、扭曲、重叠块和复合插值预测方法。
变换编码(Transform Coding):
- 核心变换:如DCT(离散余弦变换)或DWT(离散小波变换),用于将空间域数据转换到频率域。
- 变换选择和信号:允许编码器选择最合适的变换类型,并传输这一选择。
量化(Quantization):
- 对变换后的系数进行量化,减少数据量,同时影响视频质量。
熵编码(Entropy Coding):
- 多符号算术编码引擎:一种高效的编码方法,用于进一步压缩数据。
- 系数编码:对量化后的变换系数进行编码。
环路滤波和后处理(Loop Filtering and Post-processing):
- 去块滤波器:减少块效应,改善视觉质量。
- 约束方向增强滤波器:增强图像的边缘,提高细节清晰度。
- 环路恢复滤波器:进一步改善图像质量,减少编码伪影。
- 帧超分辨率和胶片颗粒合成:提高视频分辨率和模拟胶片效果。
屏幕内容编码(Screen Content Coding):
- 针对屏幕内容(如文本、图表)的特定编码技术,包括内块复制、调色板模式和内容类型检测。
AV1编码框架的设计允许它适应不同类型的视频内容,并在保持高质量视频输出的同时实现高压缩率。
块分区
编码块分区
在AV1编码中,使用不同大小的编码块(Coding Blocks, CBs),这些块构成了视频帧的基本处理单元。最大的编码块被称为超块(Superblocks),它们有两种尺寸:128×128或64×64像素。默认情况下,超块的尺寸是128×128像素,但这个尺寸可以在序列头信息(Sequence Header)中进行信号传递,以适应不同的编码需求。
在AV1编码中,超块(superblocks)可以进一步划分为更小的编码块(coding blocks)。这种划分策略在比特流(bitstream)中进行信号传递。除了不进行划分的模式PARTITION_NONE
,AV1支持多达九种不同的划分模式,具体如下:
- 不划分模式(No-partitioning mode):
PARTITION_NONE
: 表示超块不进行进一步划分。
四划分模式(4-partition modes):
PARTITION_SPLIT
:将超块等分为四个较小的块,并且允许递归划分,即每个子块可以再次被划分。PARTITION_VERT_4
:垂直划分为四个条状块。PARTITION_HORZ_4
:水平划分为四个条状块。三划分模式(T-shaped partition modes):
PARTITION_HORZ_A
和PARTITION_HORZ_B
:两种不同的水平T形划分。PARTITION_VERT_A
和PARTITION_VERT_B
:两种不同的垂直T形划分。二划分模式(2-partition modes):
PARTITION_HORZ
:将超块水平划分为两个部分。PARTITION_VERT
:将超块垂直划分为两个部分。
划分注意事项
在所有划分模式中,只有
PARTITION_SPLIT
允许递归划分,即子块可以继续被划分为更小的块。对于其他划分模式,子块不能再进一步划分。此外,还有一些限制条件:
PARTITION_VERT_4
和PARTITION_HORZ_4
模式不允许用于8×8或128×128的块尺寸。- T形划分模式不允许用于8×8的块。
编码块划分优点
- 这种灵活的划分机制使得AV1编码器能够根据视频内容的特性选择最合适的划分方式,从而在保持视频质量的同时提高压缩效率。例如,在快速运动或细节丰富的区域可能需要更小的块来捕捉细节,在平坦区域则可以使用较大的块来减少编码比特。
变换块分区
在AV1编码中,无论是内预测(intra prediction)编码块还是帧间预测(inter prediction)编码块,它们都可以进一步划分为多个变换块(transform blocks)。这种划分可以有最多两级深度。变换块的大小由变换划分模式(transform partitioning mode)和编码块(coding block)的大小共同决定。
变换块的尺寸可以是多种不同的尺寸,例如4x4、8x8、16x16、32x32、64x64等。变换块的尺寸选择取决于当前编码块的尺寸以及变换划分模式。例如,一个较大的编码块可能在第一级变换划分中被划分为多个较小的变换块,然后在第二级变换划分中进一步细分。
在AV1编码中,变换类型可以根据变换块的比例进行概括,具体如下:
1:1 方块(Square Blocks):
- 当变换块是正方形时(例如,4x4、8x8等),在进行下一级的变换划分时,会创建四个相同大小的1:1正方形变换块。例如,一个8x8的变换块可以划分为四个8x8的子变换块。
1:2 或 2:1 非方块(Non-square Blocks):
- 当变换块是水平或垂直的非正方形时(例如,4x8或8x4),在进行下一级的变换划分时,会创建两个1:1正方形变换块。这意味着一个4x8的变换块可以划分为两个4x4的变换块,或者一个8x4的变换块也可以划分为两个4x4的变换块。
1:4 或 4:1 非方块:
- 当变换块是更细长的水平或垂直非正方形时(例如,4x16或16x4),在进行下一级的变换划分时,会创建两个1:2或2:1的非正方形变换块。例如,一个4x16的变换块可以划分为两个8x8的变换块,或者一个16x4的变换块可以划分为两个8x2的变换块。
帧内亮度分量编码块与变换块关系
在AV1编码中,对于内预测编码块的亮度(luma)分量,所有的变换块(transform blocks)必须具有相同的尺寸。这是为了确保编码的一致性和简化解码过程。以下是具体的例子和说明:
亮度分量的变换块尺寸一致性:
- 假设有一个32×16的编码块(coding block),在第一级变换划分时,会创建两个尺寸相同的16×16变换块。
- 如果进行第二级变换划分,那么每个16×16的变换块将被进一步划分为四个8×8的变换子块,最终得到八个8×8的变换子块。
变换块的划分示例:
- 内预测编码块的变换块划分通常在文档或规范中的图示中展示,以可视化的方式说明变换块如何被划分。
- 图中的箭头表示变换块的编码顺序,这有助于理解编码过程中各个变换块是如何被依次处理的。
变换块的编码顺序:
- 编码顺序可能基于多种因素,如视频内容的预测特性、纹理分布、运动信息等。编码顺序的选择可以影响编码效率和最终的视频质量。
变换块尺寸选择的重要性:
- 变换块的尺寸选择对于编码效率至关重要。对于亮度分量,尺寸的选择可能更加注重保持变换块的一致性,以适应内预测编码块的特性
帧间亮度分量编码块与变换块关系
对于帧间预测(inter prediction)编码块的亮度(luma)分量,在第一级变换划分之后,每个子块可以在第二级变换划分中独立地进行进一步划分。这种机制允许帧间编码块具有可变的变换块大小,从而为编码器提供了更大的灵活性来适应不同的视频内容和编码需求。
以下是具体的说明:
第一级变换划分:
- 在第一级变换划分中,一个较大的编码块被划分为若干个较小的子块。这些子块的大小可以相同,也可以不同,这取决于编码器的选择。
第二级变换划分的独立性:
- 在第二级变换划分中,每个由第一级划分得到的子块可以独立地选择不同的变换块大小。这意味着,编码器可以根据每个子块的内容特性来选择最合适的变换块大小。
变换块大小的可变性:
- 插值编码块的变换块大小可以是可变的,这意味着编码器可以根据视频帧中每个区域的运动和纹理特性来优化变换块的尺寸。例如,对于快速运动的区域,可能需要较小的变换块来捕捉细节;而对于较慢运动或平坦的区域,则可以使用较大的变换块来提高编码效率。
变换块划分示例:
- 插值编码块的变换块划分通常在文档或规范中的图示中展示。这些图示说明了变换块如何根据不同的子块独立地进行划分。
编码器的优化选择:
- 编码器可以根据视频内容的分析结果来选择最佳的变换块大小。这种优化可以提高压缩效率,同时保持或提高视频质量。
色度分量编码块与变换块关系
在AV1编码中,色度(chroma)分量的变换块(transform block)大小通常与相应的色度编码块(coding block)大小相同。这确保了变换块能够与编码块保持一致,从而优化编码过程。然而,存在一个特殊情况,即当色度编码块的宽度或高度大于32像素时,色度变换块的宽度或高度会被设置为32像素。以下是具体规则的说明:
相同大小规则:
- 通常情况下,色度分量的变换块大小直接对应于色度编码块的大小。这意味着如果编码块是16x16,那么变换块也将是16x16。
最大尺寸限制:
- 如果色度编码块的宽度或高度超过32像素,无论实际尺寸如何,色度变换块的尺寸都将被限制为32x32像素。这个限制确保了变换块不会超过这个最大尺寸。
尺寸调整:
- 当色度编码块大于32像素时,可能需要调整变换块的尺寸以适应最大尺寸限制。例如,如果一个色度编码块是64x32,那么在变换过程中,它将被划分为两个32x32的变换块。
编码效率:
- 这种尺寸限制有助于保持编码过程的一致性和效率。32x32像素的变换块是一个常见的最大尺寸,可以平衡编码效率和解码复杂度。
适应性:
- 尽管存在最大尺寸限制,AV1编码器仍然需要根据色度分量的特性和视频内容来选择最合适的编码块和变换块尺寸。
色度分量的特殊处理:
- 色度分量通常具有比亮度分量更低的分辨率,这是由于人类视觉系统对色度的敏感度低于亮度。因此,对色度分量应用最大尺寸限制可以在不显著影响视觉质量的情况下提高编码效率。
变换分区特点总结
AV1编码中,变换块(transform block)的划分方案依据编码块(coding block)的尺寸有所不同。以下是具体规则的说明:
小于或等于64×64的编码块:
- 对于尺寸小于或等于64×64像素的编码块,变换块的划分方案直接从编码块的原始尺寸开始。
大于64×64的编码块:
- 如果编码块的宽度(W)或高度(H)在亮度(luma)样本上大于64像素,编码块首先被隐式地划分为尺寸为min(W, 64)×min(H, 64)的子块。这种隐式划分不需要在比特流中进行信号传递。
隐式划分:
- 隐式划分意味着编码器自动按照64×64的网格将编码块划分为多个子块,而无需在编码过程中明确指示这种划分。
显式划分:
- 在隐式划分的基础上,每个min(W, 64)×min(H, 64)的子块可以进一步按照变换块划分方案进行显式划分。这种显式划分需要在比特流中进行信号传递,以指示具体的划分模式。
示例:
- 以128×64的编码块为例,残差块首先被隐式划分为两个64×64的子块。然后,每个64×64的子块可以进一步根据变换块划分方案被划分为更小的变换块,并且这种划分模式需要在比特流中明确信号传递。
变换块的进一步划分:
- 在显式划分步骤中,每个子块可以根据编码器的决策和视频内容的特性,被进一步划分为更小的变换块,如4×4、8×8等,具体划分模式会根据编码效率和视频质量的要求来确定。
通过这种隐式和显式的划分方法,AV1编码器能够灵活地处理不同尺寸的编码块,同时确保编码过程的效率和视频质量。隐式划分减少了需要信号传递的信息量,而显式划分允许编码器根据内容的需要选择最合适的变换块大小。
变换块分区优点
- 这种多级变换划分的机制允许编码器在编码过程中更加灵活,可以根据视频内容的特性和编码效率的需求选择最合适的变换块尺寸。较小的变换块可以更好地适应图像中的高频细节区域,而较大的变换块可以在图像的平坦区域减少编码的复杂度,提高压缩效率。
- 这种变换划分规则确保了变换块在不同级别的划分中保持一致性和高效性。变换块的尺寸和形状可以根据编码块的内容和特性进行优化,以实现更好的压缩效率和视频质量。例如,对于具有明显水平或垂直边缘的区域,使用非正方形的变换块可以更有效地表示图像内容;而对于更加平坦或细节均匀分布的区域,使用正方形变换块可能更为合适。
libaom源码中关于块分区相关说明
- 在
av1/common/eums.h
中有有关于块分区的定义,可以看到在块尺寸一共有22种,分区类型一共有10种,变换模式有4种。
typedef enum ATTRIBUTE_PACKED {BLOCK_4X4,BLOCK_4X8,BLOCK_8X4,BLOCK_8X8,BLOCK_8X16,BLOCK_16X8,BLOCK_16X16,BLOCK_16X32,BLOCK_32X16,BLOCK_32X32,BLOCK_32X64,BLOCK_64X32,BLOCK_64X64,BLOCK_64X128,BLOCK_128X64,BLOCK_128X128,BLOCK_4X16,BLOCK_16X4,BLOCK_8X32,BLOCK_32X8,BLOCK_16X64,BLOCK_64X16,BLOCK_SIZES_ALL,BLOCK_SIZES = BLOCK_4X16,BLOCK_INVALID = 255,BLOCK_LARGEST = (BLOCK_SIZES - 1)
} BLOCK_SIZE;// 4X4, 8X8, 16X16, 32X32, 64X64, 128X128
#define SQR_BLOCK_SIZES 6// Partition types. R: Recursive
//
// NONE HORZ VERT SPLIT
// +-------+ +-------+ +---+---+ +---+---+
// | | | | | | | | R | R |
// | | +-------+ | | | +---+---+
// | | | | | | | | R | R |
// +-------+ +-------+ +---+---+ +---+---+
//
// HORZ_A HORZ_B VERT_A VERT_B
// +---+---+ +-------+ +---+---+ +---+---+
// | | | | | | | | | | |
// +---+---+ +---+---+ +---+ | | +---+
// | | | | | | | | | | |
// +-------+ +---+---+ +---+---+ +---+---+
//
// HORZ_4 VERT_4
// +-----+ +-+-+-+
// +-----+ | | | |
// +-----+ | | | |
// +-----+ +-+-+-+
enum {PARTITION_NONE,PARTITION_HORZ,PARTITION_VERT,PARTITION_SPLIT,PARTITION_HORZ_A, // HORZ split and the top partition is split againPARTITION_HORZ_B, // HORZ split and the bottom partition is split againPARTITION_VERT_A, // VERT split and the left partition is split againPARTITION_VERT_B, // VERT split and the right partition is split againPARTITION_HORZ_4, // 4:1 horizontal partitionPARTITION_VERT_4, // 4:1 vertical partitionEXT_PARTITION_TYPES,PARTITION_TYPES = PARTITION_SPLIT + 1,PARTITION_INVALID = 255
} UENUM1BYTE(PARTITION_TYPE);// frame transform mode
enum {ONLY_4X4, // use only 4x4 transformTX_MODE_LARGEST, // transform size is the largest possible for pu sizeTX_MODE_SELECT, // transform specified for each blockTX_MODES,
} UENUM1BYTE(TX_MODE);