基于内容自适应的变长编码方式用于编码zigzag顺序扫描的4x4和2x2残差变换系数块。
1、 编码系数个数和零序列(coeff_token):
coeff_token = <TotalCoeff, TrailingOnes>;
TotalCoeff = 编码非零系数总数; [0 , 16]
TrailingOnes = 特殊处理的+/-1个数; [0 , 3]
2、 编码每个TrailingOne的符号:
倒序,从高频开始向前编码TrailingOne符号,每个符号一位,0为正,1为负,最多为3个。
3、 编码余下非零系数的幅值:
编码顺序:倒序,从高频开始向前编码直到DC系数,每个幅值码字level[i]包含一个幅值前缀level_prefix和一个幅值后缀level_suffix。
level[i]:
Level为实际系数的幅值。但有个例外:
当TrailingOnes<3时,那么被编码的第一个非T1 幅值肯定不是+/-1(否则将算作T1)。这个幅值如果为负就加1(如果为正就减1),例如+/-2 被映射成+/-1, +/-3映射成+/-2进行编码,这样可以用较短的变长码.
levelCode:
如果 level[i]为正, levelCode = (Level[i] << 1) - 2;
如果 level[i]为负, levelCode = -(Level[i] << 1) - 1;
计算level_prefix:
编码时:
level_prefix = levelCode / (1 << suffixLength);
根据level_prefix查标准表9-6得到码字
解码时:
从比特流的当前位置开始读取,计算为0的leading bits数量。0的长度即为level_prefix值,对应关系可察看标准文档中表9-6。
计算suffixLength:
suffixLength为0-6 比特,其长度是自适应变换的。
suffixLength 增长过程:
1、 初始化suffixLength = 0 ; 如果有超过10个非零系数,并且少于3个TailingOnes,这时suffixLength = 1;
2、 编码最高频的非零系数;
3、 如果这个系数的幅值大于一定的阈值,则增长suffixLength
当前suffixLength |
增加suffixLength的系数阈值 |
0 |
0 |
1 |
3 |
2 |
6 |
3 |
12 |
4 |
24 |
5 |
48 |
6 |
N/A |
更新suffixLength函数如下:
if(suffixLength == 0)
++suffixLength;
else if(level[i] > (3<<suffixLength-1) && suffixLength < 6)
++suffixLength;
计算levelSuffixSize: (后缀是长度为levelSuffixSize的无符号整数)
除了以下两种情况levelSuffixSize等于suffixLength:
1、 level_prefix == 14 && suffixLength == 0 时, levelSuffixSize = 4;
2、 level_prefix >= 15 时,levelSuffixSize = level_prefix – 3;
4、 编码最后一个非零系数前零的个数
使用VLC编码最高频非零系数前所有零的个数
total_zeros:既为最高非零系数前所有零的个数;编码表见标准表9-7;表9-8;表9-9
5、 编码每个零游程
zerosLeft: 当前系数之前所有的零的个数
run_before: 紧接当前系数前的零个数