From f5d1f77d010e34781c8f92137d673ad93c037142 Mon Sep 17 00:00:00 2001
From: zhipin <zhipin.deng@bytedance.com>
Date: Fri, 15 May 2020 12:32:06 +0800
Subject: [PATCH] JVET-R0058: the combination of RPR, subpictures, and
 scalability

---
 cfg/multi-layer/two_layers_ELonlyILP.cfg      |  29 +++
 ...llText_subpicture_4_slice_2_hor_subpic.cfg |  48 +++++
 source/App/EncoderApp/EncApp.cpp              |  22 ++-
 source/App/EncoderApp/EncAppCfg.cpp           |  25 ++-
 source/App/EncoderApp/EncAppCfg.h             |   8 +
 source/Lib/CommonLib/InterPrediction.cpp      |  12 +-
 source/Lib/CommonLib/Mv.cpp                   |  52 +++++
 source/Lib/CommonLib/Mv.h                     |   7 +-
 source/Lib/CommonLib/Slice.cpp                |   9 +
 source/Lib/CommonLib/Slice.h                  |  14 ++
 source/Lib/CommonLib/TypeDef.h                |   1 +
 source/Lib/CommonLib/UnitTools.cpp            |  55 ++++++
 source/Lib/CommonLib/UnitTools.h              |   3 +
 source/Lib/DecoderLib/DecLib.cpp              |  25 ++-
 source/Lib/DecoderLib/DecSlice.cpp            |  15 +-
 source/Lib/DecoderLib/VLCReader.cpp           |  14 +-
 source/Lib/EncoderLib/EncCfg.h                |  11 +-
 source/Lib/EncoderLib/EncGOP.cpp              | 181 ++++++++++++------
 source/Lib/EncoderLib/EncLib.cpp              |  47 ++++-
 source/Lib/EncoderLib/EncLib.h                |   7 +-
 source/Lib/EncoderLib/EncSlice.cpp            |   6 +-
 source/Lib/EncoderLib/InterSearch.cpp         |  29 +--
 source/Lib/EncoderLib/InterSearch.h           |   6 +
 source/Lib/EncoderLib/VLCWriter.cpp           |  11 +-
 24 files changed, 536 insertions(+), 101 deletions(-)
 create mode 100644 cfg/multi-layer/two_layers_ELonlyILP.cfg
 create mode 100644 cfg/partitioning/BasketballDrillText_subpicture_4_slice_2_hor_subpic.cfg

diff --git a/cfg/multi-layer/two_layers_ELonlyILP.cfg b/cfg/multi-layer/two_layers_ELonlyILP.cfg
new file mode 100644
index 000000000..3bca52040
--- /dev/null
+++ b/cfg/multi-layer/two_layers_ELonlyILP.cfg
@@ -0,0 +1,29 @@
+#======== Layers ===============
+MaxLayers                     : 2
+MaxSublayers                  : 1
+AllLayersSameNumSublayersFlag : 0
+AllIndependentLayersFlag      : 0
+AllowablePredDirection 	  	  : 1 1 1 1 1 	  # equal to 0 specifies the picture in the i-th temporal layer is allowed to use both inter-layer and intra-layer preditions
+											  # equal to 1 specifies the picture in the i-th temporal layer is allowed to use inter-layer predition only
+										      # equal to 2 specifies the picture in the i-th temporal layer is allowed to use intra-layer predition only
+											  
+#======== OLSs ===============
+EachLayerIsAnOlsFlag          : 0
+OlsModeIdc                    : 2
+NumOutputLayerSets            : 2
+OlsOutputLayer1               : 1 0
+NumPTLsInVPS                  : 2
+#======== Layer-0 ===============
+LayerId0                      : 0
+#======== Layer-1 ===============
+LayerId1                      : 1
+NumRefLayers1                 : 1
+RefLayerIdx1                  : 0
+#======== OLS-0 ===============
+OlsPTLIdx0                    : 0
+#======== OLS-1 ===============
+LevelPTL1                     : 6.2
+OlsPTLIdx1                    : 1
+
+
+
diff --git a/cfg/partitioning/BasketballDrillText_subpicture_4_slice_2_hor_subpic.cfg b/cfg/partitioning/BasketballDrillText_subpicture_4_slice_2_hor_subpic.cfg
new file mode 100644
index 000000000..e72abb014
--- /dev/null
+++ b/cfg/partitioning/BasketballDrillText_subpicture_4_slice_2_hor_subpic.cfg
@@ -0,0 +1,48 @@
+#======== File I/O ===============
+InputFile                     : BasketballDrillText_832x480_50.yuv
+InputBitDepth                 : 8           # Input bitdepth
+InputChromaFormat             : 420         # Ratio of luminance to chrominance samples
+FrameRate                     : 50          # Frame Rate per second
+FrameSkip                     : 0           # Number of frames to be skipped in input
+SourceWidth                   : 832         # Input  frame width
+SourceHeight                  : 480         # Input  frame height
+FramesToBeEncoded             : 500         # Number of frames to be coded
+
+Level                         : 3.1
+
+#============ Subpictures ==================
+# example cfg file, assuming an 832x480 input sequence with CTU size = 128x128, and split to 4 rectangular slices, each slice include one tile.
+# example 2 subpictures in a 832x480 picture:
+#----------
+#|    |   |
+#|    |   |
+#|----|---|--> horizontally divided into 2 subpicture, each subpicture contains two slices
+#|    |   |
+#|    |   |
+#----------
+
+SubPicInfoPresentFlag                   : 1             # subpicture information present flag(0: OFF, 1: ON)
+NumSubPics                              : 2             # number of subpictures in a picture
+SubPicCtuTopLeftX                       : 0 0           # specifies horizontal position of top left CTU of i-th subpicture in unit of CtbSizeY 
+SubPicCtuTopLeftY                       : 0 2           # specifies vertical position of top left CTU of i-th subpicture in unit of CtbSizeY
+SubPicWidth                             : 7 7           # specifies the width of the i-th subpicture in units of CtbSizeY
+SubPicHeight                            : 2 2           # specifies the height of the i-th subpicture in units of CtbSizeY
+SubPicTreatedAsPicFlag                  : 1 1           # equal to 1 specifies that the i-th subpicture of each coded picture in the CLVS is treated as a picture in the decoding process excluding in-loop filtering operations
+LoopFilterAcrossSubpicEnabledFlag       : 0 0           # equal to 1 specifies that in-loop filtering operations may be performed across the boundaries of the i-th subpicture in each coded picture in the CLVS
+SubPicIdMappingExplicitlySignalledFlag  : 0             # equal to 1 specifies that the subpicture ID mapping is explicitly signalled, either in the SPS or in the PPSs
+SubPicIdMappingInSpsFlag                : 0             # specifies that subpicture ID mapping is signalled in the SPS(0: OFF, 1: ON)
+SubPicIdLen                             : 0             # the number of bits used to represent the syntax element sps_subpic_id[ i ]
+SubPicId                                : 0             # subpicture ID of the i-th subpicture
+
+
+#============ Tiles / Slices ================
+EnablePicPartitioning         : 1                       # Enable picture partitioning (0: single tile, single slice, 1: multiple tiles/slices can be used)
+
+# 24 tiles and 6 rectangular slices
+TileColumnWidthArray          : 4                       # Tile column widths in units of CTUs. Last column width will be repeated uniformly to cover any remaining picture width
+TileRowHeightArray            : 2                       # Tile row heights in units of CTUs. Last row height will be repeated uniformly to cover any remaining picture height  
+RasterScanSlices              : 0                       # Raster-scan or rectangular slices (0: rectangular, 1: raster-scan)
+RectSliceFixedWidth           : 1                       # Fixed rectangular slice width in units of tiles (0: disable this feature and use RectSlicePositions instead)
+RectSliceFixedHeight          : 1                       # Fixed rectangular slice height in units of tiles (0: disable this feature and use RectSlicePositions instead)
+DisableLoopFilterAcrossTiles  : 1                       # Loop filtering (DBLK/SAO/ALF) applied across tile boundaries or not (0: filter across tile boundaries  1: do not filter across tile boundaries)
+DisableLoopFilterAcrossSlices : 1                       # Loop filtering (DBLK/SAO/ALF) applied across slice boundaries or not (0: filter across slice boundaries 1: do not filter across slice boundaries)
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 9f293af2c..c9004e612 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -103,6 +103,19 @@ void EncApp::xInitLibCfg()
     if (!vps.getAllIndependentLayersFlag())
     {
       vps.setEachLayerIsAnOlsFlag(0);
+#if JVET_R0058
+      for (int i = 0; i < m_maxTempLayer; i++)
+      {
+        vps.setPredDirection(i, 0);
+      }
+      for (int i = 0; i < m_predDirectionArray.size(); i++)
+      {
+        if (m_predDirectionArray[i] != ' ')
+        {
+          vps.setPredDirection(i >> 1, int(m_predDirectionArray[i] - 48));
+        }
+      }
+#endif
     }
   }
 
@@ -114,7 +127,6 @@ void EncApp::xInitLibCfg()
     if (i > 0 && !vps.getAllIndependentLayersFlag())
     {
       vps.setIndependentLayerFlag( i, m_numRefLayers[i] ? false : true );
-
       if (!vps.getIndependentLayerFlag(i))
       {
         for (int j = 0, k = 0; j < i; j++)
@@ -238,7 +250,11 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setSourceHeight                                      ( m_iSourceHeight );
   m_cEncLib.setConformanceWindow                                 ( m_confWinLeft / SPS::getWinUnitX( m_InputChromaFormatIDC ), m_confWinRight / SPS::getWinUnitX( m_InputChromaFormatIDC ), m_confWinTop / SPS::getWinUnitY( m_InputChromaFormatIDC ), m_confWinBottom / SPS::getWinUnitY( m_InputChromaFormatIDC ) );
   m_cEncLib.setScalingRatio                                      ( m_scalingRatioHor, m_scalingRatioVer );
+#if JVET_R0058
+  m_cEncLib.setResChangeInClvsEnabled                            ( m_resChangeInClvsEnabled );
+#else
   m_cEncLib.setRPREnabled                                        ( m_rprEnabled );
+#endif
   m_cEncLib.setSwitchPocPeriod                                   ( m_switchPocPeriod );
   m_cEncLib.setUpscaledOutput                                    ( m_upscaledOutput );
   m_cEncLib.setFramesToBeEncoded                                 ( m_framesToBeEncoded );
@@ -1149,7 +1165,11 @@ void EncApp::xWriteOutput( int iNumEncoded, std::list<PelUnitBuf*>& recBufList )
       const PelUnitBuf* pcPicYuvRec = *(iterPicYuvRec++);
       if (!m_reconFileName.empty())
       {
+#if JVET_R0058
+        if( m_cEncLib.isResChangeInClvsEnabled() && m_cEncLib.getUpscaledOutput() )
+#else
         if( m_cEncLib.isRPREnabled() && m_cEncLib.getUpscaledOutput() )
+#endif
         {
           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 );
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 497afeedd..fb988e9b0 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1382,6 +1382,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ( "MaxSublayers",                                   m_maxSublayers,                               1, "Max number of Sublayers")
   ( "AllLayersSameNumSublayersFlag",                  m_allLayersSameNumSublayersFlag,           true, "All layers same num sublayersflag")
   ( "AllIndependentLayersFlag",                       m_allIndependentLayersFlag,                true, "All layers are independent layer")
+#if JVET_R0058
+  ("AllowablePredDirection",                          m_predDirectionArray, string(""),                "prediction directions allowed for i-th temporal layer")
+#endif
   ( "LayerId%d",                                      m_layerId,                    0, MAX_VPS_LAYERS, "Max number of Sublayers")
   ( "NumRefLayers%d",                                 m_numRefLayers,               0, MAX_VPS_LAYERS, "Number of direct reference layer index of i-th layer")
   ( "RefLayerIdx%d",                                  m_refLayerIdxStr,    string(""), MAX_VPS_LAYERS, "Reference layer index(es)")
@@ -1425,13 +1428,21 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   po::ErrorReporter err;
   const list<const char*>& argv_unhandled = po::scanArgv(opts, argc, (const char**) argv, err);
 
+#if JVET_R0058
+  m_resChangeInClvsEnabled = m_scalingRatioHor != 1.0 || m_scalingRatioVer != 1.0;
+#else
   m_rprEnabled = m_scalingRatioHor != 1.0 || m_scalingRatioVer != 1.0;
+#endif
   if( m_fractionOfFrames != 1.0 )
   {
     m_framesToBeEncoded = int( m_framesToBeEncoded * m_fractionOfFrames );
   }
 
-  if( m_rprEnabled && !m_switchPocPeriod )
+#if JVET_R0058
+  if (m_resChangeInClvsEnabled && !m_switchPocPeriod)
+#else
+  if (m_rprEnabled && !m_switchPocPeriod)
+#endif
   {
     m_switchPocPeriod = m_iFrameRate / 2 / m_iGOPSize * m_iGOPSize;
   }
@@ -1628,7 +1639,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
     }
 
     CHECK( m_subPicIdLen > 16, "SubPicIdLen must not exceed 16 bits" );
-    CHECK( m_rprEnabled, "RPR and subpictures cannot be enabled together" );
+#if JVET_R0058
+    CHECK(m_resChangeInClvsEnabled, "resolution change in CLVS and subpictures cannot be enabled together");
+#else
+    CHECK(m_rprEnabled, "RPR and subpictures cannot be enabled together");
+#endif
   }
 
   if (m_cfgSubpictureLevelInfoSEI.m_enabled)
@@ -3828,7 +3843,11 @@ void EncAppCfg::xPrintParameter()
   msg( VERBOSE, "NumWppThreads:%d+%d ", m_numWppThreads, m_numWppExtraLines );
   msg( VERBOSE, "EnsureWppBitEqual:%d ", m_ensureWppBitEqual );
 
-  if( m_rprEnabled )
+#if JVET_R0058
+  if (m_resChangeInClvsEnabled)
+#else
+  if (m_rprEnabled)
+#endif
   {
     msg( VERBOSE, "RPR:(%1.2lfx, %1.2lfx)|%d ", m_scalingRatioHor, m_scalingRatioVer, m_switchPocPeriod );
   }
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 6bd0a61c2..c995933d7 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -706,7 +706,11 @@ protected:
 
   double      m_scalingRatioHor;
   double      m_scalingRatioVer;
+#if JVET_R0058
+  bool        m_resChangeInClvsEnabled;
+#else
   bool        m_rprEnabled;
+#endif
   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.
@@ -723,6 +727,10 @@ protected:
   int         m_maxSublayers;
   bool        m_allLayersSameNumSublayersFlag;
   bool        m_allIndependentLayersFlag;
+#if JVET_R0058
+  std::string m_predDirectionArray;
+#endif
+
   int         m_numRefLayers[MAX_VPS_LAYERS];
   std::string m_refLayerIdxStr[MAX_VPS_LAYERS];
   bool        m_eachLayerIsAnOlsFlag;
diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index 0a7e90530..ac3ac1fea 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -476,7 +476,11 @@ void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList&
 
   if( !pu.cu->affine )
   {
+#if JVET_R0058
+    if (!isIBC)
+#else
     if( !isIBC && pu.cu->slice->getRefPic( eRefPicList, iRefIdx )->isRefScaled( pu.cs->pps ) == false )
+#endif
     {
 #if JVET_Q0764_WRAP_AROUND_WITH_RPR
       if( !pu.cs->pps->getWrapAroundEnabledFlag() )
@@ -1095,7 +1099,9 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
         {
           wrapRef = false;
           m_storedMv[h / AFFINE_MIN_BLOCK_SIZE * MVBUFFER_SIZE + w / AFFINE_MIN_BLOCK_SIZE].set(iMvScaleTmpHor, iMvScaleTmpVer);
-          if( refPic->isRefScaled( pu.cs->pps ) == false )
+#if !JVET_R0058
+          if (refPic->isRefScaled(pu.cs->pps) == false)
+#endif
           {
             clipMv(tmpMv, pu.lumaPos(), pu.lumaSize(), *pu.cs->sps, *pu.cs->pps);
             iMvScaleTmpHor = tmpMv.getHor();
@@ -1119,7 +1125,9 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
         else
         {
           wrapRef = false;
-          if( refPic->isRefScaled( pu.cs->pps ) == false )
+#if !JVET_R0058
+          if (refPic->isRefScaled(pu.cs->pps) == false)
+#endif
           {
             clipMv(curMv, pu.lumaPos(), pu.lumaSize(), *pu.cs->sps, *pu.cs->pps);
           }
diff --git a/source/Lib/CommonLib/Mv.cpp b/source/Lib/CommonLib/Mv.cpp
index 2bfb1333a..528c3c4dd 100644
--- a/source/Lib/CommonLib/Mv.cpp
+++ b/source/Lib/CommonLib/Mv.cpp
@@ -51,6 +51,57 @@ void roundAffineMv( int& mvx, int& mvy, int nShift )
   mvy = (mvy + nOffset - (mvy >= 0)) >> nShift;
 }
 
+#if JVET_R0058
+void (*clipMv) ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps );
+
+void clipMvInPic ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps )
+{
+  if (sps.getWrapAroundEnabledFlag())
+  {
+    wrapClipMv(rcMv, pos, size, &sps, &pps);
+    return;
+  }
+
+  int iMvShift = MV_FRACTIONAL_BITS_INTERNAL;
+  int iOffset = 8;
+  int iHorMax = (pps.getPicWidthInLumaSamples() + iOffset - (int)pos.x - 1) << iMvShift;
+  int iHorMin = (-(int)sps.getMaxCUWidth() - iOffset - (int)pos.x + 1) << iMvShift;
+
+  int iVerMax = (pps.getPicHeightInLumaSamples() + iOffset - (int)pos.y - 1) << iMvShift;
+  int iVerMin = (-(int)sps.getMaxCUHeight() - iOffset - (int)pos.y + 1) << iMvShift;
+
+  rcMv.setHor(std::min(iHorMax, std::max(iHorMin, rcMv.getHor())));
+  rcMv.setVer(std::min(iVerMax, std::max(iVerMin, rcMv.getVer())));
+}
+
+void clipMvInSubpic ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps )
+{
+  if (sps.getWrapAroundEnabledFlag())
+  {
+    wrapClipMv(rcMv, pos, size, &sps, &pps);
+    return;
+  }
+
+  int iMvShift = MV_FRACTIONAL_BITS_INTERNAL;
+  int iOffset = 8;
+  int iHorMax = (pps.getPicWidthInLumaSamples() + iOffset - (int)pos.x - 1) << iMvShift;
+  int iHorMin = (-(int)sps.getMaxCUWidth() - iOffset - (int)pos.x + 1) << iMvShift;
+
+  int iVerMax = (pps.getPicHeightInLumaSamples() + iOffset - (int)pos.y - 1) << iMvShift;
+  int iVerMin = (-(int)sps.getMaxCUHeight() - iOffset - (int)pos.y + 1) << iMvShift;
+  const SubPic& curSubPic = pps.getSubPicFromPos(pos);
+  if (curSubPic.getTreatedAsPicFlag())
+  {
+    iHorMax = ((curSubPic.getSubPicRight() + 1) + iOffset - (int)pos.x - 1) << iMvShift;
+    iHorMin = (-(int)sps.getMaxCUWidth() - iOffset - ((int)pos.x - curSubPic.getSubPicLeft()) + 1) << iMvShift;
+
+    iVerMax = ((curSubPic.getSubPicBottom() + 1) + iOffset - (int)pos.y - 1) << iMvShift;
+    iVerMin = (-(int)sps.getMaxCUHeight() - iOffset - ((int)pos.y - curSubPic.getSubPicTop()) + 1) << iMvShift;
+  }
+  rcMv.setHor(std::min(iHorMax, std::max(iHorMin, rcMv.getHor())));
+  rcMv.setVer(std::min(iVerMax, std::max(iVerMin, rcMv.getVer())));
+}
+#else
 void clipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS& sps, const PPS& pps )
 {
 #if JVET_Q0764_WRAP_AROUND_WITH_RPR
@@ -82,6 +133,7 @@ void clipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS&
   rcMv.setHor( std::min( iHorMax, std::max( iHorMin, rcMv.getHor() ) ) );
   rcMv.setVer( std::min( iVerMax, std::max( iVerMin, rcMv.getVer() ) ) );
 }
+#endif
 
 bool wrapClipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS *sps, const PPS *pps )
 {
diff --git a/source/Lib/CommonLib/Mv.h b/source/Lib/CommonLib/Mv.h
index e06db56a9..f019c3a74 100644
--- a/source/Lib/CommonLib/Mv.h
+++ b/source/Lib/CommonLib/Mv.h
@@ -281,12 +281,17 @@ namespace std
     }
   };
 };
+#if JVET_R0058
+extern void(*clipMv) ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps );
+void clipMvInPic ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps );
+void clipMvInSubpic ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps );
+#else
 void clipMv ( Mv& rcMv, const struct Position& pos,
               const struct Size& size,
               const class SPS& sps
             , const class PPS& pps
 );
-
+#endif
 bool wrapClipMv( Mv& rcMv, const Position& pos,
                  const struct Size& size,
                  const SPS *sps
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index b70cd5767..b6d8ff6d7 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -1961,6 +1961,12 @@ VPS::VPS()
   , m_sublayerDpbParamsPresentFlag( false )
   , m_targetOlsIdx( -1 )
 {
+#if JVET_R0058
+  for (int i = 0; i < MAX_VPS_SUBLAYERS; i++)
+  {
+    m_vpsCfgPredDirection[i] = 0;
+  }
+#endif
   for (int i = 0; i < MAX_VPS_LAYERS; i++)
   {
     m_vpsLayerId[i] = 0;
@@ -2505,6 +2511,9 @@ SPS::SPS()
 , m_GDREnabledFlag            ( true )
 , m_SubLayerCbpParametersPresentFlag ( true )
 , m_rprEnabledFlag            ( false )
+#if JVET_R0058
+, m_resChangeInClvsEnabledFlag ( false )
+#endif
 , m_maxNumMergeCand(MRG_MAX_NUM_CANDS)
 , m_maxNumAffineMergeCand(AFFINE_MRG_MAX_NUM_CANDS)
 , m_maxNumIBCMergeCand(IBC_MRG_MAX_NUM_CANDS)
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index fada6a97b..293a1d0e0 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -928,6 +928,9 @@ private:
   uint32_t              m_vpsLayerId[MAX_VPS_LAYERS];
   bool                  m_vpsAllLayersSameNumSubLayersFlag;
   bool                  m_vpsAllIndependentLayersFlag;
+#if JVET_R0058
+  uint32_t              m_vpsCfgPredDirection[MAX_VPS_SUBLAYERS];
+#endif
   bool                  m_vpsIndependentLayerFlag[MAX_VPS_LAYERS];
   bool                  m_vpsDirectRefLayerFlag[MAX_VPS_LAYERS][MAX_VPS_LAYERS];
   bool                  m_vpsEachLayerIsAnOlsFlag;
@@ -994,6 +997,10 @@ public:
 
   bool              getAllIndependentLayersFlag() const { return m_vpsAllIndependentLayersFlag; }
   void              setAllIndependentLayersFlag(bool t) { m_vpsAllIndependentLayersFlag = t; }
+#if JVET_R0058
+  uint32_t          getPredDirection(uint32_t tmplayer) const { return m_vpsCfgPredDirection[tmplayer]; }
+  void              setPredDirection(uint32_t tmplayer, uint32_t t) { m_vpsCfgPredDirection[tmplayer] = t; }
+#endif
 
   bool              getIndependentLayerFlag(uint32_t layerIdx) const { return m_vpsIndependentLayerFlag[layerIdx]; }
   void              setIndependentLayerFlag(uint32_t layerIdx, bool t) { m_vpsIndependentLayerFlag[layerIdx] = t; }
@@ -1460,6 +1467,9 @@ private:
   bool              m_SubLayerCbpParametersPresentFlag;
 
   bool              m_rprEnabledFlag;
+#if JVET_R0058
+  bool              m_resChangeInClvsEnabledFlag;
+#endif
   bool              m_interLayerPresentFlag;
 
   uint32_t          m_log2ParallelMergeLevelMinus2;
@@ -1849,6 +1859,10 @@ void                    setCCALFEnabledFlag( bool b )
   void      setRprEnabledFlag( bool flag )                                          { m_rprEnabledFlag = flag; }
   bool      getInterLayerPresentFlag()                                        const { return m_interLayerPresentFlag; }
   void      setInterLayerPresentFlag( bool b )                                      { m_interLayerPresentFlag = b; }
+#if JVET_R0058
+  bool      getResChangeInClvsEnabledFlag()                               const     { return m_resChangeInClvsEnabledFlag; }
+  void      setResChangeInClvsEnabledFlag(bool flag)                                { m_resChangeInClvsEnabledFlag = flag; }
+#endif
 
   uint32_t  getLog2ParallelMergeLevelMinus2() const { return m_log2ParallelMergeLevelMinus2; }
   void      setLog2ParallelMergeLevelMinus2(uint32_t mrgLevel) { m_log2ParallelMergeLevelMinus2 = mrgLevel; }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index b62daf9ea..143465b76 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -51,6 +51,7 @@
 #include <cassert>
 
 //########### place macros to be removed in next cycle below this line ###############
+#define JVET_R0058                                        1 // JVET-R0058: the combination of RPR, subpictures, and scalability 
 
 #define JVET_Q0764_WRAP_AROUND_WITH_RPR                   1 // JVET-Q0764: Combination of wrap around offset and RPR
 
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 444ff8b32..2bb4a1dff 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -135,6 +135,61 @@ bool CU::getRprScaling( const SPS* sps, const PPS* curPPS, Picture* refPic, int&
   return refPic->isRefScaled( curPPS );
 }
 
+#if JVET_R0058
+void CU::isConformanceILRP(Slice *slice)
+{
+  const int numRefList = (slice->getSliceType() == B_SLICE) ? (2) : (1);
+
+  //constraint 1: The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] has the same subpicture layout as the current picture 
+  bool isAllRefSameSubpicLayout = true;
+  for (int iNumRef = 0; iNumRef < numRefList; iNumRef++) // loop over l0 and l1
+  {
+    RefPicList  eRefPicList = (iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
+    for (int iRefIdx = 0; iRefIdx < slice->getNumRefIdx(eRefPicList); iRefIdx++)
+    {
+      const Picture* refPic = slice->getRefPic(eRefPicList, iRefIdx);
+
+      if (refPic->cs->pps->getNumSubPics() != slice->getPic()->cs->pps->getNumSubPics())
+      {
+        isAllRefSameSubpicLayout = false;
+        goto outloopCon1;
+      }
+      else
+      {
+        for (int i = 0; i < slice->getPic()->cs->pps->getNumSubPics(); i++)
+        {
+          if (refPic->cs->pps->getSubPic(i).getSubPicWidthInCTUs() != slice->getPic()->cs->pps->getSubPic(i).getSubPicWidthInCTUs()
+            || refPic->cs->pps->getSubPic(i).getSubPicHeightInCTUs() != slice->getPic()->cs->pps->getSubPic(i).getSubPicHeightInCTUs()
+            || refPic->cs->pps->getSubPic(i).getSubPicCtuTopLeftX() != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftX()
+            || refPic->cs->pps->getSubPic(i).getSubPicCtuTopLeftY() != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftY())
+          {
+            isAllRefSameSubpicLayout = false;
+            goto outloopCon1;
+          }
+        }
+      }
+    }
+  }
+outloopCon1:
+
+  //constraint 2: The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] is an ILRP for which the value of sps_num_subpics_minus1 is equal to 0
+  if (!isAllRefSameSubpicLayout)
+  {
+    for (int iNumRef = 0; iNumRef < numRefList; iNumRef++) // loop over l0 and l1
+    {
+      RefPicList  eRefPicList = (iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
+      for (int iRefIdx = 0; iRefIdx < slice->getNumRefIdx(eRefPicList); iRefIdx++)
+      {
+        const Picture* refPic = slice->getRefPic(eRefPicList, iRefIdx)->unscaledPic;
+        CHECK(!(refPic->layerId != slice->getPic()->layerId && refPic->cs->pps->getNumSubPics() == 1), "The inter-layer reference shall contain a single subpicture or have same subpicture layout with the current picture");
+      }
+    }
+  }
+
+  return;
+}
+#endif
+
 bool CU::isIntra(const CodingUnit &cu)
 {
   return cu.predMode == MODE_INTRA;
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index 9f6f0cfcf..b4e4b342c 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -122,6 +122,9 @@ namespace CU
   bool    isSbtMode                   (const uint8_t sbtInfo);
   bool    isSameSbtSize               (const uint8_t sbtInfo1, const uint8_t sbtInfo2);
   bool    getRprScaling               ( const SPS* sps, const PPS* curPPS, Picture* refPic, int& xScale, int& yScale );
+#if JVET_R0058
+  void    isConformanceILRP           (Slice *slice);
+#endif
 }
 // PU tools
 namespace PU
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index e7403050c..e3ede012d 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -563,7 +563,11 @@ Picture* DecLib::xGetNewPicBuffer( const SPS &sps, const PPS &pps, const uint32_
   }
   else
   {
+#if JVET_R0058
+    if( !pcPic->Y().Size::operator==( Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ) ) || pps.pcv->maxCUWidth != sps.getMaxCUWidth() || pps.pcv->maxCUHeight != sps.getMaxCUHeight() || pcPic->layerId != layerId )
+#else
     if( !pcPic->Y().Size::operator==( Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ) ) || pps.pcv->maxCUWidth != sps.getMaxCUWidth() || pps.pcv->maxCUHeight != sps.getMaxCUHeight() )
+#endif
     {
       pcPic->destroy();
       pcPic->create( sps.getChromaFormatIdc(), Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ), sps.getMaxCUWidth(), sps.getMaxCUWidth() + 16, true, layerId );
@@ -1406,6 +1410,18 @@ void DecLib::xCheckParameterSetConstraints(const int layerId)
   const int minCuSize = 1 << sps->getLog2MinCodingBlockSize();
   CHECK( ( pps->getPicWidthInLumaSamples() % ( std::max( 8, minCuSize) ) ) != 0, "Coded frame width must be a multiple of Max(8, the minimum unit size)" );
   CHECK( ( pps->getPicHeightInLumaSamples() % ( std::max( 8, minCuSize) ) ) != 0, "Coded frame height must be a multiple of Max(8, the minimum unit size)" );
+#if JVET_R0058
+  if (!sps->getResChangeInClvsEnabledFlag())
+  {
+    CHECK(pps->getPicWidthInLumaSamples() != sps->getMaxPicWidthInLumaSamples(), "When res_change_in_clvs_allowed_flag equal to 0, the value of pic_width_in_luma_samples shall be equal to pic_width_max_in_luma_samples.");
+    CHECK(pps->getPicHeightInLumaSamples() != sps->getMaxPicHeightInLumaSamples(), "When res_change_in_clvs_allowed_flag equal to 0, the value of pic_height_in_luma_samples shall be equal to pic_height_max_in_luma_samples.");
+  }
+  if (sps->getResChangeInClvsEnabledFlag())
+  {
+    CHECK(sps->getSubPicInfoPresentFlag() != 0, "When res_change_in_clvs_allowed_flag is equal to 1, the value of subpic_info_present_flag shall be equal to 0.");
+  }
+  CHECK(sps->getResChangeInClvsEnabledFlag() && sps->getVirtualBoundariesEnabledFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0");
+#else
   if( !sps->getRprEnabledFlag() )
   {
     CHECK( pps->getPicWidthInLumaSamples() != sps->getMaxPicWidthInLumaSamples(), "When res_change_in_clvs_allowed_flag equal to 0, the value of pic_width_in_luma_samples shall be equal to pic_width_max_in_luma_samples." );
@@ -1417,6 +1433,7 @@ void DecLib::xCheckParameterSetConstraints(const int layerId)
   }
 
   CHECK( sps->getRprEnabledFlag() && sps->getVirtualBoundariesPresentFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0" );
+#endif
 
   if( sps->getCTUSize() + 2 * ( 1 << sps->getLog2MinCodingBlockSize() ) > pps->getPicWidthInLumaSamples() )
   {
@@ -1526,12 +1543,10 @@ void DecLib::xCheckParameterSetConstraints(const int layerId)
 
       CHECK( currentSubPicIdx == NOT_VALID, "Sub-picture was not found" );
       CHECK( !previousSubPicIds.count( layerId ), "Sub-picture information of the previously decoded picture was not stored" );
-
       if( previousSubPicIds[layerId][currentSubPicIdx] != slice->getSliceSubPicId() )
       {
         CHECK( !slice->isIRAP(), "For reordered sub-pictures, the slice NAL shall be in the range of IDR_W_RADL to CRA_NUT, inclusive" )
       }
-
       // store PPS ID to have sub-picture info for the next pictures when last rectangular slice in the picture is encountered
       if( slice->getSliceID() + 1 == pps->getNumSlicesInPic() )
       {
@@ -1922,6 +1937,12 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   pcSlice->constructRefPicList(m_cListPic);
   pcSlice->checkRPL(pcSlice->getRPL0(), pcSlice->getRPL1(), m_associatedIRAPDecodingOrderNumber, m_cListPic);
   pcSlice->checkSTSA(m_cListPic);
+#if JVET_R0058
+  if (m_pcPic->cs->vps && !m_pcPic->cs->vps->getIndependentLayerFlag(m_pcPic->cs->vps->getGeneralLayerIdx(nalu.m_nuhLayerId)) && m_pcPic->cs->pps->getNumSubPics() > 1)
+  {
+    CU::isConformanceILRP(pcSlice);
+  }
+#endif
 
   pcSlice->scaleRefPicList( scaledRefPic, m_pcPic->cs->picHeader, m_parameterSetManager.getAPSs(), m_picHeader.getLmcsAPS(), m_picHeader.getScalingListAPS(), true );
 
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index eb7926794..ce569de6a 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -130,7 +130,16 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
 
   DTRACE( g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", slice->getPOC() );
 
-
+#if JVET_R0058
+  if (slice->getSliceType() != I_SLICE && slice->getRefPic(REF_PIC_LIST_0, 0)->cs->pps->getNumSubPics() > 1)
+  {
+    clipMv = clipMvInSubpic;
+  }
+  else
+  {
+    clipMv = clipMvInPic;
+  }
+#endif
   // for every CTU in the slice segment...
   unsigned subStrmId = 0;
   for( unsigned ctuIdx = 0; ctuIdx < slice->getNumCtuInSlice(); ctuIdx++ )
@@ -162,7 +171,11 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
         for (int idx = 0; idx < n; idx++)
         {
           Picture *refPic = slice->getRefPic((RefPicList)rlist, idx);
+#if JVET_R0058
+          if (!refPic->getSubPicSaved() && refPic->unscaledPic->cs->pps->getNumSubPics() > 1)
+#else
           if (!refPic->getSubPicSaved())
+#endif
           {
             refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
             refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index f358314bf..a46112ce0 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -1370,9 +1370,19 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
     READ_FLAG(     uiCode, "separate_colour_plane_flag");        CHECK(uiCode != 0, "separate_colour_plane_flag shall be equal to 0");
     pcSPS->setSeparateColourPlaneFlag( uiCode != 0 );
   }
-
+#if JVET_R0058
+  READ_FLAG(uiCode, "ref_pic_resampling_enabled_flag");          pcSPS->setRprEnabledFlag(uiCode);
+  if (uiCode)
+  {
+    READ_FLAG(uiCode, "res_change_in_clvs_allowed_flag");        pcSPS->setResChangeInClvsEnabledFlag(uiCode);
+  }
+  else
+  {
+    pcSPS->setResChangeInClvsEnabledFlag(0);
+  }
+#else
   READ_FLAG( uiCode, "res_change_in_clvs_allowed_flag" );        pcSPS->setRprEnabledFlag( uiCode );
-
+#endif
   if (pcSPS->getProfileTierLevel()->getConstraintInfo()->getNoResChangeInClvsConstraintFlag())
   {
     CHECK(uiCode != 0, "When no_res_change_in_clvs_constraint_flag is equal to 1, res_change_in_clvs_allowed_flag shall be equal to 0");
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 0913fa106..4ebd7f2b4 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -757,7 +757,11 @@ protected:
 #endif
   double      m_scalingRatioHor;
   double      m_scalingRatioVer;
+#if JVET_R0058
+  bool        m_resChangeInClvsEnabled;
+#else
   bool        m_rprEnabled;
+#endif
   int         m_switchPocPeriod;
   int         m_upscaledOutput;
   int         m_numRefLayers[MAX_VPS_LAYERS];
@@ -1929,8 +1933,13 @@ public:
 #endif
 
   void        setScalingRatio( double hor, double ver )              { m_scalingRatioHor = hor, m_scalingRatioVer = ver;  }
-  void        setRPREnabled( bool b )                                { m_rprEnabled = b;    }
+#if JVET_R0058
+  void        setResChangeInClvsEnabled(bool b)                      { m_resChangeInClvsEnabled = b; }
+  bool        isResChangeInClvsEnabled()                        const { return m_resChangeInClvsEnabled; }
+#else
+  void        setRPREnabled(bool b) { m_rprEnabled = b; }
   bool        isRPREnabled()                                   const { return m_rprEnabled; }
+#endif
   void        setSwitchPocPeriod( int p )                            { m_switchPocPeriod = p;}
   void        setUpscaledOutput( int b )                             { m_upscaledOutput = b; }
   int         getUpscaledOutput()                              const { return m_upscaledOutput; }
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 2d3c47095..213ff1953 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -1768,7 +1768,6 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice)
   if (slice->getSPS()->getUseLmcs())
   {
     const SliceType sliceType = slice->getSliceType();
-
     m_pcReshaper->getReshapeCW()->rspTid = slice->getTLayer() + (slice->isIntra() ? 0 : 1);
     m_pcReshaper->getReshapeCW()->rspSliceQP = slice->getSliceQp();
 
@@ -2164,7 +2163,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
     if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 ||
         (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) )
-      || ( !pcSlice->isIRAP() && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers( pcSlice->getPic()->cs->vps->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) ) )
+      || (!pcSlice->isIRAP() && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId())))
       )
     {
       xCreateExplicitReferencePictureSetFromReference( pcSlice, rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1() );
@@ -2251,6 +2250,15 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     //  Set reference list
     pcSlice->constructRefPicList(rcListPic);
 
+#if JVET_R0058
+    const VPS* vps = pcPic->cs->vps;
+    int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx(pcPic->layerId);
+    if (vps && !vps->getIndependentLayerFlag(layerIdx) && pcPic->cs->pps->getNumSubPics() > 1)
+    {
+      CU::isConformanceILRP(pcSlice);
+    }
+#endif
+
     xPicInitHashME( pcPic, pcSlice->getPPS(), rcListPic );
 
     if( m_pcCfg->getUseAMaxBT() )
@@ -2721,6 +2729,19 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         m_pcSliceEncoder->setLosslessSlice(pcPic, isLossless);
 #endif
 
+#if JVET_R0058
+        if (pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic(REF_PIC_LIST_0, 0)->unscaledPic->cs->pps->getNumSubPics() > 1)
+        {
+          clipMv = clipMvInSubpic;
+          m_pcEncLib->getInterSearch()->setMvClipInSubPic(true);
+        }
+        else
+        {
+          clipMv = clipMvInPic;
+          m_pcEncLib->getInterSearch()->setMvClipInSubPic(false);
+        }
+#endif
+
         m_pcSliceEncoder->precompressSlice( pcPic );
         m_pcSliceEncoder->compressSlice   ( pcPic, false, false );
 
@@ -3905,7 +3926,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
 
   PelStorage upscaledRec;
 
-  if( m_pcEncLib->isRPREnabled() )
+#if JVET_R0058
+  if (m_pcEncLib->isResChangeInClvsEnabled())
+#else
+  if (m_pcEncLib->isRPREnabled())
+#endif
   {
     const CPelBuf& upscaledOrg = sps.getUseLmcs() ? pcPic->M_BUFS( 0, PIC_TRUE_ORIGINAL_INPUT).get( COMPONENT_Y ) : pcPic->M_BUFS( 0, PIC_ORIGINAL_INPUT).get( COMPONENT_Y );
     upscaledRec.create( pic.chromaFormat, Area( Position(), upscaledOrg ) );
@@ -3933,7 +3958,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
 
     // when RPR is enabled, picture padding is picture specific due to possible different picture resoluitons, however only full resolution padding is stored in EncLib
     // get per picture padding from the conformance window, in this case if conformance window is set not equal to the padding then PSNR results may be inaccurate
-    if( m_pcEncLib->isRPREnabled() )
+#if JVET_R0058
+    if (m_pcEncLib->isResChangeInClvsEnabled())
+#else
+    if (m_pcEncLib->isRPREnabled())
+#endif
     {
       Window& conf = pcPic->getConformanceWindow();
       padX = conf.getWindowRightOffset() * SPS::getWinUnitX( format );
@@ -3966,7 +3995,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
     }
 #endif
 
-    if( m_pcEncLib->isRPREnabled() )
+#if JVET_R0058
+    if (m_pcEncLib->isResChangeInClvsEnabled())
+#else
+    if (m_pcEncLib->isRPREnabled())
+#endif
     {
       const CPelBuf& upscaledOrg = sps.getUseLmcs() ? pcPic->M_BUFS( 0, PIC_TRUE_ORIGINAL_INPUT ).get( compID ) : pcPic->M_BUFS( 0, PIC_ORIGINAL_INPUT ).get( compID );
 
@@ -4243,7 +4276,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
       }
       msg( NOTICE, "]" );
     }
-    if( m_pcEncLib->isRPREnabled() )
+#if JVET_R0058
+    if (m_pcEncLib->isResChangeInClvsEnabled())
+#else
+    if (m_pcEncLib->isRPREnabled())
+#endif
     {
       msg( NOTICE, "\nPSNR2: [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", upscaledPSNR[COMPONENT_Y], upscaledPSNR[COMPONENT_Cb], upscaledPSNR[COMPONENT_Cr] );
     }
@@ -5085,7 +5122,10 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
   Picture* pic = slice->getPic();
   const VPS* vps = slice->getPic()->cs->vps;
   int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx( pic->layerId );
-
+#if JVET_R0058
+  bool isIntraLayerPredAllowed = vps->getIndependentLayerFlag(layerIdx) || (vps->getPredDirection(slice->getTLayer()) != 1);
+  bool isInterLayerPredAllowed = !vps->getIndependentLayerFlag(layerIdx) && (vps->getPredDirection(slice->getTLayer()) != 2);
+#endif
   ReferencePictureList* pLocalRPL0 = slice->getLocalRPL0();
   *pLocalRPL0 = ReferencePictureList( slice->getSPS()->getInterLayerPresentFlag() );
 
@@ -5095,44 +5135,55 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
   uint32_t numOfRefPic = rpl0->getNumberOfShorttermPictures() + rpl0->getNumberOfLongtermPictures();
   uint32_t refPicIdxL0 = 0;
 
-  for( int ii = 0; ii < numOfRefPic; ii++ )
+#if JVET_R0058
+  if (isIntraLayerPredAllowed)
   {
-    // loop through all pictures in the reference picture buffer
-    PicList::iterator iterPic = rcListPic.begin();
-    bool isAvailable = false;
-
-    pocCycle = 1 << ( slice->getSPS()->getBitsForPOC() );
-    while( iterPic != rcListPic.end() )
+#endif
+    for (int ii = 0; ii < numOfRefPic; ii++)
     {
-      rpcPic = *( iterPic++ );
+      // loop through all pictures in the reference picture buffer
+      PicList::iterator iterPic = rcListPic.begin();
+      bool isAvailable = false;
 
-      if( rpcPic->layerId == pic->layerId )
+      pocCycle = 1 << (slice->getSPS()->getBitsForPOC());
+      while (iterPic != rcListPic.end())
       {
-        if( !rpl0->isRefPicLongterm( ii ) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl0->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
-        {
-          isAvailable = true;
-          break;
-        }
-        else if( rpl0->isRefPicLongterm( ii ) && rpcPic->referenced && ( rpcPic->getPOC() & ( pocCycle - 1 ) ) == rpl0->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
+        rpcPic = *(iterPic++);
+
+        if (rpcPic->layerId == pic->layerId)
         {
-          isAvailable = true;
-          break;
+          if (!rpl0->isRefPicLongterm(ii) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl0->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP))
+          {
+            isAvailable = true;
+            break;
+          }
+          else if (rpl0->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == rpl0->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP))
+          {
+            isAvailable = true;
+            break;
+          }
         }
       }
-    }
 
-    if( isAvailable )
-    {
-      pLocalRPL0->setRefPicIdentifier( refPicIdxL0, rpl0->getRefPicIdentifier( ii ), rpl0->isRefPicLongterm( ii ), false, NOT_VALID );
-      refPicIdxL0++;
-      numOfSTRPL0 = numOfSTRPL0 + ( ( rpl0->isRefPicLongterm( ii ) ) ? 0 : 1 );
-      numOfLTRPL0 += ( rpl0->isRefPicLongterm( ii ) && !rpl0->isInterLayerRefPic( ii ) ) ? 1 : 0;
-      isAvailable = false;
+      if (isAvailable)
+      {
+        pLocalRPL0->setRefPicIdentifier(refPicIdxL0, rpl0->getRefPicIdentifier(ii), rpl0->isRefPicLongterm(ii), false, NOT_VALID);
+        refPicIdxL0++;
+        numOfSTRPL0 = numOfSTRPL0 + ((rpl0->isRefPicLongterm(ii)) ? 0 : 1);
+        numOfLTRPL0 += (rpl0->isRefPicLongterm(ii) && !rpl0->isInterLayerRefPic(ii)) ? 1 : 0;
+        isAvailable = false;
+      }
     }
+#if JVET_R0058
   }
+#endif
 
   // inter-layer reference pictures are added to the end of the reference picture list
+#if JVET_R0058
+  if (layerIdx && vps && !vps->getAllIndependentLayersFlag() && isInterLayerPredAllowed)
+#else
   if( layerIdx && vps && !vps->getAllIndependentLayersFlag() )
+#endif
   {
     numOfRefPic = rpl0->getNumberOfInterLayerPictures() ? rpl0->getNumberOfInterLayerPictures() : m_pcEncLib->getNumRefLayers( layerIdx );
 
@@ -5145,8 +5196,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
       {
         rpcPic = *( iterPic++ );
         int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId );
-
-        if( rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag( layerIdx, refLayerIdx ) )
+        if (rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag(layerIdx, refLayerIdx))
         {
           pLocalRPL0->setRefPicIdentifier( refPicIdxL0, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) );
           refPicIdxL0++;
@@ -5191,44 +5241,54 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
   numOfRefPic = rpl1->getNumberOfShorttermPictures() + rpl1->getNumberOfLongtermPictures();
   uint32_t refPicIdxL1 = 0;
 
-  for( int ii = 0; ii < numOfRefPic; ii++ )
+#if JVET_R0058
+  if (isIntraLayerPredAllowed)
   {
-    // loop through all pictures in the reference picture buffer
-    PicList::iterator iterPic = rcListPic.begin();
-    bool isAvailable = false;
-    pocCycle = 1 << ( slice->getSPS()->getBitsForPOC() );
-    while( iterPic != rcListPic.end() )
+#endif
+    for (int ii = 0; ii < numOfRefPic; ii++)
     {
-      rpcPic = *( iterPic++ );
-
-      if( rpcPic->layerId == pic->layerId )
+      // loop through all pictures in the reference picture buffer
+      PicList::iterator iterPic = rcListPic.begin();
+      bool isAvailable = false;
+      pocCycle = 1 << (slice->getSPS()->getBitsForPOC());
+      while (iterPic != rcListPic.end())
       {
-        if( !rpl1->isRefPicLongterm( ii ) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl1->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
-        {
-          isAvailable = true;
-          break;
-        }
-        else if( rpl1->isRefPicLongterm( ii ) && rpcPic->referenced && ( rpcPic->getPOC() & ( pocCycle - 1 ) ) == rpl1->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) )
+        rpcPic = *(iterPic++);
+        if (rpcPic->layerId == pic->layerId)
         {
-          isAvailable = true;
-          break;
+          if (!rpl1->isRefPicLongterm(ii) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl1->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP))
+          {
+            isAvailable = true;
+            break;
+          }
+          else if (rpl1->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == rpl1->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP))
+          {
+            isAvailable = true;
+            break;
+          }
         }
       }
-    }
 
-    if( isAvailable )
-    {
-      pLocalRPL1->setRefPicIdentifier( refPicIdxL1, rpl1->getRefPicIdentifier( ii ), rpl1->isRefPicLongterm( ii ), false, NOT_VALID );
-      refPicIdxL1++;
-      numOfSTRPL1 = numOfSTRPL1 + ( ( rpl1->isRefPicLongterm( ii ) ) ? 0 : 1 );
-      numOfLTRPL1 += ( rpl1->isRefPicLongterm( ii ) && !rpl1->isInterLayerRefPic( ii ) ) ? 1 : 0;
-      isAvailable = false;
+      if (isAvailable)
+      {
+        pLocalRPL1->setRefPicIdentifier(refPicIdxL1, rpl1->getRefPicIdentifier(ii), rpl1->isRefPicLongterm(ii), false, NOT_VALID);
+        refPicIdxL1++;
+        numOfSTRPL1 = numOfSTRPL1 + ((rpl1->isRefPicLongterm(ii)) ? 0 : 1);
+        numOfLTRPL1 += (rpl1->isRefPicLongterm(ii) && !rpl1->isInterLayerRefPic(ii)) ? 1 : 0;
+        isAvailable = false;
+      }
     }
+#if JVET_R0058
   }
+#endif
 
 
   // inter-layer reference pictures are added to the end of the reference picture list
+#if JVET_R0058
+  if (layerIdx && vps && !vps->getAllIndependentLayersFlag() && isInterLayerPredAllowed)
+#else
   if( layerIdx && vps && !vps->getAllIndependentLayersFlag() )
+#endif
   {
     numOfRefPic = rpl1->getNumberOfInterLayerPictures() ? rpl1->getNumberOfInterLayerPictures() : m_pcEncLib->getNumRefLayers( layerIdx );
 
@@ -5241,8 +5301,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL
       {
         rpcPic = *( iterPic++ );
         int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId );
-
-        if( rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag( layerIdx, refLayerIdx ) )
+        if (rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag(layerIdx, refLayerIdx))
         {
           pLocalRPL1->setRefPicIdentifier( refPicIdxL1, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) );
           refPicIdxL1++;
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 6f8c06a57..a7f0cb946 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -260,7 +260,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
   // initialize APS
   xInitRPL(sps0, isFieldCoding);
 
-  if( m_rprEnabled )
+#if JVET_R0058
+  if (m_resChangeInClvsEnabled)
+#else
+  if (m_rprEnabled)
+#endif
   {
     PPS &pps = *( m_ppsMap.allocatePS( ENC_PPS_ID_RPR ) );
     Window& inputScalingWindow = pps0.getScalingWindow();
@@ -443,7 +447,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
   {
     xInitScalingLists( sps0, aps0 );
   }
-  if( m_rprEnabled )
+#if JVET_R0058
+  if (m_resChangeInClvsEnabled)
+#else
+  if (m_rprEnabled)
+#endif
   {
     xInitScalingLists( sps0, *m_apsMap.getPS( ENC_PPS_ID_RPR ) );
   }
@@ -624,8 +632,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
       ppsID += ( getSwitchPOC() != -1 && ( m_iPOCLast + 1 >= getSwitchPOC() ) ? 1 : 0 );
     }
 #endif
-
+#if JVET_R0058
+    if( m_resChangeInClvsEnabled && m_intraPeriod == -1 )
+#else
     if( m_rprEnabled && m_intraPeriod == -1 )
+#endif
     {
       const int poc = m_iPOCLast + ( m_compositeRefEnabled ? 2 : 1 );
 
@@ -649,7 +660,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
     const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
     const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() );
 
-    if( m_rprEnabled )
+#if JVET_R0058
+    if (m_resChangeInClvsEnabled)
+#else
+    if (m_rprEnabled)
+#endif
     {
       pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Y ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Y ) );
       pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Cb ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Cb ) );
@@ -944,7 +959,11 @@ void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Pict
   {
     rpcPic = new Picture;
     rpcPic->create( sps.getChromaFormatIdc(), Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ), sps.getMaxCUWidth(), sps.getMaxCUWidth() + 16, false, m_layerId );
-    if( m_rprEnabled )
+#if JVET_R0058
+    if (m_resChangeInClvsEnabled)
+#else
+    if (m_rprEnabled)
+#endif
     {
       const PPS &pps0 = *m_ppsMap.getPS(0);
       rpcPic->M_BUFS(0, PIC_ORIGINAL_INPUT).create(sps.getChromaFormatIdc(), Area(Position(), Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples())));
@@ -1156,7 +1175,11 @@ void EncLib::xInitSPS( SPS& sps )
   sps.setVPSId( m_vps->getVPSId() );
   sps.setMaxPicWidthInLumaSamples( m_iSourceWidth );
   sps.setMaxPicHeightInLumaSamples( m_iSourceHeight );
+#if JVET_R0058
+  if (m_resChangeInClvsEnabled)
+#else
   if (m_rprEnabled)
+#endif
   {
     int maxPicWidth = std::max(m_iSourceWidth, (int)((double)m_iSourceWidth / m_scalingRatioHor + 0.5));
     int maxPicHeight = std::max(m_iSourceHeight, (int)((double)m_iSourceHeight / m_scalingRatioVer + 0.5));
@@ -1423,12 +1446,20 @@ void EncLib::xInitSPS( SPS& sps )
 
   sps.setInterLayerPresentFlag( m_layerId > 0 && m_vps->getMaxLayers() > 1 && !m_vps->getAllIndependentLayersFlag() && !m_vps->getIndependentLayerFlag( m_vps->getGeneralLayerIdx( m_layerId ) ) );
   CHECK( m_vps->getIndependentLayerFlag( m_vps->getGeneralLayerIdx( m_layerId ) ) && sps.getInterLayerPresentFlag(), " When vps_independent_layer_flag[GeneralLayerIdx[nuh_layer_id ]]  is equal to 1, the value of inter_layer_ref_pics_present_flag shall be equal to 0." );
-
-  sps.setRprEnabledFlag( m_rprEnabled || sps.getInterLayerPresentFlag() );
+#if JVET_R0058
+  sps.setResChangeInClvsEnabledFlag(m_resChangeInClvsEnabled);
+  sps.setRprEnabledFlag((m_resChangeInClvsEnabled) || sps.getInterLayerPresentFlag());
+#else
+  sps.setRprEnabledFlag(m_rprEnabled || sps.getInterLayerPresentFlag());
+#endif
 
   sps.setLog2ParallelMergeLevelMinus2( m_log2ParallelMergeLevelMinus2 );
 
-  CHECK( sps.getRprEnabledFlag() && sps.getVirtualBoundariesEnabledFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0" );
+#if JVET_R0058
+  CHECK(sps.getResChangeInClvsEnabledFlag() && sps.getVirtualBoundariesEnabledFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0");
+#else
+  CHECK(sps.getRprEnabledFlag() && sps.getVirtualBoundariesEnabledFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0");
+#endif
 }
 
 void EncLib::xInitHrdParameters(SPS &sps)
diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h
index 3a2e28cd4..f75c629b5 100644
--- a/source/Lib/EncoderLib/EncLib.h
+++ b/source/Lib/EncoderLib/EncLib.h
@@ -282,8 +282,11 @@ public:
                std::list<PelUnitBuf*>& rcListPicYuvRecOut,
                int& iNumEncoded, bool isTff );
 
-
-  void printSummary( bool isField ) { m_cGOPEncoder.printOutSummary( m_uiNumAllPicCoded, isField, m_printMSEBasedSequencePSNR, m_printSequenceMSE, m_printHexPsnr, m_rprEnabled, m_spsMap.getFirstPS()->getBitDepths() ); }
+#if JVET_R0058
+  void printSummary(bool isField) { m_cGOPEncoder.printOutSummary(m_uiNumAllPicCoded, isField, m_printMSEBasedSequencePSNR, m_printSequenceMSE, m_printHexPsnr, m_resChangeInClvsEnabled, m_spsMap.getFirstPS()->getBitDepths()); }
+#else
+  void printSummary(bool isField) { m_cGOPEncoder.printOutSummary(m_uiNumAllPicCoded, isField, m_printMSEBasedSequencePSNR, m_printSequenceMSE, m_printHexPsnr, m_rprEnabled, m_spsMap.getFirstPS()->getBitDepths()); }
+#endif
 
   int getLayerId() const { return m_layerId; }
   VPS* getVPS()          { return m_vps;     }
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index c821cdbe7..fd0537a84 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -430,7 +430,6 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
 
   // slice type
   SliceType eSliceType;
-
   eSliceType=B_SLICE;
   if (m_pcCfg->getIntraPeriod() > 0 )
   {
@@ -1379,7 +1378,6 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c
     }
   }
 #endif // ENABLE_QPA
-
   bool checkPLTRatio = m_pcCfg->getIntraPeriod() != 1 && pcSlice->isIRAP();
   if (checkPLTRatio)
   {
@@ -1566,7 +1564,11 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
         for (int idx = 0; idx < n; idx++)
         {
           Picture *refPic = pcSlice->getRefPic((RefPicList)rlist, idx);
+#if JVET_R0058
+          if (!refPic->getSubPicSaved() && refPic->unscaledPic->cs->pps->getNumSubPics() > 1)
+#else
           if (!refPic->getSubPicSaved())
+#endif
           {
             refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
             refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index fa8fc9e99..4c3a8ee33 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -1408,6 +1408,10 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR
 
   rcMvSrchRngLT <<= 2;
   rcMvSrchRngRB <<= 2;
+#if JVET_R0058
+  bool temp = m_bMvClipInSubPic;
+  m_bMvClipInSubPic = true;
+#endif
   xClipMv(rcMvSrchRngLT, pu.cu->lumaPos(),
          pu.cu->lumaSize(),
          sps
@@ -1418,6 +1422,9 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR
          sps
       , *pu.cs->pps
   );
+#if JVET_R0058
+  m_bMvClipInSubPic = temp;
+#endif
   rcMvSrchRngLT >>= 2;
   rcMvSrchRngRB >>= 2;
 }
@@ -3253,6 +3260,7 @@ Distortion InterSearch::xGetTemplateCost( const PredictionUnit& pu,
 
   const Picture* picRef = pu.cu->slice->getRefPic( eRefPicList, iRefIdx );
   clipMv( cMvCand, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
+
   // prediction pattern
   const bool bi = pu.cu->slice->testWeightPred() && pu.cu->slice->getSliceType()==P_SLICE;
 
@@ -3397,6 +3405,7 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
 
     Mv bestInitMv = (bBi ? rcMv : rcMvPred);
     Mv cTmpMv = bestInitMv;
+
     clipMv( cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
     cTmpMv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
     m_cDistParam.cur.buf = cStruct.piRefY + (cTmpMv.ver * cStruct.iRefStride) + cTmpMv.hor;
@@ -3436,9 +3445,7 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
 
     if( !bQTBTMV )
     {
-      xSetSearchRange(pu, bestInitMv, iSrchRng, cStruct.searchRange
-        , cStruct
-      );
+      xSetSearchRange(pu, bestInitMv, iSrchRng, cStruct.searchRange, cStruct);
     }
     xPatternSearch( cStruct, rcMv, ruiCost);
   }
@@ -3503,7 +3510,6 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
 }
 
 
-
 void InterSearch::xSetSearchRange ( const PredictionUnit& pu,
                                     const Mv& cMvPred,
                                     const int iSrchRng,
@@ -3514,7 +3520,6 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu,
   const int iMvShift = MV_FRACTIONAL_BITS_INTERNAL;
   Mv cFPMvPred = cMvPred;
   clipMv( cFPMvPred, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
-
   Mv mvTL(cFPMvPred.getHor() - (iSrchRng << iMvShift), cFPMvPred.getVer() - (iSrchRng << iMvShift));
   Mv mvBR(cFPMvPred.getHor() + (iSrchRng << iMvShift), cFPMvPred.getVer() + (iSrchRng << iMvShift));
 
@@ -3778,9 +3783,7 @@ void InterSearch::xTZSearch( const PredictionUnit& pu,
     // set search range
     Mv currBestMv(cStruct.iBestX, cStruct.iBestY );
     currBestMv <<= MV_FRACTIONAL_BITS_INTERNAL;
-    xSetSearchRange(pu, currBestMv, m_iSearchRange >> (bFastSettings ? 1 : 0), sr
-      , cStruct
-    );
+    xSetSearchRange(pu, currBestMv, m_iSearchRange >> (bFastSettings ? 1 : 0), sr, cStruct);
   }
   if (m_pcEncCfg->getUseHashME() && (m_currRefPicList == 0 || pu.cu->slice->getList1IdxToList0Idx(m_currRefPicIndex) < 0))
   {
@@ -4012,6 +4015,7 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu,
   int   iStartX                 = 0;
   int   iStartY                 = 0;
   int   iDist                   = 0;
+
   clipMv( rcMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
   rcMv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_QUARTER);
   rcMv.divideByPowerOf2(2);
@@ -4084,9 +4088,7 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu,
     // set search range
     Mv currBestMv(cStruct.iBestX, cStruct.iBestY );
     currBestMv <<= 2;
-    xSetSearchRange( pu, currBestMv, m_iSearchRange, sr
-      , cStruct
-    );
+    xSetSearchRange( pu, currBestMv, m_iSearchRange, sr, cStruct );
   }
   if (m_pcEncCfg->getUseHashME() && (m_currRefPicList == 0 || pu.cu->slice->getList1IdxToList0Idx(m_currRefPicIndex) < 0))
   {
@@ -5756,7 +5758,6 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
             acMvTemp[j].set(centerMv[j].getHor() + (testPos[i][0] << mvShift), centerMv[j].getVer() + (testPos[i][1] << mvShift));
             clipMv( acMvTemp[j], pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps );
             xPredAffineBlk(COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cu->slice->clpRng(COMPONENT_Y));
-
             Distortion costTemp = m_pcRdCost->getDistPart(predBuf.Y(), pBuf->Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, distFunc);
             uint32_t bitsTemp = ruiBits;
             bitsTemp += xCalcAffineMVBits(pu, acMvTemp, acMvPred);
@@ -7789,7 +7790,11 @@ void InterSearch::xClipMv( Mv& rcMv, const Position& pos, const struct Size& siz
   int verMax = ( pps.getPicHeightInLumaSamples() + offset - (int)pos.y - 1 ) << mvShift;
   int verMin = ( -( int ) sps.getMaxCUHeight()   - offset - ( int ) pos.y + 1 ) << mvShift;
   const SubPic &curSubPic = pps.getSubPicFromPos(pos);
+#if JVET_R0058
+  if (curSubPic.getTreatedAsPicFlag() && m_bMvClipInSubPic)
+#else
   if (curSubPic.getTreatedAsPicFlag())
+#endif
   {
     horMax = ((curSubPic.getSubPicRight() + 1)  + offset - (int)pos.x - 1) << mvShift;
     horMin = (-(int)sps.getMaxCUWidth()  - offset - ((int)pos.x - curSubPic.getSubPicLeft()) + 1) << mvShift;
diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h
index 126832e4b..80eb1fab9 100644
--- a/source/Lib/EncoderLib/InterSearch.h
+++ b/source/Lib/EncoderLib/InterSearch.h
@@ -172,6 +172,9 @@ protected:
   bool            m_skipSbtAll;                         // to skip all SBT modes for the current PU
   uint8_t         m_histBestSbt;                        // historical best SBT mode for PU of certain SSE values
   uint8_t         m_histBestMtsIdx;                     // historical best MTS idx  for PU of certain SSE values
+#if JVET_R0058
+  bool            m_bMvClipInSubPic;
+#endif
 
 public:
   InterSearch();
@@ -317,6 +320,9 @@ public:
   void resetSavedAffineMotion();
   void storeAffineMotion( Mv acAffineMv[2][3], int16_t affineRefIdx[2], EAffineModel affineType, int bcwIdx );
   bool searchBv(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize);
+#if JVET_R0058
+  void setMvClipInSubPic(bool bFlag) { m_bMvClipInSubPic = bFlag; }
+#endif
 protected:
 
   /// sub-function for motion vector refinement used in fractional-pel accuracy
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index b03c45c8d..457013878 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -847,9 +847,15 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   }
 
   const uint32_t chromaArrayType = separate_colour_plane_flag ? 0 : format;
-
+#if JVET_R0058
+  WRITE_FLAG(pcSPS->getRprEnabledFlag(), "ref_pic_resampling_enabled_flag");
+  if (pcSPS->getRprEnabledFlag())
+  {
+    WRITE_FLAG(pcSPS->getResChangeInClvsEnabledFlag(), "res_change_in_clvs_allowed_flag");
+  }
+#else
   WRITE_FLAG( pcSPS->getRprEnabledFlag(), "res_change_in_clvs_allowed_flag" );
-
+#endif
   WRITE_UVLC( pcSPS->getMaxPicWidthInLumaSamples(), "pic_width_max_in_luma_samples" );
   WRITE_UVLC( pcSPS->getMaxPicHeightInLumaSamples(), "pic_height_max_in_luma_samples" );
   Window conf = pcSPS->getConformanceWindow();
@@ -920,7 +926,6 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
       }
     }
   }
-
   WRITE_UVLC( pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8,                      "bit_depth_minus8" );
   WRITE_FLAG( pcSPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "sps_entropy_coding_sync_enabled_flag" );
 #if JVET_R0165_OPTIONAL_ENTRY_POINT
-- 
GitLab