From f200afeb17dd1ab8e32bce4f7c76173ac7bb7eca Mon Sep 17 00:00:00 2001
From: Kenneth Andersson <kenneth.r.andersson@ericsson.com>
Date: Thu, 22 Oct 2020 19:55:21 +0200
Subject: [PATCH] JVET-T0064 Addition of ALF filter strength control to VTM

---
 cfg/encoder_intra_vtm.cfg                     |  1 +
 cfg/encoder_lowdelay_P_vtm.cfg                |  1 +
 cfg/encoder_lowdelay_vtm.cfg                  |  1 +
 cfg/encoder_randomaccess_vtm.cfg              |  1 +
 cfg/encoder_randomaccess_vtm_gop16.cfg        |  1 +
 doc/software-manual.tex                       |  6 ++++++
 source/App/EncoderApp/EncApp.cpp              |  3 +++
 source/App/EncoderApp/EncAppCfg.cpp           |  3 +++
 source/App/EncoderApp/EncAppCfg.h             |  3 +++
 source/Lib/CommonLib/TypeDef.h                |  1 +
 .../Lib/EncoderLib/EncAdaptiveLoopFilter.cpp  | 20 ++++++++++++++++++-
 source/Lib/EncoderLib/EncCfg.h                |  7 +++++++
 12 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/cfg/encoder_intra_vtm.cfg b/cfg/encoder_intra_vtm.cfg
index 685d9d1ff..bcbc82566 100644
--- a/cfg/encoder_intra_vtm.cfg
+++ b/cfg/encoder_intra_vtm.cfg
@@ -88,6 +88,7 @@ LMChroma                     : 1      # use CCLM only
 DepQuant                     : 1
 IMV                          : 1
 ALF                          : 1
+ALFStrength                  : 1.0
 IBC                          : 0      # turned off in CTC
 AllowDisFracMMVD             : 1
 AffineAmvr                   : 0
diff --git a/cfg/encoder_lowdelay_P_vtm.cfg b/cfg/encoder_lowdelay_P_vtm.cfg
index 1a78ff8bd..228b11448 100644
--- a/cfg/encoder_lowdelay_P_vtm.cfg
+++ b/cfg/encoder_lowdelay_P_vtm.cfg
@@ -111,6 +111,7 @@ LMChroma                     : 1      # use CCLM only
 DepQuant                     : 1
 IMV                          : 1
 ALF                          : 1
+ALFStrength                  : 1.0
 CIIP                         : 1
 IBC                          : 0      # turned off in CTC
 AllowDisFracMMVD             : 1
diff --git a/cfg/encoder_lowdelay_vtm.cfg b/cfg/encoder_lowdelay_vtm.cfg
index e8b3e708a..7128d34d7 100644
--- a/cfg/encoder_lowdelay_vtm.cfg
+++ b/cfg/encoder_lowdelay_vtm.cfg
@@ -112,6 +112,7 @@ LMChroma                     : 1      # use CCLM only
 DepQuant                     : 1
 IMV                          : 1
 ALF                          : 1
+ALFStrength                  : 1.0
 BCW                          : 1
 BcwFast                      : 1
 CIIP                         : 1
diff --git a/cfg/encoder_randomaccess_vtm.cfg b/cfg/encoder_randomaccess_vtm.cfg
index 0b7a5a0b7..7335eb88b 100644
--- a/cfg/encoder_randomaccess_vtm.cfg
+++ b/cfg/encoder_randomaccess_vtm.cfg
@@ -140,6 +140,7 @@ LMChroma                     : 1      # use CCLM only
 DepQuant                     : 1
 IMV                          : 1
 ALF                          : 1
+ALFStrength                  : 1.0
 BCW                          : 1
 BcwFast                      : 1
 BIO                          : 1
diff --git a/cfg/encoder_randomaccess_vtm_gop16.cfg b/cfg/encoder_randomaccess_vtm_gop16.cfg
index ae60960fa..ad36d6b97 100644
--- a/cfg/encoder_randomaccess_vtm_gop16.cfg
+++ b/cfg/encoder_randomaccess_vtm_gop16.cfg
@@ -124,6 +124,7 @@ LMChroma                     : 1      # use CCLM only
 DepQuant                     : 1
 IMV                          : 1
 ALF                          : 1
+ALFStrength                  : 1.0
 BCW                          : 1
 BcwFast                      : 1
 BIO                          : 1
diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index 21d80063e..e0b757176 100644
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -2868,6 +2868,12 @@ switched at CTB level. Set to 1 to disable alternative chroma filters.
 Value shall be in the range 1..8.
 \\
 
+\Option{ALFStrength} &
+%\ShortOption{\None} &
+\Default{1.0} &
+Enables control of ALF filter strength. The parameter scales the magnitudes of the ALF filter coefficients for both luma and chroma.
+\\
+
 \Option{CCALF} &
 %\ShortOption{\None} &
 \Default{true} &
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 86afb73ab..9fde5120b 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -1036,6 +1036,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setForceSingleSplitThread                            ( m_forceSplitSequential );
 #endif
   m_cEncLib.setUseALF                                            ( m_alf );
+#if JVET_T0064
+  m_cEncLib.setALFStrength                                       (m_alfStrength);
+#endif
   m_cEncLib.setUseCCALF                                          ( m_ccalf );
   m_cEncLib.setCCALFQpThreshold                                  ( m_ccalfQpThreshold );
   m_cEncLib.setLmcs                                              ( m_lmcsEnabled );
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index faea0ed16..e4806a2ce 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1375,6 +1375,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("DebugCTU",                                        m_debugCTU,                                  -1, "If DebugBitstream is present, load frames up to this POC from this bitstream. Starting with DebugPOC-frame at CTUline containin debug CTU.")
   ("EnsureWppBitEqual",                               m_ensureWppBitEqual,                      false, "Ensure the results are equal to results with WPP-style parallelism, even if WPP is off")
   ( "ALF",                                             m_alf,                                    true, "Adaptive Loop Filter\n" )
+#if JVET_T0064
+  ("ALFStrength", m_alfStrength, 1.0, "Adaptive Loop Filter strength. The parameter scales the magnitudes of the ALF filter coefficients for both luma and chroma.")
+#endif
   ( "CCALF",                                           m_ccalf,                                  true, "Cross-component Adaptive Loop Filter" )
   ( "CCALFQpTh",                                       m_ccalfQpThreshold,                         37, "QP threshold above which encoder reduces CCALF usage")
   ( "RPR",                                            m_rprEnabledFlag,                          true, "Reference Sample Resolution" )
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 7f8d11414..25ccd9710 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -693,6 +693,9 @@ protected:
   bool        m_forceDecodeBitstream1;
 
   bool        m_alf;                                          ///< Adaptive Loop Filter
+#if JVET_T0064
+  double      m_alfStrength;
+#endif
   bool        m_ccalf;
   int         m_ccalfQpThreshold;
 
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 933b9db6e..be47c68b8 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -55,6 +55,7 @@
 #define JVET_S0219_ASPECT1                                1 // JVET-S0219 aspect1 : removal non-referred APS parameter set in the non-output layer. 
 #define JVET_R0193                                        1 // JVET-R0193: signalling of the number of maximum sublayers used for inter-layer prediction for each layer
 #define JVET_R0193_S0141                                  1 // JVET-S0141 item 47 : item 47: In the general sub-bitstream extraction process, specify the conditions under which an output sub-bitstream is required to be a conforming bitstream such that the value of tIdTarget is specified to be in the range of 0 to vps_ptl_max_tid[ vps_ols_ptl_idx[ targetOlsIdx ] ], inclusive (instead of 0 to 6 inclusive). (JVET-S0158 aspect 1)
+#define JVET_T0064                                        1 // JVET-T0064: control of filter strength for ALF
 
 //########### place macros to be be kept below this line ###############
 #define JVET_S0257_DUMP_360SEI_MESSAGE                    1 // Software support of 360 SEI messages
diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
index f034b57d9..5aa96f3d0 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
@@ -1834,7 +1834,12 @@ double EncAdaptiveLoopFilter::deriveCoeffQuant( int *filterClipp, int *filterCoe
   filterCoeffQuant[numCoeff - 1] = 0;
 
   int modified=1;
-
+#if JVET_T0064
+  if( m_encCfg->getALFStrength() != 1.0 )
+  {
+    modified = 0;
+  }
+#endif
   double errRef=cov.calcErrorForCoeffs( filterClipp, filterCoeffQuant, numCoeff, bitDepth );
   while( modified )
   {
@@ -1878,7 +1883,11 @@ void EncAdaptiveLoopFilter::roundFiltCoeff( int *filterCoeffQuant, double *filte
   for( int i = 0; i < numCoeff; i++ )
   {
     int sign = filterCoeff[i] > 0 ? 1 : -1;
+#if JVET_T0064
+    filterCoeffQuant[i] = int((filterCoeff[i] * m_encCfg->getALFStrength()) * sign * factor + 0.5) * sign;
+#else
     filterCoeffQuant[i] = int( filterCoeff[i] * sign * factor + 0.5 ) * sign;
+#endif
   }
 }
 
@@ -2721,7 +2730,16 @@ void  EncAdaptiveLoopFilter::alfEncoderCtb(CodingStructure& cs, AlfParam& alfPar
           double         costOn = MAX_DOUBLE;
           ctxTempStart = AlfCtx(m_CABACEstimator->getCtx());
           int iBestFilterSetIdx = 0;
+#if JVET_T0064
+          int firstFilterSetIdx = 0;
+          if (m_encCfg->getALFStrength() != 1.0)
+          {
+            firstFilterSetIdx = NUM_FIXED_FILTER_SETS;
+          }
+          for (int filterSetIdx = firstFilterSetIdx; filterSetIdx < numFilterSet; filterSetIdx++)
+#else
           for (int filterSetIdx = 0; filterSetIdx < numFilterSet; filterSetIdx++)
+#endif
           {
             //rate
             m_CABACEstimator->getCtx() = AlfCtx(ctxTempStart);
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 1f15e503e..ddd1aa4d6 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -732,6 +732,9 @@ protected:
 #endif
 
   bool        m_alf;                                          ///< Adaptive Loop Filter
+#if JVET_T0064
+  double      m_alfStrength;
+#endif
   bool        m_ccalf;
   int         m_ccalfQpThreshold;
 #if JVET_O0756_CALCULATE_HDRMETRICS
@@ -1903,6 +1906,10 @@ public:
 #endif
   void         setUseALF( bool b ) { m_alf = b; }
   bool         getUseALF()                                      const { return m_alf; }
+#if JVET_T0064
+  void         setALFStrength( double s) { m_alfStrength = s; }
+  double       getALFStrength()                                 const { return m_alfStrength; }
+#endif
   void         setUseCCALF( bool b )                                  { m_ccalf = b; }
   bool         getUseCCALF()                                    const { return m_ccalf; }
   void         setCCALFQpThreshold( int b )                           { m_ccalfQpThreshold = b; }
-- 
GitLab