coding_unit函数解码一个cu的预测模式、预测数据、残差数据等信息。
其实,编码端的coding_unit是如何编码的,解码端的coding_unit按照相同的顺序如何解码就行。
函数return一个bool值,表示当前cu是否是这一帧的最后一个cu。
由于VTM3.0中加入了很多的编码工具,所以相较于VTM1,coding_unit函数会对更多的模式的信息进行解码.
对于帧内pu的几种模式的解码过程没有细看,以后补上。
bool CABACReader::coding_unit( CodingUnit &cu, Partitioner &partitioner, CUCtx& cuCtx )
{
CodingStructure& cs = *cu.cs;
#if JVET_L0293_CPR
cs.chType = partitioner.chType;
#endif
// transquant bypass flag
if( cs.pps->getTransquantBypassEnabledFlag() )
{
cu_transquant_bypass_flag( cu ); //变换系数旁路编码标志
}
// skip flag
#if JVET_L0293_CPR
if (!cs.slice->isIntra() && cu.Y().valid())
#else
if( !cs.slice->isIntra() )
#endif
{
cu_skip_flag( cu ); //skip模式时的skip_flag
}
// skip data
if( cu.skip )
{
cs.addTU ( cu, partitioner.chType );
PredictionUnit& pu = cs.addPU( cu, partitioner.chType );
MergeCtx mrgCtx; //merge候选列表
prediction_unit ( pu, mrgCtx ); //解码skip模式数据,构建merge列表,解码得到merge_idx,从而得到skip模式信息
return end_of_ctu( cu, cuCtx );
}
// prediction mode and partitioning data
pred_mode ( cu ); //解码帧内还是帧间预测
cu.partSize = SIZE_2Nx2N;
// --> create PUs
CU::addPUs( cu );
#if JVET_L0283_MULTI_REF_LINE
extend_ref_line( cu ); //MRL模式信息解码
#endif
// pcm samples
if( CU::isIntra(cu) && cu.partSize == SIZE_2Nx2N )
{
pcm_flag( cu );
if( cu.ipcm ) //pcm模式
{
TransformUnit& tu = cs.addTU( cu, partitioner.chType );
pcm_samples( tu );
return end_of_ctu( cu, cuCtx );
}
}
// prediction data ( intra prediction modes / reference indexes + motion vectors )
cu_pred_data( cu ); //预测信息的解码,帧内亮度色度的模式信息,或帧间的merge_Idx、refIdx、mv、mvd等这些
// residual data ( coded block flags + transform coefficient levels )
cu_residual( cu, partitioner, cuCtx ); //残差数据,变换系数的解码
// check end of cu
return end_of_ctu( cu, cuCtx ); //return当前cu是否是这一帧的最后一个cu
}
//解码帧内帧间
void CABACReader::pred_mode( CodingUnit& cu )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__PRED_MODE );
if( cu