帧内预测之角度预测
为了捕捉自然视频中呈现的任意边缘方向,VVC中的帧内传统角度预测模式数从HEVC中使用的33个扩展到65个。在下图中,VVC中的新的角度预测模式被描绘成红色虚线箭头,并且planar和DC模式保持不变。
H.265/HEVC H.266/VVC
在HEVC中,每个帧内编码块都是正方形的且每边的长度是2的幂,因此,使用DC模式进行帧内预测时不需要除法运算。在VVC中,帧内编码块可以是矩形,为了避免用DC模式进行帧内预测时需要进行除法运算,VVC只计算较长一边的均值作为预测值。
1、帧内模式编码(MPM列表的构建)
如果直接对预测块的模式进行编码,那么对于67种模式需要7bit来编码,数据量很大。VVC采取和HEVC一样的方法,先构建最可能模式列表(most probable mode ,MPM),在VVC内MPM list里有6个预测模式(无论是否应用MRL和ISP),如果该块的预测模式在MPM中只需要编码其索引号(只需要3bit),如果该块的预测模式不在MPM中而是在61个non-MPM模式中,在熵编码阶段使用截断二元码(Truncated Binary Code ,TBC)编码其模式。
MPM列表是基于左边相邻块和上方相邻块的帧内模式构造的,如上图所示,构造方法如下:
- 当左边块和上边块不可参考时,其帧内模式默认设置为Planar模式
- 如果左边块和上边块都是非角度模式时
- MPM list -> {Planar,DC,V,H,V--4,V+4}
- 如果左边块和上边块其中一个是角度模式,另一个不是角度模式时
- 设Max是左边块和上边块较大的模式
- MPM list ->{Planar, Max, Max − 1, Max + 1, Max − 2, Max + 2}
- 如果左边块和上边块都是角度模式且它们不同时
- 设Max是左边块和上边块较大的模式
- 设Min是左边块和上边块较小的模式
- 如果Max - Min 的等于 1
- 则 MPM list -> {Planar, Left, Above, Min – 1, Max + 1, Min – 2}
- 如果如果Max - Min 的大于等于62
- 则MPM list ->{Planar, Left, Above, Min + 1, Max – 1, Min + 2}
- 如果如果Max - Min 的等于2
- 则MPM list -> {Planar, Left, Above, Min + 1, Min – 1, Max + 1}
- 否则,MPM list ->{Planar, Left, Above, Min – 1, –Min + 1, Max – 1}
- 如果左边块和上边块时相同的角度模式时
- MPM list –>{Planar, Left, Left − 1, Left + 1, Left − 2, Left + 2}}
MPM索引码字的第一个bin是CABAC上下文编码的。总共使用三个上下文,分别对应于当前帧内块是启用了MRL、启用了ISP还是正常的帧内块。
生成MPM列表时候,需要删除重复的模式,以便包含在MPM列表的模式唯一。
2、针对矩形块的宽角度模式
在HEVC中,由于帧内预测块都是正方形的所以各个角度预测模式使用的概率是相等的。而在VVC中,帧内预测块可能是矩形块,对于水平类的块(宽大于高)上边的参考像素使用概率大于左边参考像素的使用概率,对于垂直类的块(高大于宽)上边的参考像素使用概率小于左边参考像素的使用概率。因此,VVC引入了宽角度预测模式,在对矩形块预测时,将传统的角度预测模式转换为宽角度预测模式。
如图,模式2 ~ 66表示传统的帧内预测模式,模式 -1 ~ -14以及模式67 ~ 80表示宽角度预测模式。
宽角度预测模式仍然使用使用传统角度模式索引发出信号,在解码端在将传统角度模式再转换为宽角度预测模式,这样的话帧内预测模式的总数和帧内模式编码方法保持不变, 并且帧内模式编码方法不变。
Reference samples for wide-angular intra prediction
宽角度预测模式参考像素如上图所示,为了支持宽角度预测方向,上图定义了长度为2W+1的顶部参考和长度为2H+1的左侧参考。
宽角度帧内预测模式的替换取决于块的宽高比。具体如下表所示:
宽高比 | 被替换的角度模式 | 替换后的角度模式 |
W / H == 16 | Modes 2,3,4,5,6,7,8,9,10,11,12, 13,14,15 | 67,68,69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 |
W / H == 8 | Modes 2,3,4,5,6,7,8,9,10,11,12, 13 | 67,68,69, 70, 71, 72, 73, 74, 75, 76, 77, 78 |
W / H == 4 | Modes 2,3,4,5,6,7,8,9,10,11 | 67,68,69, 70, 71, 72, 73, 74, 75, 76 |
W / H == 2 | Modes 2,3,4,5,6,7,8,9 | 67,68,69, 70, 71, 72 |
W / H == 1 | None | None |
W / H == 1/2 | Modes 59,60,61,62,63,64,65,66 | -6,-5,-4,-3,-2,-1 |
W / H == 1/4 | Mode 57,58,59,60,61,62,63,64,65,66 | -10,-9,-8,-7,-6,-5,-4,-3,-2,-1 |
W / H == 1/8 | Modes 55, 56,57,58,59,60,61,62,63,64,65,66 | -12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1 |
W / H == 1/16 | Modes 53, 54, 55, 56,57,58,59,60,61,62,63,64,65,66 | -14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1 |
如上图所示,当对矩形块使用宽角度预测时,垂直相邻的两个预测像素可能使用两个不相邻的参考像素。为了减少参考像素间距∆pα带来的负面影响,需要对参考像素进行低通滤波和平滑处理。当预测模式是[-14, -12, -10, -6, 72, 76, 78, 80]时,参考像素可以不经处理直接使用。
角度模式向宽角度模式的转换代码如下所示:
int PU::getWideAngle( const TransformUnit &tu, const uint32_t dirMode, const ComponentID compID )
{
//This function returns a wide angle index taking into account that the values 0 and 1 are reserved
//for Planar and DC respectively, as defined in the Spec. Text.
if( dirMode < 2 )
{
return ( int ) dirMode;
}
const CompArea& area = tu.cu->ispMode && isLuma(compID) ? tu.cu->blocks[compID] : tu.blocks[ compID ];
int width = area.width;
int height = area.height;
int modeShift[ ] = { 0, 6, 10, 12, 14, 15 };
int deltaSize = abs( floorLog2( width ) - floorLog2( height ) );
int predMode = dirMode;
if( width > height && dirMode < 2 + modeShift[ deltaSize ] )
{
predMode += ( VDIA_IDX - 1 );
}
else if( height > width && predMode > VDIA_IDX - modeShift[ deltaSize ] )
{
predMode -= ( VDIA_IDX + 1 );
}
return predMode;
}
3、4抽头插值滤波器和参考像素的平滑
在HEVC中,对角度预测模式(不包括Planar和DC)使用两抽头线性插值滤波器进行滤波。在VVC中,采用四抽头高斯插值滤波器来进行滤波,从而提高帧内角度预测精度。
VVC帧内参考像素滤波总共存在三种滤波器,一种是对满足一定条件下的参考像素进行平滑滤波 ([1 2 1]/4 滤波器);另外两种是对预测时非整数像素位置的插值滤波器,VVC共使用两组四抽头的插值滤波器:三次插值滤波器和高斯插值滤波器,其中三次插值滤波器能保留更多细节纹理,高斯插值滤波器的滤波效果更为平滑。
- 将角度预测模式分为以下:
- A垂直或水平模式(HOR_IDX, VER_IDX)
- B表示非分数角度的方向模式(−14、−12、−10、−6、2、34、66、72、76、78、80)和planar模式
- 其它
-
如果角度模式属于A,不进行滤波处理,直接将复制参考像素得到预测像素。
-
如果角度模式属于B,且必须满足全部以下几种条件时,才需要对参考像素进行平滑滤波,直接将滤波后的值作为预测像素不进行插值处理。
-
参考行索引为0
-
TU内像素数大于32,即width * height > 32
-
亮度分量
-
不是ISP模式
-
-
如果角度模式属于C,则需要使用插值滤波器以获得非整数位置像素。当同时满足以下几种条件时,使用高斯插值滤波器,否则使用三次插值滤波器:
-
MRL索引等于0
-
非ISP模式
- minDistVerHor大于intraHorVerDistThres[nTbS],其中minDistVerHor和intraHorVerDistThres[nTbS]的确定如下:
-
将minDistVerHor设置为Min(Abs(predModeIntra−50),Abs(predModeIntra−18))
-
将nTbS设置为(Log2(W)+Log2(H))>>1
-
根据以下表格设置 intraHorVerDistThres[ nTbS ]
-
-
nTbS = 2 | nTbS = 3 | nTbS = 4 | nTbS = 5 | nTbS = 6 | nTbS = 7 | |
intraHorVerDistThres[ nTbS ] | 24 | 14 | 2 | 0 | 0 | 0 |
三次插值滤波器(fC)和高斯插值滤波器(fG)的滤波系数如下所示:(其中,当三次插值滤波器对应的分数像素位置为0时,仅fc[p][1]有值,表示不进行插值)
插值滤波器的使用和预测像素的计算如下所示,这里,i0 表示预测样本投影在参考样本中最接近左侧整数的位置,p∈ {0, . . . ,31},以1/32像素精度构成预测像素投影的分数部分
Fractional sample position p | fC interpolation filter coefficients | fG interpolation filter coefficients | ||||||
fC[ p ][ 0 ] | fC[ p ][ 1 ] | fC[ p ][ 2 ] | fC[ p ][ 3 ] | fG[ p ][ 0 ] | fG[ p ][ 1 ] | fG[ p ][ 2 ] | fG[ p ][ 3 ] | |
0 | 0 | 64 | 0 | 0 | 16 | 32 | 16 | 0 |
1 | −1 | 63 | 2 | 0 | 16 | 32 | 16 | 0 |
2 | −2 | 62 | 4 | 0 | 15 | 31 | 17 | 1 |
3 | −2 | 60 | 7 | −1 | 15 | 31 | 17 | 1 |
4 | −2 | 58 | 10 | −2 | 14 | 30 | 18 | 2 |
5 | −3 | 57 | 12 | −2 | 14 | 30 | 18 | 2 |
6 | −4 | 56 | 14 | −2 | 13 | 29 | 19 | 3 |
7 | −4 | 55 | 15 | −2 | 13 | 29 | 19 | 3 |
8 | −4 | 54 | 16 | −2 | 12 | 28 | 20 | 4 |
9 | −5 | 53 | 18 | −2 | 12 | 28 | 20 | 4 |
10 | −6 | 52 | 20 | −2 | 11 | 27 | 21 | 5 |
11 | −6 | 49 | 24 | −3 | 11 | 27 | 21 | 5 |
12 | −6 | 46 | 28 | −4 | 10 | 26 | 22 | 6 |
13 | −5 | 44 | 29 | −4 | 10 | 26 | 22 | 6 |
14 | −4 | 42 | 30 | −4 | 9 | 25 | 23 | 7 |
15 | −4 | 39 | 33 | −4 | 9 | 25 | 23 | 7 |
16 | −4 | 36 | 36 | −4 | 8 | 24 | 24 | 8 |
17 | −4 | 33 | 39 | −4 | 8 | 24 | 24 | 8 |
18 | −4 | 30 | 42 | −4 | 7 | 23 | 25 | 9 |
19 | −4 | 29 | 44 | −5 | 7 | 23 | 25 | 9 |
20 | −4 | 28 | 46 | −6 | 6 | 22 | 26 | 10 |
21 | −3 | 24 | 49 | −6 | 6 | 22 | 26 | 10 |
22 | −2 | 20 | 52 | −6 | 5 | 21 | 27 | 11 |
23 | −2 | 18 | 53 | −5 | 5 | 21 | 27 | 11 |
24 | −2 | 16 | 54 | −4 | 4 | 20 | 28 | 12 |
25 | −2 | 15 | 55 | −4 | 4 | 20 | 28 | 12 |
26 | −2 | 14 | 56 | −4 | 3 | 19 | 29 | 13 |
27 | −2 | 12 | 57 | −3 | 3 | 19 | 29 | 13 |
28 | −2 | 10 | 58 | −2 | 2 | 18 | 30 | 14 |
29 | −1 | 7 | 60 | −2 | 2 | 18 | 30 | 14 |
30 | 0 | 4 | 62 | −2 | 1 | 17 | 31 | 15 |
31 | 0 | 2 | 63 | −1 | 1 | 17 | 31 | 15 |
判断是否对参考像素进行滤波的代码:帧内预测之初始化帧内预测参数(initPredIntraParams)
使用[1 2 1]对参考像素进行平滑滤波的代码:帧内预测之参考像素获取及滤波(xFilterReferenceSamples)
进行预测过程中,对非整像素位置进行插值滤波的代码:帧内预测之角度预测函数(predIntraAng、xPredIntraAng)