HEVC學習(二十八) —— 量化之二

Void TComTrQuant::transformNxN( TComDataCU* pcCU, 
                               Pel*        pcResidual,   //!< 殘差
                               UInt        uiStride, 
                               TCoeff*     rpcCoeff,	   //!< 殘差經變換且量化後的係數 
#if ADAPTIVE_QP_SELECTION
                               Int*&       rpcArlCoeff, 
#endif
                               UInt        uiWidth, 
                               UInt        uiHeight, 
                               UInt&       uiAbsSum, 
                               TextType    eTType, 
                               UInt        uiAbsPartIdx,
                               Bool        useTransformSkip
                               )
{
  if (pcCU->getCUTransquantBypass(uiAbsPartIdx)) //!< 如果變換、量化過程被旁路,則直接將殘差pcResidual賦值給rpcCoeff
  {																		//!< 計算殘差絕對值的和並返回
    uiAbsSum=0;
    for (UInt k = 0; k<uiHeight; k++)
    {
      for (UInt j = 0; j<uiWidth; j++)
      {
        rpcCoeff[k*uiWidth+j]= pcResidual[k*uiStride+j];
        uiAbsSum += abs(pcResidual[k*uiStride+j]);
      }
    }
    return;
  }
  UInt uiMode;  //luma intra pred
   if(eTType == TEXT_LUMA && pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTRA )
  {
    uiMode = pcCU->getLumaIntraDir( uiAbsPartIdx );	//!< 獲取PU的幀內預測模式
  }
  else
  {
    uiMode = REG_DCT;
  }
  
  uiAbsSum = 0;
  assert( (pcCU->getSlice()->getSPS()->getMaxTrSize() >= uiWidth) );
  Int bitDepth = eTType == TEXT_LUMA ? g_bitDepthY : g_bitDepthC;
  if(useTransformSkip) //!< TS模式
  {
    xTransformSkip(bitDepth, pcResidual, uiStride, m_plTempCoeff, uiWidth, uiHeight );
  }
  else
  {
    xT(bitDepth, uiMode, pcResidual, uiStride, m_plTempCoeff, uiWidth, uiHeight ); //!< m_plTempCoeff存放的是殘差經變換後的係數
  }
  xQuant( pcCU, m_plTempCoeff, rpcCoeff,
#if ADAPTIVE_QP_SELECTION
       rpcArlCoeff,
#endif
       uiWidth, uiHeight, uiAbsSum, eTType, uiAbsPartIdx );	//!< 量化,rpcCoeff存放最終結果
}


在Void TEncGOP::compressGOP中有這麼一段值得關注,主要對量化係數矩陣的值進行設置:

 if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF) //!< ("ScalingList",  m_useScalingListId, 0, "0: no scaling list, 1: default scaling lists, 2: scaling lists specified in ScalingListFile"),即默認程序會進入該條件體
    {
      m_pcEncTop->getTrQuant()->setFlatScalingList(); //!< 重點關注該函數的實現,即量化係數矩陣是如何賦值的
      m_pcEncTop->getTrQuant()->setUseScalingList(false);
      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
    }
    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_DEFAULT)
    {
      pcSlice->setDefaultScalingList ();
      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
      m_pcEncTop->getTrQuant()->setUseScalingList(true);
    }
    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_FILE_READ)
    {
      if(pcSlice->getScalingList()->xParseScalingList(m_pcCfg->getScalingListFile()))
      {
        pcSlice->setDefaultScalingList ();
      }
      pcSlice->getScalingList()->checkDcOfMatrix();
      m_pcEncTop->getSPS()->setScalingListPresentFlag(pcSlice->checkDefaultScalingList());
      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
      m_pcEncTop->getTrQuant()->setUseScalingList(true);
    }
    else
    {
      printf("error : ScalingList == %d no support\n",m_pcEncTop->getUseScalingListId());
      assert(0);
    }

進入到ScalingList的設置函數中:

/** set flat matrix value to quantized coefficient
 */
Void TComTrQuant::setFlatScalingList()
{
  UInt size,list;
  UInt qp;

  for(size=0;size<SCALING_LIST_SIZE_NUM;size++) //!< sizeID
  {
    for(list = 0; list <  g_scalingListNum[size]; list++) //!< MatrixID
    {
      for(qp=0;qp<SCALING_LIST_REM_NUM;qp++)	//!< 0~5
      {
        xsetFlatScalingList(list,size,qp);
        setErrScaleCoeff(list,size,qp);
      }
    }
  }
}

關注函數xsetFlatScalingList

Void TComTrQuant::xsetFlatScalingList(UInt list, UInt size, UInt qp)
{
  UInt i,num = g_scalingListSize[size]; //!< 對應SizeID下Matrix的尺寸(行數乘列數),4x4,8x8,16x16,32x32
  Int *quantcoeff;
  Int *dequantcoeff;
  Int quantScales = g_quantScales[qp]; //!< 26214,23302,20560,18396,16384,14564
  Int invQuantScales = g_invQuantScales[qp]<<4; //!< 40,45,51,57,64,72

  quantcoeff   = getQuantCoeff(list, qp, size);
  dequantcoeff = getDequantCoeff(list, qp, size);

  for(i=0;i<num;i++) //!< 對Matrix中所有元素賦予相同的值,即所謂的"flat"
  { 
    *quantcoeff++ = quantScales;
    *dequantcoeff++ = invQuantScales;
  }
}



 

發佈了97 篇原創文章 · 獲贊 855 · 訪問量 106萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章