H.266/VVC-VTM代码学习-帧内预测01-初始化帧内预测参数IntraPrediction::initPredIntraParams

H.266/VVC专栏传送

上一篇:无
下一篇:H.266/VVC-VTM代码学习-帧内预测02-获取参考像素并对其滤波xFillReferenceSamples、xFilterReferenceSamples

前言

VTM是H.266/VVC视频编码标准的参考软件,研究VTM代码给研究人员解释了VVC编码标准的详细标准规范与细节。

本文是笔者对VTM代码的一点学习记录,成文于笔者刚开始接触VVC期间,期间很多概念和理论框架还很不成熟,若文中存在错误欢迎批评指正,也欢迎广大视频编码学习者沟通交流、共同进步。

VTM代码的下载及编译请参考博文:
【视频编码学习】H.266/VVC参考软件VTM配置运行(VTM-6.0版本)
本文涉及的代码存在于工程下的/lib/CommonLib/SourceFiles/IntraPrediction.cpp文件中。

一、主要函数

1.函数代码

// Function for initialization of intra prediction parameters
void IntraPrediction::initPredIntraParams(const PredictionUnit & pu, const CompArea area, const SPS& sps)
{
  const ComponentID compId = area.compID;
  const ChannelType chType = toChannelType(compId);
  //是否使用ISP(多划分预测)
  const bool        useISP = NOT_INTRA_SUBPARTITIONS != pu.cu->ispMode && isLuma( chType );
  //CU大小
  const Size   cuSize    = Size( pu.cu->blocks[compId].width, pu.cu->blocks[compId].height );
  //PU大小
  const Size   puSize    = Size( area.width, area.height );
  const Size&  blockSize = useISP ? cuSize : puSize;
  //预测模式
  const int      dirMode = PU::getFinalIntraMode(pu, chType);
  //将预测模式转换为宽角度模式
  const int     predMode = getModifiedWideAngle( blockSize.width, blockSize.height, dirMode );

  //模式标号大于34视作垂直类模式
  m_ipaParam.isModeVer            = predMode >= DIA_IDX;
  //获得参考行索引
  m_ipaParam.multiRefIndex        = isLuma (chType) ? pu.multiRefIdx : 0 ;
  //参考像素滤波初始化为否
  m_ipaParam.refFilterFlag        = false;
  //插值初始化为否
  m_ipaParam.interpolationFlag    = false;
  //是否提供PDPC技术(若PU边长均≥4且使用0号参考行则提供PDPC)
  m_ipaParam.applyPDPC            = (puSize.width >= MIN_TB_SIZEY && puSize.height >= MIN_TB_SIZEY) && m_ipaParam.multiRefIndex == 0;
  //记录角度模式关于垂直或水平的偏移量
  //若predMode>=34,则intraPredAngLeMode=predMode-VER_IDX(50)
  //若predMode<34,则intraPredAngLeMode=predMode-HOR_IDX(18)
  //宽角度模式是-14~80,故该值范围为-32~30
  const int    intraPredAngleMode = (m_ipaParam.isModeVer) ? predMode - VER_IDX : -(predMode - HOR_IDX);
  int absAng = 0;
  //预测模式是角度模式(即模式号大于DC)且模式号小于LUMA模式总数67
  if (dirMode > DC_IDX && dirMode < NUM_LUMA_MODE) // intraPredAngle for directional modes
  {
  	//偏离水平或垂直不同程度的不同模式对应的模式偏移值offset
    static const int angTable[32]    = { 0,    1,    2,    3,    4,    6,     8,   10,   12,   14,   16,   18,   20,   23,   26,   29,   32,   35,   39,  45,  51,  57,  64,  73,  86, 102, 128, 171, 256, 341, 512, 1024 };
    // (512 * 32) / offset
    static const int invAngTable[32] = {
      0,   16384, 8192, 5461, 4096, 2731, 2048, 1638, 1365, 1170, 1024, 910, 819, 712, 630, 565,
      512, 468,   420,  364,  321,  287,  256,  224,  191,  161,  128,  96,  64,  48,  32,  16
    };

	//模式偏离水平或垂直的值(取绝对值),值范围为0~32
    const int     absAngMode         = abs(intraPredAngleMode);
    //模式19~49(模式号大于水平,小于垂直)为-1,其他为1
    const int     signAng            = intraPredAngleMode < 0 ? -1 : 1;
    //角度模式对应偏移值offset
                  absAng             = angTable  [absAngMode];
	//角度偏移值的倒数*512*32,后续便于除法运算
    m_ipaParam.absInvAngle           = invAngTable[absAngMode];
    //预测角度(带正负号的偏移值)
    m_ipaParam.intraPredAngle        = signAng * absAng;
    if (intraPredAngleMode < 0)
    {
      //模式19~49不用PDPC
      m_ipaParam.applyPDPC = false;
    }
    else if (intraPredAngleMode > 0)
    {
      //预测模式对应侧的长度
      //类垂直模式为PU高,类水平模式为PU宽
      const int sideSize = m_ipaParam.isModeVer ? puSize.height : puSize.width;
      const int maxScale = 2;

      m_ipaParam.angularScale = std::min(maxScale, floorLog2(sideSize) - (floorLog2(3 * m_ipaParam.absInvAngle - 2) - 8));
      m_ipaParam.applyPDPC &= m_ipaParam.angularScale >= 0;
    }
  }
  /********************判断是否对参考像素进行滤波**********************/
  //high level conditions and DC intra prediction
  //若SPS标识参考像素滤波不可用
  //或当前块不是Luma块
  //或使用ISP(多划分预测)
  //或使用MIP(矩阵加权帧内预测)
  //或使用非第0行参考像素
  //或使用DC模式时
  //不进行之后的判断并且保持不滤波的初始设置
  if(   sps.getSpsRangeExtension().getIntraSmoothingDisabledFlag()
    || !isLuma( chType )
    || useISP
    || PU::isMIP( pu, chType )
    || m_ipaParam.multiRefIndex
    || DC_IDX == dirMode
    )
  {
  }
  //LumaBDPCM模式或者chromaBDPCM模式不滤波
  else if ((isLuma(chType) && pu.cu->bdpcmMode) || (!isLuma(chType) && pu.cu->bdpcmModeChroma))
  {
    m_ipaParam.refFilterFlag = false;
  }
  else if (dirMode == PLANAR_IDX)//Planar模式若PU w*h > 32 就参考像素滤波
  {
    m_ipaParam.refFilterFlag = puSize.width * puSize.height > 32 ? true : false;
  }
  //不用多划分预测(ISP)时
  else if (!useISP)
  {
    bool filterFlag = false;
    {
      //与水平模式或垂直模式的模式标号差
      const int diff = std::min<int>( abs( predMode - HOR_IDX ), abs( predMode - VER_IDX ) );
      //log2(width)和log2(height)的均值
      const int log2Size = ((floorLog2(puSize.width) + floorLog2(puSize.height)) >> 1);
      CHECK( log2Size >= MAX_INTRA_FILTER_DEPTHS, "Size not supported" );
      //与水平模式或垂直模式的模式标号差是否大于log2(width)和log2(height)的均值对应的值
      //log2(width)和log2(height)的均值		对应值
      //			0						24
      //			1						24
      //			2						24
      //			3						14
      //			4						2
      //			5						0
      //			6						0
      //			7						0
      filterFlag = (diff > m_aucIntraFilter[log2Size]);
    }

    // Selelection of either ([1 2 1] / 4 ) refrence filter OR Gaussian 4-tap interpolation filter
    if (filterFlag)
    {
      //return ((absAng & 31) == 0) 即是否为32的整数倍
      const bool isRefFilter       =  isIntegerSlope(absAng);
      CHECK( puSize.width * puSize.height <= 32, "DCT-IF interpolation filter is always used for 4x4, 4x8, and 8x4 luma CB" );
      m_ipaParam.refFilterFlag     =  isRefFilter;//角度偏移值为32整数倍时启用参考像素滤波
      m_ipaParam.interpolationFlag = !isRefFilter;//插值标志与参考像素滤波标志相反
    }
  }
}

2.逻辑结构

1.基础参数初始化:确定预测模式标号、CU大小、PU大小、将预测模式转换为宽角度下的预测模式、确定预测角度模式是垂直类还是水平类。

2.通过预测模式标号确定预测角度偏移值offset,并准备offset的倒数便于后续除法运算。

3.判断是否使用PDPC。

4.判断是否对参考像素进行滤波。

二、部分代码涉及知识

1.VVC中的预测模式中加入了宽角度模式,如图所示。
在这里插入图片描述
2.VVC中使用了PDPC技术,使最终预测值结合了滤波前和滤波后的参考像素值。从代码上看,PDPC技术的使用范围是:
(1) (puSize.width >= 4) && (puSize.height >= 4) && (m_ipaParam.multiRefIndex == 0),即PU尺寸两个维度都不小于4且使用0号参考行。
(2)模式19~49不使用PDPC。
(3)使用PDPC时,angularScale必须不小于0。

3.判断是否对参考像素进行滤波时,以下情况使用参考像素滤波:
(1)Planar模式若PU尺寸 > 32 就进行参考像素滤波。
(2)当前模式与水平模式或垂直模式的模式标号差大于log2(width)和log2(height)的均值对应的值(对应值见下表),且角度偏移值是否为32的整数倍,进行参考像素滤波。

log2(width)和log2(height)的均值对应值
024
124
224
314
42
50
60
70

上一篇:无
下一篇:H.266/VVC-VTM代码学习-帧内预测02-获取参考像素并对其滤波xFillReferenceSamples、xFilterReferenceSamples

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值