H.266/VVC专栏传送
上一篇:H.266/VVC-VTM代码学习23-编码块RDO选择模式(Intra与Inter)initCULevel()
下一篇:
前言
VTM是H.266/VVC视频编码标准的参考软件,研究VTM代码给研究人员解释了VVC编码标准的详细标准规范与细节。
本文是笔者对VTM代码的一点学习记录,成文于笔者刚开始接触VVC期间,期间很多概念和理论框架还很不成熟,若文中存在错误欢迎批评指正,也欢迎广大视频编码学习者沟通交流、共同进步。
VTM代码的下载及编译请参考博文:
【视频编码学习】H.266/VVC参考软件VTM配置运行(VTM-6.0版本)
一、简介
getImplicitSplit() 函数是在 partitioner.canSplit 函数中调用的重要函数,该函数的作用是根据当前块位置和尺寸确定其隐藏划分模式。若存在隐藏划分模式,则在当前块 RDO 列表加入 split 模式时直接添加隐藏划分模式对应划分模式。
二、代码详解
PartSplit QTBTPartitioner::getImplicitSplit( const CodingStructure &cs )
{
// 若已存在隐藏划分模式,则直接返回存在的隐藏划分模式
if( m_partStack.back().checkdIfImplicit )
{
return m_partStack.back().implicitSplit;
}
// 划分模式初始化为不划分
PartSplit split = CU_DONT_SPLIT;
if( split == CU_DONT_SPLIT )
{
// 当前区域的左下角是否包含在图片中
const bool isBlInPic = cs.picture->Y().contains( currArea().Y().bottomLeft() );
// 当前区域的右上角是否包含在图片中
const bool isTrInPic = cs.picture->Y().contains( currArea().Y().topRight() );
// 当前亮度区域
const CompArea& area = currArea().Y();
// 最大二叉树划分尺寸
const unsigned maxBtSize = cs.pcv->getMaxBtSize( *cs.slice, chType );
// 当前区域宽度、高度均小于等于最大BT尺寸,当前MT深度小于最大BT深度+当前隐藏BT深度,则允许BT
const bool isBtAllowed = area.width <= maxBtSize && area.height <= maxBtSize && currMtDepth < (cs.pcv->getMaxBtDepth(*cs.slice, chType) + currImplicitBtDepth);
// 最小QT尺寸
const unsigned minQtSize = cs.pcv->getMinQtSize( *cs.slice, chType );
// 当前区域宽度、高度均大于最小QT尺寸,且当前BT深度为0,则允许QT
const bool isQtAllowed = area.width > minQtSize && area.height > minQtSize && currBtDepth == 0;
// 若当前块左下角不在当前帧 且 当前块右上角不在当前帧 且 允许QT
// 则划分模式设置为QT
if( !isBlInPic && !isTrInPic && isQtAllowed )
{
split = CU_QUAD_SPLIT;
}
// 若当前块左下角不在当前帧 且 允许BT 且 当前区域宽小于等于最大TB尺寸
// 则划分模式设置为BH
else if( !isBlInPic && isBtAllowed && area.width <= MAX_TB_SIZEY )
{
split = CU_HORZ_SPLIT;
}
// 若当前块右上角不在当前帧 且 允许BT 且 当前区域高小于等于最大TB尺寸
// 则划分模式设置为VT
else if( !isTrInPic && isBtAllowed && area.height <= MAX_TB_SIZEY )
{
split = CU_VERT_SPLIT;
}
// 若当前块左下角或右上角还不在当前帧
// 则划分模式设置为QT
else if( !isBlInPic || !isTrInPic )
{
split = CU_QUAD_SPLIT;
}
// 若当前为 DualTree 且 当前区域宽或高大于64
// 则划分模式设置为QT
if (CS::isDualITree(cs) && (currArea().Y().width > 64 || currArea().Y().height > 64))
{
split = CU_QUAD_SPLIT;
}
// 若当前块左下角或右上角不在当前帧 且 划分模式仍为初始的不划分
// 则划分模式设置为QT
if( (!isBlInPic || !isTrInPic) && split == CU_DONT_SPLIT )
{
split = CU_QUAD_SPLIT;
}
}
// 将划分模式存储为隐藏划分模式
m_partStack.back().checkdIfImplicit = true;
m_partStack.back().isImplicit = split != CU_DONT_SPLIT;
m_partStack.back().implicitSplit = split;
return split;
}
}
上一篇:H.266/VVC-VTM代码学习23-编码块RDO选择模式(Intra与Inter)initCULevel()
下一篇:H.266/VVC-VTM代码学习25-VTM中RDcost的计算与λ的设定(一)