量化(二)

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;  
  }  
}  


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