H.266/VCコード学習26:VTM 5.0のIntraPredictionクラスとその対応するグローバル関数
83921 ワード
千呼万喚が始まり、VTM 5.0のrc 1バージョンがついにリリースされました.前VTM 4に基づく.0の内容は、すべてのイントラ予測の関数が学習されています.今日はVTM 5を見てみましょう.0におけるイントラ予測の変更は,C++に関連するもの:IntraPredictionクラスの定義にも注目する.
文書ディレクトリ1 IntraPredictionクラス 1.1 private部分(VTM 4.0) VTM5.0変更: 1.2 protected部分(VTM 4.0) VTM5.0変更: 1.3 public部分(VTM 4.0) VTM5.0変更: 2初期化プロセスおよびプロファイルプロセス 3グローバル関数(参照画素が利用可能であるか否か及び利用可能な数を判断する) .
1 IntraPredictionクラス
全体的に、いくつかのイントラ予測プロセスにおけるいくつかの重要なパラメータを格納するために、いくつかのイントラ技術を新たに追加したほか、IntraPredParamクラスも追加した.したがって、新しいバージョンでは、関数のパラメータ数が一定に減少し、コードがより簡素化されたフラグでもあります.
1.1 private部(VTM 4.0)
C++でprivateで主に定義されているのはデータです.ここでは、IntraPredictionクラスのprivateに格納されているのはピクセルキャッシュ値であることがわかります.
VTM5.0変更:
privateではVTM 5.0は以下の2つの部分コードを追加した:1、イントラ予測パラメータ、2、ALWIPマトリクスイントラ予測(深さ学習の方法で訓練してマトリクスパラメータのセットを得て、彼らで予測する)
1.2 protected部分(VTM 4.0)
protectedはサブクラスにとってpublicであり、制限はありません.他の外部classではprotectedがprivateになります.
VTM5.0変更:
protected、VTM 5.0では、イントラ予測のパラメータを1つのクラスで管理し、広い角度モードとフィルタとの統一方法も追加した.
1.3 public部分(VTM 4.0)
VTM5.0変更:
publicでは、VTM 5.0では主にALWIP行列のイントラ予測の具体的な実装を追加した.
2初期化プロセスとプロファイルプロセス
3グローバル関数(参照画素が利用可能か否か及び利用可能数を判断)
グローバル関数はプログラム全体で使用され、これらの関数はプログラム全体のどこでも呼び出されます.つまり、IntraPredictionクラスだけではありません.ここには5つありますが、いずれも参照画素を取得する際に使用されるもので、isAboveLeftAvailable、isLeftAvailable、isLeftAvailable、isAboveRightAvailable、isBelowLeftAvailableです.
このクラスの総括を通じて、前のC++学習に対して1-10は更に強固になったと言えるが、もちろんもっと重要なのは後の仕事がVTM 5になることだ.0の上で展開して、新技術の理解とコードの学習はまた1つの難関で、革命はまだ成功していないで、同志は依然として努力しなければなりません.の
文書ディレクトリ
1 IntraPredictionクラス
全体的に、いくつかのイントラ予測プロセスにおけるいくつかの重要なパラメータを格納するために、いくつかのイントラ技術を新たに追加したほか、IntraPredParamクラスも追加した.したがって、新しいバージョンでは、関数のパラメータ数が一定に減少し、コードがより簡素化されたフラグでもあります.
1.1 private部(VTM 4.0)
C++でprivateで主に定義されているのはデータです.ここでは、IntraPredictionクラスのprivateに格納されているのはピクセルキャッシュ値であることがわかります.
private:
Pel* m_piYuvExt[MAX_NUM_COMPONENT][NUM_PRED_BUF];// , buffer
int m_iYuvExtSize;//
Pel* m_yuvExt2[MAX_NUM_COMPONENT][4];
int m_yuvExtSize2;
static const uint8_t m_aucIntraFilter[MAX_NUM_CHANNEL_TYPE][MAX_INTRA_FILTER_DEPTHS];// ?
Pel* m_piTemp;//
Pel* m_pMdlmTemp; // for MDLM mode MDLM
VTM5.0変更:
privateではVTM 5.0は以下の2つの部分コードを追加した:1、イントラ予測パラメータ、2、ALWIPマトリクスイントラ予測(深さ学習の方法で訓練してマトリクスパラメータのセットを得て、彼らで予測する)
struct IntraPredParam //parameters of Intra Prediction
{
bool refFilterFlag; //
bool applyPDPC; // PDPC
bool isModeVer; // ( 35-66)
int multiRefIndex; //
int whRatio; //
int hwRatio; //
int intraPredAngle;//
int invAngle; //
bool interpolationFlag;
IntraPredParam() : // , IntraPredParam
refFilterFlag ( false ),
applyPDPC ( false ),
isModeVer ( false ),
multiRefIndex ( -1 ),
whRatio ( 0 ),
hwRatio ( 0 ),
intraPredAngle ( std::numeric_limits<int>::max() ),
invAngle ( std::numeric_limits<int>::max() ),
interpolationFlag ( false ) {}
};
IntraPredParam m_ipaParam;// IntraPredParam
#if JVET_N0217_MATRIX_INTRAPRED
MatrixIntraPrediction m_matrixIntraPred;//ALWIP
#endif
1.2 protected部分(VTM 4.0)
protectedはサブクラスにとってpublicであり、制限はありません.他の外部classではprotectedがprivateになります.
protected:
ChromaFormat m_currChromaFormat;//
int m_topRefLength;//
int m_leftRefLength;//
// prediction
void xPredIntraPlanar ( const CPelBuf &pSrc, PelBuf &pDst, const SPS& sps );//PLANAR
void xPredIntraDc ( const CPelBuf &pSrc, PelBuf &pDst, const ChannelType channelType, const bool enableBoundaryFilter = true );//DC
#if HEVC_USE_HOR_VER_PREDFILTERING
void xPredIntraAng ( const CPelBuf &pSrc, PelBuf &pDst, const ChannelType channelType, const uint32_t dirMode, const ClpRng& clpRng, const bool bEnableEdgeFilters, const SPS& sps
, int multiRefIdx
, const bool enableBoundaryFilter = true );
#else
#if JVET_M0102_INTRA_SUBPARTITIONS
void xPredIntraAng ( const CPelBuf &pSrc, PelBuf &pDst, const ChannelType channelType, const uint32_t dirMode, const ClpRng& clpRng, const SPS& sps,
int multiRefIdx,
const bool useFilteredPredSamples,
const bool useISP = false,
const Size cuSize = Size( 0, 0 ) );//
#else
void xPredIntraAng ( const CPelBuf &pSrc, PelBuf &pDst, const ChannelType channelType, const uint32_t dirMode, const ClpRng& clpRng, const SPS& sps
, int multiRefIdx
, const bool useFilteredPredSamples );
#endif
#endif
Pel xGetPredValDc ( const CPelBuf &pSrc, const Size &dstSize );// DC
void xFillReferenceSamples ( const CPelBuf &recoBuf, Pel* refBufUnfiltered, const CompArea &area, const CodingUnit &cu );//
void xFilterReferenceSamples ( const Pel* refBufUnfiltered, Pel* refBufFiltered, const CompArea &area, const SPS &sps//
, int multiRefIdx
);
#if HEVC_USE_DC_PREDFILTERING
// dc filtering
void xDCPredFiltering ( const CPelBuf &pSrc, PelBuf &pDst, const ChannelType &channelType );
#endif
static int getWideAngle ( int width, int height, int predMode );// : ,
void setReferenceArrayLengths ( const CompArea &area );//
void destroy ();//
void xFilterGroup ( Pel* pMulDst[], int i, Pel const* const piSrc, int iRecStride, bool bAboveAvaillable, bool bLeftAvaillable);//
void xGetLMParameters(const PredictionUnit &pu, const ComponentID compID, const CompArea& chromaArea, int& a, int& b, int& iShift);// LM
VTM5.0変更:
protected、VTM 5.0では、イントラ予測のパラメータを1つのクラスで管理し、広い角度モードとフィルタとの統一方法も追加した.
void initPredIntraParams ( const PredictionUnit & pu, const CompArea compArea, const SPS& sps );//
#if JVET_N0435_WAIP_HARMONIZATION
static bool isIntegerSlope(const int absAng) { return (0 == (absAng & 0x1F)); }//
#else
static bool isIntegerSlope ( const int absAng ) { return (0 == (absAng & 0x1F)) && absAng <=32; } // integer-slope modes 2, DIA_IDX and VDIA_IDX. "absAng <=32" restricts wide-angle integer modes
#endif
#if JVET_N0413_RDPCM
void xPredIntraBDPCM ( const CPelBuf &pSrc, PelBuf &pDst, const uint32_t dirMode, const ClpRng& clpRng );// RDPCM
#endif
1.3 public部分(VTM 4.0)
public:
IntraPrediction();//
virtual ~IntraPrediction();//
void init (ChromaFormat chromaFormatIDC, const unsigned bitDepthY);//
// Angular Intra
void predIntraAng ( const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu, const bool useFilteredPredSamples );
#if JVET_M0043_LWIP_MEMOPT
void predIntraLwip ( const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu );
#endif
Pel* getPredictorPtr (const ComponentID compID, const bool bUseFilteredPredictions = false) { return m_piYuvExt[compID][bUseFilteredPredictions?PRED_BUF_FILTERED:PRED_BUF_UNFILTERED]; }//
// Cross-component Chroma
void predIntraChromaLM(const ComponentID compID, PelBuf &piPred, const PredictionUnit &pu, const CompArea& chromaArea, int intraDir);//LM
void xGetLumaRecPixels(const PredictionUnit &pu, CompArea chromaArea);// LM
/// set parameters from CU data for accessing intra data
void initIntraPatternChType (const CodingUnit &cu, const CompArea &area, const bool bFilterRefSamples = false );//
static bool useFilteredIntraRefSamples( const ComponentID &compID, const PredictionUnit &pu, bool modeSpecific, const UnitArea &tuArea );// ?
static bool useDPCMForFirstPassIntraEstimation(const PredictionUnit &pu, const uint32_t &uiDirMode);
void geneWeightedPred (const ComponentID compId, PelBuf &pred, const PredictionUnit &pu, Pel *srcBuf);
Pel* getPredictorPtr2 (const ComponentID compID, uint32_t idx) { return m_yuvExt2[compID][idx]; }
void switchBuffer (const PredictionUnit &pu, ComponentID compID, PelBuf srcBuff, Pel *dst);
void geneIntrainterPred (const CodingUnit &cu);
#if JVET_M0043_LWIP_MEMOPT
void prepareBlockLwip ( const PredictionUnit &pu );
#endif
VTM5.0変更:
publicでは、VTM 5.0では主にALWIP行列のイントラ予測の具体的な実装を追加した.
#if JVET_N0217_MATRIX_INTRAPRED
// Matrix-based intra prediction
void initIntraMip (const PredictionUnit &pu);// ALWIP
void predIntraMip (const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu);//
#endif
#if HM_MDIS_AS_IN_JEM && JVET_N0193_LFNST
static bool getPlanarMDISCondition( const UnitArea &tuArea ) { return abs( PLANAR_IDX - HOR_IDX ) > m_aucIntraFilter[ CHANNEL_TYPE_LUMA ][ ( ( g_aucLog2[ tuArea.Y().width ] + g_aucLog2[ tuArea.Y().height ] ) >> 1 ) ]; }
#endif
2初期化プロセスとプロファイルプロセス
// ====================================================================================================================
// Constructor / destructor / initialize
// ====================================================================================================================
IntraPrediction::IntraPrediction()// , nullptr
:
m_currChromaFormat( NUM_CHROMA_FORMAT )//: ,
{
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)//
{
for (uint32_t buf = 0; buf < NUM_PRED_BUF; buf++)//
{
m_piYuvExt[ch][buf] = nullptr;// nullptr
}
}
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)
{
for (uint32_t buf = 0; buf < 4; buf++)
{
m_yuvExt2[ch][buf] = nullptr;
}
}
m_piTemp = nullptr;//
m_pMdlmTemp = nullptr;//MDLM
}
IntraPrediction::~IntraPrediction()// , destroy()
{
destroy();
}
void IntraPrediction::destroy()// ,
{
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)
{
for (uint32_t buf = 0; buf < NUM_PRED_BUF; buf++)
{
delete[] m_piYuvExt[ch][buf];//delete[] new m_piYuvExt[], *m_piYuvExt
m_piYuvExt[ch][buf] = nullptr;
}
}
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)
{
for (uint32_t buf = 0; buf < 4; buf++)
{
delete[] m_yuvExt2[ch][buf];
m_yuvExt2[ch][buf] = nullptr;
}
}
delete[] m_piTemp;
m_piTemp = nullptr;
delete[] m_pMdlmTemp;
m_pMdlmTemp = nullptr;
// , , delete[]
}
void IntraPrediction::init(ChromaFormat chromaFormatIDC, const unsigned bitDepthY)//
{
/************ , , **************/
// if it has been initialised before, but the chroma format has changed, release the memory and start again.
if (m_piYuvExt[COMPONENT_Y][PRED_BUF_UNFILTERED] != nullptr && m_currChromaFormat != chromaFormatIDC)
{
destroy();
}
if (m_yuvExt2[COMPONENT_Y][0] != nullptr && m_currChromaFormat != chromaFormatIDC)
{
destroy();
}
m_currChromaFormat = chromaFormatIDC;
/********************* , ************************/
if (m_piYuvExt[COMPONENT_Y][PRED_BUF_UNFILTERED] == nullptr) // check if first is null (in which case, nothing initialised yet)
{
m_iYuvExtSize = (MAX_CU_SIZE * 2 + 1 + MAX_REF_LINE_IDX * 33) * (MAX_CU_SIZE * 2 + 1 + MAX_REF_LINE_IDX * 33);
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)
{
for (uint32_t buf = 0; buf < NUM_PRED_BUF; buf++)
{
m_piYuvExt[ch][buf] = new Pel[m_iYuvExtSize];
}
}
}
if (m_yuvExt2[COMPONENT_Y][0] == nullptr) // check if first is null (in which case, nothing initialised yet)
{
m_yuvExtSize2 = (MAX_CU_SIZE) * (MAX_CU_SIZE);
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)
{
for (uint32_t buf = 0; buf < 4; buf++)
{
m_yuvExt2[ch][buf] = new Pel[m_yuvExtSize2];
}
}
}
if (m_piTemp == nullptr)
{
m_piTemp = new Pel[(MAX_CU_SIZE + 1) * (MAX_CU_SIZE + 1)];
}
if (m_pMdlmTemp == nullptr)
{
m_pMdlmTemp = new Pel[(2 * MAX_CU_SIZE + 1)*(2 * MAX_CU_SIZE + 1)];//MDLM will use top-above and left-below samples.
}
}
3グローバル関数(参照画素が利用可能か否か及び利用可能数を判断)
グローバル関数はプログラム全体で使用され、これらの関数はプログラム全体のどこでも呼び出されます.つまり、IntraPredictionクラスだけではありません.ここには5つありますが、いずれも参照画素を取得する際に使用されるもので、isAboveLeftAvailable、isLeftAvailable、isLeftAvailable、isAboveRightAvailable、isBelowLeftAvailableです.
/****************** ***************/
bool isAboveLeftAvailable(const CodingUnit &cu, const ChannelType &chType, const Position &posLT)
{
const CodingStructure& cs = *cu.cs;
const Position refPos = posLT.offset(-1, -1);//
const CodingUnit* pcCUAboveLeft = cs.isDecomp( refPos, chType ) ? cs.getCURestricted( refPos, cu, chType ) : nullptr;// , CU,
const bool isConstrained = cs.pps->getConstrainedIntraPred();//
bool bAboveLeftFlag;
if (isConstrained)// : ,
{
bAboveLeftFlag = pcCUAboveLeft && CU::isIntra(*pcCUAboveLeft);
}
else// :
{
bAboveLeftFlag = (pcCUAboveLeft ? true : false);
}
return bAboveLeftFlag;//
}
/****************** ***************/
int isAboveAvailable(const CodingUnit &cu, const ChannelType &chType, const Position &posLT, const uint32_t uiNumUnitsInPU, const uint32_t unitWidth, bool *bValidFlags)
{
const CodingStructure& cs = *cu.cs;
const bool isConstrained = cs.pps->getConstrainedIntraPred();//
bool *pbValidFlags = bValidFlags;//
int iNumIntra = 0;//
int maxDx = uiNumUnitsInPU * unitWidth;
for (uint32_t dx = 0; dx < maxDx; dx += unitWidth)
{
const Position refPos = posLT.offset(dx, -1);//
const CodingUnit* pcCUAbove = cs.isDecomp(refPos, chType) ? cs.getCURestricted(refPos, cu, chType) : nullptr;// , CU,
if( pcCUAbove && ( ( isConstrained && CU::isIntra( *pcCUAbove ) ) || !isConstrained ) )// , +1, true
{
iNumIntra++;// +1
*pbValidFlags = true;//
}
else if( !pcCUAbove )// , ,
{
return iNumIntra;
}
pbValidFlags++;// ( )
}
return iNumIntra;//
}
/*** ***/
/****************** ***************/
int isLeftAvailable(const CodingUnit &cu, const ChannelType &chType, const Position &posLT, const uint32_t uiNumUnitsInPU, const uint32_t unitHeight, bool *bValidFlags)
{
const CodingStructure& cs = *cu.cs;
const bool isConstrained = cs.pps->getConstrainedIntraPred();
bool *pbValidFlags = bValidFlags;
int iNumIntra = 0;
int maxDy = uiNumUnitsInPU * unitHeight;
for (uint32_t dy = 0; dy < maxDy; dy += unitHeight)
{
const Position refPos = posLT.offset(-1, dy);
const CodingUnit* pcCULeft = cs.isDecomp(refPos, chType) ? cs.getCURestricted(refPos, cu, chType) : nullptr;
if( pcCULeft && ( ( isConstrained && CU::isIntra( *pcCULeft ) ) || !isConstrained ) )
{
iNumIntra++;
*pbValidFlags = true;
}
else if( !pcCULeft )
{
return iNumIntra;
}
pbValidFlags--; // opposite direction
}
return iNumIntra;
}
/****************** ***************/
int isAboveRightAvailable(const CodingUnit &cu, const ChannelType &chType, const Position &posRT, const uint32_t uiNumUnitsInPU, const uint32_t unitWidth, bool *bValidFlags )
{
const CodingStructure& cs = *cu.cs;
const bool isConstrained = cs.pps->getConstrainedIntraPred();
bool *pbValidFlags = bValidFlags;
int iNumIntra = 0;
uint32_t maxDx = uiNumUnitsInPU * unitWidth;
for (uint32_t dx = 0; dx < maxDx; dx += unitWidth)
{
const Position refPos = posRT.offset(unitWidth + dx, -1);
const CodingUnit* pcCUAbove = cs.isDecomp(refPos, chType) ? cs.getCURestricted(refPos, cu, chType) : nullptr;
if( pcCUAbove && ( ( isConstrained && CU::isIntra( *pcCUAbove ) ) || !isConstrained ) )
{
iNumIntra++;
*pbValidFlags = true;
}
else if( !pcCUAbove )
{
return iNumIntra;
}
pbValidFlags++;
}
return iNumIntra;
}
/****************** ***************/
int isBelowLeftAvailable(const CodingUnit &cu, const ChannelType &chType, const Position &posLB, const uint32_t uiNumUnitsInPU, const uint32_t unitHeight, bool *bValidFlags )
{
const CodingStructure& cs = *cu.cs;
const bool isConstrained = cs.pps->getConstrainedIntraPred();
bool *pbValidFlags = bValidFlags;
int iNumIntra = 0;
int maxDy = uiNumUnitsInPU * unitHeight;
for (uint32_t dy = 0; dy < maxDy; dy += unitHeight)
{
const Position refPos = posLB.offset(-1, unitHeight + dy);
const CodingUnit* pcCULeft = cs.isDecomp(refPos, chType) ? cs.getCURestricted(refPos, cu, chType) : nullptr;
if( pcCULeft && ( ( isConstrained && CU::isIntra( *pcCULeft ) ) || !isConstrained ) )
{
iNumIntra++;
*pbValidFlags = true;
}
else if ( !pcCULeft )
{
return iNumIntra;
}
pbValidFlags--; // opposite direction
}
return iNumIntra;
}
このクラスの総括を通じて、前のC++学習に対して1-10は更に強固になったと言えるが、もちろんもっと重要なのは後の仕事がVTM 5になることだ.0の上で展開して、新技術の理解とコードの学習はまた1つの難関で、革命はまだ成功していないで、同志は依然として努力しなければなりません.の