H.266/VCコード学習26:VTM 5.0のIntraPredictionクラスとその対応するグローバル関数


千呼万喚が始まり、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に格納されているのはピクセルキャッシュ値であることがわかります.
    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つの難関で、革命はまだ成功していないで、同志は依然として努力しなければなりません.の