最近在做一些较上层的内容,从老师和师兄师姐的博客里学到了很多,对VTM代码有了进一步的理解。VTM4.0代码整体结构如下,并会后面分别介绍几个主要函数的作用。
EncSlice::encodeCtus
大体操作:以CTU为单位,对划分后的内容进行熵编码。
每个slice为一帧。一帧中对所有CTU(128*128)都进行编码(for循环每个CTU,分别调用compressCtu函数),具体来说主要是setlambda、ctrlQP、compressCtu、coding_tree_unit等操作。
1、EncCu::compressCtu
大体操作:完成对CTU的划分,根据RDCOST确定各种预测参数。
初始化CTU和当前上下文指针。调用两次xCompressCU函数,对CU进行两次操作:第一次xCompressCU只对亮度进行预测,第二次xCompressCU只对色度进行预测(如果是B帧或者P帧,则亮度和色度预测一起在第一个xCompressCU函数中完成?)。因此,帧内预测在亮度预测完成后才进行色度预测。
EncCu::xCompressCU
大体操作:进行CU的划分和模式的选择。
测试当前模式是什么,有如下几种可能,并进入对应的操作,通过计算对比可以得到各种具体模式的代价值,更新代价值。
以下即各种模式的入口:
1、帧间模式:xCheckRDCostInterIMV或 xCheckRDCostInter;
2、帧间Affine模式:xCheckRDCostAffineMerge2Nx2N;
3、帧间merge模式:xCheckRDCostMerge2Nx2N;
4、帧间merge的triangle模式:xCheckRDCostMergeTriangle2Nx2N;
5、帧内模式:xCheckRDCostIntra;
6、PCM模式:xCheckIntraPCM;
7、CPR模式:xCheckRDCostCPRMode;
8、CPR的merge模式:xCheckRDCostCPRModeMerge2Nx2N;
9、划分模式:xCheckModeSplit,调用xCheckModeSplit进行划分,会依据 “Depth” 的值及代价选择是否继续划分,这里会递归调用xCompressCU。
其他情况:错误,抛出异常。最后设置状态,记录最优CU信息。
2、CABACWriter::coding_tree
大体操作:coding_tree_unit中初始化CTU,对亮度和色度的qp一起进行coding_tree,递归调用自身进行划分。
结束后coding_unit。
CABACWriter::coding_unit
根据前面xCompressCU完成CU各种信息的编码。进入对应的编码操作:
1、如果有变换绕过标志:CABACWriter::cu_transquant_bypass_flag
2、如果有Skip标志:CABACWriter::cu_skip_flag
3、CABACWriter::pred_mode
4、如果有PCM标志:CABACWriter::pcm_flag
5、编码数据:
CABACWriter::cu_pred_data
CABACWriter::cu_residual
CABACWriter::end_of_ctu