void Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom, uint32_t& zOrder)
{
uint32_t depth = cuGeom.depth;//geometric CU几何结构
ModeDepth& md = m_modeDepth[depth];
md.bestMode = NULL; bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);//为ture非叶子节点,还需继续分裂
bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);// if (m_param->analysisMode == X265_ANALYSIS_LOAD)
{
uint8_t* reuseDepth = &m_reuseIntraDataCTU->depth[parentCTU.m_cuAddr * parentCTU.m_numPartitions];
uint8_t* reuseModes = &m_reuseIntraDataCTU->modes[parentCTU.m_cuAddr * parentCTU.m_numPartitions];
char* reusePartSizes = &m_reuseIntraDataCTU->partSizes[parentCTU.m_cuAddr * parentCTU.m_numPartitions]; if (mightNotSplit && depth == reuseDepth[zOrder] && zOrder == cuGeom.encodeIdx)
{
m_quant.setQPforQuant(parentCTU); PartSize size = (PartSize)reusePartSizes[zOrder];
Mode& mode = size == SIZE_2Nx2N ? md.pred[PRED_INTRA] : md.pred[PRED_INTRA_NxN];
mode.cu.initSubCU(parentCTU, cuGeom);
checkIntra(mode, cuGeom, size, &reuseModes[zOrder]);
checkBestMode(mode, depth); if (m_bTryLossless)
tryLossless(cuGeom); if (mightSplit)
addSplitFlagCost(*md.bestMode, cuGeom.depth); // increment zOrder offset to point to next best depth in sharedDepth buffer
zOrder += g_depthInc[g_maxCUDepth - ][reuseDepth[zOrder]];
mightSplit = false;
}
}
else if (mightNotSplit)
{
m_quant.setQPforQuant(parentCTU); md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL);//intra2Nx2N 模式
checkBestMode(md.pred[PRED_INTRA], depth); if (depth == g_maxCUDepth)
{
md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);
checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL);//INTRA_NxN 模式
checkBestMode(md.pred[PRED_INTRA_NxN], depth);
} if (m_bTryLossless)
tryLossless(cuGeom); if (mightSplit)
addSplitFlagCost(*md.bestMode, cuGeom.depth);
} if (mightSplit)
{
Mode* splitPred = &md.pred[PRED_SPLIT];
splitPred->initCosts();
CUData* splitCU = &splitPred->cu;
splitCU->initSubCU(parentCTU, cuGeom);//分裂成4四subCU uint32_t nextDepth = depth + ;
ModeDepth& nd = m_modeDepth[nextDepth];
invalidateContexts(nextDepth);
Entropy* nextContext = &m_rqt[depth].cur; for (uint32_t subPartIdx = ; subPartIdx < ; subPartIdx++)
{
const CUGeom& childGeom = *(&cuGeom + cuGeom.childOffset + subPartIdx);
if (childGeom.flags & CUGeom::PRESENT)
{
m_modeDepth[].fencYuv.copyPartToYuv(nd.fencYuv, childGeom.encodeIdx);
m_rqt[nextDepth].cur.load(*nextContext);
compressIntraCU(parentCTU, childGeom, zOrder);//递归 // Save best CU and pred data for this sub CU
splitCU->copyPartFrom(nd.bestMode->cu, childGeom, subPartIdx);
splitPred->addSubCosts(*nd.bestMode);
nd.bestMode->reconYuv.copyToPartYuv(splitPred->reconYuv, childGeom.numPartitions * subPartIdx);
nextContext = &nd.bestMode->contexts;
}
else
{
/* record the depth of this non-present sub-CU */
splitCU->setEmptyPart(childGeom, subPartIdx);
zOrder += g_depthInc[g_maxCUDepth - ][nextDepth];
}
}
nextContext->store(splitPred->contexts);
if (mightNotSplit)
addSplitFlagCost(*splitPred, cuGeom.depth);
else
updateModeCost(*splitPred);
checkBestMode(*splitPred, depth);
} checkDQP(md.bestMode->cu, cuGeom); /* Copy best data to encData CTU and recon */
md.bestMode->cu.copyToPic(depth);
if (md.bestMode != &md.pred[PRED_SPLIT])
md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic, parentCTU.m_cuAddr, cuGeom.encodeIdx);
}
05-11 02:15