HM块划分有关的函数

最近需要研究HM的与块划分有关的函数(TLibEncoder\TEncCu),但是网上可参考的资料很少,加上这部分的代码比较繁杂,所以本文基于最新的16.20版本,尝试剖析一下其实现原理,后续会更新x265对应部分的源码剖析。

HM15.0此部分的代码分析可以参考[这篇博客](https://blog.csdn.net/qq_21880777/article/details/78827285)。

CTU层次

基本分为两步,首先压缩CTU,然后编码CTU

TEncCu::compressCtu压缩CTU

  1. 初始化顶层的CTU数据,m_ppcBestCU[0]->initCtu()m_ppcTempCU[0]->initCtu()
  2. 递归的调用xCompressCU()压缩CTU

TEncCu::encodeCtu编码CTU

  1. 根据Slice的设置初始化QP的参数
  2. 递归调用xEncodeCU()编码CTU

CU层次

xCompressCU( )

从前面的x可以看出,该方法是一个protected类型的成员函数,根据xCheckRDCostMerge2Nx2NxCheckRDCostInter定位帧间预测部分,根据xCheckRDCostIntra定位帧内预测部份。( 补充:关于HM的命名规则和项目架构可以参考我之前的一篇博客。)

传入参数为rpcBestCU,rpcTempCU,uiDepth,其中uiDepth即为当前CU划分的深度(0、1、2)。

详细步骤如下

1. 参数初始化(读取BestCU数据和参数、初始化用于计算BestCU RD cost的量化参数QP)

参数初始化分为两部分,第一部分读取rpcBestCU所代表CU的YUV数据、坐标信息、有效组件的数量,分别存放在m_ppcOriginYuv[yiDepth]uiLPelX~uiBelYnumberValidComponents中,其中有效组件的类型是枚举类型:

| 枚举类型 | 值 |

| :---------------: | :--: |

| COMPONENT_Y | 0 |

| COMPONENT_Cb | 1 |

| COMPONENT_Cr | 2 |

| MAX_NUM_COMPONENT | 3 |

第二部分,解析图片参数集pps(picture parameter set)和 序列参数集sps(sequence parameter set),主要是解析参数集中有关量化参数QP的设置,QP由四个参数控制,分别是iBaseQPiMinQPiMaxQPisAddLowestQP

首先xComputeQP()根据 输入父CUrpcBestCU和 当前划分深度uiDepth计算iBaseQP,然后使用四种方法确定iMinQP和`iMaxQP:

  • 默认(可以是一个范围)
  • 由亮度等级确定QP(value)
  • 由目标码率确定QP(value,万帅)
  • TQB模式(value)
// ToDo: 注释中的参数值根据第一个CU的运行情况确定
// iMinQP = 上下限截断(iBaseQP-idQP),  iMaxQP = 上下限截断(iBaseQP+idQP)

// 方法1 (默认,根据pps和sps设置QP最大值和最小值), idQP
if( uiDepth <= pps.getMaxCuDQPDepth() )
  {
    Int idQP = m_pcEncCfg->getMaxDeltaQP(); // 0
    iMinQP = Clip3( -sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP-idQP ); // clip3(minVal,maxVal,a),MAX_QP=51,-sps.getQpBDOffset(CHANNEL_TYPE_LUMA)=51
    iMaxQP = Clip3( -sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP+idQP ); // 查看 iBaseQP 和 idQP的值
  }
  else
  {
    // 默认该QP的最大值和最小值相同,此时QP只能选择`rpcTempCU->getQP(0)`
    iMinQP = rpcTempCU->getQP(0);
    iMaxQP = rpcTempCU->getQP(0);
  }

  // 方法2:根据luma level计算QP offset
  // 如果可以将亮度等级转化为QP等级(`m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()==True`),则进行转化
  if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
  {
    if ( uiDepth <= pps.getMaxCuDQPDepth() )
    {
      // keep using the same m_QP_LUMA_OFFSET in the same CTU
      m_lumaQPOffset = calculateLumaDQP(rpcTempCU, 0, m_ppcOrigYuv[uiDepth]);
    }
    iMinQP = Clip3(-sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP - m_lumaQPOffset);
    iMaxQP = iMinQP; // force encode choose the modifi
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值