VTM10.0代码学习12:xCheckModeSplit()

此系列是为了记录自己学习VTM10.0的过程,目前正在看编码端。主要的参考文档有JVET-S2001-vH和JVET-S2002-v1。由于本人水平有限,出现的错误恳请大家指正,欢迎与大家一起交流进步。


上一篇博文(VTM10.0代码学习11)的末尾留着一个涉及CU划分的分支没讲,本篇博文就来说说。这个分支里会调用函数xCheckModeSplit(),而这个函数里面又会调用xCompressCU()。所以从CTU到任何一个CU的编码过程可以描述为如下,先从compressCtu()开始,之后就是xCompressCU()和xCheckModeSplit()的交替。那接下来就先从xCompressCU()中涉及划分的分支说起


1. 涉及划分的分支

int signalModeConsVal = tempCS->signalModeCons( getPartSplit( currTestMode ), partitioner, modeTypeParent );
int numRoundRdo = signalModeConsVal == LDT_MODE_TYPE_SIGNAL ? 2 : 1;
bool skipInterPass = false;
for( int i = 0; i < numRoundRdo; i++ )
{
   
}

这三个变量皆与modeType的设置有关系。当numRoundRdo为2时,modeType需要先后设置为MODE_TYPE_INTER和MODE_TYPE_INTRA进行测试。

for循环里的内容就参考1.1小节


1.1 for循环

if( signalModeConsVal == LDT_MODE_TYPE_SIGNAL )
{
   
    tempCS->modeType = partitioner.modeType = (i == 0) ? MODE_TYPE_INTER : MODE_TYPE_INTRA;
}
else if( signalModeConsVal == LDT_MODE_TYPE_INFER )
{
   
    tempCS->modeType = partitioner.modeType = MODE_TYPE_INTRA;
}
else if( signalModeConsVal == LDT_MODE_TYPE_INHERIT )
{
   
    tempCS->modeType = partitioner.modeType = modeTypeParent;
}

设置modeType


if( modeTypeParent == MODE_TYPE_ALL && tempCS->modeType == MODE_TYPE_INTER )
{
   
    m_pcIntraSearch->setSaveCuCostInSCIPU( true );
    m_pcIntraSearch->setNumCuInSCIPU( 0 );
}
else if( modeTypeParent == MODE_TYPE_ALL && tempCS->modeType != MODE_TYPE_INTER )
{
   
    m_pcIntraSearch->setSaveCuCostInSCIPU( false );
    if( tempCS->modeType == MODE_TYPE_ALL )
    {
   
        m_pcIntraSearch->setNumCuInSCIPU( 0 );
    }
}

与SCIPU有关


xCheckModeSplit( tempCS, bestCS, partitioner, currTestMode, modeTypeParent, skipInterPass );
//recover cons modes
tempCS->modeType = partitioner.modeType = modeTypeParent;
tempCS->treeType = partitioner.treeType = treeTypeParent;
partitioner.chType = chTypeParent;

xCheckModeSplit():进行划分模式的测试,具体参考第2大节

之后恢复到未划分之前的modeType、treeType和chType


if( modeTypeParent == MODE_TYPE_ALL )
{
   
    m_pcIntraSearch->setSaveCuCostInSCIPU( false );
    if( numRoundRdo == 2 && tempCS->modeType == MODE_TYPE_INTRA )
    {
   
        m_pcIntraSearch->initCuAreaCostInSCIPU();
    }
}

与SCIPU有关


if( skipInterPass )
{
   
    break;
}

如果skipInterPass为True,跳过之后modeType为MODE_TYPE_INTRA的测试


2. xCheckModeSplit()

const int qp                = encTestMode.qp;
const Slice &slice          = *tempCS->slice;
const int oldPrevQp         = tempCS->prevQP[partitioner.chType];
const auto oldMotionLut     = tempCS->motionLut;
const auto oldPLT           = tempCS->prevPLT;

const PartSplit split = getPartSplit( encTestMode );
const ModeType modeTypeChild = partitioner.modeType;

tempCS->initStructData( qp );

oldPrevQp、oldMotionLut和oldPLT都是进行划分模式测试之后需要恢复的变量

split:当前测试的划分模式

modeTypeChild:划分后的modeType

initStructData():初始化父CU的tempCS


m_CABACEstimator->getCtx() = m_CurrCtx->start;

const TempCtx ctxStartSP( m_CtxCache, SubCtx( Ctx::SplitFlag,   m_CABACEstimator->getCtx() ) );
const TempCtx ctxStartQt( m_CtxCache, SubCtx
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值