關於浮點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:
這裏寫圖片描述

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