关于浮点QP

总所周知,QP是整数。然而HM/JEM均支持浮点QP(floating point QP),而且HM中从HM-1.0就开始支持了,这是为什么呢?先来看配置文件的参数说明:
这里写图片描述

从上图可以看出,配置文件中的QP被程序读进来的时候是一个浮点数Double TAppEncCfg::m_fQP。读进来之后在函数TAppEncCfg::parseCfg中对这个浮点QP进行如下处理:

  // allocate slice-based dQP values
  m_aidQP = new Int[ m_framesToBeEncoded + m_iGOPSize + 1 ];
  ::memset( m_aidQP, 0, sizeof(Int)*( m_framesToBeEncoded + m_iGOPSize + 1 ) );

  // handling of floating-point QP values
  // if QP is not integer, sequence is split into two sections having QP and QP+1
  m_iQP = (Int)( m_fQP );
  if ( m_iQP < m_fQP )
  {
    Int iSwitchPOC = (Int)( m_framesToBeEncoded - (m_fQP - m_iQP)*m_framesToBeEncoded + 0.5 );
    // iSwitchPOC须是key帧,所以需要取整
    iSwitchPOC = (Int)( (Double)iSwitchPOC / m_iGOPSize + 0.5 )*m_iGOPSize;
    for ( Int i=iSwitchPOC; i<m_framesToBeEncoded + m_iGOPSize + 1; i++ )
    {
      m_aidQP[i] = 1;
    }
  }

上面的代码中,将poc小于iSwitchPOC的帧级QP偏置置为0,poc大于iSwitchPOC的帧级QP偏置置为1。其中,TEncCfg::m_aidQP
就是delta QP(QP偏置);如果m_fQP更接近m_iQP,iSwitchPOC更偏向0,如果m_fQP更接近m_iQP+1,iSwitchPOC更偏向m_framesToBeEncoded+m_iGOPSize。
再在TEncSlice::initEncSlice中用TEncCfg::m_aidQP修改slice级QP:

  // modify QP
  Int* pdQPs = m_pcCfg->getdQPs();
  if ( pdQPs )
  {
    dQP += pdQPs[ rpcSlice->getPOC() ];
  }

简言之,浮点QP是所有base QP的均值,且前面部分帧的base QP为[m_fQP],后面部分帧的base QP为[m_fQP]+1。
下面是一个例子,在不开率控的情况下设置QP为32.5,FramesToBeEncoded为9。从图中可以看出,前二个GOP的QP的base QP为32,第三个GOP的QP的base QP为33:
这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章