x265中checkIntra()分析(版本2.8)
程序员文章站
2022-07-07 11:58:36
...
一. 函数调用关系图:
二.函数具体实现流程:
三. 源码注释分析:
/*
=======Analysed by : yangxin
=======Date: 2018.9
=======Function: checkIntra(),实现full RD search of intra modes
=======参数: intraMode:存放帧内模式数据;cuGeom:CU的几何结构;partSize:运动分区,帧内只有2Nx2N和NxN
*/
void Search::checkIntra(Mode& intraMode, const CUGeom& cuGeom, PartSize partSize)
{
CUData& cu = intraMode.cu;
cu.setPartSizeSubParts(partSize);//--设置运动分区的子块位置
cu.setPredModeSubParts(MODE_INTRA);//--设置预测模式子块为为帧内模式
uint32_t tuDepthRange[2];
cu.getIntraTUQtDepthRange(tuDepthRange, 0);//--TU的深度范围确定
intraMode.initCosts();//--初始化cost
//***==== a=a+b,亮度失真,遍历所有角度模式,RDO search of luma intra modes; result is fully encoded luma. luma distortion is returned
intraMode.lumaDistortion += estIntraPredQT(intraMode, cuGeom, tuDepthRange);
if (m_csp != X265_CSP_I400)//--不是4:0:0的颜色空间
{
intraMode.chromaDistortion += estIntraPredChromaQT(intraMode, cuGeom);//--色度失真
intraMode.distortion += intraMode.lumaDistortion + intraMode.chromaDistortion;//--总失真=亮度失真+色度失真
}
else//--4:0:0
intraMode.distortion += intraMode.lumaDistortion;//--
cu.m_distortion[0] = intraMode.distortion;
/*=======熵编码部分==============================*/
m_entropyCoder.resetBits();//--熵编码复位清理
if (m_slice->m_pps->bTransquantBypassEnabled)
m_entropyCoder.codeCUTransquantBypassFlag(cu.m_tqBypass[0]);
int skipFlagBits = 0;
if (!m_slice->isIntra())
{
m_entropyCoder.codeSkipFlag(cu, 0);
skipFlagBits = m_entropyCoder.getNumberOfWrittenBits();
m_entropyCoder.codePredMode(cu.m_predMode[0]);
}
m_entropyCoder.codePartSize(cu, 0, cuGeom.depth);//--编码运动分区
m_entropyCoder.codePredInfo(cu, 0);//--encode intra prediction mode.
intraMode.mvBits = m_entropyCoder.getNumberOfWrittenBits() - skipFlagBits;
bool bCodeDQP = m_slice->m_pps->bUseDQP;
m_entropyCoder.codeCoeff(cu, 0, bCodeDQP, tuDepthRange);
m_entropyCoder.store(intraMode.contexts);
intraMode.totalBits = m_entropyCoder.getNumberOfWrittenBits(); //--总bit
intraMode.coeffBits = intraMode.totalBits - intraMode.mvBits - skipFlagBits; //--DCT系数bit
const Yuv* fencYuv = intraMode.fencYuv;
if (m_rdCost.m_psyRd)//--心理视觉上的rd
//==return the difference in energy between the source block and the recon block
intraMode.psyEnergy = m_rdCost.psyCost(cuGeom.log2CUSize - 2, fencYuv->m_buf[0], fencYuv->m_size, intraMode.reconYuv.m_buf[0], intraMode.reconYuv.m_size);
else if(m_rdCost.m_ssimRd)//--客观rd
//==原与重建的失真计算,Calculate dc and ac normalization factor
intraMode.ssimEnergy = m_quant.ssimDistortion(cu, fencYuv->m_buf[0], fencYuv->m_size, intraMode.reconYuv.m_buf[0], intraMode.reconYuv.m_size, cuGeom.log2CUSize, TEXT_LUMA, 0);
//==Sum of Square Error (pixel, pixel) fenc alignment not assumed 平方误差之和
intraMode.resEnergy = primitives.cu[cuGeom.log2CUSize - 2].sse_pp(intraMode.fencYuv->m_buf[0], intraMode.fencYuv->m_size, intraMode.predYuv.m_buf[0], intraMode.predYuv.m_size);
updateModeCost(intraMode);//--更新模式cost值
checkDQP(intraMode, cuGeom);//---update CBF flags and QP values to be internally consistent
}