- 原文地址:https://aomediacodec.github.io/av1-spec/av1-spec.pdf
- 没有梯子的下载地址:AV1 Bitstream & Decoding Process Specification
- 摘要:这份文档定义了开放媒体联盟(Alliance for Open Media)AV1视频编解码器的比特流格式和解码过程。
- 规范:此文档规定了开放媒体联盟(Alliance for Open Media)AV1比特流格式和解码过程。
约定
通用
- 数学运算符及其优先级规则与C编程语言中使用的类似。特别地,定义了截断整数除法的操作。
- 用于保存运动矢量的两个元素数组(变量名以"Mv"或"Mvs"结尾)可以使用数组表示法(例如 Mv[0] 和 Mv[1])或仅使用变量名(例如 Mv)进行访问。仅使用变量名时,只定义了赋值和等式/不等式测试操作。数组赋值使用 A = B 表示,意味着与单独赋值 A[0] = B[0] 和 A[1] = B[1] 相同。两个运动矢量的等式测试使用 A == B 表示,意味着与 (A[0] == B[0] && A[1] == B[1]) 相同。不等式测试定义为 A != B,意味着与 (A[0] != B[0] || A[1] != B[1]) 相同。
- 当一个变量被说成可以用x位有符号整数表示时,意味着该变量大于或等于 -(1 << (x-1)),且小于或等于 (1 << (x-1)) - 1。
- 本文档中的关键词“must”, “must not”, “required”, “shall”, “shall not”, “should”, “should not”, “recommended”, “may”, 和 “optional”应按照RFC 2119中的描述进行解释。
算术运算符
+ | 加法 |
- | 减法(作为二元运算符)或否定(作为一元前缀运算符) |
* | 乘法 |
/ | 整数除法,结果向零截断。例如,7/4 和 -7/-4 都截断为 1,而 -7/4 和 7/-4 都截断为 -1。 |
a%b | a 除以 b 的余数。a 和 b 都是正整数。 |
÷ | 浮点数(算术)除法。 |
ceil(x) | 大于或等于 x 的最小整数。 |
floor(x) | 小于或等于 x 的最大整数。 |
逻辑运算符
a&&b | 逻辑与操作,用于判断 a 和 b 是否都为真。 |
a||b | 逻辑或操作,用于判断 a 和 b 是否至少有一个为真。 |
! | 逻辑非操作 |
位运算符
& | 按位与操作。对两个数的二进制表示进行逐位与运算。 |
| | 按位或操作。对两个数的二进制表示进行逐位或运算。 |
^ | 按位异或操作。对两个数的二进制表示进行逐位异或运算。 |
~ | 按位取反操作。对数的二进制表示进行逐位取反。 |
a>>b | 右移位操作。将 a 的二进制补码表示形式向右移动 b 个比特位置。这个运算符仅用于 b 为非负整数的情况。向右移动时,原来最左边的位被移到最右边,左侧空出的位用符号位(即最左边的位)填充。 |
a<<b | 左移位操作。将 a 的二进制补码表示形式向左移动 b 个比特位置。这个运算符仅用于 b 为非负整数的情况。向左移动时,原来最右边的位被移到最左边,右侧空出的位用0填充。 |
赋值
= | 赋值运算符。将右侧表达式的值赋给左侧的变量。 |
++ | 自增运算符。x++ 相当于 x = x + 1。当这个运算符用于数组索引时,变量值在自增操作之前被获取。 |
– | 自减运算符。x-- 相当于 x = x - 1。当这个运算符用于数组索引时,变量值在自减操作之前被获取。 |
+= | 加法赋值运算符。例如,x += 3 对应于 x = x + 3。 |
-= | 减法赋值运算符。例如,x -= 3 对应于 x = x - 3。 |
数学函数
- 这些数学函数 (Abs, Clip3, Clip1, Min, Max, Round2 and Round2Signed) 定义如下:
- Round2 函数的标准定义使用了数学中的幂和除法操作。这里提供了一个使用整数操作的等效定义:
Round2(x, n) {
if (n == 0)
return x;
return (x + (1 << (n - 1))) >> n;
}
这个函数对数值 x 进行舍入,n 指定了要舍入到的小数位的位数。如果 n 为 0,则直接返回 x。否则,通过加上 2 的 (n-1) 次方,然后向右位移 n 位来实现舍入。
- FloorLog2(x) 函数定义为输入 x 的以 2 为底的对数的向下取整值。输入 x 总是一个整数,并且总是大于或等于 1。这个函数用于找出 x 的最显著位(即最高位的 1)的位置:
FloorLog2(x) {
s = 0;
while (x != 0) {
x = x >> 1;
s++;
}
return s - 1;
}
这个函数通过不断地将 x 右移直到 x 为 0,来计算 x 的二进制表示中最高位 1 的位置。
- CeilLog2(x) 函数定义为输入 x 的以 2 为底的对数的向上取整值。当 x 为 0 时,函数定义为返回 0。输入 x 总是一个整数,并且总是大于或等于 0。这个函数用于计算表示范围从 0 到 x-1 的值所需的位数:
CeilLog2(x) {
if (x < 2)
return 0;
i = 1;
p = 2;
while (p < x) {
i++;
p = p << 1;
}
return i;
}
这个函数通过不断地将 2 的幂次方翻倍,直到这个值大于或等于 x,来计算所需的位数。
描述比特流语法的方法
- 比特流中语法元素的描述风格类似于C编程语言。语法元素在比特流中用粗体表示。每个语法元素都通过其名称(只使用小写字母和下划线字符)和其编码表示方法的描述符来描述。解码过程根据语法元素的值以及之前已解码的语法元素的值来执行。当语法元素的值在语法表或文本中使用时,它以常规类型(即非粗体)显示。如果语法元素的值正在被计算(例如,用默认值而不是在比特流中编码来写入),它也以常规类型显示(例如,tile_size_minus_1)。
- 在某些情况下,语法表可能使用其他从语法元素值派生的变量的值。这些变量在语法表或文本中出现,由小写字母和大写字母混合命名,且不包含任何下划线字符。以大写字母开头的变量是为了解码当前语法结构和所有依赖的语法结构而派生的。这些变量可用于后续语法结构的解码过程。以小写字母开头的变量仅在它们派生的过程中使用。(允许使用单字符变量。)
- 常量值以全部大写字母和下划线字符显示(例如,MI_SIZE)。 常量查找表以单词形式出现(每个单词的首字母大写,其余字母小写),用下划线分隔(例如,Block_Width[…])。 十六进制表示法,通过在十六进制数前加上0x来表示,当位数是4的倍数时可能使用。例如,0x1a表示比特串0001 1010。 二进制表示法通过在二进制数前加上0b来表示。例如,0b00011010表示比特串0001 1010。二进制数可能包含下划线字符以提高可读性。如果存在,下划线字符从最低位(LSB)开始每4个二进制数字出现一次。例如,0b11010也可以写作0b1_1010。值等于0代表测试语句中的FALSE条件。任何非0值代表TRUE。
- 以下表格列出了语法规范格式的例子。当语法元素以粗体出现时(例如syntax_element),它指定这个语法元素是从比特流中解析出来的。
函数
- 用于语法描述的比特流函数在本节中指定。其他函数包含在语法表中。如果一个部分直接或间接通过子进程导致从比特流中读取语法元素,则该部分被称为语法。其余部分被称为函数。
- 这些函数的规范使用了比特流位置指示器。这个比特流位置指示器定位了下一个要读取的比特的位置。
- get_position():返回比特流位置指示器的值。
- init_symbol(sz):根据第8.2.2节的规定,用sz字节的大小初始化符号解码器的算术解码过程。
- exit_symbol():按照第8.2.4节的描述退出算术解码过程(这包括读取尾随比特)。
描述符
- 常规:以下描述符指定了语法元素的解析方式。小写描述符指定了在比特流中由整数位数表示的语法元素;大写描述符指定了由算术编码表示的语法元素。
- f(n):在比特流中直接出现的无符号 n 位数字。比特按从高到低的顺序读取。调用第8.1节指定的解析过程,并将语法元素设置为返回值。
- uvlc(n):在比特流中直接出现的变长无符号 n 位数字。对于这个描述符的解析过程如下:
- le(n):在比特流中直接出现的无符号小端模式的 n 字节数字。对于这个描述符的解析过程如下:
- leb128():无符号整数,由变长的小端字节表示。
- 注意:这个语法元素仅在比特流位置对齐到字节时才会出现。
- 在这种编码中,每个字节的最高位(最左边的位)如果等于1,则表示需要继续读取更多字节;如果等于0,则表示编码结束。
- 在这个过程中间读取的字节数将被设置为一个变量
Leb128Bytes
。这个描述符的解析过程如下:
- 比特流一致性的要求是,leb128解析过程返回的值必须小于或等于 (1 << 32) - 1。
- leb128_byte包含从比特流中读取的8位。最低的7位被用来计算变量的值。最高有效位用来指示是否还有更多的字节需要读取。
- 比特流一致性的要求是,如果i等于7,则leb128_byte的最高有效位必须等于0。(这确保了这种语法描述符永远不会使用超过8个字节。)
- 注意:根据编码的前导零比特的数量,同一值有多种编码方式。没有要求说这个语法描述符必须使用最压缩的表示形式。这对编码器的实现很有用,因为它允许在数值最终确定后,稍后填充固定数量的空间。
- su(n):从比特流中的n位无符号整数转换而来的有符号整数。(无符号整数对应于有符号整数的最低n位。)这个描述符的解析过程如下:
- ns(n):无符号编码整数,最大数值数量为 n(即输出范围在 0 到 n-1 之间)。
- 这个描述符类似于 f(CeilLog2(n)),但通过对于值范围的较低部分编码时减少1个比特,减少了在编码非2的幂次方值范围时产生的浪费。例如,当 n 等于 5 时,编码如下(同时也呈现了完整的二进制编码以供比较):
- 这个描述符的解析过程指定如下:
"ns"这个缩写代表非对称(non-symmetric)。这种编码是非对称的,因为不是所有值都使用相同数量的比特进行编码。
- 这个描述符类似于 f(CeilLog2(n)),但通过对于值范围的较低部分编码时减少1个比特,减少了在编码非2的幂次方值范围时产生的浪费。例如,当 n 等于 5 时,编码如下(同时也呈现了完整的二进制编码以供比较):
- L(n):无符号算术编码的 n 位数字被编码为 n 个标志(一个“字面量”)。这些标志是从高阶到低阶顺序读取的。语法元素被设置为 read_literal(n) 的返回值(见第 8.2.5 节以了解这个过程的规范)。
- S():一个算术编码的符号,编码自最多包含16个条目的小字母表。该符号是根据上下文敏感的累积分布函数(CDF)进行解码的(见第8.3节以了解这个过程的规范)。
- NS(n):无符号算术编码整数,最大值数量为 n(即输出范围在 0 到 n-1 之间)。这个描述符与 ns(n) 相同,只是底层的比特是算术编码的。
- 这个描述符的解析过程规定如下:
- 这个描述符的解析过程规定如下:
原文