十五帧内编码:2预测当前块的预测模式

Posted 叮咚咕噜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十五帧内编码:2预测当前块的预测模式相关的知识,希望对你有一定的参考价值。

从协议文档规定中来学习如何导出某一个子块,即一个宏块内部的4 * 4像素块,他是如何计算帧内计算模式的,以及如何通过帧内预测计算出这16个像素的预测块。
大体就是下面三步:
1、获取预测模式
2、根据预测模式求出当前宏块的预测值
3、根绝当前宏块的预测值和之前解析出的残差数据求出实际的像素值
本节我们先了解第一部分

一、宏块预测结构

在前面的博文:【H.264/AVC视频编解码技术详解】十二、解析H.264码流的宏块结构(下):H.264帧内编码宏块的预测结构中,我们解析了H.264码流中的宏块结构,并且分析了其中的语法元素mb_pred()。mb_pred()包含了帧内预测宏块的预测数据,其定义为:
在这里插入图片描述

其中,表示帧内预测模式的语法元素有:

  1. prev_intra4x4_pred_mode_flag和prev_intra8x8_pred_mode_flag:表示帧内预测模式预测标识。如果该标识位为1,表示预测出的帧内预测模式是实际的模式,否则就需要另外传递实际的帧内预测模式。
  2. rem_intra4x4_pred_mode和rem_intra8x8_pred_modeg:表示额外传递的实际帧内预测模式
  3. intra_chroma_pred_mode:表示色度分量的预测模式,取值范围为[0,3],分别代表DC(0)、水平(1)、垂直(2)和平面模式(3)。

二、计算实际的帧内预测模式

2.0导出4 * 4的子块的预测模式的步骤:

以4×4模式的亮度信号为例,该部分的解析方式定义在标准文档的8.3.1.1节。

  1. 计算相邻块的位置等参数:mbAddrA、luma4x4BlkIdxA、mbAddrB、luma4x4BlkIdxB
  2. 推导flag数据dcPredModePredictedFlag
  3. 推导相邻块的等效帧内预测模式
  4. 从相邻块的帧内预测模式得出当前块的预测模式

2.1 计算相邻块的位置等参数

2.1.1 计算相邻块的位置

计算亮度4×4相邻块的方式在标准文档的6.4.10.4节指定:

该过程的输入数据为当前亮度4×4块在宏块内的索引序号luma4x4BlkIdx;

输出数据为:

  • 相邻块A所属宏块地址mbAddrA:当前宏块或者左方宏块,根据luma4x4BlkIdx的不同选择;
  • 相邻块A的子块索引luma4x4BlkIdxA:左邻域子块在mbAddrA宏块内的索引;
  • 相邻块B所属宏块地址mbAddrB:当前宏块或者上方宏块,根据luma4x4BlkIdx的不同选择;
  • 相邻块B的子块索引luma4x4BlkIdxB:上邻域子块在mbAddrB宏块内的索引;
    左方相邻块信息mbAddrA、luma4x4BlkIdxA和右侧相信块信息mbAddrB、luma4x4BlkIdxB的计算方法:通过子块位置的坐标差值(xD,yD)。 标准文档表6-2
    在这里插入图片描述
    多数情况下,H.264中的一个block都以4×4像素为大小,宽高相等,因此上图中ABCD四个邻块的坐标差值分别为:
  • 邻块A:(-1, 0)
  • 邻块B:(0, -1)
  • 邻块C:(4, -1)
  • 邻块D:(-1,-1)

2.1.2 获取当前宏块左上角像素相对整个宏块的位置

输入:当前亮度4×4块在宏块内的索引序号luma4x4BlkIdx
输出:当前块左上角像素对于整个宏块的相对位置(x,y) (x=0…15 y=0…15)
该部分在6.4.3中指定。计算中使用了InverseRasterScan函数,该函数是个分段函数,在标准文档中定义为公式(5-7)。

  • 4 * 4亮度块的扫描顺序:
    在这里插入图片描述

  • 计算公式
    在这里插入图片描述

2.1.3参考像素对于当前宏块的相对位置

计算的是当前基于当前宏块的相对位置:(xN是代码左边和上边宏块,x表示当前宏块,xD表示的是相对偏移)

(xN,yN) = (x + xD, y + yD);

2.1.4通过参考像素的位置的相对位置获取相邻块的参数

我们已经可以获取相邻块相对于当前宏块的位置(xN,yN),通过(xN,yN)获取相邻块参数的方法定义与6.4.11.1节(只考虑帧编码情况)。通过(xN,yN)的取值情况,可以判断参考像素所在宏块的位置以及其他信息:

  • xN < 0, yN < 0:参考像素位于当前宏块的左上角,宏块位置为mbAddrD。
  • xN < 0, 0 <= yN < 16:参考像素位于当前宏块左侧,宏块位置为AmbAddrA。
  • 0 <= xN < 16, yN < 0:参考像素位于当前宏块上方,宏块位置为mbAddrB。
  • 0 <= xN < 16, 0 <= yN < 16:参考像素位于当前宏块内部,宏块位置即为当前宏块。
  • xN >= 16, yN < 0:参考像素位于当前宏块右上方,宏块位置为mbAddrC。
  • xN >= 16, 0 <= yN < 16:参考像素位于当前宏块右方,实际上不可获得。
  • yN >=16:参考像素位于当前宏块的下一行,实际上不可获得。

从参考像素相对当前块位置(xN,yN)计算宏块位置,可以计算参考像素在参考宏块中的相对位置(xW,yW)。计算方法为:

xW = (xN + 16) % 16;
yW = (yN + 16) % 16;

2.1.5获取指定的相邻块在所在宏块中的索引

如果参考像素所在的宏块实际上不可获得,则整个宏块索引皆定义为不可得,否则计算方式定义在6.4.12.1节中,即对于像素(x,y):

luma4x4BlkIdx = 8 * (y/8) + 4 * (x/8) + 2 * ((y%8)/4) + ((x%8)/4)

2.2 推导DC模式标识——dcPredModePredictedFlag

当满足以下条件的任意一种时,dcPredModePredictedFlag的值被设为1。

  • 宏块AmbAddrA不可获得;
  • 宏块AmbAddrB不可获得;
  • 宏块AmbAddrA可获得,但在标识位constrained_intra_pred_flag限定为1的情况下以帧间模式进行编码;
  • 宏块AmbAddrA可获得,但在标识位constrained_intra_pred_flag限定为1的情况下以帧间模式进行编码;

在其他情况下,dcPredModePredictedFlag的值被设为0。

2.3推导相邻块的等效帧内预测模式

这一步骤的目的是推导出相邻块A和B的帧内预测模式。而实际上有时候,如某个相邻块不可获得那么其预测模式也会有相应的替代方法。具体来说:

  • 如果dcPredModePredictedFlag被设为1,或者相邻块A或B所在的宏块不是Intra 4×4或8×8模式,那么A或者B的预测模式intra4x4(8x8)PredModeA/B的值设为2;
  • 若不满足前款条件,则继续判断:
    • 若相邻块A或B所在的宏块按照Intra4x4模式编码,那么其预测模式intra4x4(8x8)PredModeA/B设为Intra4x4PredMode[ luma4x4BlkIdxN ];
    • 如果按照Intra8x8模式进行编码,其预测模式设为Intra8x8PredMode[ luma4x4BlkIdxN >> 2 ]。

2.4 从相邻块的帧内预测模式得出当前块的预测模式

现在我们已经获得的信息有:

  • 左方相邻块A的预测模式;
  • 上方相邻块B的预测模式;
  • 码流中读取的语法元素prev_intra4x4_pred_mode_flag;

从上述数据中获取当前块的预测模式的方式在文档8.3.1.1中如下表示:

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

  1. 从左侧和上方相邻块的预测模式中选取较小的一个作为预先定义模式。
  2. 判断码流中读取的标志位prev_intra4x4_pred_mode_flag,如果该标志位为1,则预先定义模式就是当前块的预测模式;
  3. 如果标志位prev_intra4x4_pred_mode_flag为0,则根据码流中解析出的语法元素 rem_intra4x4_pred_mode判断。如果rem_intra4x4_pred_mode的值小于预定义模式的值则选用rem_intra4x4_pred_mode;如果大于等于预定义模式,则当前块的预测模式设为rem_intra4x4_pred_mode + 1。

2.5总结

其实标准文档中定义的繁杂无比的解析方式,简而言之可以分为两步:

  • 获取左侧和上方子块的预测模式,并选择较小的那个作为当前的模式预测值;
  • 码流中指定了要不要用这个预测值。如果用,那么这个预测值就是当前块的帧内预测模式;否则就从后续读取的预测模式中计算。

以上是关于十五帧内编码:2预测当前块的预测模式的主要内容,如果未能解决你的问题,请参考以下文章

十五帧内编码:4生成预测像素块

H264解析Demo11帧内预测编码_1_预测当前块的预测模式

十五帧内编码:1帧内编码的基本原理

视频编解码 — 帧内预测

音视频开发之旅(58) -H.264 帧内预测

音视频开发之旅(58) -H.264 帧内预测