码流进入解码器,先后通过“获取MV和参考索引操作”和“帧间预测像素解码操作”得到帧间预测像素矩阵,包括1个16×16的亮度矩阵和2个8×8的色度矩阵。
获取MV和参考索引操作
这时候的码流中的数据是mbPartIdx和subMbPartIdx,经过“获取MV和参考帧索引操作”后输出的数据是mvL0、mvL1、mvCL0、mvCL1、refIdxL0、refIdxL1、predFlagL0和predFlagL1。
1. 当宏块为普通类型时,计算mvL0/1使用的公式和流程如下:
mvL0/1[0/1] = mvpL0/1[0/1] + mvd_l0/1[mbPartIdx][subMbPartIdx][0/1]
2. 当宏块为Skip类型时,
2.1. P和SP
首先,以mbPartIdx=0,subMbPartIdx=0为输入,得到“临近块运动数据推导”的输出;
然后,若1)mbAddrA不存在;2)mbAddrB不存在;3)refIdxL0A=0,且mvL0A两个分量都等于0;4)refIdxL0B=0,且mvL0B两个分量都等于0。如果四个命题任一为true,mvL0的x和y都为0;如果四个命题都为false,那么就根据“中值亮度MV推导”得出结果。
2.2. B(除了B_Skip还有B_Direct_16×16和B_Direct_8×8)
以mbPartIdx和subMbPartIdx为输入,输出refIdxL0、refIdxL1、mvL0、mvL1、predFlagL0和predFlagL1。此外,direct_spatial_mv_pred_flag也会影响输出,为0时输出为空间直接预测模式;为1时输出时间直接预测模式。
3. 当获取宏块的色度MV时,
输入亮度矢量mvL0/1和redIdxL0/1,输出色度矢量mvCL0/1。(色度精度为亮度的一半,若亮度为1/4精度,则色度为1/8精度)。
当宏块为帧宏块,色度mv的水平和竖直分量通过乘2将亮度映射到色度实现;
当宏块为场宏块,色度mv的水平分量通过一种类似Intra的plane模式计算得到,竖直分量通过下表得到。
帧间预测像素解码
前面解出来了mv,下一步就该根据mv找到参考像素了。
再说明一下几个定义
- mbPartIdx:宏块分割
- subMbPartIdx:亚宏块分割
- partWidth和partHeight:分割宽高变量
- mvL0和mvL1:亮度运动矢量
- mvCL0和mvCL1:色度运动矢量
- refIdxL0和refIdxL1:参考索引
- predFlagL0和predFlagL1:预测表使用索引
- predPart:帧间预测像素(包括一个partWidth×partHeight尺寸的亮度预测像素predPartL和两个尺寸为亮度一半的色度预测像素predPartCb、predPartCr)
整个帧间预测参考像素解码处理流程如下所示:
参考图像选择是很复杂的一个过程,先跳过不描述。
然后是内插,该处理过程输入为mbPartIdx、subMbPartIdx、亮度像素单元的partWidth和partHeight、mvLX、
mvCLX、 refPicLXL、refPicLXCb、refPicLXCb;输出为一个预测亮度像素值矩阵(partWidth)×(partHeight)的predPartLXL、两个预测色度像素值矩阵 (partWidth/2)x(partHeight/2)的predPartLXCb, and predPartLXCr。
设(xAL, yAL)为当前分割的左上亮度整像素位置,是一个相对值;设(xIntL,yIntL)是亮度整像素位置;设(xFracL,yFracL)是1/4像素位置;设(xIntC,yIntC)是色度整像素位置;设(xFracC,yFracC)是1/8像素位置。
通过输入(xIntL, yIntL)、(xFracL, yFracL)、参考图像refPicLXL的亮度像素矩阵,通过内插操作就可得预测亮度像素值predPartLXL[xL, yL];通过输入(xIntC, yIntC)、(xFracC, yFracC)、参考图像refPicLXC的亮度像素矩阵,通过内插操作就可得预测亮度像素值predPartLXC[xC, yC]。
内插操作是一系列固定的流程,这里先不介绍了。
最后是加权预测处理过程,该处理过程输入为mbPartIdx、subMbPartIdx、predFlagL0和predFlagL1、predPartLXL、predPartLXCb和predPartLXCr。输出为predPartL、predPartCb和 predPartCr。
P片和SP片中predFlagL0=1宏块或分割有如下处理过程:
1) 若 weighted_pred_flag=0,采用缺省加权处理;
2) 若 weighted_pred_flag=1,采用加权处理。
B 片中predFlagL0=1 或predFlagL=1 宏块或分割有如下处理过程:
1) 若weighted_bipred_idc=0,采用缺省加权处理;
2) 若weighted_bipred_idc=1, 采用加权处理;
3) 若weighted_bipred_idc=2,若predFlagL0=1且predFlagL1=1, 采用加权处理;若predFlagL0=1或predFlagL1=1,采用缺省加权处理。
缺省加权处理的方式如下:
加权处理的方式如下:
上面logWD,o0和o1根据不同的flag有不同的值,不再细说。