From 7c36bb62823fdcc704e284db59f1a3d55f4b032c Mon Sep 17 00:00:00 2001
From: Kenneth Andersson <kenneth.r.andersson@ericsson.com>
Date: Thu, 2 Feb 2023 17:21:41 +0100
Subject: [PATCH 1/2] JVET-AB0081: Upscaling filter for display 12-tap luma and
 6-tap chroma

---
 source/App/DecoderApp/DecApp.cpp    |   8 ++
 source/App/DecoderApp/DecAppCfg.cpp |   3 +
 source/App/DecoderApp/DecAppCfg.h   |   3 +
 source/App/EncoderApp/EncApp.cpp    |   7 ++
 source/App/EncoderApp/EncAppCfg.cpp |   3 +
 source/App/EncoderApp/EncAppCfg.h   |   3 +
 source/Lib/CommonLib/Picture.cpp    | 149 +++++++++++++++++++++++++++-
 source/Lib/CommonLib/Picture.h      |  11 +-
 source/Lib/CommonLib/TypeDef.h      |   1 +
 source/Lib/EncoderLib/EncCfg.h      |   8 +-
 source/Lib/EncoderLib/EncGOP.cpp    |   5 +
 source/Lib/Utilities/VideoIOYuv.cpp |  10 +-
 source/Lib/Utilities/VideoIOYuv.h   |   5 +-
 13 files changed, 211 insertions(+), 5 deletions(-)

diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp
index 85f63bb0f..13f7afca4 100644
--- a/source/App/DecoderApp/DecApp.cpp
+++ b/source/App/DecoderApp/DecApp.cpp
@@ -678,7 +678,11 @@ void DecApp::xWriteOutput( PicList* pcListPic, uint32_t tId )
           ChromaFormat chromaFormatIDC = sps->getChromaFormatIdc();
           if( m_upscaledOutput )
           {
+#if JVET_AB0081
+            m_cVideoIOYuvReconFile[pcPic->layerId].writeUpscaledPicture(*sps, *pcPic->cs->pps, pcPic->getRecoBuf(), m_outputColourSpaceConvert, m_packedYUVMode, m_upscaledOutput, NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range, m_upscaleFilterForDisplay);
+#else
             m_cVideoIOYuvReconFile[pcPic->layerId].writeUpscaledPicture( *sps, *pcPic->cs->pps, pcPic->getRecoBuf(), m_outputColourSpaceConvert, m_packedYUVMode, m_upscaledOutput, NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
+#endif
           }
           else
           {
@@ -825,7 +829,11 @@ void DecApp::xFlushOutput( PicList* pcListPic, const int layerId )
             ChromaFormat chromaFormatIDC = sps->getChromaFormatIdc();
             if( m_upscaledOutput )
             {
+#if JVET_AB0081
+              m_cVideoIOYuvReconFile[pcPic->layerId].writeUpscaledPicture(*sps, *pcPic->cs->pps, pcPic->getRecoBuf(), m_outputColourSpaceConvert, m_packedYUVMode, m_upscaledOutput, NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range, m_upscaleFilterForDisplay);
+#else
               m_cVideoIOYuvReconFile[pcPic->layerId].writeUpscaledPicture( *sps, *pcPic->cs->pps, pcPic->getRecoBuf(), m_outputColourSpaceConvert, m_packedYUVMode, m_upscaledOutput, NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
+#endif
             }
             else
             {
diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp
index d96c20493..fde54606f 100644
--- a/source/App/DecoderApp/DecAppCfg.cpp
+++ b/source/App/DecoderApp/DecAppCfg.cpp
@@ -125,6 +125,9 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
   ("MCTSCheck",                m_mctsCheck,                           false,       "If enabled, the decoder checks for violations of mc_exact_sample_value_match_flag in Temporal MCTS ")
   ("targetSubPicIdx",          m_targetSubPicIdx,                     0,           "Specify which subpicture shall be written to output, using subpic index, 0: disabled, subpicIdx=m_targetSubPicIdx-1 \n" )
   ( "UpscaledOutput",          m_upscaledOutput,                          0,       "Upscaled output for RPR" )
+#if JVET_AB0081
+  ("UpscaleFilterForDisplay", m_upscaleFilterForDisplay,                  2, "Filters used for upscaling reconstruction to full resolution (2: ECM 12 - tap luma and 6 - tap chroma MC filters, 1 : Alternative 12 - tap luma and 6 - tap chroma filters, 0 : VVC 8 - tap luma and 4 - tap chroma MC filters)")
+#endif
   ;
 
   po::setDefaults(opts);
diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h
index ba7c0338e..667f6b74b 100644
--- a/source/App/DecoderApp/DecAppCfg.h
+++ b/source/App/DecoderApp/DecAppCfg.h
@@ -88,6 +88,9 @@ protected:
   bool          m_mctsCheck;
 
   int          m_upscaledOutput;                     ////< Output upscaled (2), decoded but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR.
+#if JVET_AB0081
+  int          m_upscaleFilterForDisplay;
+#endif
   int           m_targetSubPicIdx;                    ///< Specify which subpicture shall be write to output, using subpicture index
 public:
   DecAppCfg();
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index b84af181d..73c9e5cb2 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -271,6 +271,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setResChangeInClvsEnabled                            ( m_resChangeInClvsEnabled );
   m_cEncLib.setSwitchPocPeriod                                   ( m_switchPocPeriod );
   m_cEncLib.setUpscaledOutput                                    ( m_upscaledOutput );
+#if JVET_AB0081
+  m_cEncLib.setUpscaleFilerForDisplay                            (m_upscaleFilterForDisplay);
+#endif
 #if JVET_AC0096
   m_cEncLib.setRprFunctionalityTestingEnabledFlag                (m_rprFunctionalityTestingEnabledFlag);
   m_cEncLib.setRprSwitchingSegmentSize                           (m_rprSwitchingSegmentSize);
@@ -1458,7 +1461,11 @@ void EncApp::xWriteOutput( int iNumEncoded, std::list<PelUnitBuf*>& recBufList )
           const SPS& sps = *m_cEncLib.getSPS( 0 );
           const PPS& pps = *m_cEncLib.getPPS( ( sps.getMaxPicWidthInLumaSamples() != pcPicYuvRec->get( COMPONENT_Y ).width || sps.getMaxPicHeightInLumaSamples() != pcPicYuvRec->get( COMPONENT_Y ).height ) ? ENC_PPS_ID_RPR : 0 );
 #endif
+#if JVET_AB0081
+          m_cVideoIOYuvReconFile.writeUpscaledPicture(sps, pps, *pcPicYuvRec, ipCSC, m_packedYUVMode, m_cEncLib.getUpscaledOutput(), NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range, m_upscaleFilterForDisplay);
+#else
           m_cVideoIOYuvReconFile.writeUpscaledPicture( sps, pps, *pcPicYuvRec, ipCSC, m_packedYUVMode, m_cEncLib.getUpscaledOutput(), NUM_CHROMA_FORMAT, m_bClipOutputVideoToRec709Range );
+#endif
         }
         else
         {
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 8400a092d..d2ae5ce8b 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1438,6 +1438,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ( "FractionNumFrames",                              m_fractionOfFrames,                         1.0, "Encode a fraction of the specified in FramesToBeEncoded frames" )
   ( "SwitchPocPeriod",                                m_switchPocPeriod,                            0, "Switch POC period for RPR" )
   ( "UpscaledOutput",                                 m_upscaledOutput,                             0, "Output upscaled (2), decoded but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR" )
+#if JVET_AB0081
+  ("UpscaleFilterForDisplay",                         m_upscaleFilterForDisplay,                    2, "Filters used for upscaling reconstruction to full resolution (2: ECM 12-tap luma and 6-tap chroma MC filters, 1: Alternative 12-tap luma and 6-tap chroma filters, 0: VVC 8-tap luma and 4-tap chroma MC filters)")
+#endif
 #if JVET_AC0096
   ("RPRFunctionalityTesting",                         m_rprFunctionalityTestingEnabledFlag,     false, "Enables RPR functionality testing")
   ("RPRSwitchingResolutionOrderList", cfg_rprSwitchingResolutionOrderList, cfg_rprSwitchingResolutionOrderList, "Order of resolutions for each segment in RPR functionality testing where 0,1,2,3 corresponds to full resolution,4/5,2/3 and 1/2")
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 86544d404..c7fafe933 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -720,6 +720,9 @@ protected:
   double      m_fractionOfFrames;                             ///< encode a fraction of the frames as specified in FramesToBeEncoded
   int         m_switchPocPeriod;
   int         m_upscaledOutput;                               ////< Output upscaled (2), decoded cropped but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR.
+#if JVET_AB0081
+  int         m_upscaleFilterForDisplay;
+#endif
 #if JVET_AC0096
   int         m_rprSwitchingResolutionOrderList[MAX_RPR_SWITCHING_ORDER_LIST_SIZE];
   int         m_rprSwitchingQPOffsetOrderList[MAX_RPR_SWITCHING_ORDER_LIST_SIZE];
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index a7205badc..bd1ea4355 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -636,11 +636,128 @@ const TFilterCoeff DownsamplingFilterSRC[8][16][12] =
     }
 };
 
+#if JVET_AB0081
+const TFilterCoeff m_lumaFilter12_alt[16][12] =
+{
+{ 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, },
+{ 1, -1, 0, 3, -12, 253, 16, -6, 2, 0, 0, 0, },
+{ 0, 0, -3, 9, -24, 250, 32, -11, 4, -1, 0, 0, },
+{ 0, 0, -4, 12, -32, 241, 52, -18, 8, -4, 2, -1, },
+{ 0, 1, -6, 15, -38, 228, 75, -28, 14, -7, 3, -1, },
+{ 0, 1, -7, 18, -43, 214, 96, -33, 16, -8, 3, -1, },
+{ 1, 0, -6, 17, -44, 196, 119, -40, 20, -10, 4, -1, },
+{ 0, 2, -9, 21, -47, 180, 139, -43, 20, -10, 4, -1, },
+{ -1, 3, -9, 21, -46, 160, 160, -46, 21, -9, 3, -1, },
+{ -1, 4, -10, 20, -43, 139, 180, -47, 21, -9, 2, 0, },
+{ -1, 4, -10, 20, -40, 119, 196, -44, 17, -6, 0, 1, },
+{ -1, 3, -8, 16, -33, 96, 214, -43, 18, -7, 1, 0, },
+{ -1, 3, -7, 14, -28, 75, 228, -38, 15, -6, 1, 0, },
+{ -1, 2, -4, 8, -18, 52, 241, -32, 12, -4, 0, 0, },
+{ 0, 0, -1, 4, -11, 32, 250, -24, 9, -3, 0, 0, },
+{ 0, 0, 0, 2, -6, 16, 253, -12, 3, 0, -1, 1, },
+};
+const TFilterCoeff m_chromaFilter6_alt[32][6] =
+{
+{0, 0, 256, 0, 0, 0, },
+{ 1, -6, 256, 6, -1, 0, },
+{ 2, -11, 254, 14, -4, 1, },
+{ 4, -18, 252, 23, -6, 1, },
+{ 6, -24, 249, 32, -9, 2, },
+{ 6, -26, 244, 41, -12, 3, },
+{ 7, -30, 239, 53, -18, 5, },
+{ 8, -34, 235, 61, -19, 5, },
+{ 10, -38, 228, 72, -22, 6, },
+{ 10, -39, 220, 84, -26, 7, },
+{ 10, -40, 213, 94, -29, 8, },
+{ 11, -42, 205, 105, -32, 9, },
+{ 11, -42, 196, 116, -35, 10, },
+{ 11, -42, 186, 128, -37, 10, },
+{ 11, -42, 177, 138, -38, 10, },
+{ 11, -41, 167, 148, -40, 11, },
+{ 11, -41, 158, 158, -41, 11, },
+{ 11, -40, 148, 167, -41, 11, },
+{ 10, -38, 138, 177, -42, 11, },
+{ 10, -37, 128, 186, -42, 11, },
+{ 10, -35, 116, 196, -42, 11, },
+{ 9, -32, 105, 205, -42, 11, },
+{ 8, -29, 94, 213, -40, 10, },
+{ 7, -26, 84, 220, -39, 10, },
+{ 6, -22, 72, 228, -38, 10, },
+{ 5, -19, 61, 235, -34, 8, },
+{ 5, -18, 53, 239, -30, 7, },
+{ 3, -12, 41, 244, -26, 6, },
+{ 2, -9, 32, 249, -24, 6, },
+{ 1, -6, 23, 252, -18, 4, },
+{ 1, -4, 14, 254, -11, 2, },
+{ 0, -1, 6, 256, -6, 1, }
+};
+
+const TFilterCoeff m_lumaFilter12[16][12] =
+{
+    { 0,     0,     0,     0,     0,   256,     0,     0,     0,     0,     0,     0, },
+    {-1,     2,    -3,     6,   -14,   254,    16,    -7,     4,    -2,     1,     0, },
+    {-1,     3,    -7,    12,   -26,   249,    35,   -15,     8,    -4,     2,     0, },
+    {-2,     5,    -9,    17,   -36,   241,    54,   -22,    12,    -6,     3,    -1, },
+    {-2,     5,   -11,    21,   -43,   230,    75,   -29,    15,    -8,     4,    -1, },
+    {-2,     6,   -13,    24,   -48,   216,    97,   -36,    19,   -10,     4,    -1, },
+    {-2,     7,   -14,    25,   -51,   200,   119,   -42,    22,   -12,     5,    -1, },
+    {-2,     7,   -14,    26,   -51,   181,   140,   -46,    24,   -13,     6,    -2, },
+    {-2,     6,   -13,    25,   -50,   162,   162,   -50,    25,   -13,     6,    -2, },
+    {-2,     6,   -13,    24,   -46,   140,   181,   -51,    26,   -14,     7,    -2, },
+    {-1,     5,   -12,    22,   -42,   119,   200,   -51,    25,   -14,     7,    -2, },
+    {-1,     4,   -10,    19,   -36,    97,   216,   -48,    24,   -13,     6,    -2, },
+    {-1,     4,    -8,    15,   -29,    75,   230,   -43,    21,   -11,     5,    -2, },
+    {-1,     3,    -6,    12,   -22,    54,   241,   -36,    17,    -9,     5,    -2, },
+    { 0,     2,    -4,     8,   -15,    35,   249,   -26,    12,    -7,     3,    -1, },
+    { 0,     1,    -2,     4,    -7,    16,   254,   -14,     6,    -3,     2,    -1, },
+};
+
+const TFilterCoeff m_chromaFilter6[32][6] =
+{
+    {0, 0, 256, 0, 0, 0},
+    {1, -6, 256, 7, -2, 0},
+    {2, -11, 253, 15, -4, 1},
+    {3, -16, 251, 23, -6, 1},
+    {4, -21, 248, 33, -10, 2},
+    {5, -25, 244, 42, -12, 2},
+    {7, -30, 239, 53, -17, 4},
+    {7, -32, 234, 62, -19, 4},
+    {8, -35, 227, 73, -22, 5},
+    {9, -38, 220, 84, -26, 7},
+    {10, -40, 213, 95, -29, 7},
+    {10, -41, 204, 106, -31, 8},
+    {10, -42, 196, 117, -34, 9},
+    {10, -41, 187, 127, -35, 8},
+    {11, -42, 177, 138, -38, 10},
+    {10, -41, 168, 148, -39, 10},
+    {10, -40, 158, 158, -40, 10},
+    {10, -39, 148, 168, -41, 10},
+    {10, -38, 138, 177, -42, 11},
+    {8, -35, 127, 187, -41, 10},
+    {9, -34, 117, 196, -42, 10},
+    {8, -31, 106, 204, -41, 10},
+    {7, -29, 95, 213, -40, 10},
+    {7, -26, 84, 220, -38, 9},
+    {5, -22, 73, 227, -35, 8},
+    {4, -19, 62, 234, -32, 7},
+    {4, -17, 53, 239, -30, 7},
+    {2, -12, 42, 244, -25, 5},
+    {2, -10, 33, 248, -21, 4},
+    {1, -6, 23, 251, -16, 3},
+    {1, -4, 15, 253, -11, 2},
+    {0, -2, 7, 256, -6, 1},
+};
+#endif
 void Picture::sampleRateConv( const std::pair<int, int> scalingRatio, const std::pair<int, int> compScale,
                               const CPelBuf& beforeScale, const int beforeScaleLeftOffset, const int beforeScaleTopOffset,
                               const PelBuf& afterScale, const int afterScaleLeftOffset, const int afterScaleTopOffset,
                               const int bitDepth, const bool useLumaFilter, const bool downsampling,
+#if !JVET_AB0081
                               const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag )
+#else
+                              const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag,
+                              const bool rescaleForDisplay, const int upscaleFilterForDisplay )
+#endif
 {
   const Pel* orgSrc = beforeScale.buf;
   const int orgWidth = beforeScale.width;
@@ -662,8 +779,21 @@ void Picture::sampleRateConv( const std::pair<int, int> scalingRatio, const std:
     return;
   }
 
+#if JVET_AB0081
+  const TFilterCoeff* filterHor = useLumaFilter ? &InterpolationFilter::m_lumaFilter[0][0] : &InterpolationFilter::m_chromaFilter[0][0];
+  const TFilterCoeff* filterVer = useLumaFilter ? &InterpolationFilter::m_lumaFilter[0][0] : &InterpolationFilter::m_chromaFilter[0][0];
+  if (rescaleForDisplay)
+  {
+    if (upscaleFilterForDisplay != 0)
+    {
+      filterHor = useLumaFilter ? (upscaleFilterForDisplay == 1 ? &m_lumaFilter12_alt[0][0] : &m_lumaFilter12[0][0]) : (upscaleFilterForDisplay == 1 ? &m_chromaFilter6_alt[0][0] : &m_chromaFilter6[0][0]);
+      filterVer = useLumaFilter ? (upscaleFilterForDisplay == 1 ? &m_lumaFilter12_alt[0][0] : &m_lumaFilter12[0][0]) : (upscaleFilterForDisplay == 1 ? &m_chromaFilter6_alt[0][0] : &m_chromaFilter6[0][0]);
+    }
+  }
+#else
   const TFilterCoeff* filterHor = useLumaFilter ? &InterpolationFilter::m_lumaFilter[0][0] : &InterpolationFilter::m_chromaFilter[0][0];
   const TFilterCoeff* filterVer = useLumaFilter ? &InterpolationFilter::m_lumaFilter[0][0] : &InterpolationFilter::m_chromaFilter[0][0];
+#endif
   const int numFracPositions = useLumaFilter ? 15 : 31;
   const int numFracShift = useLumaFilter ? 4 : 5;
   const int posShiftX = SCALE_RATIO_BITS - numFracShift + compScale.first;
@@ -738,9 +868,16 @@ void Picture::sampleRateConv( const std::pair<int, int> scalingRatio, const std:
     filterVer = &DownsamplingFilterSRC[verFilter][0][0];
   }
 
+#if JVET_AB0081
+  int filterLengthsLuma[3] = { 8, 12, 12 };
+  int filterLengthsChroma[3] = { 4, 6, 6 };
+  int log2NormList[3] = { 12, 16, 16 };
+  const int filterLength = downsampling ? 12 : (rescaleForDisplay ? (useLumaFilter ? filterLengthsLuma[upscaleFilterForDisplay] : filterLengthsChroma[upscaleFilterForDisplay]) : useLumaFilter ? NTAPS_LUMA : NTAPS_CHROMA);
+  const int log2Norm = downsampling ? 14 : (rescaleForDisplay ? log2NormList[upscaleFilterForDisplay] : 12);
+#else
   const int filterLength = downsampling ? 12 : ( useLumaFilter ? NTAPS_LUMA : NTAPS_CHROMA );
   const int log2Norm = downsampling ? 14 : 12;
-
+#endif
   int *buf = new int[orgHeight * scaledWidth];
   int maxVal = ( 1 << bitDepth ) - 1;
 
@@ -805,7 +942,12 @@ void Picture::rescalePicture( const std::pair<int, int> scalingRatio,
                               const CPelUnitBuf& beforeScaling, const Window& scalingWindowBefore,
                               const PelUnitBuf& afterScaling, const Window& scalingWindowAfter,
                               const ChromaFormat chromaFormatIDC, const BitDepths& bitDepths, const bool useLumaFilter, const bool downsampling,
+#if !JVET_AB0081
                               const bool horCollocatedChromaFlag, const bool verCollocatedChromaFlag )
+#else
+                              const bool horCollocatedChromaFlag, const bool verCollocatedChromaFlag,
+                              bool rescaleForDisplay, int upscaleFilterForDisplay )
+#endif
 {
   for( int comp = 0; comp < ::getNumberValidComponents( chromaFormatIDC ); comp++ )
   {
@@ -817,7 +959,12 @@ void Picture::rescalePicture( const std::pair<int, int> scalingRatio,
                     beforeScale, scalingWindowBefore.getWindowLeftOffset() * SPS::getWinUnitX( chromaFormatIDC ), scalingWindowBefore.getWindowTopOffset() * SPS::getWinUnitY( chromaFormatIDC ),
                     afterScale, scalingWindowAfter.getWindowLeftOffset() * SPS::getWinUnitX( chromaFormatIDC ), scalingWindowAfter.getWindowTopOffset() * SPS::getWinUnitY( chromaFormatIDC ),
                     bitDepths.recon[toChannelType(compID)], downsampling || useLumaFilter ? true : isLuma( compID ), downsampling,
+#if !JVET_AB0081
                     isLuma( compID ) ? 1 : horCollocatedChromaFlag, isLuma( compID ) ? 1 : verCollocatedChromaFlag );
+#else
+                    isLuma(compID) ? 1 : horCollocatedChromaFlag, isLuma(compID) ? 1 : verCollocatedChromaFlag,
+                    rescaleForDisplay, upscaleFilterForDisplay );
+#endif
   }
 }
 
diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h
index 66073bf61..6bc1239e6 100644
--- a/source/Lib/CommonLib/Picture.h
+++ b/source/Lib/CommonLib/Picture.h
@@ -174,14 +174,23 @@ struct Picture : public UnitArea
                                 const CPelBuf& beforeScale, const int beforeScaleLeftOffset, const int beforeScaleTopOffset,
                                 const PelBuf& afterScale, const int afterScaleLeftOffset, const int afterScaleTopOffset,
                                 const int bitDepth, const bool useLumaFilter, const bool downsampling,
+#if !JVET_AB0081
                                 const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag );
+#else
+                                const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag,
+                                const bool rescaleForDisplay, const int upscaleFilterForDisplay );
+#endif
 
   static void   rescalePicture( const std::pair<int, int> scalingRatio,
                                 const CPelUnitBuf& beforeScaling, const Window& scalingWindowBefore,
                                 const PelUnitBuf& afterScaling, const Window& scalingWindowAfter,
                                 const ChromaFormat chromaFormatIDC, const BitDepths& bitDepths, const bool useLumaFilter, const bool downsampling,
+#if !JVET_AB0081
                                 const bool horCollocatedChromaFlag, const bool verCollocatedChromaFlag );
-
+#else
+                                const bool horCollocatedChromaFlag, const bool verCollocatedChromaFlag,
+                                bool rescaleForDisplay = false, int upscaleFilterForDisplay = 0 );
+#endif
 private:
   Window        m_conformanceWindow;
   Window        m_scalingWindow;
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 2321069f5..20e39e97e 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -54,6 +54,7 @@
 
 //########### place macros to be removed in next cycle below this line ###############
 #define JVET_AC0096                                        1 // RPR functionality testing
+#define JVET_AB0081                                        1 // Upscaling filter for display 12-tap luma and 6-tap chroma
 
 #define JVET_AA0098_MAX_MTT_DEPTH_TID                      1 // JVET-X0144: max MTT hierarchy depth set by temporal ID
 #if JVET_AA0098_MAX_MTT_DEPTH_TID
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index b076d9a8a..b53fa9a5d 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -788,6 +788,9 @@ protected:
   double      m_scalingRatioVer3;
 #endif
   int         m_upscaledOutput;
+#if JVET_AB0081
+  int         m_upscaleFilterForDisplay;
+#endif
   int         m_numRefLayers[MAX_VPS_LAYERS];
   bool        m_avoidIntraInDepLayer;
 
@@ -2037,7 +2040,10 @@ public:
 #endif
   void        setUpscaledOutput( int b )                             { m_upscaledOutput = b; }
   int         getUpscaledOutput()                              const { return m_upscaledOutput; }
-
+#if JVET_AB0081
+  void        setUpscaleFilerForDisplay(int b)                       { m_upscaleFilterForDisplay = b; }
+  int         getUpscaleFilerForDisplay()                      const { return m_upscaleFilterForDisplay; }
+#endif
   void        setNumRefLayers( int* numRefLayers )                   { std::memcpy( m_numRefLayers, numRefLayers, sizeof( m_numRefLayers ) ); }
   int         getNumRefLayers( int layerIdx )                  const { return m_numRefLayers[layerIdx];  }
 
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 349116a8e..4c65f835e 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -4282,7 +4282,12 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
     CU::getRprScaling( &sps, pps, pcPic, xScale, yScale );
     std::pair<int, int> scalingRatio = std::pair<int, int>( xScale, yScale );
 
+#if JVET_AB0081
+    bool rescaleForDisplay = true;
+    Picture::rescalePicture(scalingRatio, picC, pcPic->getScalingWindow(), upscaledRec, pps->getScalingWindow(), format, sps.getBitDepths(), false, false, sps.getHorCollocatedChromaFlag(), sps.getVerCollocatedChromaFlag(), rescaleForDisplay, m_pcCfg->getUpscaleFilerForDisplay());
+#else
     Picture::rescalePicture( scalingRatio, picC, pcPic->getScalingWindow(), upscaledRec, pps->getScalingWindow(), format, sps.getBitDepths(), false, false, sps.getHorCollocatedChromaFlag(), sps.getVerCollocatedChromaFlag() );
+#endif
   }
 
   for (int comp = 0; comp < ::getNumberValidComponents(formatD); comp++)
diff --git a/source/Lib/Utilities/VideoIOYuv.cpp b/source/Lib/Utilities/VideoIOYuv.cpp
index 8a30ccc5d..afdaf700d 100644
--- a/source/Lib/Utilities/VideoIOYuv.cpp
+++ b/source/Lib/Utilities/VideoIOYuv.cpp
@@ -1252,7 +1252,11 @@ void VideoIOYuv::ColourSpaceConvert(const CPelUnitBuf &src, PelUnitBuf &dest, co
   }
 }
 
+#if !JVET_AB0081
 bool VideoIOYuv::writeUpscaledPicture( const SPS& sps, const PPS& pps, const CPelUnitBuf& pic, const InputColourSpaceConversion ipCSC, const bool bPackedYUVOutputMode, int outputChoice, ChromaFormat format, const bool bClipToRec709 )
+#else
+bool VideoIOYuv::writeUpscaledPicture(const SPS& sps, const PPS& pps, const CPelUnitBuf& pic, const InputColourSpaceConversion ipCSC, const bool bPackedYUVOutputMode, int outputChoice, ChromaFormat format, const bool bClipToRec709, int upscaleFilterForDisplay)
+#endif
 {
   ChromaFormat chromaFormatIDC = sps.getChromaFormatIdc();
   bool ret = false;
@@ -1284,8 +1288,12 @@ bool VideoIOYuv::writeUpscaledPicture( const SPS& sps, const PPS& pps, const CPe
       int xScale = ( ( refPicWidth << SCALE_RATIO_BITS ) + ( curPicWidth >> 1 ) ) / curPicWidth;
       int yScale = ( ( refPicHeight << SCALE_RATIO_BITS ) + ( curPicHeight >> 1 ) ) / curPicHeight;
 
+#if JVET_AB0081
+      bool rescaleForDisplay = true;
+      Picture::rescalePicture(std::pair<int, int>(xScale, yScale), pic, pps.getScalingWindow(), upscaledPic, afterScaleWindowFullResolution, chromaFormatIDC, sps.getBitDepths(), false, false, sps.getHorCollocatedChromaFlag(), sps.getVerCollocatedChromaFlag(), rescaleForDisplay, upscaleFilterForDisplay);
+#else
       Picture::rescalePicture( std::pair<int, int>( xScale, yScale ), pic, pps.getScalingWindow(), upscaledPic, afterScaleWindowFullResolution, chromaFormatIDC, sps.getBitDepths(), false, false, sps.getHorCollocatedChromaFlag(), sps.getVerCollocatedChromaFlag() );
-
+#endif
       ret = write( sps.getMaxPicWidthInLumaSamples(), sps.getMaxPicHeightInLumaSamples(), upscaledPic,
         ipCSC,
         bPackedYUVOutputMode,
diff --git a/source/Lib/Utilities/VideoIOYuv.h b/source/Lib/Utilities/VideoIOYuv.h
index bf2c47056..34ae68af3 100644
--- a/source/Lib/Utilities/VideoIOYuv.h
+++ b/source/Lib/Utilities/VideoIOYuv.h
@@ -101,8 +101,11 @@ public:
   int   getFileBitdepth( int ch )           { return m_fileBitdepth[ch];  }
 
   bool  writeUpscaledPicture( const SPS& sps, const PPS& pps, const CPelUnitBuf& pic,
+#if !JVET_AB0081
     const InputColourSpaceConversion ipCSC, const bool bPackedYUVOutputMode, int outputChoice = 0, ChromaFormat format = NUM_CHROMA_FORMAT, const bool bClipToRec709 = false ); ///< write one upsaled YUV frame
-
+#else
+    const InputColourSpaceConversion ipCSC, const bool bPackedYUVOutputMode, int outputChoice = 0, ChromaFormat format = NUM_CHROMA_FORMAT, const bool bClipToRec709 = false, int        upscaleFilterForDisplay = 2); ///< write one upsaled YUV frame
+#endif
 };
 
 #endif // __VIDEOIOYUV__
-- 
GitLab


From 4965cb855ba291ed6836ed1ec38c4e5d6c63528e Mon Sep 17 00:00:00 2001
From: Kenneth Andersson <kenneth.r.andersson@ericsson.com>
Date: Thu, 2 Feb 2023 18:59:11 +0100
Subject: [PATCH 2/2] Removed last underscore in variable names

---
 source/Lib/CommonLib/Picture.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index bd1ea4355..e30e6e0c3 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -637,7 +637,7 @@ const TFilterCoeff DownsamplingFilterSRC[8][16][12] =
 };
 
 #if JVET_AB0081
-const TFilterCoeff m_lumaFilter12_alt[16][12] =
+const TFilterCoeff m_lumaFilter12Alt[16][12] =
 {
 { 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, },
 { 1, -1, 0, 3, -12, 253, 16, -6, 2, 0, 0, 0, },
@@ -656,7 +656,7 @@ const TFilterCoeff m_lumaFilter12_alt[16][12] =
 { 0, 0, -1, 4, -11, 32, 250, -24, 9, -3, 0, 0, },
 { 0, 0, 0, 2, -6, 16, 253, -12, 3, 0, -1, 1, },
 };
-const TFilterCoeff m_chromaFilter6_alt[32][6] =
+const TFilterCoeff m_chromaFilter6Alt[32][6] =
 {
 {0, 0, 256, 0, 0, 0, },
 { 1, -6, 256, 6, -1, 0, },
@@ -786,8 +786,8 @@ void Picture::sampleRateConv( const std::pair<int, int> scalingRatio, const std:
   {
     if (upscaleFilterForDisplay != 0)
     {
-      filterHor = useLumaFilter ? (upscaleFilterForDisplay == 1 ? &m_lumaFilter12_alt[0][0] : &m_lumaFilter12[0][0]) : (upscaleFilterForDisplay == 1 ? &m_chromaFilter6_alt[0][0] : &m_chromaFilter6[0][0]);
-      filterVer = useLumaFilter ? (upscaleFilterForDisplay == 1 ? &m_lumaFilter12_alt[0][0] : &m_lumaFilter12[0][0]) : (upscaleFilterForDisplay == 1 ? &m_chromaFilter6_alt[0][0] : &m_chromaFilter6[0][0]);
+      filterHor = useLumaFilter ? (upscaleFilterForDisplay == 1 ? &m_lumaFilter12Alt[0][0] : &m_lumaFilter12[0][0]) : (upscaleFilterForDisplay == 1 ? &m_chromaFilter6Alt[0][0] : &m_chromaFilter6[0][0]);
+      filterVer = useLumaFilter ? (upscaleFilterForDisplay == 1 ? &m_lumaFilter12Alt[0][0] : &m_lumaFilter12[0][0]) : (upscaleFilterForDisplay == 1 ? &m_chromaFilter6Alt[0][0] : &m_chromaFilter6[0][0]);
     }
   }
 #else
-- 
GitLab