TComPicYuv、TComPic、TComPicSym、TComDataCU以及TComYuv的關係

TComPicYuv、TComPic、TComPicSym、TComDataCU以及TComYuv的關係


    首先用一張圖來描述它們之間的關係



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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章