IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> VTM代码学习 1一 DATA STRUCTURES -> 正文阅读

[C++知识库]VTM代码学习 1一 DATA STRUCTURES

新的视频编码标准参考软件相较于上一代参考软件HM,
有着z-index 类等函数叠加顺序上不优,TcomdataCU这个数据模型太模糊等等细节问题。
新加入了面向对象设计程序,取消了z-index的使用,消除CTU->z-index的信号寻址。

在这里插入图片描述

整体的数据结构模型

在这里插入图片描述

引导位置部分 Navigation

  1. Size, Position, Area (Position + Size)
    代表基本的二维导航信息

Size
宽度、高度:UInt–描述矩形的大小
Position
x,y:Int–描述一个点的2D位置
Area:Position + Size
位于特定位置的特定大小的矩形
CompArea:Area
多分量信号的特定分量(compID)内的区域

struct Size
{
  SizeType width; //数据成员宽和高。typedef uint32_t SizeType;
  SizeType height;

  Size()                                              : width(0),      height(0)       { }//构造函数列表初始化为0
  Size(const SizeType _width, const SizeType _height) : width(_width), height(_height) { }//构造函数

  bool operator!=(const Size &other)      const { return (width != other.width) || (height != other.height); }//常量成员函数
  bool operator==(const Size &other)      const { return (width == other.width) && (height == other.height); }
  uint32_t area()                             const { return (uint32_t) width * (uint32_t) height; }//常量成员函数,area 返回长乘宽等于面积
#if REUSE_CU_RESULTS_WITH_MULTIPLE_TUS
  void resizeTo(const Size newSize)             { width = newSize.width; height = newSize.height; }
#endif
};
struct Position
{
  PosType x;//typedef int PosType; int型,此刻的坐标值
  PosType y;

  Position()                                   : x(0),  y(0)  { }//构造函数
  Position(const PosType _x, const PosType _y) : x(_x), y(_y) { }

  bool operator!=(const Position &other)  const { return x != other.x || y != other.y; }//两个区域是否是同一区域,不相等则返回true;下面函数相反
  bool operator==(const Position &other)  const { return x == other.x && y == other.y; }

  Position offset(const Position pos)                 const { return Position(x + pos.x, y + pos.y); }//常量偏移值函数,返回偏移后的坐标
  Position offset(const PosType _x, const PosType _y) const { return Position(x + _x   , y + _y   ); }
  void     repositionTo(const Position newPos)              { x  = newPos.x; y  = newPos.y; }//更新位置信息,去到新位置
  void     relativeTo  (const Position origin)              { x -= origin.x; y -= origin.y; }//
//得到新位置和上一个位置的相对距离
  Position operator-( const Position &other )         const { return{ x - other.x, y - other.y }; //位置操作函数常量,返回当前位置与某一位置的距离}
};
struct Area : public Position, public Size//继承两个类
{
  Area()                                                                         : Position(),       Size()       { }
  Area(const Position &_pos, const Size &_size)                                  : Position(_pos),   Size(_size)  { }
  Area(const PosType _x, const PosType _y, const SizeType _w, const SizeType _h) : Position(_x, _y), Size(_w, _h) { }

        Position& pos()                           { return *this; } //pos引用函数返回对象以作为引用//返回引用在内存中不产生被返回值的副本,局部变量不要引用返回
  const Position& pos()                     const { return *this; }
        Size&     size()                          { return *this; }// size()函数返回对象
  const Size&     size()                    const { return *this; }

  const Position& topLeft()                 const { return *this; } //topleft函数返回对象
        Position  topRight()                const { return { (PosType) (x + width - 1), y                          }; //返回块右上位置,下面类似函数用于返回区域的左下右下中心位置}
        Position  bottomLeft()              const { return { x                        , (PosType) (y + height - 1) }; }
        Position  bottomRight()             const { return { (PosType) (x + width - 1), (PosType) (y + height - 1) }; }
        Position  center()                  const { return { (PosType) (x + width / 2), (PosType) (y + height / 2) }; }

  bool contains(const Position &_pos)       const { return (_pos.x >= x) && (_pos.x < (x + width)) && (_pos.y >= y) && (_pos.y < (y + height)); }//判断某个位置是否在此位置内,在的话返回true
  bool contains(const Area &_area)          const { return contains(_area.pos()) && contains(_area.bottomRight()); }//判断一个区域的右下位置加上高宽度后与左上位置是否是都在当前区域内

  bool operator!=(const Area &other)        const { return (Size::operator!=(other)) || (Position::operator!=(other)); } // 判断区域是否与当前区域一致
  bool operator==(const Area &other)        const { return (Size::operator==(other)) && (Position::operator==(other)); }
};

  1. compArea
    给定组件(块)中的区域
  2. UnitArea
    表示多通道信号中的一个区域
    描述协同定位的组件的组成的一组块
enum ComponentID//通道部分
{
  COMPONENT_Y         = 0,
  COMPONENT_Cb        = 1,
  COMPONENT_Cr        = 2,
  MAX_NUM_COMPONENT   = 3,
  JOINT_CbCr          = MAX_NUM_COMPONENT,
  MAX_NUM_TBLOCKS     = MAX_NUM_COMPONENT
};

struct CompArea : public Area
{
  CompArea() : Area(), chromaFormat(NUM_CHROMA_FORMAT), compID(MAX_NUM_TBLOCKS)                                                                                                                                 { }//构造函数初始化列表,采样格式以及区域所在通道初始化
  CompArea(const ComponentID _compID, const ChromaFormat _cf, const Area &_area, const bool isLuma = false)                                          : Area(_area),          chromaFormat(_cf), compID(_compID) { if (isLuma) xRecalcLumaToChroma(); }//构造函数重载+5
  CompArea(const ComponentID _compID, const ChromaFormat _cf, const Position& _pos, const Size& _size, const bool isLuma = false)                    : Area(_pos, _size),    chromaFormat(_cf), compID(_compID) { if (isLuma) xRecalcLumaToChroma(); }
  CompArea(const ComponentID _compID, const ChromaFormat _cf, const uint32_t _x, const uint32_t _y, const uint32_t _w, const uint32_t _h, const bool isLuma = false) : Area(_x, _y, _w, _h), chromaFormat(_cf), compID(_compID) { if (isLuma) xRecalcLumaToChroma(); }

  ChromaFormat chromaFormat; //采样方式
  ComponentID compID;//通道

  Position chromaPos() const;//声明色度位置
  Position lumaPos()   const;//声明亮度位置常量

  Size     chromaSize() const;//声明
  Size     lumaSize()   const;

  Position compPos( const ComponentID compID ) const; //yuv哪个通道
  Position chanPos( const ChannelType chType ) const;//y uv哪个通道
  //声明与定义获取comp部分的的位置函数 
  Position topLeftComp    (const ComponentID _compID) const { return recalcPosition(chromaFormat, compID, _compID, *this);                                                     }
  Position topRightComp   (const ComponentID _compID) const { return recalcPosition(chromaFormat, compID, _compID, { (PosType) (x + width - 1), y                          }); }
  Position bottomLeftComp (const ComponentID _compID) const { return recalcPosition(chromaFormat, compID, _compID, { x                        , (PosType) (y + height - 1 )}); }
  Position bottomRightComp(const ComponentID _compID) const { return recalcPosition(chromaFormat, compID, _compID, { (PosType) (x + width - 1), (PosType) (y + height - 1 )}); }
   //常量函数,判断取样格式、通道数目、区域的宽高不为零 是否正确有效
  bool valid() const { return chromaFormat < NUM_CHROMA_FORMAT && compID < MAX_NUM_TBLOCKS && width != 0 && height != 0; }
  //判断other位置与当前位置是否一致,
  const bool operator==(const CompArea &other) const
  {
    if (chromaFormat != other.chromaFormat) return false;
    if (compID       != other.compID)       return false;

    return Position::operator==(other) && Size::operator==(other);
  }

  const bool operator!=(const CompArea &other) const { return !(operator==(other)); }

#if REUSE_CU_RESULTS_WITH_MULTIPLE_TUS
  void     resizeTo          (const Size& newSize)          { Size::resizeTo(newSize); }//继承size重新调整当前unit的大小,
#endif
  //继承position 的重新调整位置,得到两个位置的距离
  void     repositionTo      (const Position& newPos)       { Position::repositionTo(newPos); }
  void     positionRelativeTo(const CompArea& origCompArea) { Position::relativeTo(origCompArea); }

private:
	//亮度到色度,中间是移位操作
  void xRecalcLumaToChroma();
};
struct UnitArea
{
  ChromaFormat chromaFormat; //色度格式,默认都用 CHROMA_420 =1
  UnitBlocksType blocks; //二维数组typedef static_vector<CompArea, MAX_NUM_TBLOCKS> UnitBlocksType; 此单元块类型是个二维数组

  UnitArea() : chromaFormat(NUM_CHROMA_FORMAT) { }//构造函数初始列表先初始化采样格式
  UnitArea(const ChromaFormat _chromaFormat);//重载
  UnitArea(const ChromaFormat _chromaFormat, const Area &area);
  UnitArea(const ChromaFormat _chromaFormat, const CompArea  &blkY);
  UnitArea(const ChromaFormat _chromaFormat,       CompArea &&blkY);
  UnitArea(const ChromaFormat _chromaFormat, const CompArea  &blkY, const CompArea  &blkCb, const CompArea  &blkCr);
  UnitArea(const ChromaFormat _chromaFormat,       CompArea &&blkY,       CompArea &&blkCb,       CompArea &&blkCr);

        CompArea& Y()                                  { return blocks[COMPONENT_Y];  }
        //y通道部分的区域函数,返回 区域的块类型数组的第一个数据(下标为0),因为是Y通道,下面类似
  const CompArea& Y()                            const { return blocks[COMPONENT_Y];  }
        CompArea& Cb()                                 { return blocks[COMPONENT_Cb]; }
  const CompArea& Cb()                           const { return blocks[COMPONENT_Cb]; }
        CompArea& Cr()                                 { return blocks[COMPONENT_Cr]; }
  const CompArea& Cr()                           const { return blocks[COMPONENT_Cr]; }

        CompArea& block(const ComponentID comp)       { return blocks[comp]; }//根据不同通道返回块的第几个元素
  const CompArea& block(const ComponentID comp) const { return blocks[comp]; }

  bool contains(const UnitArea& other) const; //声明包含函数,判断单元区域是否相互包含
  bool contains(const UnitArea& other, const ChannelType chType) const;

        CompArea& operator[]( const int n )       { return blocks[n]; }// 返回blocks数组
  const CompArea& operator[]( const int n ) const { return blocks[n]; }
  //判断是否是相同的单元区域
  const bool operator==(const UnitArea &other) const
  {
    if (chromaFormat != other.chromaFormat)   return false;
    if (blocks.size() != other.blocks.size()) return false;

    for (uint32_t i = 0; i < blocks.size(); i++)
    {
      if (blocks[i] != other.blocks[i]) return false;
    }

    return true;
  }
// 继承父类的一些操作
#if REUSE_CU_RESULTS_WITH_MULTIPLE_TUS
  void resizeTo    (const UnitArea& unit);
#endif
  void repositionTo(const UnitArea& unit);

  const bool operator!=(const UnitArea &other) const { return !(*this == other); }
//继承返回y通道色度通道blocks里元素的位置
  const Position& lumaPos () const { return Y(); }
  const Size&     lumaSize() const { return Y(); }

  const Position& chromaPos () const { return Cb(); }
  const Size&     chromaSize() const { return Cb(); }
	// 声明单通道的comp channal 单元区域函数
  const UnitArea  singleComp(const ComponentID compID) const;
  const UnitArea  singleChan(const ChannelType chType) const;

  const SizeType  lwidth()  const { return Y().width; }  /*! luma width  */
  const SizeType  lheight() const { return Y().height; } /*! luma height */

  const PosType   lx() const { return Y().x; }           /*! luma x-pos */
  const PosType   ly() const { return Y().y; }           /*! luma y-pos */
//blocks里面有元素才是正常
  bool valid() const { return chromaFormat != NUM_CHROMA_FORMAT && blocks.size() > 0; }
};

UnitArea
blocks [0…N-1]: CompArea
由N个块组成的组合体,a multi-component compound consisting of N blocks
CodingUnit : UnitArea
描述如何对这个UnitArea描述的区域进行编码
PredictionUnit : UnitArea
描述如何生成该UnitArea的预测信号
TransformUnit : UnitArea
描述如何应用此UnitArea的转换编码

信号存储器部分(signal storage)

  1. AreaBuf
    描述二维信号在线性存储器中的存储布局
    包含简单的操作(复制、填充等)。)

(1) AreaBuf (defined for Pel and TCoeff as PelAreaBuf and CoeffAreaBuf)

at(x,y) –返回位置(x,y)处的信号值
bufAt(x,y) –返回指向缓冲区位置(x,y)的原始指针
subBuf(x,y,w,h) -返回一个AreaBuf,描述一个大小为(w,h)的区域偏移量(x,y)
fill(val) –用定义的值填充指定区域
copy from(other) –从其他区域复制内容
substract、addAvg、reconstruct、removeHighFreq –替代TComYuv功能的方法
(2) UnitBuf (similar interface to AreaBuf)
bufs[0…n-1]:Areabuf–包含不同组件的信号描述

  1. UnitAreaBuf
    描述了多分量二维信号在线性存储器中的存储布局
    包含简单的操作(复制、填充等)。)
  2. PelStorage
    一个UnitAreaBuf,它也分配自己的内存

编码信息(coding information)

  1. picture
    包含输入和输出信号以及元数据(切片信息等。)
  2. CodingUnit, PredictionUnit, TransformUnit
    单个单元的单个对象
    包含相应的信息
    包括位置信息(从UnitArea获得)
  3. CodingStructure
    管理编码单元,将它们与图片链接
    包含自上而下RD搜索的附加功能
struct CodingUnit : public UnitArea //继承自Unitarea
{
  CodingStructure *cs; //父级CU的cs
  Slice *slice; //cu所在的slice
  ChannelType    chType; //通道类型

  PredMode       predMode; //预测类型enum PredMode  MODE_INTER     = 0,     ///< inter-prediction mode

  uint8_t          depth;   // number of all splits, applied with generalized splits
  uint8_t          qtDepth; // number of applied quad-splits, before switching to the multi-type-tree (mtt)
  // a triple split would increase the mtDepth by 1, but the qtDepth by 2 in the first and last part and by 1 in the middle part (because of the 1-2-1 split proportions)
  uint8_t          btDepth; // number of applied binary splits, after switching to the mtt (or it's equivalent)
  uint8_t          mtDepth; // the actual number of splits after switching to mtt (equals btDepth if only binary splits are allowed)
  int8_t          chromaQpAdj; //色度qp偏移值
  int8_t          qp;  //cu的编码qp
  SplitSeries    splitSeries; //uint64_t 生成当前cu尺寸时,ctu划分顺序
  TreeType       treeType; //default tree status (for single-tree slice, TREE_D means joint tree; for dual-tree I slice, TREE_D means TREE_L for luma and TREE_C for chroma)
  ModeType       modeType;//intra inter ibc palette几种模式类型
  ModeTypeSeries modeTypeSeries; //用于对不同拆分深度的Modetype进行编码uint64_t
  bool           skip; //skip模式
  bool           mmvdSkip; //skipwith mmvd模式
  bool           affine; //是否是仿射模式
  int            affineType; //仿射运动类型(4,6 参数)
  bool           colorTransform; //颜色变换?
  bool           geoFlag; // 
  int            bdpcmMode; //
  int            bdpcmModeChroma;
  uint8_t          imv; //运动矢量的精度
  bool           rootCbf; //coding block flag (三通道都为零则为零)
  uint8_t        sbtInfo; //sub block transform info 
  uint32_t           tileIdx; //hevc中的tile
  //好多还不知道的变量
  uint8_t         mtsFlag; 
  uint32_t        lfnstIdx; 
  uint8_t         BcwIdx; 
  int             refIdxBi[2];
  bool           mipFlag;

  // needed for fast imv mode decisions
  int8_t          imvNumCand;
  uint8_t          smvdMode;
  uint8_t        ispMode;
  bool           useEscape[MAX_NUM_CHANNEL_TYPE];
  bool           useRotation[MAX_NUM_CHANNEL_TYPE];
  bool           reuseflag[MAX_NUM_CHANNEL_TYPE][MAXPLTPREDSIZE];
  uint8_t        lastPLTSize[MAX_NUM_CHANNEL_TYPE];
  uint8_t        reusePLTSize[MAX_NUM_CHANNEL_TYPE];
  uint8_t        curPLTSize[MAX_NUM_CHANNEL_TYPE];
  Pel            curPLT[MAX_NUM_COMPONENT][MAXPLTSIZE];
//构造函数
  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;

  TransformUnit *firstTU;
  TransformUnit *lastTU;
#if ENABLE_SPLIT_PARALLELISM

  int64_t cacheId;
  bool    cacheUsed;
#endif
  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;
  const bool        checkCCLMAllowed() const;
  const bool        isSepTree() const;
  const bool        isLocalSepTree() const;
  const bool        isConsInter() const { return modeType == MODE_TYPE_INTER; }
  const bool        isConsIntra() const { return modeType == MODE_TYPE_INTRA; }
};

编码结构结构体

class CodingStructure 
{
public:

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

  Picture         *picture;//与picture的映射
  CodingStructure *parent; //上层的cs
  CodingStructure *bestCS;//最佳的cs
  Slice           *slice;//所在的slice

  UnitScale        unitScale[MAX_NUM_COMPONENT];//单元的尺寸数组enum ComponentID的数组大小

  int         baseQP;//cs下的基础qp值
  int         prevQP[MAX_NUM_CHANNEL_TYPE];//
  int         currQP[MAX_NUM_CHANNEL_TYPE];//当前qp值数组
  int         chromaQpAdj; //色度qp偏移值
  const SPS *sps; //
  const PPS *pps;//
  PicHeader *picHeader; // picture header class 
  APS*       alfApss[ALF_CTB_MAX_NUM_APS];
  APS *      lmcsAps;
  APS *      scalinglistAps;
  const VPS *vps; 
  const PreCalcValues* pcv;  // 预定义和计算得到的block相关参数

  CodingStructure(CUCache&, PUCache&, TUCache&);//构造函数

  void create(const UnitArea &_unit, const bool isTopLayer, const bool isPLTused); //通过UnitArea声明创造cs
  void create(const ChromaFormat &_chromaFormat, const Area& _area, const bool isTopLayer, const bool isPLTused);

  void destroy(); //销毁函数
  void releaseIntermediateData(); //解除中间数据

  void rebindPicBufs(); //重更新picture缓冲

  void createCoeffs(const bool isPLTused);  分配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;
  const TransformUnit  *getTU(const Position &pos, const ChannelType _chType, const int subTuIdx = -1) const;

  CodingUnit     *getCU(const Position &pos, const ChannelType _chType);
  CodingUnit     *getLumaCU( const Position &pos );
  PredictionUnit *getPU(const Position &pos, const ChannelType _chType);
  TransformUnit  *getTU(const Position &pos, const ChannelType _chType, const int subTuIdx = -1);
  //获取position处的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中,为了并行编码
  const CodingUnit     *getCURestricted(const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType) const;
  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 pu tu 
  CodingUnit&     addCU(const UnitArea &unit, const ChannelType _chType);
  PredictionUnit& addPU(const UnitArea &unit, const ChannelType _chType);
  TransformUnit&  addTU(const UnitArea &unit, const ChannelType _chType);
  void            addEmptyTUs(Partitioner &partitioner); 
	//遍历 unitarea 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;
  // ---------------------------------------------------------------------------
  // encoding search utilities  编码rd搜索相关参数和方法
  // ---------------------------------------------------------------------------

  static_vector<double, NUM_ENC_FEATURES> features;   //enum EncModeFeature

  double      cost;
  bool        useDbCost;
  double      costDbOffset;
  double      lumaCost; //亮度代价
  uint64_t      fracBits;
  Distortion  dist;
  Distortion  interHad;
  TreeType    treeType; //because partitioner can not go deep to tu and cu coding (e.g., addCU()), need another variable for indicating treeType
  ModeType    modeType;
//clear所有数据信号buf和编码信息
  void initStructData  (const int &QP = MAX_INT, const bool &skipMotBuf = false);
  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, const bool updateCost);
  void useSubStructure (const CodingStructure& cs, const ChannelType chType,                          const bool cpyPred, const bool cpyReco, const bool cpyOrgResi, const bool cpyResi, const bool updateCost) { useSubStructure(cs, chType, cs.area, cpyPred, cpyReco, cpyOrgResi, cpyResi, updateCost); }
// 清空编码信息
  void clearTUs();
  void clearPUs();
  void clearCUs();
  const int signalModeCons( const PartSplit split, Partitioner &partitioner, const ModeType modeTypeParent ) const;
  void clearCuPuTuIdxMap  ( const UnitArea &_area, uint32_t numCu, uint32_t numPu, uint32_t numTu, uint32_t* pOffset );
  void getNumCuPuTuOffset ( uint32_t* pArray )
  {
    pArray[0] = m_numCUs;     pArray[1] = m_numPUs;     pArray[2] = m_numTUs;
    pArray[3] = m_offsets[0]; pArray[4] = m_offsets[1]; pArray[5] = m_offsets[2];
  }


private:
  void createInternals(const UnitArea& _unit, const bool isTopLayer, const bool isPLTused);// 预分配空间,并清空数据

public:
// 存放CS中所有cu,pu,tu
  std::vector<    CodingUnit*> cus;
  std::vector<PredictionUnit*> pus;
  std::vector< TransformUnit*> tus;

  LutMotionCand motionLut;

  void addMiToLut(static_vector<MotionInfo, MAX_NUM_HMVP_CANDS>& lut, const MotionInfo &mi);

  PLTBuf prevPLT;
  void resetPrevPLT(PLTBuf& prevPLT);
  void reorderPrevPLT(PLTBuf& prevPLT, uint8_t curPLTSize[MAX_NUM_CHANNEL_TYPE], Pel curPLT[MAX_NUM_COMPONENT][MAXPLTSIZE], bool reuseflag[MAX_NUM_CHANNEL_TYPE][MAXPLTPREDSIZE], uint32_t compBegin, uint32_t numComp, bool jointPLT);
  void setPrevPLT(PLTBuf predictor);
  void storePrevPLT(PLTBuf& predictor);
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;

  PelStorage m_pred;
  PelStorage m_resi;
  PelStorage m_reco;
  PelStorage m_orgr;

  TCoeff *m_coeffs [ MAX_NUM_COMPONENT ];
  Pel    *m_pcmbuf [ MAX_NUM_COMPONENT ];
  bool   *m_runType[ MAX_NUM_CHANNEL_TYPE ];
  int     m_offsets[ MAX_NUM_COMPONENT ];

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

public:
  CodingStructure *bestParent;
  double        tmpColorSpaceCost;
  bool          firstColorSpaceSelected;
  double        tmpColorSpaceIntraCost[2];
  bool          firstColorSpaceTestOnly;
  bool resetIBCBuffer;

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

  const CMotionBuf getMotionBuf( const     Area& _area ) const;
  const CMotionBuf getMotionBuf( const UnitArea& _area ) const { return getMotionBuf( _area.Y() // UnitArea的亮度的area的motion field); }
  const CMotionBuf getMotionBuf()                        const { return getMotionBuf(  area.Y() );// cs的motion field }

  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;
         PelUnitBuf&  getRecoBufRef() { return m_reco; }

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

struct Picture : public UnitArea
{
  uint32_t margin;
  Picture();

  void create( const ChromaFormat &_chromaFormat, const Size &size, const unsigned _maxCUSize, const unsigned margin, const bool bDecoder, const int layerId, const bool gopBasedTemporalFilterEnabled = false );
  void destroy();

  void createTempBuffers( const unsigned _maxCUSize );
  void destroyTempBuffers();

         PelBuf     getOrigBuf(const CompArea &blk);
  const CPelBuf     getOrigBuf(const CompArea &blk) const;
         PelUnitBuf getOrigBuf(const UnitArea &unit);
  const CPelUnitBuf getOrigBuf(const UnitArea &unit) const;
         PelUnitBuf getOrigBuf();
  const CPelUnitBuf getOrigBuf() const;
         PelBuf     getOrigBuf(const ComponentID compID);
  const CPelBuf     getOrigBuf(const ComponentID compID) const;
         PelUnitBuf getTrueOrigBuf();
  const CPelUnitBuf getTrueOrigBuf() const;
        PelBuf      getTrueOrigBuf(const CompArea &blk);
  const CPelBuf     getTrueOrigBuf(const CompArea &blk) const;

         PelUnitBuf getFilteredOrigBuf();
  const CPelUnitBuf getFilteredOrigBuf() const;
         PelBuf     getFilteredOrigBuf(const CompArea &blk);
  const CPelBuf     getFilteredOrigBuf(const CompArea &blk) const;

         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 ComponentID compID, bool wrap=false);
  const CPelBuf     getRecoBuf(const ComponentID compID, bool wrap=false) const;
         PelBuf     getRecoBuf(const CompArea &blk, bool wrap=false);
  const CPelBuf     getRecoBuf(const CompArea &blk, bool wrap=false) const;
         PelUnitBuf getRecoBuf(const UnitArea &unit, bool wrap=false);
  const CPelUnitBuf getRecoBuf(const UnitArea &unit, bool wrap=false) const;
         PelUnitBuf getRecoBuf(bool wrap=false);
  const CPelUnitBuf getRecoBuf(bool wrap=false) const;

         PelBuf     getBuf(const ComponentID compID, const PictureType &type);
  const CPelBuf     getBuf(const ComponentID compID, const PictureType &type) const;
         PelBuf     getBuf(const CompArea &blk,      const PictureType &type);
  const CPelBuf     getBuf(const CompArea &blk,      const PictureType &type) const;
         PelUnitBuf getBuf(const UnitArea &unit,     const PictureType &type);
  const CPelUnitBuf getBuf(const UnitArea &unit,     const PictureType &type) const;

  void extendPicBorder( const PPS *pps );
  void extendWrapBorder( const PPS *pps );
  void finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHeader *picHeader, APS** alfApss, APS* lmcsAps, APS* scalingListAps );

  int  getPOC()                               const { return poc; }
  int  getDecodingOrderNumber()               const { return m_decodingOrderNumber; }
  void setDecodingOrderNumber(const int val)        { m_decodingOrderNumber = val;  }
  NalUnitType getPictureType()                const { return m_pictureType;         }
  void setPictureType(const NalUnitType val)        { m_pictureType = val;          }
  void setBorderExtension( bool bFlag)              { m_bIsBorderExtended = bFlag;}
  Pel* getOrigin( const PictureType &type, const ComponentID compID ) const;

  void setLossyQPValue(int i)                 { m_lossyQP = i; }
  int getLossyQPValue()                       const { return m_lossyQP; }
  void      fillSliceLossyLosslessArray(std::vector<uint16_t> sliceLosslessArray, bool mixedLossyLossless);
  bool      losslessSlice(uint32_t sliceIdx)  const { return m_lossylosslessSliceArray[sliceIdx]; }

  int           getSpliceIdx(uint32_t idx) const { return m_spliceIdx[idx]; }
  void          setSpliceIdx(uint32_t idx, int poc) { m_spliceIdx[idx] = poc; }
  void          createSpliceIdx(int nums);
  bool          getSpliceFull();
  static void   sampleRateConv( const std::pair<int, int> scalingRatio, const std::pair<int, int> compScale,
                                const CPelBuf& beforeScale, const int beforeScaleLeftOffset, const int beforeScaleTopOffset,
                                const PelBuf& afterScale, const int afterScaleLeftOffset, const int afterScaleTopOffset,
                                const int bitDepth, const bool useLumaFilter, const bool downsampling,
                                const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag );

  static void   rescalePicture( const std::pair<int, int> scalingRatio,
                                const CPelUnitBuf& beforeScaling, const Window& scalingWindowBefore,
                                const PelUnitBuf& afterScaling, const Window& scalingWindowAfter,
                                const ChromaFormat chromaFormatIDC, const BitDepths& bitDepths, const bool useLumaFilter, const bool downsampling,
                                const bool horCollocatedChromaFlag, const bool verCollocatedChromaFlag );

private:
  Window        m_conformanceWindow;
  Window        m_scalingWindow;
  int           m_decodingOrderNumber;
  NalUnitType   m_pictureType;

public:
  bool m_isSubPicBorderSaved;

  PelStorage m_bufSubPicAbove;
  PelStorage m_bufSubPicBelow;
  PelStorage m_bufSubPicLeft;
  PelStorage m_bufSubPicRight;

  PelStorage m_bufWrapSubPicAbove;
  PelStorage m_bufWrapSubPicBelow;

  void    saveSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight);
  void  extendSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight);
  void restoreSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight);

  bool getSubPicSaved()          { return m_isSubPicBorderSaved; }
  void setSubPicSaved(bool bVal) { m_isSubPicBorderSaved = bVal; }
  bool m_bIsBorderExtended;
  bool m_wrapAroundValid;
  unsigned m_wrapAroundOffset;
  bool referenced;
  bool reconstructed;
  bool neededForOutput;
  bool usedByCurr;
  bool longTerm;
  bool topField;
  bool fieldPic;
  int  m_prevQP[MAX_NUM_CHANNEL_TYPE];
  bool precedingDRAP; // preceding a DRAP picture in decoding order
  bool nonReferencePictureFlag;

  int  poc;
  uint32_t temporalId;
  int      layerId;
  std::vector<SubPic> subPictures;
  int numSlices;
  std::vector<int> sliceSubpicIdx;

  bool subLayerNonReferencePictureDueToSTSA;

  int* m_spliceIdx;
  int  m_ctuNums;
  int m_lossyQP;
  std::vector<bool> m_lossylosslessSliceArray;
  bool interLayerRefPicFlag;


#if ENABLE_SPLIT_PARALLELISM
  PelStorage m_bufs[PARL_SPLIT_MAX_NUM_JOBS][NUM_PIC_TYPES];
#else
  PelStorage m_bufs[NUM_PIC_TYPES];
#endif
  const Picture*           unscaledPic;

  TComHash           m_hashMap;
  TComHash*          getHashMap() { return &m_hashMap; }
  const TComHash*    getHashMap() const { return &m_hashMap; }
  void               addPictureToHashMapForInter();

  CodingStructure*   cs;
  std::deque<Slice*> slices;
  SEIMessages        SEIs;

  uint32_t           getPicWidthInLumaSamples() const                                { return  getRecoBuf( COMPONENT_Y ).width; }
  uint32_t           getPicHeightInLumaSamples() const                               { return  getRecoBuf( COMPONENT_Y ).height; }
  Window&            getConformanceWindow()                                          { return  m_conformanceWindow; }
  const Window&      getConformanceWindow() const                                    { return  m_conformanceWindow; }
  Window&            getScalingWindow()                                              { return  m_scalingWindow; }
  const Window&      getScalingWindow()                                        const { return  m_scalingWindow; }
  bool               isRefScaled( const PPS* pps ) const                             { return  unscaledPic->getPicWidthInLumaSamples()    != pps->getPicWidthInLumaSamples()                ||
                                                                                               unscaledPic->getPicHeightInLumaSamples()   != pps->getPicHeightInLumaSamples()               ||
                                                                                               getScalingWindow().getWindowLeftOffset()   != pps->getScalingWindow().getWindowLeftOffset()  ||
                                                                                               getScalingWindow().getWindowRightOffset()  != pps->getScalingWindow().getWindowRightOffset() ||
                                                                                               getScalingWindow().getWindowTopOffset()    != pps->getScalingWindow().getWindowTopOffset()   ||
                                                                                               getScalingWindow().getWindowBottomOffset() != pps->getScalingWindow().getWindowBottomOffset(); }
  bool               isWrapAroundEnabled( const PPS* pps ) const                     { return  pps->getWrapAroundEnabledFlag() && !isRefScaled( pps ); }

  void         allocateNewSlice();
  Slice        *swapSliceObject(Slice * p, uint32_t i);
  void         clearSliceBuffer();

  MCTSInfo     mctsInfo;
  std::vector<AQpLayer*> aqlayer;

#if !KEEP_PRED_AND_RESI_SIGNALS
private:
  UnitArea m_ctuArea;
#endif

#if ENABLE_SPLIT_PARALLELISM
public:
  void finishParallelPart   ( const UnitArea& ctuArea );
#endif
#if ENABLE_SPLIT_PARALLELISM
public:
  Scheduler                  scheduler;
#endif

public:
  SAOBlkParam    *getSAO(int id = 0)                        { return &m_sao[id][0]; };
  void            resizeSAO(unsigned numEntries, int dstid) { m_sao[dstid].resize(numEntries); }
  void            copySAO(const Picture& src, int dstid)    { std::copy(src.m_sao[0].begin(), src.m_sao[0].end(), m_sao[dstid].begin()); }

#if ENABLE_QPA
  std::vector<double>     m_uEnerHpCtu;                         ///< CTU-wise L2 or squared L1 norm of high-passed luma input
  std::vector<Pel>        m_iOffsetCtu;                         ///< CTU-wise DC offset (later QP index offset) of luma input
 #if ENABLE_QPA_SUB_CTU
  std::vector<int8_t>     m_subCtuQP;                           ///< sub-CTU-wise adapted QPs for delta-QP depth of 1 or more
 #endif
#endif

  std::vector<SAOBlkParam> m_sao[2];

  std::vector<uint8_t> m_alfCtuEnableFlag[MAX_NUM_COMPONENT];
  uint8_t* getAlfCtuEnableFlag( int compIdx ) { return m_alfCtuEnableFlag[compIdx].data(); }
  std::vector<uint8_t>* getAlfCtuEnableFlag() { return m_alfCtuEnableFlag; }
  void resizeAlfCtuEnableFlag( int numEntries )
  {
    for( int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++ )
    {
      m_alfCtuEnableFlag[compIdx].resize( numEntries );
      std::fill( m_alfCtuEnableFlag[compIdx].begin(), m_alfCtuEnableFlag[compIdx].end(), 0 );
    }
  }
  std::vector<short> m_alfCtbFilterIndex;
  short* getAlfCtbFilterIndex() { return m_alfCtbFilterIndex.data(); }
  std::vector<short>& getAlfCtbFilterIndexVec() { return m_alfCtbFilterIndex; }
  void resizeAlfCtbFilterIndex(int numEntries)
  {
    m_alfCtbFilterIndex.resize(numEntries);
    for (int i = 0; i < numEntries; i++)
    {
      m_alfCtbFilterIndex[i] = 0;
    }
  }
  std::vector<uint8_t> m_alfCtuAlternative[MAX_NUM_COMPONENT];
  std::vector<uint8_t>& getAlfCtuAlternative( int compIdx ) { return m_alfCtuAlternative[compIdx]; }
  uint8_t* getAlfCtuAlternativeData( int compIdx ) { return m_alfCtuAlternative[compIdx].data(); }
  void resizeAlfCtuAlternative( int numEntries )
  {
    for( int compIdx = 1; compIdx < MAX_NUM_COMPONENT; compIdx++ )
    {
      m_alfCtuAlternative[compIdx].resize( numEntries );
      std::fill( m_alfCtuAlternative[compIdx].begin(), m_alfCtuAlternative[compIdx].end(), 0 );
    }
  }
};

编码结构codingstructure:

为了便于管理,新增了一个类CodingStructure把一帧中的CU全都放在了这里,这样对CU的操作变得更加方便,可以直接通过坐标来取得所要的CU

  1. 包含CodingUnit等。实例化并映射它们到picture上
  2. TComDataCU的替换,但全局分配
    顶层编码结构包含帧中的所有CU、PU和TU信息
    子级编码结构包含一个特定单位区域的表示
  3. 创建之后,它是空的,需要被填充
    addCU/PU/TU方法创建并映射特定的对象
    getCU/PU/TU获取使用全局位置寻址的特定对象
  4. 动态分配所需的资源
    使用dynamic_cache(动态缓存)提高性能

codingStructure中的几个操作:
area:unit area——描述编码结构跨越图片中的哪个区域
addCU(UnitArea)-创建并定位一个跨越UnitArea的编码单元
getCU(Position)–返回位于指定位置的编码单位
(PredictionUnit, TransformUnit有模拟接口)
set decomp(CompArea)–将指定的CompArea设置为重建的
set decomp(UnitArea)-模拟多通道操作
is decomp(Position)-告知该位置的重建信号是否已生成

initStructData(…)–清除当前包含的所有数据(信号和编码信息)
init substructure(…)–在层次结构的底部链接新的编码结构
use substructure(…)–从子结构中复制编码数据
copy structure(…)–从另一个结构复制编码数据,不依赖于父子绑定

codingstructure 的 rdcost过程

通过codingstruture的分层级联搜索:
best-temp搜索方案。
codingstructure在一个局部的区域建立,访问UnitArea之外需要返回上层的cs。
cs1是cs2的父节点,父节点不知道子节点,但是最好的子节点将传递给父节点。
通过cs2访问(32,32)位置的CU,直接就返回cu2这个cu单元。
在这里插入图片描述
而想要获取非cs2所在的area的cu,可以通过父节点cs1,最后返回[16,32]的cu单元。
在这里插入图片描述
想要通过cs1父节点访问子节点位置的cu,访问不到,只能返回null。
在这里插入图片描述

partitioner

  1. 一个简单的类管理分裂(CU和TU,四叉树和MTT)
  2. 建模为一个堆栈——在当前处理的区域上创建新的拆分作为拆分级别
  3. 比较于HEVC
    包含当前拆分信息的访问器(partitioner.curr*)
    深度(CU,TU)以及实际的当前UnitArea
  4. 对于QTBT和其他(除HEVC功能外)
    允许设置分割限制(例如,特定级别的约束分割)
    允许执行分割合理性检查(canSplit)
    // 需提前了解其他数据结构
typedef std::vector <UnitArea> Partitioning;//最划分区数,>=4
struct PartLevel
{//划分的级别结构体,包含
  PartSplit    split; //划分的方式
  Partitioning parts; //
  unsigned     idx;  //处理到当前子块的编号
  bool         checkdIfImplicit;
  bool         isImplicit;
  PartSplit    implicitSplit;
  PartSplit    firstSubPartSplit;
  bool         canQtSplit;  //是否可以四叉树划分
  bool         qgEnable; //qg?
  bool         qgChromaEnable;
  int          modeType;  //模式的类型
//构造
  PartLevel();
  PartLevel( const PartSplit _split, const Partitioning&  _parts );
  PartLevel( const PartSplit _split,       Partitioning&& _parts );
};
typedef static_vector<PartLevel, 2 * MAX_CU_DEPTH + 1> PartitioningStack; //PartLevel的堆栈,二维数组 ,存放ctu不同级别的块划分树 static const int MAX_CU_DEPTH =                                     7; ///< log2(CTUSize)
class Partitioner
{//partitioner用于记录ctu递归中的划分树,通过堆栈记录ctu的划分树,
protected:
  PartitioningStack m_partStack; //划分块的栈, 记录每一层划分树的情况
#if _DEBUG
  UnitArea          m_currArea;//当前处理的区域
#endif

public:
  unsigned currDepth; //当前划分的深度,总的吧
  unsigned currQtDepth;//当前qt的深度
  unsigned currTrDepth;//tu深度
  unsigned currBtDepth;//btshendu 
  unsigned currMtDepth;//当前mtt的深度
  unsigned currSubdiv; //
  Position currQgPos;
  Position currQgChromaPos;

  unsigned currImplicitBtDepth; 
  ChannelType chType; 
  TreeType treeType; //树类型
  ModeType modeType; 

  virtual ~Partitioner                    () { }
  //一些堆栈的操作:
  const PartLevel& currPartLevel          () const { return m_partStack.back(); }//出栈?当前的等级
  const UnitArea&  currArea               () const { return currPartLevel().parts[currPartIdx()]; }
  const unsigned   currPartIdx            () const { return currPartLevel().idx; }
  const PartitioningStack& getPartStack   () const { return m_partStack; }//返回树划分堆栈
  const bool currQgEnable                 () const { return currPartLevel().qgEnable; }
  const bool currQgChromaEnable           () const { return currPartLevel().qgChromaEnable; }
//typedef       uint64_t          SplitSeries;       ///< used to encoded the splits that caused a particular CU size
//typedef       uint64_t          ModeTypeSeries;    ///< used to encoded the ModeType at different split depth
  SplitSeries getSplitSeries              () const;//声明获取划分列表
  ModeTypeSeries getModeTypeSeries        () const;

  virtual void initCtu                    ( const UnitArea& ctuArea, const ChannelType _chType, const Slice& slice )    = 0;
  virtual void splitCurrArea              ( const PartSplit split, const CodingStructure &cs )                          = 0;
  virtual void exitCurrSplit              ()                                                                            = 0;
  virtual bool nextPart                   ( const CodingStructure &cs, bool autoPop = false )                           = 0;
  virtual bool hasNextPart                ()                                                                            = 0;

  virtual void setCUData                  ( CodingUnit& cu );

  virtual void copyState                  ( const Partitioner& other );

public:
  virtual void canSplit                   ( const CodingStructure &cs, bool& canNo, bool& canQt, bool& canBh, bool& canBv, bool& canTh, bool& canTv ) = 0;
  virtual bool canSplit                   ( const PartSplit split,                          const CodingStructure &cs ) = 0;
  virtual bool isSplitImplicit            ( const PartSplit split,                          const CodingStructure &cs ) = 0;
  virtual PartSplit getImplicitSplit      (                                                 const CodingStructure &cs ) = 0;
  bool isSepTree                          ( const CodingStructure &cs );
  bool isLocalSepTree                     ( const CodingStructure &cs );
  bool isConsInter                        () { return modeType == MODE_TYPE_INTER; }
  bool isConsIntra                        () { return modeType == MODE_TYPE_INTRA; }
};

所有权

每个数据块都由某个对象拥有,该对象需要分配和释放它

由EncLib或DecLib拥有
拥有信号缓冲区、切片对象、SEI消息和TileMap
AreaBuf,UnitBuf
不拥有任何数据
像素存储
可能拥有缓冲区(取决于create或createFromBuf是否用于创建)
拥有的数据存储在m_origin成员中

编码结构
顶层:归图片所有
链接到图片的信号缓冲区,不拥有它们
其他(RD-Search中的临时):归EncCu或IntraSearch所有
包含自己的信号缓冲器,拥有它们
总是拥有描述结构和布局的缓冲区(不是信号)
拥有变换系数缓冲器
不拥有CodingUnit等。,只通过dynamic_cache链接到它们

编码单元,预测单元,转换单元
归dynamic_cache所有–对象需要由get获取,由cache释放
变压器单元
不拥有变换系数缓冲器
从编码结构到缓冲区的链接
动态缓存
顶层缓存是全局的(在运行时动态分配,在退出时释放)
RD-搜索缓存归EncCu和IntraSearch所有

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:09:20  更:2022-04-27 11:09:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 22:53:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码