/*
計算CU在partSize下的最優幀內預測,得到其rdcost
過程:
1.設置partSize和predMode
2.計算TUsize的上下限tuDepthRange[2]
3.初始化cost
4.分析當前CU的最優幀內預測模式,並累計當前CU的total_distortion = luma_distortion + chroma_distortion
5.重置bits
6.若旁路trans和quan,則編碼TransquantBypassFlag
7.若非Islice,則編碼skipFlag和predMode
8.編碼partSize和predInfo
9.得到編碼幀內預測信息的mv_bits = predMode + partSize + predInfo
10.編碼殘差係數
11.保存熵編碼上下文
12.得到編碼CU的總bits開銷all_bits
13.計算energy
14.計算rdcost = total_distortion + lambda * all_bits
*/
void Search::checkIntra(Mode& intraMode, const CUGeom& cuGeom, PartSize partSize)
{
CUData& cu = intraMode.cu;
//設置partSize
cu.setPartSizeSubParts(partSize);
//設置predMode爲intra
cu.setPredModeSubParts(MODE_INTRA);
//得到TU的深度範圍[tuDepthRange[0],tuDepthRange[1]]
uint32_t tuDepthRange[2];
cu.getIntraTUQtDepthRange(tuDepthRange, 0);
//初始化cost
intraMode.initCosts();
//計算當前CU的最優幀內預測模式,並累計其distortion
intraMode.lumaDistortion += estIntraPredQT(intraMode, cuGeom, tuDepthRange);
//若有色度,則計算CU色度的最優幀內預測模式,並累加上色度的distortion
if (m_csp != X265_CSP_I400)
{
intraMode.chromaDistortion += estIntraPredChromaQT(intraMode, cuGeom);
intraMode.distortion += intraMode.lumaDistortion + intraMode.chromaDistortion;
}
//若無色度則只算上luma的distortion
else
intraMode.distortion += intraMode.lumaDistortion;
cu.m_distortion[0] = intraMode.distortion;
//重置bits
m_entropyCoder.resetBits();
//若旁路trans和quan,則編碼其flag
if (m_slice->m_pps->bTransquantBypassEnabled)
m_entropyCoder.codeCUTransquantBypassFlag(cu.m_tqBypass[0]);
int skipFlagBits = 0;
//若非Islice
if (!m_slice->isIntra())
{
//編碼skipFlag
m_entropyCoder.codeSkipFlag(cu, 0);
//得到編碼skipFlag的bits開銷
skipFlagBits = m_entropyCoder.getNumberOfWrittenBits();
//編碼predMode
m_entropyCoder.codePredMode(cu.m_predMode[0]);
}
//編碼partSize
m_entropyCoder.codePartSize(cu, 0, cuGeom.depth);
//編碼predInfo
m_entropyCoder.codePredInfo(cu, 0);
//得到編碼predMode + partSize + predInfo的bits開銷
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);
//得到編碼當前CU的總bits開銷
intraMode.totalBits = m_entropyCoder.getNumberOfWrittenBits();
//得到編碼當前CU係數的總bits開銷
intraMode.coeffBits = intraMode.totalBits - intraMode.mvBits - skipFlagBits;
const Yuv* fencYuv = intraMode.fencYuv;
//計算energy
if (m_rdCost.m_psyRd)
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)
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);
//計算殘差energy
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);
//計算intraMode的rdcost = distortion(fenc, recon) + lambda * all_bits
updateModeCost(intraMode);
checkDQP(intraMode, cuGeom);
}
Search::checkIntra()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.