VTM3.0代码阅读:CU、PU、TU

喜欢而已 提交于 2019-12-27 03:01:05

VTM中的cu、pu和tu在使用时都是作为CodingStructure类的成员变量来使用的,即作为CS中cus、pus和tus数组中的一个变量来使用的,毕竟VTM中的操作都是以CS作为最基本的类来执行的。
VTM不会像JEM中那样将cu、pu和tu区分起来看待:JEM中在划分完cu后,在处理pu时会有8种划分模式,tu也会根据pu的划分方式有自己的划分。VTM则移除了这种对cu、pu和tu的严格区分,只是将cu、pu和tu视为当前块cs的三种类型的数据,CTU划分树得到cu之后不再进行pu和tu的继续划分了(当然tu会因为变换块的大小关系可能划分为小块)
CU、PU和TU的结构体中包含的数据如下:
( 由于VTM3.0中添加了很多的编码工具,所以cu、pu、tu中所保存记录的信息也有相应的添加。)

struct CodingUnit : public UnitArea
{
  CodingStructure *cs;			//所归属的cs
  Slice *slice;
  ChannelType    chType;

  PredMode       predMode;		//intra、inter
  PartSize       partSize;		//VTM中均为2Nx2N

  uint8_t          depth;      //所有划分模式的depth
  uint8_t          qtDepth;    //QT深度
  // 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; 	//BT深度
  uint8_t          mtDepth;		//TT+BT深度
  int8_t          chromaQpAdj;
  int8_t          qp;			//量化参数
  SplitSeries    splitSeries;	//64位长整数,记录ctu划分树划分到cu时的各个depth的划分模式
  bool           skip;			//是否为skip模式
#if JVET_L0054_MMVD
  bool           mmvdSkip;		//mmvd模式flag
#endif
  bool           affine;		//affine模式flag
  int            affineType;	//affine模式类型,4/6参数
#if JVET_L0124_L0208_TRIANGLE
  bool           triangle;		//三角预测模式flag
#endif
  bool           transQuantBypass;
  bool           ipcm;			//是否为pcm模式
  uint8_t          imv;			//整数mv
  bool           rootCbf;
#if HEVC_TILES_WPP
  uint32_t           tileIdx;
#endif
  uint8_t          emtFlag;
#if JVET_L0646_GBI
  uint8_t         GBiIdx;		//广义Bi
  int             refIdxBi[2];
#endif
  // needed for fast imv mode decisions
  int8_t          imvNumCand;
#if JVET_L0293_CPR
  bool           cpr;			//CPR模式flag
#endif

  unsigned    idx;			//cu存储在cs中的cus数组中的idx
  CodingUnit *next;			//idx表示在数组中位置,nest指向数组中下一个cu

  PredictionUnit *firstPU;	//cu会记录它的pu和tu
  PredictionUnit *lastPU;	//cu的pu和tu是cs.pus和cs.tus的一段

  TransformUnit *firstTU;
  TransformUnit *lastTU;
	//.....
};
struct IntraPredictionData		//帧内预测数据
{
  uint32_t  intraDir[MAX_NUM_CHANNEL_TYPE];	//帧内预测亮度和色度模式
#if JVET_L0283_MULTI_REF_LINE
  int       multiRefIdx;		//帧内MRL模式的multiRefIdx
#endif
};
struct IntraPredictionData		//帧内预测数据
{
  uint32_t  intraDir[MAX_NUM_CHANNEL_TYPE];	//帧内预测亮度和色度模式
#if JVET_L0283_MULTI_REF_LINE
  int       multiRefIdx;		//帧内MRL模式的multiRefIdx
#endif
};
struct InterPredictionData		//帧间预测数据
{
  bool      mergeFlag;		//是否merge
  uint8_t     mergeIdx;		//mergeidx
#if JVET_L0054_MMVD
  bool           mmvdMergeFlag;		//mmvd模式flag
  uint32_t       mmvdMergeIdx;		//mmvd模式的mergeidx
#endif
  uint8_t     interDir;		//帧间预测方向:1-前向、2-后向、3-双向
  uint8_t     mvpIdx  [NUM_REF_PIC_LIST_01];		//mvp在AMVP列表中的idx
  uint8_t     mvpNum  [NUM_REF_PIC_LIST_01];		//AMVP列表中mvp数目
  Mv        mvd     [NUM_REF_PIC_LIST_01];			//mvd
  Mv        mv      [NUM_REF_PIC_LIST_01];			//mv=mvp+mvd
  int16_t     refIdx  [NUM_REF_PIC_LIST_01];		//参考帧
  MergeType mergeType;							//merge模式类型
  Mv        mvdAffi [NUM_REF_PIC_LIST_01][3];		//Affine模式各控制点的mvd
#if JVET_L0694_AFFINE_LINEBUFFER_CLEANUP
  Mv        mvAffi[NUM_REF_PIC_LIST_01][3];			//Affine模式各控制点的mv
#endif
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
  bool      mhIntraFlag;					//CIIP模式flag
#endif
#if JVET_L0293_CPR		//CPR模式的mv
  Mv        bv;                             // block vector for CPR
  Mv        bvd;                            // block vector difference for CPR
#endif
};
struct PredictionUnit : public UnitArea, public IntraPredictionData, public InterPredictionData
{									//pu直接继承了上面帧内和帧间的数据
  CodingUnit      *cu;		//pu所属的cu
  CodingStructure *cs;		//pu所属的cs
  ChannelType      chType;

  unsigned        idx;		//pu存储在cs中的pus数组中的idx
  PredictionUnit *next;		//cs.pus中指向下一个pu
	//.....
};
struct TransformUnit : public UnitArea
{
  CodingUnit      *cu;		//tu所属的cu
  CodingStructure *cs;
  ChannelType      chType;

  uint8_t        depth;		//tu如果进行划分时的深度
  uint8_t        emtIdx;
  uint8_t        cbf          [ MAX_NUM_TBLOCKS ];	//tu是否已经经过变换量化
  RDPCMMode    rdpcm        [ MAX_NUM_TBLOCKS ];	//pcm模式			 pcm模式是省去求残差、变换和量化
  bool         transformSkip[ MAX_NUM_TBLOCKS ];	//transformSkip模式  TS模式是省去变换
  int8_t        compAlpha    [ MAX_NUM_TBLOCKS ];

  unsigned       idx;		//与cu和pu一样,cs.tus中的位置idx
  TransformUnit *next;
	//.....
private:
  TCoeff *m_coeffs[ MAX_NUM_TBLOCKS ];	//其实这里只是记录当前tu的变换系数的存储位置,tu的变换系数数据存储在cs中。参考addTU函数就能理解
  Pel    *m_pcmbuf[ MAX_NUM_TBLOCKS ];	//pcm模式时的像素buf
};
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!