VVC学习之四:VTM中的数据结构——CodingUnit、PredictionUnit、TransformUnit

文章目录

    • CodingUnit
    • PredictionUnit
    • TransformUnit

基本单元的结构体中,只定义了CU、PU、TU的属性信息,其头文件为Unit.h,对基本单元的操作定义在UnitTools.h中。命名空间CU中定义了对CodingUnit的操作,命名空间PUTU分别定义了在预测和量化中用到的方法。

CodingUnit

描述UnitArea定义的区域的压缩方法和方式。

struct CodingUnit : public UnitArea
{
  CodingStructure *cs;        // 父级CodingStructure
  Slice *slice;        // 指向CU所属slice
  ChannelType    chType;       // 颜色通道类型

  PredMode       predMode;       // 预测模式,帧内还是帧间

  uint8_t          depth;   // 总深度,为QTBTTT的深度,所有划分类型,一旦划分则+1
  uint8_t          qtDepth; // 四叉树深度
  //  btDepth和mtDepth都是描述MT的深度,在只有BT划分时,两者相等;但是CU使用TT划分时,两端的BTdepth将比mtdepth大1
  uint8_t          btDepth; // 二叉树深度
  uint8_t          mtDepth; // 多叉树深度
  int8_t          chromaQpAdj;           // 色度QP偏移值
  int8_t          qp;       // 实际编码QP值
  SplitSeries    splitSeries;             // 其二进制数标识生成当前CU尺寸时,CTU划分顺序
  bool           skip;                // 是否SKIP模式
  bool           mmvdSkip;         // 是否SKIP with MMVD模式
  bool           affine;         // 是否是affine 模式
  int            affineType;                // 仿射运动模型类型(四参数、六参数)
  bool           triangle;         // 是否三角形运动估计
  bool           transQuantBypass;         // 是否是transform 和 quantization pass by
  bool           ipcm;          // 是否 IPCM模式
  uint8_t          imv;         // 运动适量精度
  bool           rootCbf;         // coding block flag (三个通道都要为0,则为0)
#if JVET_M0140_SBT
  uint8_t        sbtInfo;                // sub-block transform 信息
#endif
#if HEVC_TILES_WPP
  uint32_t           tileIdx;
#endif
#if !JVET_M0464_UNI_MTS
  uint8_t          emtFlag;                      // 多核变换,变换核信息
#endif
  uint8_t         GBiIdx;         // generalized bi search?还未完全明白
  int             refIdxBi[2];         // 两个参考帧的索引
  // needed for fast imv mode decisions
  int8_t          imvNumCand;     
#if JVET_M0170_MRG_SHARELIST
  Position       shareParentPos;                 // 上层CU的位置信息
  Size           shareParentSize;                 // 上层CU的尺寸信息
#endif
#if JVET_M0483_IBC ==0
  bool           ibc;             // 是否为IBC模式
#endif
#if JVET_M0444_SMVD
  uint8_t          smvdMode;      
#endif
#if JVET_M0102_INTRA_SUBPARTITIONS
  uint8_t        ispMode;                     // 是否为ISP模式,帧内改进的逐行预测模式
#endif

           // 构造函数
  CodingUnit() : chType( CH_L ) { }
  CodingUnit(const UnitArea &unit);
  CodingUnit(const ChromaFormat _chromaFormat, const Area &area);

  CodingUnit& operator=( const CodingUnit& other );         // 运算符重载

  void initData();         // 初始化CU信息

  unsigned    idx;         // 在上层CU中的索引
  CodingUnit *next;         // 指向下一个CU,stack中

  PredictionUnit *firstPU;         // 指向所包含的第一个PU
  PredictionUnit *lastPU;         // 指向包含的最后一个PU

  TransformUnit *firstTU;         // 指向所包含的第一个TU
  TransformUnit *lastTU;         // 指向包含的最后一个TU

#if JVET_M0140_SBT
  const uint8_t     getSbtIdx() const { assert( ( ( sbtInfo >> 0 ) & 0xf ) < NUMBER_SBT_IDX ); return ( sbtInfo >> 0 ) & 0xf; }
  const uint8_t     getSbtPos() const { return ( sbtInfo >> 4 ) & 0x3; }
  void              setSbtIdx( uint8_t idx ) { CHECK( idx >= NUMBER_SBT_IDX, "sbt_idx wrong" ); sbtInfo = ( idx << 0 ) + ( sbtInfo & 0xf0 ); }
  void              setSbtPos( uint8_t pos ) { CHECK( pos >= 4, "sbt_pos wrong" ); sbtInfo = ( pos << 4 ) + ( sbtInfo & 0xcf ); }
  uint8_t           getSbtTuSplit() const;
  const uint8_t     checkAllowedSbt() const;
#endif
};

PredictionUnit

描述UnitArea的区域的预测信号的生成方式。


 // IntraPredictionData 定义了帧内预测数据,包括帧内预测模式及相关参考行索引。
 // InterPredictionData 定义了帧间预测数据,包含所有帧间预测数据(MV,refidx,merge,skip,trangleMerge,MMVD ,BV等)
 
struct PredictionUnit : public UnitArea, public IntraPredictionData, public InterPredictionData
{
  CodingUnit      *cu;         // 所属cu
  CodingStructure *cs;         // 所属cs
  ChannelType      chType;         // 颜色通道类型

  // constructors    构造函数
  PredictionUnit(): chType( CH_L ) { }
  PredictionUnit(const UnitArea &unit);
  PredictionUnit(const ChromaFormat _chromaFormat, const Area &area);

  void initData();                // PU初始化

  PredictionUnit& operator=(const IntraPredictionData& predData);
  PredictionUnit& operator=(const InterPredictionData& predData);
  PredictionUnit& operator=(const PredictionUnit& other);
  PredictionUnit& operator=(const MotionInfo& mi);

  unsigned        idx;         // CU中PU索引
#if JVET_M0170_MRG_SHARELIST
  Position shareParentPos;      // 上层CU位置和尺寸
  Size     shareParentSize;
#endif

  PredictionUnit *next;               // 指向CU中下一个PU

  // for accessing motion information, which can have higher resolution than PUs (should always be used, when accessing neighboring motion information)
  // 获取运动信息,MV的获取,可在固定位置
  const MotionInfo& getMotionInfo() const;
  const MotionInfo& getMotionInfo( const Position& pos ) const;
  MotionBuf         getMotionBuf();
  CMotionBuf        getMotionBuf() const;
};

TransformUnit

描述UnitArea的变换编码是如何进行的。

struct TransformUnit : public UnitArea
{
  CodingUnit      *cu;
  CodingStructure *cs;
  ChannelType      chType;
 #if JVET_M0427_INLOOP_RESHAPER
  int              m_chromaResScaleInv;
#endif

  uint8_t        depth;                         // TU相对深度
#if JVET_M0464_UNI_MTS
  uint8_t        mtsIdx;         // 变换核索引
#else
  uint8_t        emtIdx;
#endif
#if JVET_M0140_SBT
  bool           noResidual;               // 残差为0标志
#endif
  uint8_t        cbf        [ MAX_NUM_TBLOCKS ];               // coding block flag
  RDPCMMode    rdpcm        [ MAX_NUM_TBLOCKS ];
#if !JVET_M0464_UNI_MTS
  bool         transformSkip[ MAX_NUM_TBLOCKS ];               // 是否transform bypass
#endif
  int8_t        compAlpha   [ MAX_NUM_TBLOCKS ];

  TransformUnit() : chType( CH_L ) { }
  TransformUnit(const UnitArea& unit);
  TransformUnit(const ChromaFormat _chromaFormat, const Area &area);

  void initData();

  unsigned       idx;               // PU在CU中idx
  TransformUnit *next;               // 下一个PU、
#if JVET_M0102_INTRA_SUBPARTITIONS
  TransformUnit *prev;               // 
#endif

  void init(TCoeff **coeffs, Pel **pcmbuf);

  TransformUnit& operator=(const TransformUnit& other);
  void copyComponentFrom  (const TransformUnit& other, const ComponentID compID);
#if JVET_M0140_SBT
  void checkTuNoResidual( unsigned idx );               // 判断残差是否全0
#endif

         CoeffBuf getCoeffs(const ComponentID id);
  const CCoeffBuf getCoeffs(const ComponentID id) const;
         PelBuf   getPcmbuf(const ComponentID id);
  const CPelBuf   getPcmbuf(const ComponentID id) const;
#if JVET_M0427_INLOOP_RESHAPER                       
		// inloop reshaper 针对HDR提出的环内滤波技术
        int       getChromaAdj( )                 const;
        void      setChromaAdj(int i);
#endif

private:
  TCoeff *m_coeffs[ MAX_NUM_TBLOCKS ];
  Pel    *m_pcmbuf[ MAX_NUM_TBLOCKS ];
};

你可能感兴趣的:(VVC/H.266学习日记)