VTM10.0代码学习4:CABACReader_coding_tree_unit()

此系列是为了记录自己学习VTM10.0的过程和锻炼表达能力,主要是从解码端进行入手。由于本人水平有限,出现的错误恳请大家指正,欢迎与大家一起交流进步。


上一篇博客(VTM10.0代码学习3)提到两个重要的函数coding_tree_unit()和decompressCtu(),接下来就用两篇博客的篇幅讲解一下coding_tree_unit()这个函数,本篇博客主要是讲从码流解析得到如何将CTU划分成CU,CU级的语义信息讲解会留在下一篇博客中。


1.coding_tree_unit()

CUCtx cuCtx( qps[CH_L] );//用prevLumaQP初始化CU上下文模型类
QTBTPartitioner partitioner;//定义划分类实例

partitioner.initCtu(area, CH_L, *cs.slice);
cs.treeType = partitioner.treeType = TREE_D;//设置默认树类型
cs.modeType = partitioner.modeType = MODE_TYPE_ALL;//设置默认可进行的预测模式

cuCtx:存储着CU上下文信息(即上一个CU的某些信息),这里用先前亮度分量的QP初始化,有可能是前一个CU的亮度分量QP,也有可能是slice的默认QP

partitioner:存储着和划分相关的信息

initCtu():初始化划分类实例,提供划分的区域和是色度划分还是亮度划分的信息

treeType:cs和划分类里面都有,色度和亮度划分相同就用TREE_D表示,色度和亮度划分不同就分别用TREE_L和TREE_C表示

modeType:cs和划分类里面都有,表示可进行的预测模式


sao( cs, ctuRsAddr );//有关SAO的语法元素解码,具体参考JVET-S2001 7.3.11.3 P113

有关于SAO的,这里就不具体展开了,等看到SAO再回过头来看也不迟。这里稍微提一下,解析出来的语法元素放在帧类的属性m_sao里,是SAOBlkParam类的容器。SAOBlkParam里面存着三个分量的SAOOffset类信息,SAOOffset里面就存着对应分量解码出来的sao语法元素。


//如果当前slice开启ALF,执行以下分支
if (cs.sps->getALFEnabledFlag() && (cs.slice->getTileGroupAlfEnabledFlag(COMPONENT_Y)))
{
   
}
//如果开启CCALF,则执行以下分支
if (cs.sps->getCCALFEnabledFlag())
{
   
}

这里有两个分支,都可以与JVET-S2001里面的7.3.11.2小节对应起来,这里就不再展开。第一个分支与ALF有关,解析出来的语法元素放在帧类的属性里;第二个分支与CCALF有关,解析出来的语法元素放在slice类的属性m_ccAlfFilterControl里。


if ( CS::isDualITree(cs) && cs.pcv->chrFormat != CHROMA_400 && cs.pcv->maxCUWidth > 64 )
{
   //如果当前slice是I slice,且开启dual tree,且色度采样格式不是4:0:0,且CTU的宽高大于64
    QTBTPartitioner chromaPartitioner;//定义色度的划分类实例
    chromaPartitioner.initCtu(area, CH_C, *cs.slice);
    CUCtx cuCtxChroma(qps[CH_C]);//用prevChromaQP初始化色度的CU上下文模型类
    coding_tree(cs, partitioner, cuCtx, &chromaPartitioner, &cuCtxChroma);//具体参考JVET-S2001 7.3.11.4 P114,还包括一部分dual_tree_implicit_qt_split的内容
    qps[CH_L] = cuCtx.qp;//更新prevLumaQP
    qps[CH_C] = cuCtxChroma.qp;//更新prevChromaQP
}
else
{
   
    coding_tree(cs, partitioner, cuCtx);//具体参考JVET-S2001 7.3.11.4 P114
    qps[CH_L] = cuCtx.qp;//更新prevLumaQP
    if( CS::isDualITree( cs ) && cs.pcv->chrFormat != CHROMA_400 )
    {
   //如果当前slice是I slice,且开启dual tree,且色度采样格式不是4:0:0
        CUCtx cuCtxChroma( qps[CH_C] );//用prevChromaQP初始化色度的CU上下文模型类
        partitioner.initCtu(area, CH_C, *cs.slice);//将partitioner变为色度的划分类实例
        coding_tree(cs, partitioner, cuCtxChroma);//具体参考JVET-S2001 7.3.11.4 P114
        qps[CH_C] = cuCtxChroma.qp;//更新prevChromaQP
    }
}

当开启dual tree(意味着当前slice为I slice,采样格式不可能为4:0:0)时,同时CTU的宽高大于64执行if分支:

  • 定义色度的划分类

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值