VVC代码阅读 compressSlice()

本文详细介绍了HEVC编码标准中的compressSlice函数,涉及slice段压缩、量化参数设置、熵编码以及加权预测等关键步骤。通过分析bCompressEntireSlice和bFastDeltaQP参数,阐述了不同场景下的处理策略,并讨论了加权预测参数的计算和初始化。同时,提到了PLT编码模式的启用条件及其在编码流程中的作用。
摘要由CSDN通过智能技术生成
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();//设置图片亮度色度的previous 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函数
注意:pcPic->m_prevQP[0] = pcPic->m_prevQP[1];
encoder_intra_vtm.cfg:设定的QP=32,这里的值也为32
encoder_lowdelay_P_vtm.cfg:设定的QP=32,这里的值为31
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值