void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP )
{
// if bCompressEntireSlice is true, then the entire slice (not slice segment) is compressed,
// effectively disabling the slice-segment-mode.
Slice* const pcSlice = pcPic->slices[getSliceSegmentIdx()];
if (pcSlice->getSPS()->getSpsRangeExtension().getRrcRiceExtensionEnableFlag())
{
int bitDepth = pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
int baseLevel = (bitDepth > 12) ? (pcSlice->isIntra() ? 5 : 2 * 5 ) : (pcSlice->isIntra() ? 2 * 5 : 3 * 5);
pcSlice->setRiceBaseLevel(baseLevel);
}
else
{
pcSlice->setRiceBaseLevel(4);
}
// initialize cost values - these are used by precompressSlice (they should be parameters).
m_uiPicTotalBits = 0; //图像的总比比特数
m_uiPicDist = 0; //图像的失真参数
pcSlice->setSliceQpBase( pcSlice->getSliceQp() );
m_CABACEstimator->initCtxModels( *pcSlice );
m_pcCuEncoder->getModeCtrl()->setFastDeltaQp(bFastDeltaQP);
【笔记】HEVC 编码标准(六)——量化_lock。的博客-CSDN博客
compressSlice里为什么要有encodeCtu_小小柴的博客-CSDN博客
HEVC代码学习34:compressSlice函数_岳麓吹雪的博客-CSDN博客
bCompressEntireSlice:如果为true,则conpress整个slice,而不是ss(slice segment)
bFastDeltaQP:快速deltaQP模式,只有在2Nx2N的帧间模式中使用。默认关闭
根据定义ss(slice segment)分独立型和依赖型,独立ss只有一个且为该Slice的开始。并且依赖SS的一些信息可由独立SS推导得出。1个独立的slice segment接着多个非独立的slice segment组成slice,SS是NALU传输的单位。所以推测只有独立SS才需要传输过来编码
pcPic->slices[getSliceSegmentIdx()]: 推测这里将Slice的独立SS传入 并赋给pcSlice。slices是个slice的数组,存储slice所有ss的值,其中序号0代表独立ss。等于将当前slice的信息传入这里推测比较多,之后再确定
第一个if语句: m_rrcRiceExtensionEnableFlag标志,默认false
H.266/VVC技术学习55:熵编码_海洋之心。的博客-CSDN博客
设置m_riceBaseLevelValue,使abs_remainder 的baselevel等于4。属于熵编码
setSliceQpBase():量化设置相关
initCtxModels():与CABAC自适应二进制算术熵编码有关。其中Ctx 为context的缩写
// calculate AC/DC values for current picture
if( pcSlice->getPPS()->getUseWP() || pcSlice->getPPS()->getWPBiPred() )
{
xCalcACDCParamSlice(pcSlice);
}
//如果不是P或B帧同时没用加权预测,则为false
const bool bWp_explicit = (pcSlice->getSliceType()==P_SLICE && pcSlice->getPPS()->getUseWP()) || (pcSlice->getSliceType()==B_SLICE && pcSlice->getPPS()->getWPBiPred());
if ( bWp_explicit )
{
xEstimateWPParamSlice( pcSlice, m_pcCfg->getWeightedPredictionMethod() );
pcSlice->initWpScaling(pcSlice->getSPS());
// check WP on/off
xCheckWPEnable( pcSlice );
}
pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();//设置亮度色度的 QP
CHECK( pcPic->m_prevQP[0] == std::numeric_limits<int>::max(), "Invalid previous QP" );
CodingStructure& cs = *pcPic->cs;
cs.slice = pcSlice;
cs.pcv = pcSlice->getPPS()->pcv;//传输一些预先的参数
cs.fracBits = 0;
if( pcSlice->getFirstCtuRsAddrInSlice() == 0 && ( pcSlice->getPOC() != m_pcCfg->getSwitchPOC() || -1 == m_pcCfg->getDebugCTU() ) )
{
cs.initStructData (pcSlice->getSliceQp());
}
#if ENABLE_QPA
if (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl())
{
if (applyQPAdaptation (pcPic, pcSlice, *cs.pcv, m_pcCfg->getLumaLevelToDeltaQPMapping().mode == LUMALVL_TO_DQP_NUM_MODES,
(m_pcCfg->getBaseQP() >= 38) || (m_pcCfg->getSourceWidth() <= 512 && m_pcCfg->getSourceHeight() <= 320), m_adaptedLumaQP))
{
m_CABACEstimator->initCtxModels (*pcSlice);
pcPic->m_prevQP[0] = pcPic->m_prevQP[1] = pcSlice->getSliceQp();
if (pcSlice->getFirstCtuRsAddrInSlice() == 0)
{
cs.currQP[0] = cs.currQP[1] = pcSlice->getSliceQp(); // cf code above
}
}
}
#endif // ENABLE_QPA
bool checkPLTRatio = m_pcCfg->getIntraPeriod() != 1 && pcSlice->isIRAP();
if (checkPLTRatio)
{
m_pcCuEncoder->getModeCtrl()->setPltEnc(true);
}
else
{
bool doPlt = m_pcLib->getPltEnc();
m_pcCuEncoder->getModeCtrl()->setPltEnc(doPlt);
}
getUseWP():m_bUseWeightPred,加权预测,P 帧
getWPBiPred():m_useWeightedBiPred,双加权预测,即B 帧的预测方式(Weighting Bi-Prediction)
xCalcACDCParamSlice():计算AC,DC加权值
getWeightedPredictionMethod():WeightedPredictionMethod是一个枚举函数,里面有加权预测的几种方式选择
xEstimateWPParamSlice():这个之后再看
getSwitchPOC(),getDebugCTU():表示debug poc,debug ctu,默认值都为-1
initStructData():初始化,之后看
checkPLTRatio:PLT(palette mode coding)调色板编码模式,默认false
doPlt:开启PLT模式
if K0149_BLOCK_STATISTICS
const SPS *sps = pcSlice->getSPS();
CHECK(sps == 0, "No SPS present");
writeBlockStatisticsHeader(sps);
#endif
m_pcInterSearch->resetAffineMVList();
m_pcInterSearch->resetUniMvList();
::memset(g_isReusedUniMVsFilled, 0, sizeof(g_isReusedUniMVsFilled));
encodeCtus( pcPic, bCompressEntireSlice, bFastDeltaQP, m_pcLib );
encodeCtus():进入compressCtus函数