VVC/H.266代码阅读(VTM8.0)(五. CU语法语义解析 )

本文是本系列的第五篇博客,内容是分析CU的语法语义。
该系列相关博客为:
VVC/H.266代码阅读(VTM8.0)(一. NALU提取)
VVC/H.266代码阅读(VTM8.0)(二. non-VCLU解码)
VVC/H.266代码阅读(VTM8.0)(三. Slice到CTU的处理 )
VVC/H.266代码阅读(VTM8.0)(四. CU划分 )

VVC/H.266常见资源为:
VVC/H.266常见资源整理(提案地址、代码、资料等)

注:

  1. 考虑到从解码端分析代码,一是更加简单(解码流程无需编码工具和编码参数的择优),二是可以配合Draft文本更好地理解视频编解码的流程(解码端也都包含预测、量化、环路滤波、熵解码等流程),所以本系列从解码端入手分析VVC解码大致流程。等到解码端代码分析完后,再从编码端深入分析。
  2. 本文分析的bin文件是利用VTM8.0的编码器,以All Intra配置(IBC 打开)编码100帧得到的二进制码流(TemporalSubsampleRatio: 8,实际编码 ⌈100 / 8⌉ = 13帧)。
  3. 解码用最简单的:-b str.bin -o dec.yuv

上一篇博客的最后写道“调用CABACReader::coding_unit()分析该CU的预测模式、MV等信息 ”。所以,本篇博客从该函数开始分析。遵循draft内7.3.10.5 Coding unit syntax。

void CABACReader::coding_unit( CodingUnit &cu, Partitioner &partitioner, CUCtx& cuCtx )
{
  CodingStructure& cs = *cu.cs;
  //之前博客说过,CodingStructure结构非常重要,管理了一帧中所有的CU,PU和TU,方便读取等操作。
  PredictionUnit&    pu = cs.addPU(cu, partitioner.chType);
  //PU内存储了和预测有关的信息,比如帧内预测模式、帧间预测MV等信息
  // skip flag
  if ((!cs.slice->isIntra() || cs.slice->getSPS()->getIBCFlag()) && cu.Y().valid())
  {
    cu_skip_flag( cu );
    //开启了IBC的I帧、P、B帧会先传输skip_flag。
  }

  // skip data
  if( cu.skip )
  {
    cu.colorTransform = false;
    cs.addTU         ( cu, partitioner.chType );
    MergeCtx           mrgCtx;
    prediction_unit  ( pu, mrgCtx );
    //skip模式下,调用CABACReader::prediction_unit()、  CABACReader::merge_data()获取mergeIdx等信息
    end_of_ctu( cu, cuCtx );
    return;
  }

  // prediction mode and partitioning data
  pred_mode ( cu );
  //判断是intra ibc PLT 还是inter modea
  if (CU::isIntra(cu))
  {
    adaptive_color_transform(cu);
    //ACTflag
  }
  if (CU::isPLT(cu))
  {
    ……
    //PLT调色板模式相关参数的解析,未开启调色板,此处省略
    ……
  }

  // --> create PUs

  // prediction data ( intra prediction modes / reference indexes + motion vectors )
  cu_pred_data( cu );
  //获得CU的预测模式信息,比如intra mode 的IPM、Inter mode的MVD、参考帧信息

  // residual data ( coded block flags + transform coefficient levels )
  cu_residual( cu, partitioner, cuCtx );
  //残差信息解码

  // check end of cu
  end_of_ctu( cu, cuCtx );
}
void CABACReader::cu_pred_data( CodingUnit &cu )
{
  if( CU::isIntra( cu ) )
  {
#if JVET_Q0110_Q0785_CHROMA_BDPCM_420
    if( cu.Y().valid() )
	{
      bdpcm_mode(cu, COMPONENT_Y );
      //BDPCM Block-based Delta Pulse Code Modulation
      //BDPCM模式相关参数解析
    }
#endif
    intra_luma_pred_modes( cu );
    //亮度MPM mip isp等参数解析
#if JVET_Q0110_Q0785_CHROMA_BDPCM_420
    if( ( !cu.Y().valid() || (!cu.isSepTree() && cu.Y().valid() ) ) && isChromaEnabled(cu.chromaFormat) )
    {
      bdpcm_mode(cu, ComponentID(CHANNEL_TYPE_CHROMA));
    } 
#endif
    intra_chroma_pred_modes( cu );
    //色度intra相关参数解析
    return;
  }
  if (!cu.Y().valid()) // dual tree chroma CU
  {
    cu.predMode = MODE_IBC;
    return;
  }
  MergeCtx mrgCtx;

  for( auto &pu : CU::traversePUs( cu ) )
  {
    prediction_unit( pu, mrgCtx );
  }

  imv_mode   ( cu, mrgCtx );
  affine_amvr_mode( cu, mrgCtx );
  cu_bcw_flag( cu );

}

猜你喜欢

转载自blog.csdn.net/weixin_37524256/article/details/105944949