From 6027a29d4cf0a3b6f7f80ead3abfa78c2f4dcd11 Mon Sep 17 00:00:00 2001
From: mpeg-china <lizhang.idm@bytedance.com>
Date: Tue, 29 Jan 2019 13:17:53 -0800
Subject: [PATCH] JVET-M0277: Fixes of enabling pcm_loop_filter_disabled_flag
 with PCM mode

---
 source/Lib/CommonLib/AdaptiveLoopFilter.cpp   | 97 ++++++++++++++++++-
 source/Lib/CommonLib/AdaptiveLoopFilter.h     | 29 +++++-
 source/Lib/CommonLib/SampleAdaptiveOffset.cpp | 23 ++++-
 source/Lib/CommonLib/TypeDef.h                |  5 +
 .../Lib/CommonLib/x86/AdaptiveLoopFilterX86.h | 60 +++++++++++-
 source/Lib/EncoderLib/CABACWriter.cpp         | 14 +++
 .../Lib/EncoderLib/EncAdaptiveLoopFilter.cpp  | 22 ++++-
 source/Lib/EncoderLib/EncModeCtrl.cpp         |  8 ++
 8 files changed, 245 insertions(+), 13 deletions(-)

diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
index ed573e04c..7315dfb52 100644
--- a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
+++ b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
@@ -104,7 +104,15 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic
       {
         Area blk( xPos, yPos, width, height );
         deriveClassification( m_classifier, tmpYuv.get( COMPONENT_Y ), blk );
-        m_filter7x7Blk(m_classifier, recYuv, tmpYuv, blk, COMPONENT_Y, m_coeffFinal, m_clpRngs.comp[COMPONENT_Y]);
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+        Area blkPCM(xPos, yPos, width, height);
+        resetPCMBlkClassInfo(cs, m_classifier, tmpYuv.get(COMPONENT_Y), blkPCM);
+#endif
+        m_filter7x7Blk(m_classifier, recYuv, tmpYuv, blk, COMPONENT_Y, m_coeffFinal, m_clpRngs.comp[COMPONENT_Y]
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+          ,cs
+#endif
+        );
       }
 
       for( int compIdx = 1; compIdx < MAX_NUM_COMPONENT; compIdx++ )
@@ -117,7 +125,11 @@ void AdaptiveLoopFilter::ALFProcess( CodingStructure& cs, AlfSliceParam& alfSlic
         {
           Area blk( xPos >> chromaScaleX, yPos >> chromaScaleY, width >> chromaScaleX, height >> chromaScaleY );
 
-          m_filter5x5Blk( m_classifier, recYuv, tmpYuv, blk, compID, alfSliceParam.chromaCoeff, m_clpRngs.comp[compIdx] );
+          m_filter5x5Blk( m_classifier, recYuv, tmpYuv, blk, compID, alfSliceParam.chromaCoeff, m_clpRngs.comp[compIdx]
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+            , cs
+#endif
+          );
         }
       }
       ctuIdx++;
@@ -272,6 +284,57 @@ void AdaptiveLoopFilter::deriveClassification( AlfClassifier** classifier, const
     }
   }
 }
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+void AdaptiveLoopFilter::resetPCMBlkClassInfo(CodingStructure & cs,  AlfClassifier** classifier, const CPelBuf& srcLuma, const Area& blk)
+{
+  if ( !cs.sps->getPCMFilterDisableFlag() )
+  {
+    return;
+  }
+
+  int height = blk.pos().y + blk.height;
+  int width = blk.pos().x + blk.width;
+  const int clsSizeY = 4;
+  const int clsSizeX = 4;
+  int classIdx = m_ALF_UNUSED_CLASSIDX;
+  int transposeIdx = m_ALF_UNUSED_TRANSPOSIDX;
+
+  for( int i = blk.pos().y; i < height; i += m_CLASSIFICATION_BLK_SIZE )
+  {
+    int nHeight = std::min(i + m_CLASSIFICATION_BLK_SIZE, height) - i;
+
+    for( int j = blk.pos().x; j < width; j += m_CLASSIFICATION_BLK_SIZE )
+    {
+      int nWidth = std::min(j + m_CLASSIFICATION_BLK_SIZE, width) - j;
+      int posX = j;
+      int posY = i;
+
+      for( int subi = 0; subi < nHeight; subi += clsSizeY )
+      {
+        for( int subj = 0; subj < nWidth; subj += clsSizeX )
+        {
+          int yOffset = subi + posY;
+          int xOffset = subj + posX;
+          Position pos(xOffset, yOffset);
+
+          const CodingUnit* cu = cs.getCU(pos, CH_L);
+          if ( cu->ipcm )
+          {
+            AlfClassifier *cl0 = classifier[yOffset] + xOffset;
+            AlfClassifier *cl1 = classifier[yOffset + 1] + xOffset;
+            AlfClassifier *cl2 = classifier[yOffset + 2] + xOffset;
+            AlfClassifier *cl3 = classifier[yOffset + 3] + xOffset;
+            cl0[0] = cl0[1] = cl0[2] = cl0[3] =
+            cl1[0] = cl1[1] = cl1[2] = cl1[3] =
+            cl2[0] = cl2[1] = cl2[2] = cl2[3] =
+            cl3[0] = cl3[1] = cl3[2] = cl3[3] = AlfClassifier(classIdx, transposeIdx);
+          }
+        }
+      }
+    }
+  }
+}
+#endif
 
 void AdaptiveLoopFilter::deriveClassificationBlk( AlfClassifier** classifier, int** laplacian[NUM_DIRECTIONS], const CPelBuf& srcLuma, const Area& blk, const int shift )
 {
@@ -445,13 +508,23 @@ void AdaptiveLoopFilter::deriveClassificationBlk( AlfClassifier** classifier, in
 }
 
 template<AlfFilterType filtType>
-void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng )
+void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng 
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  ,CodingStructure& cs
+#endif
+)
 {
   const bool bChroma = isChroma( compId );
   if( bChroma )
   {
     CHECK( filtType != 0, "Chroma needs to have filtType == 0" );
   }
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  const SPS*     sps = cs.slice->getSPS();
+  bool isDualTree =CS::isDualITree(cs);
+  bool isPCMFilterDisabled = sps->getPCMFilterDisableFlag();
+  ChromaFormat nChromaFormat = sps->getChromaFormatIdc();
+#endif
 
   const CPelBuf srcLuma = recSrc.get( compId );
   PelBuf dstLuma = recDst.get( compId );
@@ -516,8 +589,26 @@ void AdaptiveLoopFilter::filterBlk( AlfClassifier** classifier, const PelUnitBuf
       {
         AlfClassifier& cl = pClass[j];
         transposeIdx = cl.transposeIdx;
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+        if( isPCMFilterDisabled && cl.classIdx== m_ALF_UNUSED_CLASSIDX && transposeIdx== m_ALF_UNUSED_TRANSPOSIDX )
+        {
+          continue;
+        }
+#endif
         coef = filterSet + cl.classIdx * MAX_NUM_ALF_LUMA_COEFF;
       }
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+      else if( isPCMFilterDisabled )
+      {
+        Position pos(i, j);
+        CodingUnit* cu = isDualTree ? cs.getCU( recalcPosition(nChromaFormat, CH_L, CH_C, pos), CH_C ): cs.getCU(pos, CH_L);
+        if ( cu->ipcm )
+        {
+          continue;
+        }
+      }
+#endif
+
 
       if( filtType == ALF_FILTER_7 )
       {
diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.h b/source/Lib/CommonLib/AdaptiveLoopFilter.h
index a0fe20959..0602502e4 100644
--- a/source/Lib/CommonLib/AdaptiveLoopFilter.h
+++ b/source/Lib/CommonLib/AdaptiveLoopFilter.h
@@ -41,7 +41,9 @@
 #include "CommonDef.h"
 
 #include "Unit.h"
-
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+#include "UnitTools.h"
+#endif
 struct AlfClassifier
 {
   AlfClassifier() {}
@@ -68,6 +70,10 @@ class AdaptiveLoopFilter
 public:
   static constexpr int   m_NUM_BITS = 8;
   static constexpr int   m_CLASSIFICATION_BLK_SIZE = 32;  //non-normative, local buffer size
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  static constexpr int m_ALF_UNUSED_CLASSIDX = 255;
+  static constexpr int m_ALF_UNUSED_TRANSPOSIDX = 255;
+#endif
 
   AdaptiveLoopFilter();
   virtual ~AdaptiveLoopFilter() {}
@@ -78,8 +84,15 @@ public:
   void destroy();
   static void deriveClassificationBlk( AlfClassifier** classifier, int** laplacian[NUM_DIRECTIONS], const CPelBuf& srcLuma, const Area& blk, const int shift );
   void deriveClassification( AlfClassifier** classifier, const CPelBuf& srcLuma, const Area& blk );
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  void resetPCMBlkClassInfo(CodingStructure & cs, AlfClassifier** classifier, const CPelBuf& srcLuma, const Area& blk);
+#endif
   template<AlfFilterType filtType>
-  static void filterBlk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng );
+  static void filterBlk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng 
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+    ,CodingStructure& cs
+#endif
+  );
 
   inline static int getMaxGolombIdx( AlfFilterType filterType )
   {
@@ -87,8 +100,16 @@ public:
   }
 
   void( *m_deriveClassificationBlk )( AlfClassifier** classifier, int** laplacian[NUM_DIRECTIONS], const CPelBuf& srcLuma, const Area& blk, const int shift );
-  void( *m_filter5x5Blk )( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng );
-  void( *m_filter7x7Blk )( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng );
+  void( *m_filter5x5Blk )( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng 
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+    ,CodingStructure& cs
+#endif
+    );
+  void( *m_filter7x7Blk )( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng 
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+    , CodingStructure& cs
+#endif
+    );
 
 #ifdef TARGET_SIMD_X86
   void initAdaptiveLoopFilterX86();
diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
index a048e366d..33a948cc6 100644
--- a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
+++ b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
@@ -634,13 +634,17 @@ void SampleAdaptiveOffset::xPCMLFDisableProcess(CodingStructure& cs)
 void SampleAdaptiveOffset::xPCMCURestoration(CodingStructure& cs, const UnitArea &ctuArea)
 {
   const SPS& sps = *cs.sps;
-
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  uint32_t numComponents = CS::isDualITree(cs) ? 1 : m_numberOfComponents;
+#endif
   for( auto &cu : cs.traverseCUs( ctuArea, CH_L ) )
   {
     // restore PCM samples
     if( ( cu.ipcm && sps.getPCMFilterDisableFlag() ) || CU::isLosslessCoded( cu ) )
     {
+#if !JVET_M0277_FIX_PCM_DISABLEFILTER
       const uint32_t numComponents = m_numberOfComponents;
+#endif
 
       for( uint32_t comp = 0; comp < numComponents; comp++ )
       {
@@ -648,6 +652,23 @@ void SampleAdaptiveOffset::xPCMCURestoration(CodingStructure& cs, const UnitArea
       }
     }
   }
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  numComponents = m_numberOfComponents;
+  if (CS::isDualITree(cs) && numComponents)
+  {
+    for (auto &cu : cs.traverseCUs(ctuArea, CH_C))
+    {
+      // restore PCM samples
+      if ((cu.ipcm && sps.getPCMFilterDisableFlag()) || CU::isLosslessCoded(cu))
+      {
+        for (uint32_t comp = 1; comp < numComponents; comp++)
+        {
+          xPCMSampleRestoration(cu, ComponentID(comp));
+        }
+      }
+    }
+  }
+#endif
 }
 
 void SampleAdaptiveOffset::xPCMSampleRestoration(CodingUnit& cu, const ComponentID compID)
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 0add5d415..3f898f376 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -83,6 +83,11 @@
 #define JVET_M0464_UNI_MTS                                1
 #define JVET_M0068_M0171_MMVD_CLEANUP                     1 // MMVD cleanup with 1) flip removal, 2) L1 zero vector fix, 3) bi-pred restriction after merge/MMVD
 
+#define JVET_M0277_FIX_PCM_DISABLEFILTER                  1 // Fixes of enabling pcm_loop_filter_disabled_flag with PCM mode
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+#define FIX_PCM                                           1 // Fix PCM bugs in VTM3
+#endif
+
 #if JVET_M0464_UNI_MTS
 typedef std::pair<int, bool> TrMode;
 typedef std::pair<int, int>  TrCost;
diff --git a/source/Lib/CommonLib/x86/AdaptiveLoopFilterX86.h b/source/Lib/CommonLib/x86/AdaptiveLoopFilterX86.h
index 947922a39..f61dc8d86 100644
--- a/source/Lib/CommonLib/x86/AdaptiveLoopFilterX86.h
+++ b/source/Lib/CommonLib/x86/AdaptiveLoopFilterX86.h
@@ -317,7 +317,11 @@ static void simdDeriveClassificationBlk( AlfClassifier** classifier, int** lapla
 }
 
 template<X86_VEXT vext>
-static void simdFilter5x5Blk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng )
+static void simdFilter5x5Blk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng 
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  , CodingStructure& cs
+#endif 
+)
 {
   static const unsigned char mask05[16] = { 8, 9, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   static const unsigned char mask03[16] = { 4, 5, 2, 3, 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
@@ -325,6 +329,13 @@ static void simdFilter5x5Blk( AlfClassifier** classifier, const PelUnitBuf &recD
 
   const bool bChroma = isChroma( compId );
 
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  const SPS*     sps = cs.slice->getSPS();
+  bool isDualTree = CS::isDualITree(cs);
+  bool isPCMFilterDisabled = sps->getPCMFilterDisableFlag();
+  ChromaFormat nChromaFormat = sps->getChromaFormatIdc();
+#endif
+
   const CPelBuf srcLuma = recSrc.get( compId );
   PelBuf dstLuma = recDst.get( compId );
 
@@ -398,8 +409,25 @@ static void simdFilter5x5Blk( AlfClassifier** classifier, const PelUnitBuf &recD
       {
         AlfClassifier& cl = pClass[j];
         transposeIdx = cl.transposeIdx;
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+        if( isPCMFilterDisabled && cl.classIdx == AdaptiveLoopFilter::m_ALF_UNUSED_CLASSIDX && transposeIdx == AdaptiveLoopFilter::m_ALF_UNUSED_TRANSPOSIDX )
+        {
+          continue;
+        }
+#endif
         coef = filterSet + cl.classIdx * MAX_NUM_ALF_LUMA_COEFF;
       }
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+      else if ( isPCMFilterDisabled )
+      {
+        Position pos(i, j);
+        CodingUnit* cu = isDualTree ? cs.getCU(recalcPosition(nChromaFormat, CH_L, CH_C, pos), CH_C) : cs.getCU(pos, CH_L);
+        if ( cu->ipcm )
+        {
+          continue;
+        }
+      }
+#endif
 
       __m128i c0, t0 = _mm_setzero_si128();
 
@@ -531,7 +559,11 @@ static void simdFilter5x5Blk( AlfClassifier** classifier, const PelUnitBuf &recD
 }
 
 template<X86_VEXT vext>
-static void simdFilter7x7Blk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng )
+static void simdFilter7x7Blk( AlfClassifier** classifier, const PelUnitBuf &recDst, const CPelUnitBuf& recSrc, const Area& blk, const ComponentID compId, short* filterSet, const ClpRng& clpRng 
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  , CodingStructure& cs
+#endif 
+)
 {
   static const unsigned char mask0[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 7, 4, 5, 2, 3 };
   static const unsigned char mask00[16] = { 2, 3, 0, 1, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 1 };
@@ -546,7 +578,12 @@ static void simdFilter7x7Blk( AlfClassifier** classifier, const PelUnitBuf &recD
   {
     CHECK( 0, "Chroma doesn't support 7x7" );
   }
-
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  const SPS*     sps = cs.slice->getSPS();
+  bool isDualTree = CS::isDualITree(cs);
+  bool isPCMFilterDisabled = sps->getPCMFilterDisableFlag();
+  ChromaFormat nChromaFormat = sps->getChromaFormatIdc();
+#endif
   const CPelBuf srcLuma = recSrc.get( compId );
   PelBuf dstLuma = recDst.get( compId );
 
@@ -622,8 +659,25 @@ static void simdFilter7x7Blk( AlfClassifier** classifier, const PelUnitBuf &recD
       {
         AlfClassifier& cl = pClass[j];
         transposeIdx = cl.transposeIdx;
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+        if ( isPCMFilterDisabled && cl.classIdx == AdaptiveLoopFilter::m_ALF_UNUSED_CLASSIDX && transposeIdx == AdaptiveLoopFilter::m_ALF_UNUSED_TRANSPOSIDX )
+        {
+          continue;
+        }
+#endif
         coef = filterSet + cl.classIdx * MAX_NUM_ALF_LUMA_COEFF;
       }
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+      else if ( isPCMFilterDisabled )
+      {
+        Position pos(i, j);
+        CodingUnit* cu = isDualTree ? cs.getCU(recalcPosition(nChromaFormat, CH_L, CH_C, pos), CH_C) : cs.getCU(pos, CH_L);
+        if ( cu->ipcm )
+        {
+          continue;
+        }
+      }
+#endif
 
       __m128i c0, c2, t1, t2;
 
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 862ed9835..58d80013f 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -729,6 +729,7 @@ void CABACWriter::coding_unit( const CodingUnit& cu, Partitioner& partitioner, C
     return;
   }
 
+#if !FIX_PCM
   // pcm samples
   if( CU::isIntra(cu) )
   {
@@ -739,10 +740,23 @@ void CABACWriter::coding_unit( const CodingUnit& cu, Partitioner& partitioner, C
       return;
     }
   }
+#endif
 
   // prediction mode and partitioning data
   pred_mode ( cu );
 
+#if FIX_PCM
+  // pcm samples
+  if( CU::isIntra(cu) )
+  {
+    pcm_data( cu, partitioner );
+    if( cu.ipcm )
+    {
+      end_of_ctu( cu, cuCtx );
+      return;
+    }
+  }
+#endif
   extend_ref_line(cu);
 
 
diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
index f8a713d34..58fa89e6a 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
@@ -253,6 +253,10 @@ void EncAdaptiveLoopFilter::ALFProcess( CodingStructure& cs, const double *lambd
   const CPelBuf& recLuma = recYuv.get( COMPONENT_Y );
   Area blk( 0, 0, recLuma.width, recLuma.height );
   deriveClassification( m_classifier, recLuma, blk );
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+  Area blkPCM(0, 0, recLuma.width, recLuma.height);
+  resetPCMBlkClassInfo(cs, m_classifier, recLuma, blkPCM);
+#endif
 
   // get CTB stats for filtering
   deriveStatsForFiltering( orgYuv, recYuv );
@@ -451,11 +455,19 @@ void EncAdaptiveLoopFilter::alfEncoder( CodingStructure& cs, AlfSliceParam& alfS
           {
             if( filterType == ALF_FILTER_5 )
             {
-              m_filter5x5Blk( m_classifier, recBuf, recExtBuf, blk, compID, coeff, m_clpRngs.comp[compIdx] );
+              m_filter5x5Blk( m_classifier, recBuf, recExtBuf, blk, compID, coeff, m_clpRngs.comp[compIdx]
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+                , cs
+#endif
+              );
             }
             else if( filterType == ALF_FILTER_7 )
             {
-              m_filter7x7Blk( m_classifier, recBuf, recExtBuf, blk, compID, coeff, m_clpRngs.comp[compIdx] );
+              m_filter7x7Blk( m_classifier, recBuf, recExtBuf, blk, compID, coeff, m_clpRngs.comp[compIdx]
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+                , cs
+#endif
+              );
             }
             else
             {
@@ -1464,6 +1476,12 @@ void EncAdaptiveLoopFilter::getBlkStats( AlfCovariance* alfCovariace, const AlfF
   {
     for( int j = 0; j < area.width; j++ )
     {
+#if JVET_M0277_FIX_PCM_DISABLEFILTER
+      if( classifier && classifier[area.y + i][area.x + j].classIdx == m_ALF_UNUSED_CLASSIDX && classifier[area.y + i][area.x + j].transposeIdx == m_ALF_UNUSED_TRANSPOSIDX )
+      {
+        continue;
+      }
+#endif
       std::memset( ELocal, 0, shape.numCoeff * sizeof( int ) );
       if( classifier )
       {
diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp
index 5c9aeb9b7..a9cdc6317 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.cpp
+++ b/source/Lib/EncoderLib/EncModeCtrl.cpp
@@ -1237,6 +1237,9 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
   const SPS&             sps         = *slice.getSPS();
   const uint32_t             numComp     = getNumberValidComponents( slice.getSPS()->getChromaFormatIdc() );
   const uint32_t             width       = partitioner.currArea().lumaSize().width;
+#if FIX_PCM
+  const uint32_t             height       = partitioner.currArea().lumaSize().height;
+#endif
   const CodingStructure *bestCS      = cuECtx.bestCS;
   const CodingUnit      *bestCU      = cuECtx.bestCU;
   const EncTestMode      bestMode    = bestCS ? getCSEncMode( *bestCS ) : EncTestMode();
@@ -1339,7 +1342,12 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
     }
 
     // PCM MODES
+#if FIX_PCM
+    return sps.getPCMEnabledFlag() && width <= ( 1 << sps.getPCMLog2MaxSize() ) && width >= ( 1 << sps.getPCMLog2MinSize() )
+            && height <= ( 1 << sps.getPCMLog2MaxSize() ) && height >= ( 1 << sps.getPCMLog2MinSize() );
+#else
     return sps.getPCMEnabledFlag() && width <= ( 1 << sps.getPCMLog2MaxSize() ) && width >= ( 1 << sps.getPCMLog2MinSize() );
+#endif
   }
   else if (encTestmode.type == ETM_IBC || encTestmode.type == ETM_IBC_MERGE)
   {
-- 
GitLab