coding_tree_unit函数进行一个CTU的信息的编码,将CTU的信息编码为二进制码
coding_tree_unit函数在两个地方会被调用:
第一个地方是EncSlice::encodeCtus,这里调用coding_tree_unit仅仅是为了更新各个上下文模型的参数,并没有真的编码传输。
第二个地方是EncSlice::encodeSlice,这里是真正的编码端将CTU信息编码为二进制码流的地方。
入口参数cs是picture即当前帧的cs,该cs.area为整个picture的区域大小,cs中包含有当前帧所有CTU的所有信息。入口参数area即当前需要编码的CTU区域,ctuRsAddr为CTU的rs扫描地址。
EncSlice::encodeCtus中调用该函数时skipSao为true,需要进行SAO,因为encodeCtus函数进行的是CTU的编码,compress完一个CTU之后还需要对它的重建像素进行SAO,以便下一个CTU的帧内预测。
EncSlice::encodeSlice真正编码时的skipSao为false,无需SAO,这时只需要考虑编码就行。
void CABACWriter::coding_tree_unit( CodingStructure& cs, const UnitArea& area, int (&qps)[2], unsigned ctuRsAddr, bool skipSao /* = false */ )
{
CUCtx cuCtx( qps[CH_L] );
Partitioner *partitioner = PartitionerFactory::get( *cs.slice );
partitioner->initCtu( area, CH_L, *cs.slice ); //partitioner用来记录CTU到各个cu的划分路径
if( !skipSao )
{
sao( *cs.slice, ctuRsAddr ); //SAO
}
coding_tree( cs, *partitioner, cuCtx ); //CTU编码
qps[CH_L] = cuCtx.qp;
if( CS::isDualITree( cs ) && cs.pcv->chrFormat != CHROMA_400 ) //DualITree,I帧,coding_tree编码帧内色度模式的信息
{
CUCtx cuCtxChroma( qps[CH_C] );
partitioner->initCtu( area, CH_C,