TComPicYuv、TComPic、TComPicSym、TComDataCU以及TComYuv的关系
转载https://blog.csdn.net/nb_vol_1/article/details/71173023
首先用一张图来描述它们之间的关系
1、HM首先使用TComPicYuv保存从文件中读取出来的YUV数据
2、利用TComPicYuv构造TComPic,并把YUV数据复制给他(TComPic包含了TComPicYuv成员)
3、TComPic表示一帧图像,包含了数据(TComPicYuv),以及图像信息(TComPicSym,在TComPicSym中还包含了TComDataCU)
4、TComPic被放入图像队列中
5、处理图像队列中的每一个TComPic,实际是处理TComPic中的每一个CTU/CU(存放在TComPicSym中)
6、从TComPic中取出每一个CTU(用TComDataCU表示),调用xCompressCU进行处理
7、根据原始的CTU初始化TEncCu中的TComDataCU(最优的和临时的),这两个在编码的时候会使用
8、把TComPic的数据复制给TComYuv对象,表示编码过程中的数据(原始,预测、残差、重建等)
9、进行编码,tempCU用于编码过程中,bestCU用于保存最优信息
10、产生的最优信息会被复制回TComPicSym中
TComPicYuv
TComPicYuv表示图像的YUV数据
- class TComPicYuv
- {
- private:
- Pel* m_apiPicBufY; // 三个颜色分量的缓冲区,包括了填充的内容
- Pel* m_apiPicBufU;
- Pel* m_apiPicBufV;
- Pel* m_piPicOrgY; // 三个颜色分量的起始地址,由m_apiPicBufY计算得到
- Pel* m_piPicOrgU;
- Pel* m_piPicOrgV;
- Int m_iPicWidth; // 图像的宽和高
- Int m_iPicHeight;
- Int m_iCuWidth; // LCU的宽和高
- Int m_iCuHeight;
- Int* m_cuOffsetY; // 每个CTU中三个颜色分量的偏移地址
- Int* m_cuOffsetC;
- Int* m_buOffsetY; // CTU中每个4x4分量的偏移地址
- Int* m_buOffsetC;
- Int m_iLumaMarginX; // Y分量的填充宽度和高度,如果图像的尺寸不是LCU的整数倍,那么需要填充
- Int m_iLumaMarginY;
- Int m_iChromaMarginX; // U、V分量的填充高度和宽度
- Int m_iChromaMarginY;
- Bool m_bIsBorderExtended; // 是否需要填充图像
- };
TComPic
TComPic表示一张图像,它包含数据(TComPicYuv)和信息(TComPicSym)
- class TComPic
- {
- private:
- UInt m_uiTLayer; // 时域层
- Bool m_bUsedByCurr; // 是否被作为参考帧
- Bool m_bIsLongTerm; // 是否为长参考图像
- TComPicSym* m_apcPicSym; // 图像的信息
- TComPicYuv* m_apcPicYuv[2]; // 图像的数据(索引0是原始图像,索引1是重建图像)
- TComPicYuv* m_pcPicYuvPred; // 图像的预测数据
- TComPicYuv* m_pcPicYuvResi; // 图像的残差数据
- Bool m_bReconstructed; // 是否被重建
- Bool m_bNeededForOutput; // 是否需要输出
- UInt m_uiCurrSliceIdx; // 在此图像中,当前条带的索引
- Bool m_bCheckLTMSB; // 没啥用
- Int m_numReorderPics[MAX_TLAYER]; // 每一层重排的图像的个数
- Window m_conformanceWindow; // 一致性窗口,用于输出
- Window m_defaultDisplayWindow; // 默认显示的窗口
- bool m_isTop; // 顶场还是底场
- bool m_isField; // 帧还是场
- // 条带的CU链表,即:
- // 每一个slice中有若干LCU,每一个LCU又被细分为各个CU
- // std::vector<TComDataCU*>就是存放LCU的CU
- // 没有用到,因为CTU的相关信息存放在TComPicSym中
- std::vector<std::vector<TComDataCU*> > m_vSliceCUDataLink;
- // 增强信息
- SEIMessages m_SEIs; ///< Any SEI messages that have been received. If !NULL we own the object.
- // 其他省略****
- };
TComPicSym
TComPicSym表示图像的信息,它内部有一个TComDataCU数组,描述了图像组每一个LCU(CTU)的信息
- class TComPicSym
- {
- private:
- UInt m_uiWidthInCU; // 图像在横向上有多少个CTU,一般认为LCU就是CTU
- UInt m_uiHeightInCU; // 图像在纵向上有多少个CTU
- UInt m_uiMaxCUWidth; // 最大的CU的尺寸:64x64
- UInt m_uiMaxCUHeight;
- UInt m_uiMinCUWidth; // 最小的CU的尺寸:4x4
- UInt m_uiMinCUHeight;
- UChar m_uhTotalDepth; // LCU可以划分的最大深度:5
- UInt m_uiNumPartitions; // CTU有多少个4x4的块
- UInt m_uiNumPartInWidth; // CTU横向上有几个4x4的块
- UInt m_uiNumPartInHeight; // CTU纵向上有几个4x4的块
- UInt m_uiNumCUsInFrame; // 图像有几个CTU
- TComSlice* m_pcTComSlice; // slice头部信息
- TComDataCU** m_apcTComDataCU; // 表示了每一个CTU,每一个TComDataCU表示CU以及其中所有4x4块的信息
- SAOParam* m_saoParam; // SAO的参数
- // 其他省略***
- };
TComDataCU
TComDataCU表示CU,它本身不存储YUV数据,只包含CU应有的语法元素(包括系数)。TComDataCU存储了CU中所有4x4小块的信息。由于LCU也是CU,因此TComDataCU既能表示LCU也能表示普通CU。
- class TComDataCU
- {
- private:
- TComPic* m_pcPic; // CU所在的图像
- TComSlice* m_pcSlice; // CU所在的条带
- TComPattern* m_pcPattern; // 用于访问临近CU
- UInt m_uiCUAddr; // 在slice中CU的地址
- UInt m_uiAbsIdxInLCU; // 在LCU中Z扫描顺序的地址
- UInt m_uiCUPelX; // 以像素为单位的CU地址
- UInt m_uiCUPelY; // 以像素为单位的CU地址
- UInt m_uiNumPartition; // 当前CU中有多少个4x4的块
- UChar* m_puhWidth; // 存放CU宽度的数组(因为CU会不断分割,每个CU都具有自己的长宽,所以村要存放,这个数组的作用就是这样的)
- UChar* m_puhHeight; // 同上
- UChar* m_puhDepth; // 存放CU深度的数组
- Int m_unitSize; // partition的最小尺寸
- /*
- ** 下面是CU中各种语法元素
- */
- Bool* m_skipFlag; // 跳过标志数组
- Char* m_pePartSize; // 分割的尺寸的数组
- Char* m_pePredMode; // 预测模式的数组
- Bool* m_CUTransquantBypass; // 用于量化
- Char* m_phQP; // 量化步长的数组
- UChar* m_puhTrIdx; // 变换索引的数组
- UChar* m_puhTransformSkip[3];// 变换跳过标志数组
- UChar* m_puhCbf[3]; // 编码块标志数组
- TComCUMvField m_acCUMvField[2]; // 运动估计的数组
- TCoeff* m_pcTrCoeffY; // Y变换系数的数组
- TCoeff* m_pcTrCoeffCb; // U变换系数的数组
- TCoeff* m_pcTrCoeffCr; // V变换系数的数组
- Pel* m_pcIPCMSampleY; // PCM 样本的缓冲区
- Pel* m_pcIPCMSampleCb;
- Pel* m_pcIPCMSampleCr;
- TComDataCU* m_pcCUAboveLeft; ///< pointer of above-left CU 当前CU左上角的CU
- TComDataCU* m_pcCUAboveRight; ///< pointer of above-right CU 当前CU右上角的CU
- TComDataCU* m_pcCUAbove; ///< pointer of above CU 当前CU上面的CU
- TComDataCU* m_pcCULeft; ///< pointer of left CU 当前CU左边的CU
- TComDataCU* m_apcCUColocated[2]; ///< pointer of temporally colocated CU's for both directions CU的变形
- TComMvField m_cMvFieldA; ///< motion vector of position A A位置的运动估计,A/B/C位置是什么?
- TComMvField m_cMvFieldB; ///< motion vector of position B B位置的运动估计
- TComMvField m_cMvFieldC; ///< motion vector of position C C位置的运动估计
- TComMv m_cMvPred; ///< motion vector predictor 运动向量预测
- Bool* m_pbMergeFlag; ///< array of merge flags 合并标志的数组
- UChar* m_puhMergeIndex; ///< array of merge candidate indices 合并候选数组
- #if AMP_MRG
- Bool m_bIsMergeAMP;
- #endif
- UChar* m_puhLumaIntraDir; ///< array of intra directions (luma) // 帧内预测 亮度部分的 方向的数组(因为LCU会分割成很多部分)
- UChar* m_puhChromaIntraDir; ///< array of intra directions (chroma) // 帧内预测 色度部分的 方向的数组
- UChar* m_puhInterDir; ///< array of inter directions // 帧间预测的方向的集合
- Char* m_apiMVPIdx[2]; ///< array of motion vector predictor candidates // 运动向量的候选集
- Char* m_apiMVPNum[2]; // 可能的运动向量的数量的数组
- Bool* m_pbIPCMFlag; // intra_pcm标志的集合
- Bool m_bDecSubCu; // 指出了解码模式
- // RD即拉格朗日率失真,这个成员表示总的失真的代价
- Double m_dTotalCost; // 总的代价
- // 总的失真
- UInt m_uiTotalDistortion; // 总的失真
- // 总的比特数
- UInt m_uiTotalBits; ///< sum of partition bits
- // 总的二进制数
- UInt m_uiTotalBins; ///< sum of partition bins
- UInt* m_sliceStartCU; ///< Start CU address of current slice 当前slice开始CU的地址
- UInt* m_sliceSegmentStartCU; ///< Start CU address of current slice 当前slice开始CU的地址
- Char m_codedQP; // 量化的编码
- };
TComYuv
TComYuv保存了每一个CU对应的YUV数据,原始数据从TComPic中得到(实际从TComPic的TComPicYuv成员中得到)。它主要用于表示编码过程中的原始数据、预测数据、残差数据以及重建数据
- class TComYuv
- {
- private:
- Pel* m_apiBufY; // 颜色分量的起始地址
- Pel* m_apiBufU;
- Pel* m_apiBufV;
- UInt m_iWidth; // CU(可以是LCU,也可以是普通CU)的宽和高
- UInt m_iHeight;
- UInt m_iCWidth; // CU色度分量的尺寸
- UInt m_iCHeight;
- };