本文是本系列的第五篇博客,内容是分析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常见资源整理(提案地址、代码、资料等)
注:
- 考虑到从解码端分析代码,一是更加简单(解码流程无需编码工具和编码参数的择优),二是可以配合Draft文本更好地理解视频编解码的流程(解码端也都包含预测、量化、环路滤波、熵解码等流程),所以本系列从解码端入手分析VVC解码大致流程。等到解码端代码分析完后,再从编码端深入分析。
- 本文分析的bin文件是利用VTM8.0的编码器,以All Intra配置(IBC 打开)编码100帧得到的二进制码流(TemporalSubsampleRatio: 8,实际编码 ⌈100 / 8⌉ = 13帧)。
- 解码用最简单的:-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 );
}