HEVC代码学习33:量化相关代码学习

来源:互联网 发布:海岛奇兵22级兵种数据 编辑:程序博客网 时间:2024/06/09 14:24

今天来看量化相关的代码。HEVC中,变换和量化是相互结合的,这里重点关注量化部分。

在HM的TLibCommon中,有TComTrQuant.h,从名字上可知是变换量化相关的,就从这个头文件入手开始学习吧。

其中使用结构体QpParam定义了QP的信息:

/// QP structstruct QpParam{   //QP = floor(QP/6)+QP%6  Int Qp;  Int per;      //per = QP/6  Int rem;      //rem = QP%6  QpParam(const Int           qpy,          const ChannelType   chType,          const Int           qpBdOffset,          const Int           chromaQPOffset,          const ChromaFormat  chFmt );  QpParam(const TComDataCU   &cu, const ComponentID compID);}; // END STRUCT DEFINITION QpParam


其中两个构造函数如下,用于计算偏移后的QP并设置QP信息。

QpParam::QpParam(const Int           qpy,                 const ChannelType   chType,                 const Int           qpBdOffset,                 const Int           chromaQPOffset,                 const ChromaFormat  chFmt ){  Int baseQp;       //基础QP  if(isLuma(chType))        //亮度分量  {    baseQp = qpy + qpBdOffset;  }  else      //色度分量  {    baseQp = Clip3( -qpBdOffset, (chromaQPMappingTableSize - 1), qpy + chromaQPOffset );    if(baseQp < 0)    {      baseQp = baseQp + qpBdOffset;    }    else    {      baseQp = getScaledChromaQP(baseQp, chFmt) + qpBdOffset;    }  }  //QP = floor(QP/6)+QP%6  Qp =baseQp;         per=baseQp/6;  rem=baseQp%6;}QpParam::QpParam(const TComDataCU &cu, const ComponentID compID){  Int chromaQpOffset = 0;  if (isChroma(compID))     //色度分量  {    chromaQpOffset += cu.getSlice()->getPPS()->getQpOffset(compID);    chromaQpOffset += cu.getSlice()->getSliceChromaQpDelta(compID);    chromaQpOffset += cu.getSlice()->getPPS()->getPpsRangeExtension().getChromaQpOffsetListEntry(cu.getChromaQpAdj(0)).u.offset[Int(compID)-1];  }  *this = QpParam(cu.getQP( 0 ),                  toChannelType(compID),                  cu.getSlice()->getSPS()->getQpBDOffset(toChannelType(compID)),                  chromaQpOffset,                  cu.getPic()->getChromaFormat());}

接下来看变换量化类TComTrQuant,其中定义了量化和反量化函数:xQuant和xDeQuant。TComTrQuant类本身的英文注释已经很清楚了,这里为了清晰,只保留了量化和反量化函数部分:

/// transform and quantization class        //变换量化类class TComTrQuant{public:  TComTrQuant();  ~TComTrQuant();  // initialize class   //初始化  Void init                 ( UInt  uiMaxTrSize,                              Bool useRDOQ                = false,                              Bool useRDOQTS              = false,                              Bool useSelectiveRDOQ       = false,                              Bool bEnc                   = false,                              Bool useTransformSkipFast   = false#if ADAPTIVE_QP_SELECTION                            , Bool bUseAdaptQpSelect      = false#endif                              );private:  // quantization  Void xQuant(       TComTU       &rTu,                     TCoeff      * pSrc,                     TCoeff      * pDes,#if ADAPTIVE_QP_SELECTION                     TCoeff      *pArlDes,#endif                     TCoeff       &uiAbsSum,               const ComponentID   compID,               const QpParam      &cQP );  // dequantization  Void xDeQuant(       TComTU       &rTu,                 const TCoeff      * pSrc,                       TCoeff      * pDes,                 const ComponentID   compID,                 const QpParam      &cQP );};// END CLASS DEFINITION TComTrQuant

xQuant和xDeQuant被变换和反变换函数transformNxN和invTransformNxN调用,在变换后直接对变换系数进行量化。由于功能很明确,而且不需要过多了解量化原理部分,函数代码就不深入看了。

原创粉丝点击