From ca39c2cca0df3815ffbf73cb39db86a54dea7e5f Mon Sep 17 00:00:00 2001
From: Zhipin Deng <zhipin.deng@bytedance.com>
Date: Mon, 22 Apr 2024 11:50:43 +0000
Subject: [PATCH] JVET-AH0065 (test 2.7): Relaxing line buffer restriction

---
 source/Lib/CommonLib/IntraPrediction.cpp |  8 ++++++++
 source/Lib/CommonLib/TypeDef.h           |  1 +
 source/Lib/CommonLib/UnitTools.cpp       |  4 ++++
 source/Lib/DecoderLib/CABACReader.cpp    |  4 ++++
 source/Lib/EncoderLib/CABACWriter.cpp    |  8 ++++++++
 source/Lib/EncoderLib/IntraSearch.cpp    | 15 ++++++++++++++-
 6 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp
index c2855198a..f9f3af1a1 100644
--- a/source/Lib/CommonLib/IntraPrediction.cpp
+++ b/source/Lib/CommonLib/IntraPrediction.cpp
@@ -4681,7 +4681,11 @@ void IntraPrediction::initIntraPatternChType(const CodingUnit &cu, const CompAre
   m_ipaParam.fetchRef2nd   = area.compID == COMPONENT_Y;
   m_ipaParam.fetchRef2nd  &= area.width * area.height >= SIZE_CONSTRAINT;
   m_ipaParam.fetchRef2nd  &= !(cu.dimd && cu.dimdBlending);
+#if JVET_AH0065_RELAX_LINE_BUFFER
+  m_ipaParam.fetchRef2nd  &= !(mrlIndex2D == MULTI_REF_LINE_IDX[MRL_NUM_REF_LINES - 1] && (cu.block(COMPONENT_Y).y <= MULTI_REF_LINE_IDX[MRL_NUM_REF_LINES - 1]));
+#else
   m_ipaParam.fetchRef2nd  &= !(mrlIndex2D == MULTI_REF_LINE_IDX[MRL_NUM_REF_LINES - 1] && ((cu.block(COMPONENT_Y).y) % ((cu.cs->sps)->getMaxCUWidth()) <= MULTI_REF_LINE_IDX[MRL_NUM_REF_LINES - 1]));
+#endif
   m_ipaParam.fetchRef2nd  &= !(mrlIndex2D == 0 && ((cu.block(COMPONENT_Y).y) % ((cu.cs->sps)->getMaxCUWidth()) == 0));
 #if JVET_AC0112_IBC_CIIP
   m_ipaParam.fetchRef2nd &= !cu.firstPU->ibcCiipFlag;
@@ -22326,7 +22330,11 @@ void IntraPrediction::initTmrlIntraParams(const PredictionUnit& pu, const CompAr
 void IntraPrediction::getTmrlSearchRange(const PredictionUnit& pu, int8_t* tmrlRefList, uint8_t* tmrlIntraList, uint8_t& sizeRef, uint8_t& sizeMode)
 {
   CodingUnit& cu = *pu.cu;
+#if JVET_AH0065_RELAX_LINE_BUFFER
+  int aboveLines = cu.block(COMPONENT_Y).y;
+#else
   int aboveLines = (cu.block(COMPONENT_Y).y) % ((cu.cs->sps)->getMaxCUWidth());
+#endif
   sizeRef = 0;
 
   for (; sizeRef < 5; sizeRef++)
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 2cfa68ec5..059102f3f 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -204,6 +204,7 @@
 #define JVET_AG0058_EIP                                   1 // JVET-AG0058: Extrapolation filter-based intra prediction mode
 #define JVET_AG0154_DECODER_DERIVED_CCP_FUSION            1 // JVET-AG0154: Decoder derived CCP mode with fusion candidates
 #define JVET_AG0059_CCP_MERGE_ENHANCEMENT                 1 // JVET-AG0059: Enhancements on CCP merge for chroma intra coding
+#define JVET_AH0065_RELAX_LINE_BUFFER                     1 // JVET-AH0065: Relaxing line buffer restriction
 
 //IBC
 #define JVET_Y0058_IBC_LIST_MODIFY                        1 // JVET-Y0058: Modifications of IBC merge/AMVP list construction, ARMC-TM-IBC part is included under JVET_W0090_ARMC_TM
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index e1634e516..dd54ca16e 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -27841,7 +27841,11 @@ bool CU::allowTmrl(const CodingUnit& cu)
     bReorder = false;
   }
 
+#if JVET_AH0065_RELAX_LINE_BUFFER
+ bool isFirstLineOfCtu = cu.block(COMPONENT_Y).y == 0;
+#else
   bool isFirstLineOfCtu = (((cu.block(COMPONENT_Y).y) & ((cu.cs->sps)->getMaxCUWidth() - 1)) == 0);
+#endif
   if (isFirstLineOfCtu)
   {
     bReorder = false;
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 90593c330..06e724e6f 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -1884,7 +1884,11 @@ void CABACReader::extend_ref_line(CodingUnit& cu)
       pu = pu->next;
       continue;
     }
+#if JVET_AH0065_RELAX_LINE_BUFFER
+    bool isFirstLineOfCtu = cu.block(COMPONENT_Y).y == 0;
+#else
     bool isFirstLineOfCtu = (((cu.block(COMPONENT_Y).y)&((cu.cs->sps)->getMaxCUWidth() - 1)) == 0);
+#endif
     if (isFirstLineOfCtu)
     {
       pu->multiRefIdx = 0;
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 9a6f3ba30..d35864514 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -1330,7 +1330,11 @@ void CABACWriter::extend_ref_line(const PredictionUnit& pu)
   {
     return;
   }
+#if JVET_AH0065_RELAX_LINE_BUFFER
+  bool isFirstLineOfCtu = cu.block(COMPONENT_Y).y == 0;
+#else
   bool isFirstLineOfCtu = (((cu.block(COMPONENT_Y).y)&((cu.cs->sps)->getMaxCUWidth() - 1)) == 0);
+#endif
   if (isFirstLineOfCtu)
   {
     return;
@@ -1413,7 +1417,11 @@ void CABACWriter::extend_ref_line(const CodingUnit& cu)
 
   for (int k = 0; k < numBlocks; k++)
   {
+#if JVET_AH0065_RELAX_LINE_BUFFER
+    bool isFirstLineOfCtu = cu.block(COMPONENT_Y).y == 0;
+#else
     bool isFirstLineOfCtu = (((cu.block(COMPONENT_Y).y)&((cu.cs->sps)->getMaxCUWidth() - 1)) == 0);
+#endif
     if (isFirstLineOfCtu)
     {
       return;
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index 51a4a5a21..e44f95cb7 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -923,7 +923,11 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
         // this should always be true
         CHECK(!pu.Y().valid(), "PU is not valid");
 #if !JVET_AB0157_TMRL || JVET_AD0082_TMRL_CONFIG
+#if JVET_AH0065_RELAX_LINE_BUFFER
+        bool isFirstLineOfCtu = pu.block(COMPONENT_Y).y == 0;
+#else
         bool isFirstLineOfCtu     = (((pu.block(COMPONENT_Y).y) & ((pu.cs->sps)->getMaxCUWidth() - 1)) == 0);
+#endif
 #if JVET_Y0116_EXTENDED_MRL_LIST
         int  numOfPassesExtendRef = MRL_NUM_REF_LINES;
         if (!sps.getUseMRL() || isFirstLineOfCtu) 
@@ -935,9 +939,13 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
           bool checkLineOutsideCtu[MRL_NUM_REF_LINES - 1];
           for (int mrlIdx = 1; mrlIdx < MRL_NUM_REF_LINES; mrlIdx++)
           {
+#if JVET_AH0065_RELAX_LINE_BUFFER
+            bool isLineOutsideCtu = (cu.block(COMPONENT_Y).y <= MULTI_REF_LINE_IDX[mrlIdx]) ? true : false;
+#else
             bool isLineOutsideCtu =
               ((cu.block(COMPONENT_Y).y) % ((cu.cs->sps)->getMaxCUWidth()) <= MULTI_REF_LINE_IDX[mrlIdx]) ? true
-                                                                                                          : false;
+                                                                                                      : false;
+#endif
             checkLineOutsideCtu[mrlIdx-1] = isLineOutsideCtu;
           }
           if (checkLineOutsideCtu[0]) 
@@ -2329,6 +2337,10 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
       numNonISPModes++;
       if (lfnstIdx == 0 && !cu.mtsFlag)
       {
+#if JVET_AH0065_RELAX_LINE_BUFFER
+        bool isFirstLineOfCtu = pu.block(COMPONENT_Y).y == 0;
+        int  numOfPassesExtendRef = ((!sps.getUseMRL() || isFirstLineOfCtu) ? 1 : 3);
+#else
         bool isFirstLineOfCtu     = (((pu.block(COMPONENT_Y).y) & ((pu.cs->sps)->getMaxCUWidth() - 1)) == 0);
 #if JVET_Y0116_EXTENDED_MRL_LIST
         int  numOfPassesExtendRef = 3;
@@ -2360,6 +2372,7 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c
         }
 #else
         int  numOfPassesExtendRef = ((!sps.getUseMRL() || isFirstLineOfCtu) ? 1 : MRL_NUM_REF_LINES);
+#endif
 #endif
         for (int mRefNum = 1; mRefNum < numOfPassesExtendRef; mRefNum++)
         {
-- 
GitLab