H.266/VTM10.1量化部分代码理解

量化部分代码相对而言比较集中,就在DepQuant::quant函数中实现。这篇文章主要梳理一下TCQ网格量化在代码中的实现。并且梳理顺序按照量化过程来展示。

主要函数、变量名称及其功能

函数:xDecideAndUpdate()
TCQ的入口函数,他的实参分别为:
abs(tCoeff[scanInfo.rasterPos])变换系数的绝对值
scanInfo当前系数的扫描信息
(zeroOut && (scanInfo.posX >= effWidth || scanInfo.posY >= effHeight))当前系数是否处于高频置零区域内的判断
defaultQuantisationCoefficient缩放系数

xDecide()
针对单个系数,具体的量化实现他的实参为:
scanInfo.spt当前系数在CG中的标志位,共有三个
absCoeff变换系数绝对值
lastOffset当前系数作为首个非零系数的RD代价
decisions网格的连线

主要函数注释

下面是xDecideAndUpdata函数的开始`.
javastript

#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
  void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, TCoeff quantCoeff,  int position )
#else
  void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, int quantCoeff, int position)
#endif
  {
    Decision* decisions = m_trellis[ scanInfo.scanIdx ]; //decisions中存储的三个量,abslevel代表某个可能的状态下的量化系数,rdcost为对应的rd代价,prevId代表与前项系数(scanpos)的状态转变。

    std::swap( m_prevStates, m_currStates );//指针指向位置交换
    
    xDecide(scanInfo.spt, absCoeff, lastOffset(scanInfo.scanIdx), decisions, zeroOut, quantCoeff,position,rem);//在完成一个系数的四个状态分别对应的level,失真distortion以及码率rate
    if( scanInfo.scanIdx )
    {
      if( scanInfo.eosbb )//eosbb==1表示该系数为CG的最后一个系数
      {
        m_commonCtx.swap();//m_currstate4个数组代表着当前已经经过viterbi算法剪裁之后的四条最优路径
        m_currStates[0].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[0] );//分别对四条路径的上下文信息进行更新(块级上下文)
        m_currStates[1].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[1] );
        m_currStates[2].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[2] );
        m_currStates[3].updateStateEOS( scanInfo, m_prevStates, m_skipStates, decisions[3] );
        ::memcpy( decisions+4, decisions, 4*sizeof(Decision) );//将常规状态转换模式的连线方式转移到后4个全零状态上
      }
      else if( !zeroOut )
      {
        switch( scanInfo.nextNbInfoSbb.num )//依据邻近块的数量来选择case,其中num为邻近块的数量(邻近块上下文信息的概念请查阅JVET相关提案以及论文)对每一条最优路径m_currstates[n]的系数级上下文信息进行更新
        //最主要的作用是更新了码率估计数组,对于下一个系数量化时,量化候选的码率查表计算有着重要影响
        {
        case 0:
          m_currStates[0].updateState<0>( scanInfo, m_prevStates, decisions[0] );
          m_currStates[1].updateState<0>( scanInfo, m_prevStates, decisions[1] );
          m_currStates[2].updateState<0>( scanInfo, m_prevStates, decisions[2] );
          m_currStates[3].updateState<0>( scanInfo, m_prevStates, decisions[3] );
          break;
        case 1:
          m_currStates[0].updateState<1>( scanInfo, m_prevStates, decisions[0] );
          m_currStates[1].updateState<1>( scanInfo, m_prevStates, decisions[1] );
          m_currStates[2].updateState<1>( scanInfo, m_prevStates, decisions[2] );
          m_currStates[3].updateState<1>( scanInfo, m_prevStates, decisions[3] );
          break;
        case 2:
          m_currStates[0].updateState<2>( scanInfo, m_prevStates, decisions[0] );
          m_currStates[1].updateState<2>( scanInfo, m_prevStates, decisions[1] );
          m_currStates[2].updateState<2>( scanInfo, m_prevStates, decisions[2] );
          m_currStates[3].updateState<2>( scanInfo, m_prevStates, decisions[3] );
          break;
        case 3:
          m_currStates[0].updateState<3>( scanInfo, m_prevStates, decisions[0] );
          m_currStates[1].updateState<3>( scanInfo, m_prevStates, decisions[1] );
          m_currStates[2].updateState<3>( scanInfo, m_prevStates, decisions[2] );
          m_currStates[3].updateState<3>( scanInfo, m_prevStates, decisions[3] );
          break;
        case 4:
          m_currStates[0].updateState<4>( scanInfo, m_prevStates, decisions[0] );
          m_currStates[1].updateState<4>( scanInfo, m_prevStates, decisions[1] );
          m_currStates[2].updateState<4>( scanInfo, m_prevStates, decisions[2] );
          m_currStates[3].updateState<4>( scanInfo, m_prevStates, decisions[3] );
          break;
        default:
          m_currStates[0].updateState<5>( scanInfo, m_prevStates, decisions[0] );
          m_currStates[1].updateState<5>( scanInfo, m_prevStates, decisions[1] );
          m_currStates[2].updateState<5>( scanInfo, m_prevStates, decisions[2] );
          m_currStates[3].updateState<5>( scanInfo, m_prevStates, decisions[3] );
        }
      }

      if( scanInfo.spt == SCAN_SOCSBB )
      {
        std::swap( m_prevStates, m_skipStates );
      }
    }
  }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值