encodeCtus函数在编码端实现一帧中所有ctu的compress,获得ctu经过VTM编译过后的各种cu、pu、tu等数据。
其中调用compressCtu函数实现一帧中所有ctu的compress,获取一帧中所有ctu经过编译后的数据。
其中调用coding_tree_unit函数,仅仅是为了确定上下文参数,并不是真正的ctu编码,真正的编码在encodeSlice()中。注意这里的coding_tree_unit函数中需要进行环路滤波
码率控制的代码,以及SAO,以后弄懂。
void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr, EncLib* pEncLib )
{
//PROF_ACCUM_AND_START_NEW_SET( getProfilerCTU( pcPic, 0, 0 ), P_PIC_LEVEL );
//PROF_START( getProfilerCTU( cs.slice->isIntra(), pcPic->scheduler.getWppThreadId() ), P_PIC_LEVEL, toWSizeIdx( cs.pcv->maxCUWidth ), toHSizeIdx( cs.pcv->maxCUHeight ) );
CodingStructure& cs = *pcPic->cs; //picture的cs,存储一帧中所有编码数据的cs
Slice* pcSlice = cs.slice;
const PreCalcValues& pcv = *cs.pcv;
const uint32_t widthInCtus = pcv.widthInCtus;
#if HEVC_TILES_WPP
const TileMap& tileMap = *pcPic->tileMap;
#endif
#if ENABLE_QPA
const int iQPIndex = pcSlice->getSliceQpBase();
int iSrcOffset = 0;
#endif
#if ENABLE_WPP_PARALLELISM
const int dataId = pcPic->scheduler.getWppDataId();
#elif ENABLE_SPLIT_PARALLELISM
const int dataId = 0;
#endif //编码器
CABACWriter* pCABACWriter = pEncLib->getCABACEncoder( PARL_PARAM0( dataId ) )->getCABACEstimator( pcSlice->getSPS() );
TrQuant* pTrQuant = pEncLib->getTrQuant( PARL_PARAM0( dataId ) );
RdCost* pRdCost = pEncLib->getRdCost( PARL_PARAM0( dataId ) );
EncCfg* pCfg = pEncLib; //配置属性
RateCtrl* pRateCtrl = pEncLib->getRateCtrl(); //码率控制
#if ENABLE_WPP_PARALLELISM
// first version dont use ctx from above
pCABACWriter->initCtxModels( *pcSlice );
#endif
#if RDOQ_CHROMA_LAMBDA
pTrQuant ->setLambdas( pcSlice->getLambdas() );
#else
pTrQuant ->setLambda ( pcSlice->getLambdas()[0] );
#endif
pRdCost ->setLambda ( pcSlice->getLambdas()[0], pcSlice->getSPS()->getBitDepths() );
int prevQP[2];
int currQP[2];
prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
currQP[0] = currQP[1] = pcSlice->getSliceQp(