VVC学习之四:VTM中的数据结构——CodingStructure

上层CodingStructure结构体管理着一帧中所有的CU,PU和TU。可以通过简单的坐标操作获取一帧中所有位置的CU信息。下层CodingStructure是进行RD搜索最优尺寸和最优预测模式的基本单元。想要深入理解VTM的代码逻辑,了解CodingStructure中的属性和方法是基础。

class CodingStructure
{
public:

  UnitArea         area;        // CodingStructure 所包含的区域

  Picture         *picture;        // 与picture的映射
  CodingStructure *parent;        // 上层cs
#if JVET_M0246_AFFINE_AMVR
  CodingStructure *bestCS;
#endif
  Slice           *slice;

  UnitScale        unitScale[MAX_NUM_COMPONENT];
  ChannelType chType;

  int         baseQP;
  int         prevQP[MAX_NUM_CHANNEL_TYPE];
  int         currQP[MAX_NUM_CHANNEL_TYPE];
  int         chromaQpAdj;        // 色度qp的offset
#if JVET_M0170_MRG_SHARELIST
  Position    sharedBndPos;
  Size        sharedBndSize;
#endif
  bool        isLossless;
  const SPS *sps;
  const PPS *pps;
#if HEVC_VPS
  const VPS *vps;
#endif
  const PreCalcValues* pcv;        // 预定义和计算得到的block相关参数

  CodingStructure(CUCache&, PUCache&, TUCache&);        // 构造
  void create( const UnitArea &_unit, const bool isTopLayer );        // 通过UnitArea创建新CS
  void create( const ChromaFormat &_chromaFormat, const Area& _area, const bool isTopLayer );        // 通过area创建新的CodingStructure
  void destroy();        // 释放CodingStructure
  void releaseIntermediateData();        // 释放编码信息

  void rebindPicBufs();
  void createCoeffs();        // 分配coeff空间
  void destroyCoeffs();

  void allocateVectorsAtPicLevel();        // 给编码信息(CUs,pus,tus)分配预留空间

  // ---------------------------------------------------------------------------
  // global accessors
  // ---------------------------------------------------------------------------

  bool isDecomp (const Position &pos, const ChannelType _chType) const;        // position处的重建信息是否已经生成
  bool isDecomp (const Position &pos, const ChannelType _chType);
  void setDecomp(const CompArea &area, const bool _isCoded = true);        // 设定特定颜色通道重建标志
  void setDecomp(const UnitArea &area, const bool _isCoded = true);        // 多通道区域重建标志

  const CodingUnit     *getCU(const Position &pos, const ChannelType _chType) const;        // 返回position处的CU
  const PredictionUnit *getPU(const Position &pos, const ChannelType _chType) const;        // 返回position处的pu
#if JVET_M0102_INTRA_SUBPARTITIONS
  const TransformUnit  *getTU(const Position &pos, const ChannelType _chType, const int subTuIdx = -1) const;        // 返回position处的tu
#else
  const TransformUnit  *getTU(const Position &pos, const ChannelType _chType) const;
#endif

  CodingUnit     *getCU(const Position &pos, const ChannelType _chType);
  PredictionUnit *getPU(const Position &pos, const ChannelType _chType);
#if JVET_M0102_INTRA_SUBPARTITIONS
  TransformUnit  *getTU(const Position &pos, const ChannelType _chType, const int subTuIdx = -1);
#else
  TransformUnit  *getTU(const Position &pos, const ChannelType _chType);
#endif

        // 获取cs第一个cu,pu,tu
  const CodingUnit     *getCU(const ChannelType &_chType) const { return getCU(area.blocks[_chType].pos(), _chType); }
  const PredictionUnit *getPU(const ChannelType &_chType) const { return getPU(area.blocks[_chType].pos(), _chType); }
  const TransformUnit  *getTU(const ChannelType &_chType) const { return getTU(area.blocks[_chType].pos(), _chType); }

  CodingUnit     *getCU(const ChannelType &_chType ) { return getCU(area.blocks[_chType].pos(), _chType); }
  PredictionUnit *getPU(const ChannelType &_chType ) { return getPU(area.blocks[_chType].pos(), _chType); }
  TransformUnit  *getTU(const ChannelType &_chType ) { return getTU(area.blocks[_chType].pos(), _chType); }


        // 获取cu,并判定是否在同一个slice和tile中,为了并行编码
#if HEVC_TILES_WPP
  const CodingUnit     *getCURestricted(const Position &pos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType) const;
#else
  const CodingUnit     *getCURestricted(const Position &pos, const unsigned curSliceIdx,                            const ChannelType _chType) const;
#endif
  const CodingUnit     *getCURestricted(const Position &pos, const CodingUnit& curCu,                               const ChannelType _chType) const;
  const PredictionUnit *getPURestricted(const Position &pos, const PredictionUnit& curPu,                           const ChannelType _chType) const;
  const TransformUnit  *getTURestricted(const Position &pos, const TransformUnit& curTu,                            const ChannelType _chType) const;

        // 为cs在UnitArea处创建CU
  CodingUnit&     addCU(const UnitArea &unit, const ChannelType _chType);
  PredictionUnit& addPU(const UnitArea &unit, const ChannelType _chType);
  TransformUnit&  addTU(const UnitArea &unit, const ChannelType _chType);

        // 遍历CS中CU,返回遍历器  typedef UnitTraverser<CodingUnit>     CUTraverser;
  CUTraverser     traverseCUs(const UnitArea& _unit, const ChannelType _chType);
  PUTraverser     traversePUs(const UnitArea& _unit, const ChannelType _chType);
  TUTraverser     traverseTUs(const UnitArea& _unit, const ChannelType _chType);

  cCUTraverser    traverseCUs(const UnitArea& _unit, const ChannelType _chType) const;
  cPUTraverser    traversePUs(const UnitArea& _unit, const ChannelType _chType) const;
  cTUTraverser    traverseTUs(const UnitArea& _unit, const ChannelType _chType) const;
  IbcLumaCoverage getIbcLumaCoverage(const CompArea& chromaArea) const;
  // ---------------------------------------------------------------------------
  // encoding search utilities     自顶向下RDsearch相关参数和方法
  // ---------------------------------------------------------------------------

  static_vector<double, NUM_ENC_FEATURES> features;

  double      cost;
#if JVET_M0102_INTRA_SUBPARTITIONS
  double      lumaCost;
#endif
  uint64_t      fracBits;
  Distortion  dist;
  Distortion  interHad;

      // clear所有数据,包括信号buf和编码信息
  void initStructData  (const int &QP = MAX_INT, const bool &_isLosses = false, const bool &skipMotBuf = false);
        // 链接新的底层CodingStructure
  void initSubStructure(      CodingStructure& cs, const ChannelType chType, const UnitArea &subArea, const bool &isTuEnc);

 // 从cs中复制编码信息
  void copyStructure   (const CodingStructure& cs, const ChannelType chType, const bool copyTUs = false, const bool copyRecoBuffer = false);
   // 从底层CS复制编码信息到当前层cs
  void useSubStructure (const CodingStructure& cs, const ChannelType chType, const UnitArea &subArea, const bool cpyPred, const bool cpyReco, const bool cpyOrgResi, const bool cpyResi);
  void useSubStructure (const CodingStructure& cs, const ChannelType chType,                          const bool cpyPred, const bool cpyReco, const bool cpyOrgResi, const bool cpyResi) { useSubStructure(cs, chType, cs.area, cpyPred, cpyReco, cpyOrgResi, cpyResi); }

 // 清空编码信息
  void clearTUs();
  void clearPUs();
  void clearCUs();


private:
  void createInternals(const UnitArea& _unit, const bool isTopLayer);     // 预分配空间,并清空数据
public:
     // 存放CS中所有cu,pu,tu
  std::vector<    CodingUnit*> cus;
  std::vector<PredictionUnit*> pus;
  std::vector< TransformUnit*> tus;

private:

  // needed for TU encoding
  bool m_isTuEnc;

  unsigned *m_cuIdx   [MAX_NUM_CHANNEL_TYPE];
  unsigned *m_puIdx   [MAX_NUM_CHANNEL_TYPE];
  unsigned *m_tuIdx   [MAX_NUM_CHANNEL_TYPE];
  bool     *m_isDecomp[MAX_NUM_CHANNEL_TYPE];

  unsigned m_numCUs;
  unsigned m_numPUs;
  unsigned m_numTUs;

  CUCache& m_cuCache;
  PUCache& m_puCache;
  TUCache& m_tuCache;

  std::vector<SAOBlkParam> m_sao;     // sao参数
     // 视频信号二维数据,“继承”Unitbuf------struct PelStorage : public PelUnitBuf
  PelStorage m_pred;
  PelStorage m_resi;
  PelStorage m_reco;
  PelStorage m_orgr;

  TCoeff *m_coeffs [ MAX_NUM_COMPONENT ];
  Pel    *m_pcmbuf [ MAX_NUM_COMPONENT ];

  int     m_offsets[ MAX_NUM_COMPONENT ];

  MotionInfo *m_motionBuf;     // 存储CS运动信息

public:

  MotionBuf getMotionBuf( const     Area& _area );    // 获取特定区域area的运动场motion field
  MotionBuf getMotionBuf( const UnitArea& _area ) { return getMotionBuf( _area.Y() ); }    // UnitArea的亮度的area的motion field
  MotionBuf getMotionBuf()                        { return getMotionBuf(  area.Y() ); }    // cs的motion field

  const CMotionBuf getMotionBuf( const     Area& _area ) const;
  const CMotionBuf getMotionBuf( const UnitArea& _area ) const { return getMotionBuf( _area.Y() ); }
  const CMotionBuf getMotionBuf()                        const { return getMotionBuf(  area.Y() ); }

  MotionInfo& getMotionInfo( const Position& pos );    // 特定位置的运动信息
  const MotionInfo& getMotionInfo( const Position& pos ) const;


public:
  // ---------------------------------------------------------------------------
  // temporary (shadowed) data accessors  数据访问接口
  // ---------------------------------------------------------------------------
         PelBuf       getPredBuf(const CompArea &blk);
  const CPelBuf       getPredBuf(const CompArea &blk) const;
         PelUnitBuf   getPredBuf(const UnitArea &unit);
  const CPelUnitBuf   getPredBuf(const UnitArea &unit) const;

         PelBuf       getResiBuf(const CompArea &blk);
  const CPelBuf       getResiBuf(const CompArea &blk) const;
         PelUnitBuf   getResiBuf(const UnitArea &unit);
  const CPelUnitBuf   getResiBuf(const UnitArea &unit) const;

         PelBuf       getRecoBuf(const CompArea &blk);
  const CPelBuf       getRecoBuf(const CompArea &blk) const;
         PelUnitBuf   getRecoBuf(const UnitArea &unit);
  const CPelUnitBuf   getRecoBuf(const UnitArea &unit) const;

         PelBuf       getOrgResiBuf(const CompArea &blk);
  const CPelBuf       getOrgResiBuf(const CompArea &blk) const;
         PelUnitBuf   getOrgResiBuf(const UnitArea &unit);
  const CPelUnitBuf   getOrgResiBuf(const UnitArea &unit) const;

         PelBuf       getOrgBuf(const CompArea &blk);
  const CPelBuf       getOrgBuf(const CompArea &blk) const;
         PelUnitBuf   getOrgBuf(const UnitArea &unit);
  const CPelUnitBuf   getOrgBuf(const UnitArea &unit) const;

         PelBuf       getOrgBuf(const ComponentID &compID);
  const CPelBuf       getOrgBuf(const ComponentID &compID) const;
         PelUnitBuf   getOrgBuf();
  const CPelUnitBuf   getOrgBuf() const;


  // pred buffer
         PelBuf       getPredBuf(const ComponentID &compID)       { return m_pred.get(compID); }
  const CPelBuf       getPredBuf(const ComponentID &compID) const { return m_pred.get(compID); }
         PelUnitBuf   getPredBuf()                                { return m_pred; }
  const CPelUnitBuf   getPredBuf()                          const { return m_pred; }

  // resi buffer
         PelBuf       getResiBuf(const ComponentID compID)        { return m_resi.get(compID); }
  const CPelBuf       getResiBuf(const ComponentID compID)  const { return m_resi.get(compID); }
         PelUnitBuf   getResiBuf()                                { return m_resi; }
  const CPelUnitBuf   getResiBuf()                          const { return m_resi; }

  // org-resi buffer
         PelBuf       getOrgResiBuf(const ComponentID &compID)       { return m_orgr.get(compID); }
  const CPelBuf       getOrgResiBuf(const ComponentID &compID) const { return m_orgr.get(compID); }
         PelUnitBuf   getOrgResiBuf()                                { return m_orgr; }
  const CPelUnitBuf   getOrgResiBuf()                          const { return m_orgr; }

  // reco buffer
         PelBuf       getRecoBuf(const ComponentID compID)         { return m_reco.get(compID); }
  const CPelBuf       getRecoBuf(const ComponentID compID)   const { return m_reco.get(compID); }
         PelUnitBuf   getRecoBuf()                                 { return m_reco; }
  const CPelUnitBuf   getRecoBuf()                           const { return m_reco; }

private:

  inline        PelBuf       getBuf(const CompArea &blk,  const PictureType &type);
  inline const CPelBuf       getBuf(const CompArea &blk,  const PictureType &type) const;
  inline        PelUnitBuf   getBuf(const UnitArea &unit, const PictureType &type);
  inline const CPelUnitBuf   getBuf(const UnitArea &unit, const PictureType &type) const;
};
  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值