I宏块使用帧内预测编码压缩数据,根据相邻宏块数据恢复当前宏块信息。值得注意的一点是,帧内预测所参考的相邻宏块数据是deblocking之前的像素值,因为上一宏块的deblocking依赖当前宏块像素值,但当前宏块数据还未重建。
帧内预测包含4种类型:
帧内预测的输入为预测模式和相邻块像素值,输出为当前块的预测值。
该模式下,16x16宏块中的亮度块,可分为16个4x4块,每个4x4块都使用Intra_4x4预测方式。其中16个4x4块的扫描顺序如下图:
对于索引号luma4x4BlkIdx为0-15的4x4块,预测过程如下:
1) 根据相邻块Intra4x4PredMode推导当前块Intra4x4PredMode;
2) 根据Intra4x4PredMode和相邻块像素值,得到当前块预测像素值。
本过程的输入是 4x4 亮度块的索引 luma4x4BlkIdx 和先前(按照解码顺序)已经得到的相邻宏块的预测方式 Intra4x4PredMode (如果可用) 和 Intra8x8PredMode(如果可用)。 本过程的输出是变量 每个4x4块的Intra4x4PredMode[ luma4x4BlkIdx ]。
下表定义了 Intra4x4PredMode[ luma4x4BlkIdx ]的值和相应的名称。
Intra4x4PredMode[ luma4x4BlkIdx ]的值为 0、1、2、3、4、5、6、7 和 8,这些值分别代表不同预测方向,如下图:
Intra4x4PredMode[ luma4x4BlkIdx ] 由以下方式得到:
1) 以下任一条件满足则使用DC预测(Intra_4x4_DC):
举个例子,I slice的第一个宏块必定使用DC预测,因为它的相邻块mbAddrA、mbAddrB都不可用。
2) 不满足上述条件,则通过相邻块预测模式预测当前块Intra4x4PredMode。
已知以下信息:mbAddrA的预测模式、mbAddrB的预测模式、码流中读取的语法元素prev_intra4x4_pred_mode_flag。
伪代码如下:
predIntra4x4PredMode = Min( intraMxMPredModeA, intraMxMPredModeB )
if( prev_intra4x4_pred_mode_flag[ luma4x4BlkIdx ] )
Intra4x4PredMode[ luma4x4BlkIdx ] = predIntra4x4PredMode
else
if( rem_intra4x4_pred_mode[ luma4x4BlkIdx ] < predIntra4x4PredMode )
Intra4x4PredMode[ luma4x4BlkIdx ] = rem_intra4x4_pred_mode[ luma4x4BlkIdx ]
else
Intra4x4PredMode[ luma4x4BlkIdx ] = rem_intra4x4_pred_mode[ luma4x4BlkIdx ] + 1
标准文档中这部分内容比较繁杂,其实可以总结为:
Intra_4x4预测需要用到的13个相邻像素值如下图所示:
相邻像素如何获取可参考帧内预测相邻像素推导过程.
首先需要判断这13个像素值是否有效。当下列4个条件满足任意一个,那么该像素便被判定为无效,不能用于预测:
Intra4x4预测根据相邻的13个像素值得到当前4x4块预测像素值。预测方式共有9种;
Dc数值为相邻像素值的均值:
1)A、B、C、D、I、J、K、L都存在时,dc为这8个像素值的均值;
2)A、B、C、D不可用时,dc为I、J、K、L这4个像素的均值;
3)I、J、K、L不可用时,dc为A、B、C、D这4个像素的均值;
4)当这8个像素都不可用时,dc为(1<<(bit_depth-1))。
当A、B、C、D、E、F、G、H 8个像素存在时才能使用这种预测模式;
以像素点a为例,做一条左下方向成45°直线,会穿过预测像素点B,预测计算过程依赖A、B、C三个像素值,pred_a = (A+2B+C+2)/4
后面的几种预测方向不是45°整数倍,要分成两种情况分别计算。
以Intra_4x4_Vertical_Right为例,像素a、j的预测值为(A+Q+1)/2;
像素f、o的预测值为(Q+2A+B+2)/4
一个宏块种的16x16亮度分量可分为4个8x8亮度块,每个8x8块都是用Intra_8x8预测方式。其中4个8x8块的扫描顺序如下:
对于索引号luma8x8BlkIdx为0-3的8x8块,预测方式推导过程、预测像素计算过程与Intra4x4类似,在此不再赘述。获取8x8块预测像素值流程如下:
1) 根据相邻块Intra8x8PredMode推导当前块Intra8x8PredMode;
2) 确定预测过程使用的相邻块预测像素是否可用
3)根据Intra8x8PredMode和相邻块预测像素值,得到当前块预测像素值。
相比于Intra_4x4和Intra_8x8,Intra_16x16的区别主要有以下几点:
Intra_16x16需要33个参考像素点,分别为当前宏块左侧16个像素点,上方16个像素点以及左上方一个像素点。这些参考像素点是否可用的判断方式于Intra_4x4类似。
4种预测模式如下:
只有上方16个参考像素有效时才可以使用,计算方法为
predL[ x, y ] = p[ x, −1 ], x, y = 0…15
只有左侧16个参考像素有效时才可以使用,计算方法为
predL[ x, y ] = p[ −1, y ], x, y = 0…15
16×16模式的DC预测模式同4×4模式的DC预测方法类似,判断左侧16个像素和上方16个像素的有效性,将其中有效部分的均值作为整个预测块的像素值。如果32个像素都无效,则预测块像素值为( 1 << ( bit_depth − 1 ) )。
一般码流中第一个I slice的第一个宏块会使用Intra_16x16_DC预测模式,对于8bit像素,其宏块预测值为128.
Intra_16x16_Plane模式要求33个像素值都存在时才能使用。计算方式如下:
predL[ x, y ] = Clip1Y( ( a + b * ( x − 7 ) + c * ( y − 7 ) + 16 ) >> 5 ),x,y = 0…15
其中,
a = 16 * ( p[−1, 15 ] + p[ 15, −1 ] )
b = ( 5 * H + 32 ) >> 6
c = ( 5 * V + 32 ) >> 6
一个宏块包含两个8x8色度块,分别为cb分量和cr分量。这两个分量使用相同的预测方式,由mb header中的语法元素intra_chroma_pred_mode决定。
这4种预测模式与Intra_16x16类似,不再赘述。