接下来有关HEVC的文章都是HEVC学习系列的延续,但由于序号偏多,为方便起见,就不再单独编号,直接以讨论内容作为题目了。
要研究CU级的代码,少不了要接触到这么一个类TComDataCU。为了比较顺畅地看代码,对这个类的重要成员自然需要有比较好的认识才行,这就是本文的目的,给大家提供一个共同讨论类中私有成员含义与作用的平台。
class TComDataCU { private: // ------------------------------------------------------------------------------------------------------------------- // class pointers // ------------------------------------------------------------------------------------------------------------------- TComPic* m_pcPic; ///< picture class pointer TComSlice* m_pcSlice; ///< slice header pointer TComPattern* m_pcPattern; ///< neighbour access class pointer // ------------------------------------------------------------------------------------------------------------------- // CU description // ------------------------------------------------------------------------------------------------------------------- UInt m_uiCUAddr; ///< CU address in a slice UInt m_uiAbsIdxInLCU; ///< absolute address in a CU. It's Z scan order UInt m_uiCUPelX; ///< CU position in a pixel (X) UInt m_uiCUPelY; ///< CU position in a pixel (Y) UInt m_uiNumPartition; ///< total number of minimum partitions in a CU UChar* m_puhWidth; ///< array of widths UChar* m_puhHeight; ///< array of heights UChar* m_puhDepth; ///< array of depths Int m_unitSize; ///< size of a "minimum partition" // ------------------------------------------------------------------------------------------------------------------- // CU data // ------------------------------------------------------------------------------------------------------------------- Bool* m_skipFlag; ///< array of skip flags Char* m_pePartSize; ///< array of partition sizes Char* m_pePredMode; ///< array of prediction modes Bool* m_CUTransquantBypass; ///< array of cu_transquant_bypass flags Char* m_phQP; ///< array of QP values UChar* m_puhTrIdx; ///< array of transform indices UChar* m_puhTransformSkip[3];///< array of transform skipping flags UChar* m_puhCbf[3]; ///< array of coded block flags (CBF) TCoeff* m_pcTrCoeffY; ///< transformed coefficient buffer (Y) TCoeff* m_pcTrCoeffCb; ///< transformed coefficient buffer (Cb) TCoeff* m_pcTrCoeffCr; ///< transformed coefficient buffer (Cr) #if ADAPTIVE_QP_SELECTION Int* m_pcArlCoeffY; ///< ARL coefficient buffer (Y) Int* m_pcArlCoeffCb; ///< ARL coefficient buffer (Cb) Int* m_pcArlCoeffCr; ///< ARL coefficient buffer (Cr) Bool m_ArlCoeffIsAliasedAllocation; ///< ARL coefficient buffer is an alias of the global buffer and must not be free()'d static Int* m_pcGlbArlCoeffY; ///< ARL coefficient buffer (Y) static Int* m_pcGlbArlCoeffCb; ///< ARL coefficient buffer (Cb) static Int* m_pcGlbArlCoeffCr; ///< ARL coefficient buffer (Cr) #endif Pel* m_pcIPCMSampleY; ///< PCM sample buffer (Y) Pel* m_pcIPCMSampleCb; ///< PCM sample buffer (Cb) Pel* m_pcIPCMSampleCr; ///< PCM sample buffer (Cr) Int* m_piSliceSUMap; ///< pointer of slice ID map std::vector<NDBFBlockInfo> m_vNDFBlock; // ------------------------------------------------------------------------------------------------------------------- // neighbour access variables // ------------------------------------------------------------------------------------------------------------------- TComDataCU* m_pcCUAboveLeft; ///< pointer of above-left CU TComDataCU* m_pcCUAboveRight; ///< pointer of above-right CU TComDataCU* m_pcCUAbove; ///< pointer of above CU TComDataCU* m_pcCULeft; ///< pointer of left CU TComDataCU* m_apcCUColocated[2]; ///< pointer of temporally colocated CU's for both directions // ------------------------------------------------------------------------------------------------------------------- // coding tool information // ------------------------------------------------------------------------------------------------------------------- UChar* m_puhLumaIntraDir; ///< array of intra directions (luma) UChar* m_puhChromaIntraDir; ///< array of intra directions (chroma) Bool* m_pbIPCMFlag; ///< array of intra_pcm flags Int m_numSucIPCM; ///< the number of succesive IPCM blocks associated with the current log2CUSize Bool m_lastCUSucIPCMFlag; ///< True indicates that the last CU is IPCM and shares the same root as the current CU. // ------------------------------------------------------------------------------------------------------------------- // misc. variables // ------------------------------------------------------------------------------------------------------------------- Bool m_bDecSubCu; ///< indicates decoder-mode Double m_dTotalCost; ///< sum of partition RD costs UInt m_uiTotalDistortion; ///< sum of partition distortion UInt m_uiTotalBits; ///< sum of partition bits UInt m_uiTotalBins; ///< sum of partition bins UInt* m_uiSliceStartCU; ///< Start CU address of current slice UInt* m_uiDependentSliceStartCU; ///< Start CU address of current slice Char m_codedQP;
其实大部分的私有成员都有注释,再结合代码中的具体应用,它们的含义和功能十有八九是能够把握住的。
注意到,在定义这个类的TComDataCU.h文件里的最后,还定义了一个命名空间RasterAddress:
namespace RasterAddress { /** Check whether 2 addresses point to the same column * \param addrA First address in raster scan order * \param addrB Second address in raters scan order * \param numUnitsPerRow Number of units in a row * \return Result of test */ static inline Bool isEqualCol( Int addrA, Int addrB, Int numUnitsPerRow ) { // addrA % numUnitsPerRow == addrB % numUnitsPerRow return (( addrA ^ addrB ) & ( numUnitsPerRow - 1 ) ) == 0; } /** Check whether 2 addresses point to the same row * \param addrA First address in raster scan order * \param addrB Second address in raters scan order * \param numUnitsPerRow Number of units in a row * \return Result of test */ static inline Bool isEqualRow( Int addrA, Int addrB, Int numUnitsPerRow ) { // addrA / numUnitsPerRow == addrB / numUnitsPerRow return (( addrA ^ addrB ) &~ ( numUnitsPerRow - 1 ) ) == 0; } /** Check whether 2 addresses point to the same row or column * \param addrA First address in raster scan order * \param addrB Second address in raters scan order * \param numUnitsPerRow Number of units in a row * \return Result of test */ static inline Bool isEqualRowOrCol( Int addrA, Int addrB, Int numUnitsPerRow ) { return isEqualCol( addrA, addrB, numUnitsPerRow ) | isEqualRow( addrA, addrB, numUnitsPerRow ); } /** Check whether one address points to the first column * \param addr Address in raster scan order * \param numUnitsPerRow Number of units in a row * \return Result of test */ static inline Bool isZeroCol( Int addr, Int numUnitsPerRow ) { // addr % numUnitsPerRow == 0 return ( addr & ( numUnitsPerRow - 1 ) ) == 0; } /** Check whether one address points to the first row * \param addr Address in raster scan order * \param numUnitsPerRow Number of units in a row * \return Result of test */ static inline Bool isZeroRow( Int addr, Int numUnitsPerRow ) { // addr / numUnitsPerRow == 0 return ( addr &~ ( numUnitsPerRow - 1 ) ) == 0; } /** Check whether one address points to a column whose index is smaller than a given value * \param addr Address in raster scan order * \param val Given column index value * \param numUnitsPerRow Number of units in a row * \return Result of test */ static inline Bool lessThanCol( Int addr, Int val, Int numUnitsPerRow ) { // addr % numUnitsPerRow < val return ( addr & ( numUnitsPerRow - 1 ) ) < val; } /** Check whether one address points to a row whose index is smaller than a given value * \param addr Address in raster scan order * \param val Given row index value * \param numUnitsPerRow Number of units in a row * \return Result of test */ static inline Bool lessThanRow( Int addr, Int val, Int numUnitsPerRow ) { // addr / numUnitsPerRow < val return addr < val * numUnitsPerRow; } };
这些个函数的功能,根据函数名,再加上注释,即使可能对实现细节还不是完全清楚,也是可以把握住它们的功能的。这样就足够了,对于读代码已经是没有任何障碍了。至于是否细究细节,这个看个人了。