VTM10.0代码学习5:coding_unit()&cu_pred_data()

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


上一篇博客(VTM10.0代码学习4)讲述了将语法元素的处理从CTU级划分到CU级,并在其2.5节提到coding_unit()这个函数。我原本以为能用一篇博客讲述完coding_unit(),但实际需要两篇,错估了自己的能力(真不想承认啊,这是我太过年轻而犯下的错)。CU级语法元素处理的主要部分可以分为预测模式的参数和变换残差,本篇博客先讲述coding_unit()这个函数,然后再详解一下如何从码流获取预测模式的参数,至于变换残差的部分就留到下一篇博客中。


1. coding_unit()

在这里画了一张流程图,希望能帮大家更好地理解


CodingStructure& cs = *cu.cs;
PredictionUnit&    pu = cs.addPU(cu, partitioner.chType);//向cs类加入当前PU

addPU:与先前提到的addCU类似,但稍微有些不同,函数的写法允许一个CU对应多个PU。但是在H.266中并不需要一个CU划分成多个PU,即使有基于子块的帧间预测,但是在语法元素传输中,一个CU还是对应一个PU就够了。


// skip flag
// 在当前CU存在亮度分量的前提下,满足当前slice不是I slice或所在CLVS允许开启IBC
if ((!cs.slice->isIntra() || cs.slice->getSPS()->getIBCFlag()) && cu.Y().valid())
{
   
    cu_skip_flag( cu );//获取cu_skip_flag和skip情况下的pred_mode_ibc_flag的获取
}

// skip data
if( cu.skip )
{
   
    cu.colorTransform = false;
    cs.addEmptyTUs( partitioner );//向cs类加入空的TU
    MergeCtx           mrgCtx;
    prediction_unit  ( pu, mrgCtx );//在这种情况下只执行了prediction_unit()里面的merge_data()函数
    end_of_ctu( cu, cuCtx );
    return;
}

第一个分支:主要解析了语法元素cu_skip_flag和在cu_skip_flag为1情况下的语法元素pred_mode_ibc_flag。前者表示当前CU是否开启skip模式,后者表示当前CU的预测模式是否是IBC。

如果当前CU开启skip模式:

  • 如果当前解码过程处于P slice或B slice,之后只可能解析语法元素pred_mode_ibc_flag和语法结构merge_data()
  • 如果当前解码过程处于I slice,之后只可能解析语法元素merge_idx

第二个分支:里面的语句之后还会遇到,目前只需要知道:在这种情况下调用prediction_unit(),只执行了里面的merge_data()函数。并跳过之后的语法元素解析。


pred_mode ( cu );//获得CU的预测模式
if (CU::isIntra(cu))
{
   
    adaptive_color_transform(cu);//解析语法元素cu_act_enabled_flag
}

pred_mode():获取当前CU的预测模式,预测模式一共有四种:传统帧内,帧间,IBC和PLT。IBC和PLT本质上也是种帧内预测,但在语法元素传输中,将其与传统帧内区分开。

分支:解析语法元素cu_act_enabled_flag,表示当前CU是否开启ACT


//解析PLT的语法元素
if (CU::isPLT(cu))
{
   
    cu.colorTransform = false;
    cs.addTU(cu, partitioner.chType);//向cs类加入TU
    if (cu.isSepTree())
    {
   
        if (isLuma(partitioner.chType))
        {
   
            cu_palette_info(cu, COMPONENT_Y, 1, cuCtx);//具体参考JVET-S2001 7.3.11.6 P121,不想跟进去看= =
        }
        if (cu.chromaFormat != CHROMA_400 && (partitioner.chType == CHANNEL_TYPE_CHROMA))
        {
   
            cu_palette_info(cu, COMPONENT_Cb, 2, cuCtx);
        }
    }
    else
    {
   
        if( cu.chromaFormat != CHROMA_400 )
        {
   
            
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值