From ba1e2bc706911db05cf651988c2de582bc9a4a97 Mon Sep 17 00:00:00 2001
From: biaowang <biao.wang@huawei.com>
Date: Fri, 31 Jan 2020 22:31:28 +0100
Subject: [PATCH 1/5] JVET-O1143: motion and in-loop filter low-level
 operations adaptation when subpic boundaries are treated as pic boundaries

---
 .../subpicture_4Slice2VerSubPic.cfg           |   4 +-
 source/App/DecoderApp/DecApp.cpp              |   2 +-
 source/App/DecoderApp/DecAppCfg.cpp           |   2 +-
 source/App/DecoderApp/DecAppCfg.h             |   2 +-
 source/Lib/CommonLib/AdaptiveLoopFilter.cpp   |  28 +-
 source/Lib/CommonLib/LoopFilter.cpp           |  57 +++-
 source/Lib/CommonLib/Mv.cpp                   |  10 +
 source/Lib/CommonLib/Picture.cpp              | 300 ++++++++++++++++++
 source/Lib/CommonLib/Picture.h                |  15 +
 source/Lib/CommonLib/SampleAdaptiveOffset.cpp |  16 +
 source/Lib/CommonLib/Slice.cpp                |  26 +-
 source/Lib/CommonLib/Slice.h                  |  27 ++
 source/Lib/CommonLib/TypeDef.h                |   4 +-
 source/Lib/CommonLib/UnitTools.cpp            |  73 +++++
 source/Lib/CommonLib/UnitTools.h              |   3 +
 source/Lib/DecoderLib/DecLib.cpp              |   3 +-
 source/Lib/DecoderLib/DecLib.h                |   2 +-
 source/Lib/DecoderLib/DecSlice.cpp            |  49 +++
 .../EncoderLib/EncSampleAdaptiveOffset.cpp    |  10 +
 source/Lib/EncoderLib/EncSlice.cpp            |  54 ++++
 source/Lib/EncoderLib/InterSearch.cpp         |  10 +
 21 files changed, 676 insertions(+), 21 deletions(-)

diff --git a/cfg/nonCTC-SliceConfigExamples/subpicture_4Slice2VerSubPic.cfg b/cfg/nonCTC-SliceConfigExamples/subpicture_4Slice2VerSubPic.cfg
index 9079e764fa..abb87dbf7c 100644
--- a/cfg/nonCTC-SliceConfigExamples/subpicture_4Slice2VerSubPic.cfg
+++ b/cfg/nonCTC-SliceConfigExamples/subpicture_4Slice2VerSubPic.cfg
@@ -34,5 +34,5 @@ TileRowHeightArray            : 2                       # Tile row heights in un
 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)
+DisableLoopFilterAcrossTiles  : 0                       # Loop filtering (DBLK/SAO/ALF) applied across tile boundaries or not (0: filter across tile boundaries  1: do not filter across tile boundaries)
+DisableLoopFilterAcrossSlices : 0                       # 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/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp
index b6584f0754..704a9c3d84 100644
--- a/source/App/DecoderApp/DecApp.cpp
+++ b/source/App/DecoderApp/DecApp.cpp
@@ -681,7 +681,7 @@ void DecApp::xCreateDecLib()
     std::ostream &os=m_seiMessageFileStream.is_open() ? m_seiMessageFileStream : std::cout;
     m_cDecLib.setDecodedSEIMessageOutputStream(&os);
   }
-#if SUBPIC_DECCHECK
+#if JVET_O1143_SUBPIC_DECCHECK
   m_cDecLib.m_targetSubPicIdx = this->m_targetSubPicIdx;
 #endif
   m_cDecLib.initScalingList();
diff --git a/source/App/DecoderApp/DecAppCfg.cpp b/source/App/DecoderApp/DecAppCfg.cpp
index 310251e87e..c3c9d55a27 100644
--- a/source/App/DecoderApp/DecAppCfg.cpp
+++ b/source/App/DecoderApp/DecAppCfg.cpp
@@ -113,7 +113,7 @@ bool DecAppCfg::parseCfg( int argc, char* argv[] )
                                                                                    "\t3: enable bit and tool statistic\n")
 #endif
   ("MCTSCheck",                m_mctsCheck,                           false,       "If enabled, the decoder checks for violations of mc_exact_sample_value_match_flag in Temporal MCTS ")
-#if SUBPIC_DECCHECK
+#if JVET_O1143_SUBPIC_DECCHECK
   ("targetSubPicIdx",          m_targetSubPicIdx,                     0,           "Specify which subpicture shall be written to output, using subpic index\n" )
 #endif
   ( "UpscaledOutput",          m_upscaledOutput,                          0,       "Upscaled output for RPR" )
diff --git a/source/App/DecoderApp/DecAppCfg.h b/source/App/DecoderApp/DecAppCfg.h
index cc45bfdd88..601504dc0c 100644
--- a/source/App/DecoderApp/DecAppCfg.h
+++ b/source/App/DecoderApp/DecAppCfg.h
@@ -76,7 +76,7 @@ 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 SUBPIC_DECCHECK
+#if JVET_O1143_SUBPIC_DECCHECK
   int           m_targetSubPicIdx;                    ///< Specify which subpicture shall be write to output, using subpicture index
 #endif
 public:
diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
index 4d862ff950..04a4a5019c 100644
--- a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
+++ b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
@@ -121,13 +121,21 @@ bool AdaptiveLoopFilter::isCrossedByVirtualBoundaries( const CodingStructure& cs
   int   ctuSize = slice.getSPS()->getCTUSize();
   const Position currCtuPos(xPos, yPos);
   const CodingUnit *currCtu = cs.getCU(currCtuPos, CHANNEL_TYPE_LUMA);
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+  SubPic curSubPic = slice.getPPS()->getSubPicFromPos(currCtuPos);
+  bool loopFilterAcrossSubPicEnabledFlag = curSubPic.getloopFilterAcrossEnabledFlag();
+#endif
   //top
   if (yPos >= ctuSize && clipTop == false)
   {
     const Position prevCtuPos(xPos, yPos - ctuSize);
     const CodingUnit *prevCtu = cs.getCU(prevCtuPos, CHANNEL_TYPE_LUMA);
     if ((!pps->getLoopFilterAcrossSlicesEnabledFlag() && !CU::isSameSlice(*currCtu, *prevCtu)) || 
-        (!pps->getLoopFilterAcrossTilesEnabledFlag()  && !CU::isSameTile(*currCtu,  *prevCtu)))
+        (!pps->getLoopFilterAcrossTilesEnabledFlag()  && !CU::isSameTile(*currCtu,  *prevCtu))
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+      || (!loopFilterAcrossSubPicEnabledFlag && !CU::isSameSubPic(*currCtu, *prevCtu))
+#endif
+      )
     {
       clipTop = true;
     }
@@ -139,7 +147,11 @@ bool AdaptiveLoopFilter::isCrossedByVirtualBoundaries( const CodingStructure& cs
     const Position nextCtuPos(xPos, yPos + ctuSize);
     const CodingUnit *nextCtu = cs.getCU(nextCtuPos, CHANNEL_TYPE_LUMA);
     if ((!pps->getLoopFilterAcrossSlicesEnabledFlag() && !CU::isSameSlice(*currCtu, *nextCtu)) || 
-        (!pps->getLoopFilterAcrossTilesEnabledFlag()  && !CU::isSameTile(*currCtu,  *nextCtu)))
+        (!pps->getLoopFilterAcrossTilesEnabledFlag()  && !CU::isSameTile(*currCtu,  *nextCtu))
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+      || (!loopFilterAcrossSubPicEnabledFlag && !CU::isSameSubPic(*currCtu, *nextCtu))
+#endif
+      )
     {
       clipBottom = true;
     }
@@ -151,7 +163,11 @@ bool AdaptiveLoopFilter::isCrossedByVirtualBoundaries( const CodingStructure& cs
     const Position prevCtuPos(xPos - ctuSize, yPos);
     const CodingUnit *prevCtu = cs.getCU(prevCtuPos, CHANNEL_TYPE_LUMA);
     if ((!pps->getLoopFilterAcrossSlicesEnabledFlag() && !CU::isSameSlice(*currCtu, *prevCtu)) || 
-        (!pps->getLoopFilterAcrossTilesEnabledFlag()  && !CU::isSameTile(*currCtu,  *prevCtu)))
+        (!pps->getLoopFilterAcrossTilesEnabledFlag()  && !CU::isSameTile(*currCtu,  *prevCtu))
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+      || (!loopFilterAcrossSubPicEnabledFlag && !CU::isSameSubPic(*currCtu, *prevCtu))
+#endif
+      )
     {
       clipLeft = true;
     }
@@ -163,7 +179,11 @@ bool AdaptiveLoopFilter::isCrossedByVirtualBoundaries( const CodingStructure& cs
     const Position nextCtuPos(xPos + ctuSize, yPos);
     const CodingUnit *nextCtu = cs.getCU(nextCtuPos, CHANNEL_TYPE_LUMA);
     if ((!pps->getLoopFilterAcrossSlicesEnabledFlag() && !CU::isSameSlice(*currCtu, *nextCtu)) || 
-        (!pps->getLoopFilterAcrossTilesEnabledFlag()  && !CU::isSameTile(*currCtu,  *nextCtu)))
+        (!pps->getLoopFilterAcrossTilesEnabledFlag()  && !CU::isSameTile(*currCtu,  *nextCtu))
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+      || (!loopFilterAcrossSubPicEnabledFlag && !CU::isSameSubPic(*currCtu, *nextCtu))
+#endif
+      )
     {
       clipRight = true;
     }
diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/LoopFilter.cpp
index a9e3a60c8e..7541b5de90 100644
--- a/source/Lib/CommonLib/LoopFilter.cpp
+++ b/source/Lib/CommonLib/LoopFilter.cpp
@@ -82,14 +82,30 @@ inline static uint32_t getRasterIdx(const Position& pos, const PreCalcValues& pc
 // utility functions
 // ====================================================================================================================
 
-static bool isAvailableLeft( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction )
+static bool isAvailableLeft( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction 
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+  , const bool bEnforceSubPicRestriction
+#endif
+)
 {
-  return ( ( !bEnforceSliceRestriction || CU::isSameSlice( cu, cu2 ) ) && ( !bEnforceTileRestriction || CU::isSameTile( cu, cu2 ) ) );
+  return ( ( !bEnforceSliceRestriction || CU::isSameSlice( cu, cu2 ) ) && ( !bEnforceTileRestriction || CU::isSameTile( cu, cu2 ) ) 
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+    && (!bEnforceSubPicRestriction || CU::isSameSubPic(cu, cu2))
+#endif
+    );
 }
 
-static bool isAvailableAbove( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction )
+static bool isAvailableAbove( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+  , const bool bEnforceSubPicRestriction
+#endif
+)
 {
-  return ( !bEnforceSliceRestriction || CU::isSameSlice( cu, cu2 ) ) && ( !bEnforceTileRestriction || CU::isSameTile( cu, cu2 ) );
+  return ( !bEnforceSliceRestriction || CU::isSameSlice( cu, cu2 ) ) && ( !bEnforceTileRestriction || CU::isSameTile( cu, cu2 ) )
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+  && (!bEnforceSubPicRestriction || CU::isSameSubPic(cu, cu2))
+#endif
+  ;
 }
 
 
@@ -680,8 +696,17 @@ void LoopFilter::xSetLoopfilterParam( const CodingUnit& cu )
   const Position& pos = cu.blocks[cu.chType].pos();
 
   m_stLFCUParam.internalEdge = true;
-  m_stLFCUParam.leftEdge     = ( 0 < pos.x ) && isAvailableLeft ( cu, *cu.cs->getCU( pos.offset( -1,  0 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag() );
-  m_stLFCUParam.topEdge      = ( 0 < pos.y ) && isAvailableAbove( cu, *cu.cs->getCU( pos.offset(  0, -1 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag() );
+
+  m_stLFCUParam.leftEdge     = ( 0 < pos.x ) && isAvailableLeft ( cu, *cu.cs->getCU( pos.offset( -1,  0 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag() 
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+    , !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()
+#endif
+  );
+  m_stLFCUParam.topEdge      = ( 0 < pos.y ) && isAvailableAbove( cu, *cu.cs->getCU( pos.offset(  0, -1 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag() 
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+    , !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()
+#endif
+  );
 }
 
 unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const Position& localPos ) const
@@ -937,7 +962,11 @@ void LoopFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edg
       // Derive neighboring PU index
       if (edgeDir == EDGE_VER)
       {
-        if (!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()))
+        if (!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+          , !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()
+#endif
+        ))
         {
           m_aapucBS[edgeDir][uiBsAbsIdx] = uiBs = 0;
           continue;
@@ -945,7 +974,11 @@ void LoopFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edg
       }
       else  // (iDir == EDGE_HOR)
       {
-        if (!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()))
+        if (!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+          , !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()
+#endif
+        ))
         {
           m_aapucBS[edgeDir][uiBsAbsIdx] = uiBs = 0;
           continue;
@@ -1205,11 +1238,19 @@ void LoopFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir ed
 
       if (edgeDir == EDGE_VER)
       {
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+        CHECK(!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag(), !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()), "Neighbour not available");
+#else
         CHECK(!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()), "Neighbour not available");
+#endif
       }
       else  // (iDir == EDGE_HOR)
       {
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+        CHECK(!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag(), !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()), "Neighbour not available");
+#else
         CHECK(!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()), "Neighbour not available");
+#endif
       }
 
       bPartPNoFilter = bPartQNoFilter = false;
diff --git a/source/Lib/CommonLib/Mv.cpp b/source/Lib/CommonLib/Mv.cpp
index 386d087468..598a26433c 100644
--- a/source/Lib/CommonLib/Mv.cpp
+++ b/source/Lib/CommonLib/Mv.cpp
@@ -66,7 +66,17 @@ void clipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS&
 
   int iVerMax = ( pps.getPicHeightInLumaSamples() + iOffset - (int)pos.y - 1 ) << iMvShift;
   int iVerMin = ( -( int ) sps.getMaxCUHeight()   - iOffset - ( int ) pos.y + 1 ) << iMvShift;
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY 
+  SubPic curSubPic = pps.getSubPicFromPos(pos);
+  if (curSubPic.getTreatedAsPicFlag()) 
+  {
+    iHorMax = (curSubPic.getSubPicWidthInLumaSample() + iOffset - (int)pos.x - 1 ) << iMvShift;
+    iHorMin = (-(int)sps.getMaxCUWidth() -  iOffset - ((int)pos.x - curSubPic.getSubPicLeft()) + 1) << iMvShift;
 
+    iVerMax = (curSubPic.getSubPicHeightInLumaSample()+ iOffset - (int)pos.y - 1) << iMvShift;
+    iVerMin = (-(int)sps.getMaxCUHeight() - iOffset - ((int)pos.y - curSubPic.getSubPicTop()) + 1) << iMvShift;
+  }
+#endif
   rcMv.setHor( std::min( iHorMax, std::max( iHorMin, rcMv.getHor() ) ) );
   rcMv.setVer( std::min( iVerMax, std::max( iVerMin, rcMv.getVer() ) ) );
 }
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index 2821a7ef36..f69d5bd64b 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -173,6 +173,9 @@ int Scheduler::getNumPicInstances() const
 Picture::Picture()
 {
   cs                   = nullptr;
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+  m_bIsSubPicBorderSaved = false;
+#endif
   m_bIsBorderExtended  = false;
   usedByCurr           = false;
   longTerm             = false;
@@ -734,6 +737,303 @@ void Picture::rescalePicture( const std::pair<int, int> scalingRatio,
   }
 }
 
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+void Picture::saveSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight)
+{
+  // 1.0 check border was extended
+  if (getSubPicSaved()) 
+  {
+    return;
+  }
+
+  // 1.1 set up margin for back up memory allocation
+  int xMargin = margin >> getComponentScaleX(COMPONENT_Y, cs->area.chromaFormat);
+  int yMargin = margin >> getComponentScaleY(COMPONENT_Y, cs->area.chromaFormat);
+
+  // 1.2 measure the size of back up memory
+  Area areaAboveBelow(0, 0, subPicWidth + 2 * xMargin, yMargin);
+  Area areaLeftRight(0, 0, xMargin, subPicHeight);
+  UnitArea unitAreaAboveBelow(cs->area.chromaFormat, areaAboveBelow);
+  UnitArea unitAreaLeftRight(cs->area.chromaFormat, areaLeftRight);
+
+  // 1.3 create back up memory
+  m_bufSubPicAbove.create(unitAreaAboveBelow);
+  m_bufSubPicBelow.create(unitAreaAboveBelow);
+  m_bufSubPicLeft.create(unitAreaLeftRight);
+  m_bufSubPicRight.create(unitAreaLeftRight);
+
+  Pel *ss0;
+  Pel *ss1;
+  Pel *dd0;
+  Pel *dd1;
+  int copylen;
+
+  for (int comp = 0; comp < getNumberValidComponents(cs->area.chromaFormat); comp++) 
+  {
+    ComponentID compID = ComponentID(comp);
+
+    // 2.1 measure the margin for each component
+    int xmargin = margin >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int ymargin = margin >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+    // 2.2 calculate the origin of the subpicture
+    int tx0 = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int ty0 = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+    // 2.3 calculate the width/height of the subPic
+    int tww = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int thh = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+
+    // 3.1.1 set reconstructed picture
+    PelBuf s = M_BUFS(0, PIC_RECONSTRUCTION).get(compID);
+    Pel *siTxt = s.bufAt(tx0, ty0);
+    Pel*  si = siTxt;
+
+    // 3.2.1 set back up buffer for left
+    PelBuf d0 = m_bufSubPicLeft.getBuf(compID);
+    Pel *diTxt0 = d0.bufAt(0, 0);
+    Pel *di0 = diTxt0;
+
+    // 3.2.2 set back up buffer for right
+    PelBuf d1 = m_bufSubPicRight.getBuf(compID);
+    Pel *diTxt1 = d1.bufAt(0, 0);
+    Pel *di1 = diTxt1;
+
+
+    // 3.2.3 copy to recon picture to back up buffer
+    ss0 = si - xmargin;
+    ss1 = si + tww;
+    dd0 = di0;
+    dd1 = di1;
+    copylen = sizeof(Pel) * xmargin;
+    for (int y = 0; y < thh; y++) 
+    {
+      ::memcpy(dd0, ss0, copylen);
+      ::memcpy(dd1, ss1, copylen);
+      ss0 += s.stride;
+      ss1 += s.stride;
+      dd0 += d0.stride;
+      dd1 += d1.stride;
+    }
+
+
+    // 3.3.1 set back up buffer for above
+    d0 = m_bufSubPicAbove.getBuf(compID);
+    diTxt0 = d0.bufAt(0, 0);
+    di0 = diTxt0;
+
+    // 3.3.2 set back up buffer for below
+    d1 = m_bufSubPicBelow.getBuf(compID);
+    diTxt1 = d1.bufAt(0, 0);
+    di1 = diTxt1;
+
+    // 3.3.3 copy to recon picture to back up buffer
+    ss0 = si - xmargin - ymargin * s.stride;
+    ss1 = si - xmargin + thh * s.stride;
+    dd0 = di0;
+    dd1 = di1;
+    copylen = sizeof(Pel) * (2 * xmargin + tww);
+    for (int y = 0; y < ymargin; y++) 
+    {
+      ::memcpy(dd0, ss0, copylen);
+      ::memcpy(dd1, ss1, copylen);
+      ss0 += s.stride;
+      ss1 += s.stride;
+      dd0 += d0.stride;
+      dd1 += d1.stride;
+    }
+  }
+}
+
+void Picture::extendSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight)
+{
+  // 1.0 check border was extended
+  if (getSubPicSaved()) 
+  {
+    return;
+  }
+
+  Pel *ss0 = 0;
+  Pel *ss1 = 0;
+  Pel *dd0 = 0;
+  Pel *dd1 = 0;
+  int copylen;
+
+  for (int comp = 0; comp < getNumberValidComponents(cs->area.chromaFormat); comp++) 
+  {
+    ComponentID compID = ComponentID(comp);
+
+    // 2.1 measure the margin for each component
+    int xmargin = margin >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int ymargin = margin >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+    // 2.2 calculate the origin of the Subpicture
+    int tx0 = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int ty0 = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+    // 2.3 calculate the width/height of the Subpicture
+    int tww = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int thh = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+    // 3.1 set reconstructed picture
+    PelBuf s = M_BUFS(0, PIC_RECONSTRUCTION).get(compID);
+    Pel *siTxt = s.bufAt(tx0, ty0);
+    Pel*  si = siTxt;
+
+    // 4.1 apply padding for left and right
+    {
+      Pel *xx0, *xx1;
+      ss0 = si - xmargin;
+      ss1 = si + tww;
+      xx0 = si + 0;
+      xx1 = si + tww - 1;
+
+      for (int y = 0; y < thh; y++) 
+      {
+        dd0 = ss0;
+        dd1 = ss1;
+        for (int x = 0; x < xmargin; x++) 
+        {
+          *dd0++ = *xx0;
+          *dd1++ = *xx1;
+        }
+
+        ss0 += s.stride;
+        ss1 += s.stride;
+        xx0 += s.stride;
+        xx1 += s.stride;
+      }
+    }
+
+    // 4.2 apply padding on bottom 
+    // si is now the (0, SubpictureHeight) (bottom left of image within bigger picture
+    si += s.stride * (thh - 1) - xmargin;
+
+    // si is now the (-marginX, SubpictureHeight-1)
+    ss0 = si + s.stride;
+    copylen = sizeof(Pel)*(tww + (xmargin << 1));
+    for (int y = 0; y < ymargin; y++)
+    {
+      ::memcpy(ss0, si, copylen);
+      ss0 += s.stride;
+    }
+
+    // 4.3 apply padding for top
+    // si is still (-marginX, SubpictureHeight-1)
+    si -= ((thh - 1) * s.stride);
+
+    // si is now (-marginX, 0)
+    ss0 = si - s.stride;
+    copylen = sizeof(Pel)*(tww + (xmargin << 1));
+    for (int y = 0; y < ymargin; y++)
+    {
+      ::memcpy(ss0, si, copylen);
+      ss0 -= s.stride;
+    }
+  } // end of for  
+}
+
+void Picture::restoreSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight)
+{
+  // 1.0 check border was extended
+  if (!getSubPicSaved()) 
+  {
+    return;
+  }
+
+  Pel *ss0;
+  Pel *ss1;
+  Pel *dd0;
+  Pel *dd1;
+  int copylen;
+
+  for (int comp = 0; comp < getNumberValidComponents(cs->area.chromaFormat); comp++) 
+  {
+    ComponentID compID = ComponentID(comp);
+
+    // 2.1 measure the margin for each component
+    int xmargin = margin >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int ymargin = margin >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+    // 2.2 calculate the origin of the subpicture
+    int tx0 = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int ty0 = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+    // 2.3 calculate the width/height of the subpicture
+    int tww = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int thh = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
+
+    // 3.1 set reconstructed picture
+    PelBuf s = M_BUFS(0, PIC_RECONSTRUCTION).get(compID);
+    Pel *siTxt = s.bufAt(tx0, ty0);
+    Pel*  si = siTxt;
+
+
+    // 4.2.1 copy from back up buffer to recon picture
+    PelBuf d0 = m_bufSubPicLeft.getBuf(compID);
+    Pel *diTxt0 = d0.bufAt(0, 0);
+    Pel *di0 = diTxt0;
+
+    // 4.2.2 set back up buffer for right
+    PelBuf d1 = m_bufSubPicRight.getBuf(compID);
+    Pel *diTxt1 = d1.bufAt(0, 0);
+    Pel *di1 = diTxt1;
+
+    // 4.2.3 copy to recon picture to back up buffer
+    ss0 = si - xmargin;
+    ss1 = si + tww;
+    dd0 = di0;
+    dd1 = di1;
+    copylen = sizeof(Pel) * xmargin;
+
+    for (int y = 0; y < thh; y++) 
+    {
+      ::memcpy(ss0, dd0, copylen);
+      ::memcpy(ss1, dd1, copylen);
+      ss0 += s.stride;
+      ss1 += s.stride;
+      dd0 += d0.stride;
+      dd1 += d1.stride;
+    }
+
+
+    // 4.3.1 copy from back up buffer to recon picture
+    d0 = m_bufSubPicAbove.getBuf(compID);
+    diTxt0 = d0.bufAt(0, 0);
+    di0 = diTxt0;
+
+    // 4.3.2 set back up buffer for below
+    d1 = m_bufSubPicBelow.getBuf(compID);
+    diTxt1 = d1.bufAt(0, 0);
+    di1 = diTxt1;
+
+    // 4.3.3 copy to recon picture to back up buffer
+    ss0 = si - xmargin - ymargin * s.stride;
+    ss1 = si - xmargin + thh * s.stride;
+    dd0 = di0;
+    dd1 = di1;
+    copylen = sizeof(Pel) * (2 * xmargin + tww);
+
+    for (int y = 0; y < ymargin; y++) 
+    {
+      ::memcpy(ss0, dd0, copylen);
+      ::memcpy(ss1, dd1, copylen);
+      ss0 += s.stride;
+      ss1 += s.stride;
+      dd0 += d0.stride;
+      dd1 += d1.stride;
+    }
+  }
+
+  // 5.0 destroy the back up memory
+  m_bufSubPicAbove.destroy();
+  m_bufSubPicBelow.destroy();
+  m_bufSubPicLeft.destroy();
+  m_bufSubPicRight.destroy();
+}
+#endif
+
 void Picture::extendPicBorder()
 {
   if ( m_bIsBorderExtended )
diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h
index 1c259541cd..b1d8ca6f45 100644
--- a/source/Lib/CommonLib/Picture.h
+++ b/source/Lib/CommonLib/Picture.h
@@ -172,6 +172,21 @@ private:
   Window        m_scalingWindow;
 
 public:
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY  
+  bool m_bIsSubPicBorderSaved;
+
+  PelStorage m_bufSubPicAbove;
+  PelStorage m_bufSubPicBelow;
+  PelStorage m_bufSubPicLeft;
+  PelStorage m_bufSubPicRight;
+
+  void    saveSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight);
+  void  extendSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight);
+  void restoreSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight);
+
+  bool getSubPicSaved()          { return m_bIsSubPicBorderSaved; }
+  void setSubPicSaved(bool bVal) { m_bIsSubPicBorderSaved = bVal; }
+#endif
   bool m_bIsBorderExtended;
   bool referenced;
   bool reconstructed;
diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
index 0953b569a4..a910f8a468 100644
--- a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
+++ b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
@@ -726,6 +726,22 @@ void SampleAdaptiveOffset::deriveLoopFilterBoundaryAvailibility(CodingStructure&
     isBelowLeftAvail  = (!isBelowLeftAvail)  ? false : CU::isSameTile(*cuCurr, *cuBelowLeft);
     isBelowRightAvail = (!isBelowRightAvail) ? false : CU::isSameTile(*cuCurr, *cuBelowRight);
   }
+
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+  // check cross subpic flags
+  SubPic curSubPic = cs.pps->getSubPicFromCU(*cuCurr);
+  if (!curSubPic.getloopFilterAcrossEnabledFlag())
+  {
+    isLeftAvail       = (!isLeftAvail)       ? false : CU::isSameSubPic(*cuCurr, *cuLeft);
+    isAboveAvail      = (!isAboveAvail)      ? false : CU::isSameSubPic(*cuCurr, *cuAbove);
+    isRightAvail      = (!isRightAvail)      ? false : CU::isSameSubPic(*cuCurr, *cuRight);
+    isBelowAvail      = (!isBelowAvail)      ? false : CU::isSameSubPic(*cuCurr, *cuBelow);
+    isAboveLeftAvail  = (!isAboveLeftAvail)  ? false : CU::isSameSubPic(*cuCurr, *cuAboveLeft);
+    isAboveRightAvail = (!isAboveRightAvail) ? false : CU::isSameSubPic(*cuCurr, *cuAboveRight);
+    isBelowLeftAvail  = (!isBelowLeftAvail)  ? false : CU::isSameSubPic(*cuCurr, *cuBelowLeft);
+    isBelowRightAvail = (!isBelowRightAvail) ? false : CU::isSameSubPic(*cuCurr, *cuBelowRight);
+  }
+#endif
 }
 
 bool SampleAdaptiveOffset::isCrossedByVirtualBoundaries(const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PicHeader* picHeader )
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index df9936f98b..a2b6fb6d4a 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -2378,6 +2378,7 @@ void PPS::initSubPic(const SPS &sps)
   m_subPics.resize(getNumSubPics());
   for (int i=0; i< getNumSubPics(); i++)
   {
+    m_subPics[i].setSubPicIdx(i);
     m_subPics[i].setSubPicCtuTopLeftX(sps.getSubPicCtuTopLeftX(i));
     m_subPics[i].setSubPicCtuTopLeftY(sps.getSubPicCtuTopLeftY(i));
     m_subPics[i].setSubPicWidthInCTUs(sps.getSubPicWidth(i));
@@ -2394,10 +2395,15 @@ void PPS::initSubPic(const SPS &sps)
     uint32_t right = std::min(m_picWidthInLumaSamples - 1, (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * m_ctuSize - 1);
     m_subPics[i].setSubPicRight(right);
     
+    m_subPics[i].setSubPicWidthInLumaSample(right - left + 1);
+
     uint32_t top = sps.getSubPicCtuTopLeftY(i) * m_ctuSize;
     m_subPics[i].setSubPicTop(top);
     
     uint32_t bottom = std::min(m_picHeightInLumaSamples - 1, (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * m_ctuSize - 1);
+
+    m_subPics[i].setSubPicHeightInLumaSample(bottom - top + 1);
+
     m_subPics[i].setSubPicBottom(bottom);
     
     for (int j = 0; j < m_numSlicesInPic; j++)
@@ -2410,7 +2416,7 @@ void PPS::initSubPic(const SPS &sps)
           ctu_y >= sps.getSubPicCtuTopLeftY(i) &&
           ctu_y < (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i))) 
       {
-         // slice in the subpicture
+         // add ctus in a slice to the subpicture it belongs to
         m_subPics[i].addCTUsToSubPic(m_sliceMap[j].getCtuAddrList());
       }
     }
@@ -2418,6 +2424,24 @@ void PPS::initSubPic(const SPS &sps)
     m_subPics[i].setloopFilterAcrossEnabledFlag(sps.getLoopFilterAcrossSubpicEnabledFlag(i));
   }
 }
+
+SubPic PPS::getSubPicFromPos(const Position& pos)  const
+{
+  for (int i = 0; i< m_numSubPics; i++)
+  {
+    if (m_subPics[i].isContainingPos(pos))
+    {
+      return m_subPics[i];
+    }
+  }
+  return m_subPics[0];
+}
+
+SubPic  PPS::getSubPicFromCU(const CodingUnit& cu) const 
+{
+  const Position lumaPos = cu.Y().valid() ? cu.Y().pos() : recalcPosition(cu.chromaFormat, cu.chType, CHANNEL_TYPE_LUMA, cu.blocks[cu.chType].pos());
+  return getSubPicFromPos(lumaPos);
+}
 #endif
 
 void PPS::initRasterSliceMap( std::vector<uint32_t> numTilesInSlice )
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index 4fb4fb24d5..fc1f1aa271 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -689,11 +689,14 @@ class SubPic
 {
 private:
   uint32_t         m_subPicID;                                  //!< ID of subpicture
+  uint32_t         m_subPicIdx;                                 //!< Index of subpicture
   uint32_t         m_numCTUsInSubPic;                           //!< number of CTUs contained in this sub-picture
   uint32_t         m_subPicCtuTopLeftX;                         //!< horizontal position of top left CTU of the subpicture in unit of CTU
   uint32_t         m_subPicCtuTopLeftY;                         //!< vertical position of top left CTU of the subpicture in unit of CTU
   uint32_t         m_subPicWidth;                               //!< the width of subpicture in units of CTU
   uint32_t         m_subPicHeight;                              //!< the height of subpicture in units of CTU
+  uint32_t         m_subPicWidthInLumaSample;                   //!< the width of subpicture in units of luma sample
+  uint32_t         m_subPicHeightInLumaSample;                  //!< the height of subpicture in units of luma sample
   uint32_t         m_firstCtuInSubPic;                          //!< the raster scan index of the first CTU in a subpicture
   uint32_t         m_lastCtuInSubPic;                           //!< the raster scan index of the last CTU in a subpicture
   uint32_t         m_subPicLeft;                                //!< the position of left boundary 
@@ -711,6 +714,8 @@ public:
 
   void             setSubPicID (uint32_t u)                {         m_subPicID = u;       }
   uint32_t         getSubPicID   ()                  const { return  m_subPicID;           }
+  void             setSubPicIdx (uint32_t u)               {         m_subPicIdx = u;      }
+  uint32_t         getSubPicIdx ()                   const { return  m_subPicIdx;          }
   void             setNumCTUsInSubPic   (uint32_t u)       {         m_numCTUsInSubPic = u;       }
   uint32_t         getNumCTUsInSubPic   ()           const { return  m_numCTUsInSubPic;           }
   void             setSubPicCtuTopLeftX (uint32_t u)       {         m_subPicCtuTopLeftX = u;     }
@@ -734,16 +739,32 @@ public:
   void             setSubPicBottom      (uint32_t u)       {         m_subPicBottom = u;          }
   uint32_t         getSubPicBottom      ()           const { return  m_subPicBottom;              }
 
+  void             setSubPicWidthInLumaSample (uint32_t u) {         m_subPicWidthInLumaSample = u;   }
+  uint32_t         getSubPicWidthInLumaSample()      const { return  m_subPicWidthInLumaSample;       }
+  void             setSubPicHeightInLumaSample(uint32_t u) {         m_subPicHeightInLumaSample = u;  }
+  uint32_t         getSubPicHeightInLumaSample()     const { return  m_subPicHeightInLumaSample;      }
+
   std::vector<uint32_t> getCtuAddrList  ()           const { return  m_ctuAddrInSubPic;           }
   void                  addCTUsToSubPic(std::vector<uint32_t> ctuAddrInSlice)
   {
     for (auto ctu:ctuAddrInSlice)
       m_ctuAddrInSubPic.push_back(ctu);    
   }
+  bool                 isContainingPos(const Position& pos) const
+  {
+    if (pos.x >= m_subPicLeft && pos.x <= m_subPicRight &&
+      pos.y >= m_subPicTop  && pos.y <= m_subPicBottom)
+      return true;
+    else
+      return false;
+  }
   void             setTreatedAsPicFlag           (bool u)  {         m_treatedAsPicFlag = u;   }
   bool             getTreatedAsPicFlag           ()  const { return  m_treatedAsPicFlag;       }
   void             setloopFilterAcrossEnabledFlag(bool u)  {         m_loopFilterAcrossSubPicEnabledFlag = u; }
   bool             getloopFilterAcrossEnabledFlag()  const { return  m_loopFilterAcrossSubPicEnabledFlag;     }
+
+  bool             isFirstCTUinSubPic(uint32_t ctuAddr)    { return  ctuAddr == m_firstCtuInSubPic;  }
+  bool              isLastCTUinSubPic(uint32_t ctuAddr)    { return  ctuAddr == m_lastCtuInSubPic;   }
 };
 #endif
 class DPS
@@ -1814,6 +1835,8 @@ public:
 #if JVET_O1143_SUBPIC_BOUNDARY
   std::vector<SubPic>    getSubPics()  const                                              {return m_subPics;          };
   void                   initSubPic(const SPS &sps);
+  SubPic                 getSubPicFromPos(const Position& pos)  const;
+  SubPic                 getSubPicFromCU (const CodingUnit& cu) const;
 #endif
   void                   initRasterSliceMap( std::vector<uint32_t> sizes );
   void                   checkSliceMap(); 
@@ -2427,7 +2450,11 @@ public:
   int                         getNumRefIdx( RefPicList e ) const                     { return m_aiNumRefIdx[e];                                      }
   Picture*                    getPic()                                               { return m_pcPic;                                               }
   const Picture*              getPic() const                                         { return m_pcPic;                                               }
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+        Picture*              getRefPic( RefPicList e, int iRefIdx) const            { return m_apcRefPicList[e][iRefIdx];                           }
+#else
   const Picture*              getRefPic( RefPicList e, int iRefIdx) const            { return m_apcRefPicList[e][iRefIdx];                           }
+#endif
   int                         getRefPOC( RefPicList e, int iRefIdx) const            { return m_aiRefPOCList[e][iRefIdx];                            }
   int                         getDepth() const                                       { return m_iDepth;                                              }
   bool                        getColFromL0Flag() const                               { return m_colFromL0Flag;                                       }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 7ad29c25d9..82b938fe38 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -92,7 +92,9 @@
 
 #define JVET_O1143_SUBPIC_BOUNDARY                        1 // treat subpicture boundary as piucture boundary
 #if JVET_O1143_SUBPIC_BOUNDARY
-#define SUBPIC_DECCHECK                                   0
+#define JVET_O1143_SUBPIC_DECCHECK                        1
+#define JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY             1 
+#define JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY              1
 #endif
 
 #define JVET_Q0495_NLALF_CLIP_CLEANUP                     1 // JVET-Q0495: Cleanup of clipping table for NL-ALF
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index ece0dcac64..ce845522c6 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -172,6 +172,13 @@ bool CU::isSameSliceAndTile(const CodingUnit& cu, const CodingUnit& cu2)
   return ( cu.slice->getIndependentSliceIdx() == cu2.slice->getIndependentSliceIdx() ) && ( cu.tileIdx == cu2.tileIdx );
 }
 
+#if JVET_O1143_SUBPIC_BOUNDARY
+bool CU::isSameSubPic(const CodingUnit& cu, const CodingUnit& cu2)
+{
+  return (cu.slice->getPPS()->getSubPicFromCU(cu).getSubPicIdx() == cu2.slice->getPPS()->getSubPicFromCU(cu2).getSubPicIdx()) ;
+}
+#endif 
+
 bool CU::isSameCtu(const CodingUnit& cu, const CodingUnit& cu2)
 {
   uint32_t ctuSizeBit = floorLog2(cu.cs->sps->getMaxCUWidth());
@@ -1069,7 +1076,18 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
     Position posC0;
     Position posC1 = pu.Y().center();
     bool C0Avail = false;
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+    bool boundaryCond = ((posRB.x + pcv.minCUWidth) < pcv.lumaWidth) && ((posRB.y + pcv.minCUHeight) < pcv.lumaHeight);
+    SubPic curSubPic = pu.cs->slice->getPPS()->getSubPicFromPos(pu.lumaPos());
+    if (curSubPic.getTreatedAsPicFlag())
+    {
+      boundaryCond = ((posRB.x + pcv.minCUWidth) <= curSubPic.getSubPicRight() &&
+                      (posRB.y + pcv.minCUHeight) <= curSubPic.getSubPicBottom());
+    }    
+    if (boundaryCond)
+#else
     if (((posRB.x + pcv.minCUWidth) < pcv.lumaWidth) && ((posRB.y + pcv.minCUHeight) < pcv.lumaHeight))
+#endif
     {
       int posYInCtu = posRB.y & pcv.maxCUHeightMask;
       if (posYInCtu + 4 < pcv.maxCUHeight)
@@ -1402,6 +1420,15 @@ bool PU::getColocatedMVP(const PredictionUnit &pu, const RefPicList &eRefPicList
     return false;
   }
 
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+  // Check the position of colocated block is within a subpicture
+  SubPic curSubPic = pu.cs->slice->getPPS()->getSubPicFromPos(pu.lumaPos());
+  if (curSubPic.getTreatedAsPicFlag())
+  {
+    if (!curSubPic.isContainingPos(pos))
+      return false;
+  }
+#endif
   RefPicList eColRefPicList = slice.getCheckLDC() ? eRefPicList : RefPicList(slice.getColFromL0Flag());
 
   const MotionInfo& mi = pColPic->cs->getMotionInfo( pos );
@@ -1778,7 +1805,18 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
     Position posC1 = pu.Y().center();
     Mv cColMv;
 
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+    bool boundaryCond = ((posRB.x + pcv.minCUWidth) < pcv.lumaWidth) && ((posRB.y + pcv.minCUHeight) < pcv.lumaHeight);
+    SubPic curSubPic = pu.cs->slice->getPPS()->getSubPicFromPos(pu.lumaPos());
+    if (curSubPic.getTreatedAsPicFlag())
+    {
+      boundaryCond = ((posRB.x + pcv.minCUWidth) <= curSubPic.getSubPicRight() &&
+                      (posRB.y + pcv.minCUHeight) <= curSubPic.getSubPicBottom());
+    }    
+    if (boundaryCond)
+#else
     if( ( ( posRB.x + pcv.minCUWidth ) < pcv.lumaWidth ) && ( ( posRB.y + pcv.minCUHeight ) < pcv.lumaHeight ) )
+#endif
     {
       int posYInCtu = posRB.y & pcv.maxCUHeightMask;
       if (posYInCtu + 4 < pcv.maxCUHeight)
@@ -2093,7 +2131,18 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
       bool C0Avail = false;
       Position posC1 = pu.Y().center();
       Mv cColMv;
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+      bool boundaryCond = ((posRB.x + pcv.minCUWidth) < pcv.lumaWidth) && ((posRB.y + pcv.minCUHeight) < pcv.lumaHeight);
+      SubPic curSubPic = pu.cs->slice->getPPS()->getSubPicFromPos(pu.lumaPos());
+      if (curSubPic.getTreatedAsPicFlag())
+      {
+        boundaryCond = ((posRB.x + pcv.minCUWidth) <= curSubPic.getSubPicRight() &&
+          (posRB.y + pcv.minCUHeight) <= curSubPic.getSubPicBottom());
+      }
+      if (boundaryCond)
+#else
       if ( ((posRB.x + pcv.minCUWidth) < pcv.lumaWidth) && ((posRB.y + pcv.minCUHeight) < pcv.lumaHeight) )
+#endif
       {
         int posYInCtu = posRB.y & pcv.maxCUHeightMask;
         if (posYInCtu + 4 < pcv.maxCUHeight)
@@ -2670,7 +2719,18 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
         Position posC0;
         bool C0Avail = false;
 
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+        bool boundaryCond = ((posRB.x + pcv.minCUWidth) < pcv.lumaWidth) && ((posRB.y + pcv.minCUHeight) < pcv.lumaHeight);
+        SubPic curSubPic = pu.cs->slice->getPPS()->getSubPicFromPos(pu.lumaPos());
+        if (curSubPic.getTreatedAsPicFlag())
+        {
+          boundaryCond = ((posRB.x + pcv.minCUWidth) <= curSubPic.getSubPicRight() &&
+            (posRB.y + pcv.minCUHeight) <= curSubPic.getSubPicBottom());
+        }
+        if (boundaryCond)
+#else
         if ( ((posRB.x + pcv.minCUWidth) < pcv.lumaWidth) && ((posRB.y + pcv.minCUHeight) < pcv.lumaHeight) )
+#endif
         {
           int posYInCtu = posRB.y & pcv.maxCUHeightMask;
           if (posYInCtu + 4 < pcv.maxCUHeight)
@@ -2860,7 +2920,20 @@ void clipColPos(int& posX, int& posY, const PredictionUnit& pu)
   int log2CtuSize = floorLog2(pu.cs->sps->getCTUSize());
   int ctuX = ((puPos.x >> log2CtuSize) << log2CtuSize);
   int ctuY = ((puPos.y >> log2CtuSize) << log2CtuSize);
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+  int horMax;
+  SubPic curSubPic = pu.cu->slice->getPPS()->getSubPicFromPos(puPos);
+  if (curSubPic.getTreatedAsPicFlag())
+  {
+    horMax = std::min((int)curSubPic.getSubPicRight(), ctuX + (int)pu.cs->sps->getCTUSize() + 3);
+  }
+  else
+  {
+    horMax = std::min((int)pu.cs->pps->getPicWidthInLumaSamples() - 1, ctuX + (int)pu.cs->sps->getCTUSize() + 3);
+  }
+#else
   int horMax = std::min( (int)pu.cs->pps->getPicWidthInLumaSamples() - 1, ctuX + (int)pu.cs->sps->getCTUSize() + 3 );
+#endif
   int horMin = std::max((int)0, ctuX);
   int verMax = std::min( (int)pu.cs->pps->getPicHeightInLumaSamples() - 1, ctuY + (int)pu.cs->sps->getCTUSize() - 1 );
   int verMin = std::max((int)0, ctuY);
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index e13475ef6c..3807321f85 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -66,6 +66,9 @@ namespace CU
   bool isSameSlice                    (const CodingUnit &cu, const CodingUnit &cu2);
   bool isSameTile                     (const CodingUnit &cu, const CodingUnit &cu2);
   bool isSameSliceAndTile             (const CodingUnit &cu, const CodingUnit &cu2);
+#if JVET_O1143_SUBPIC_BOUNDARY
+  bool isSameSubPic                   (const CodingUnit &cu, const CodingUnit &cu2);
+#endif
   bool isLastSubCUOfCtu               (const CodingUnit &cu);
   uint32_t getCtuAddr                     (const CodingUnit &cu);
   int  predictQP                      (const CodingUnit& cu, const int prevQP );
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 253f8dda0f..7c6721fe3f 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -594,7 +594,7 @@ void DecLib::executeLoopFilters()
     m_cALF.ALFProcess(cs);
   }
 
-#if SUBPIC_DECCHECK 
+#if JVET_O1143_SUBPIC_DECCHECK 
   for (int i = 0; i < cs.pps->getNumSubPics(); i++)
   {
     // keep target subpic samples untouched, for other subpics mask their output sample value to 0
@@ -605,6 +605,7 @@ void DecLib::executeLoopFilters()
       uint32_t right = SubPicNoUse.getSubPicRight();
       uint32_t top   = SubPicNoUse.getSubPicTop();
       uint32_t bottom= SubPicNoUse.getSubPicBottom();
+      printf("left %d right %d, top %d bottom %d\n", left, right, top, bottom);
       for (uint32_t row = top; row <= bottom; row++)
       {
         for (uint32_t col = left; col <= right; col++)
diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h
index 7c9e0fa6b4..8ce3c0c24e 100644
--- a/source/Lib/DecoderLib/DecLib.h
+++ b/source/Lib/DecoderLib/DecLib.h
@@ -137,7 +137,7 @@ private:
   bool                    m_scalingListUpdateFlag;
   int                     m_PreScalingListAPSId;
 
-#if SUBPIC_DECCHECK
+#if JVET_O1143_SUBPIC_DECCHECK
 public:
   int                     m_targetSubPicIdx;
 #endif
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index 9e4d1360f7..5393538dd4 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -143,6 +143,31 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
     const unsigned  maxCUSize             = sps->getMaxCUWidth();
     Position pos( ctuXPosInCtus*maxCUSize, ctuYPosInCtus*maxCUSize) ;
     UnitArea ctuArea(cs.area.chromaFormat, Area( pos.x, pos.y, maxCUSize, maxCUSize ) );
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+    SubPic curSubPic = slice->getPPS()->getSubPicFromPos(pos);
+    // padding/restore at slice level
+    if (curSubPic.getTreatedAsPicFlag() && ctuIdx==0)
+    {
+      int subPicX      = (int)curSubPic.getSubPicLeft();
+      int subPicY      = (int)curSubPic.getSubPicTop();
+      int subPicWidth  = (int)curSubPic.getSubPicWidthInLumaSample();
+      int subPicHeight = (int)curSubPic.getSubPicHeightInLumaSample();
+      for (int rlist = REF_PIC_LIST_0; rlist < NUM_REF_PIC_LIST_01; rlist++) 
+      {
+        int n = slice->getNumRefIdx((RefPicList)rlist);
+        for (int idx = 0; idx < n; idx++) 
+        {
+          Picture *refPic = slice->getRefPic((RefPicList)rlist, idx);
+          refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
+          refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
+          if (!refPic->getSubPicSaved()) 
+          {
+            refPic->setSubPicSaved(true);
+          }
+        }
+      }
+    }
+#endif
 
     DTRACE_UPDATE( g_trace_ctx, std::make_pair( "ctu", ctuRsAddr ) );
 
@@ -232,6 +257,30 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
 #endif
       subStrmId++;
     }
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+    if (curSubPic.getTreatedAsPicFlag() && ctuIdx == (slice->getNumCtuInSlice() - 1))
+    // for last Ctu in the slice
+    {
+      int subPicX = (int)curSubPic.getSubPicLeft();
+      int subPicY = (int)curSubPic.getSubPicTop();
+      int subPicWidth = (int)curSubPic.getSubPicWidthInLumaSample();
+      int subPicHeight = (int)curSubPic.getSubPicHeightInLumaSample();
+      for (int rlist = REF_PIC_LIST_0; rlist < NUM_REF_PIC_LIST_01; rlist++) 
+      {
+        int n = slice->getNumRefIdx((RefPicList)rlist);
+        for (int idx = 0; idx < n; idx++) 
+        {
+          Picture *refPic = slice->getRefPic((RefPicList)rlist, idx);
+          refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
+
+          if (refPic->getSubPicSaved()) 
+          {
+            refPic->setSubPicSaved(false);
+          }
+        }
+      }
+    }
+#endif
   }
 
   // deallocate all created substreams, including internal buffers.
diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
index 15ed5b0e24..44e214ff81 100644
--- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
+++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
@@ -1569,6 +1569,16 @@ void EncSampleAdaptiveOffset::deriveLoopFilterBoundaryAvailibility(CodingStructu
     isAboveAvail     = (!isAboveAvail)     ? false : CU::isSameTile(*cuCurr, *cuAbove);
     isAboveLeftAvail = (!isAboveLeftAvail) ? false : CU::isSameTile(*cuCurr, *cuAboveLeft);
   }
+
+#if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
+  SubPic curSubPic = cs.pps->getSubPicFromCU(*cuCurr);
+  if (!curSubPic.getloopFilterAcrossEnabledFlag())
+  {
+    isLeftAvail      = (!isLeftAvail)      ? false : CU::isSameSubPic(*cuCurr, *cuLeft);
+    isAboveAvail     = (!isAboveAvail)     ? false : CU::isSameSubPic(*cuCurr, *cuAbove);
+    isAboveLeftAvail = (!isAboveLeftAvail) ? false : CU::isSameSubPic(*cuCurr, *cuAboveLeft);
+  }
+#endif
 }
 
 //! \}
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index 979743ec46..cb0d820903 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1452,7 +1452,36 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
       cs.motionLut.lutIbc.resize(0);
     }
 
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+    SubPic curSubPic = pcSlice->getPPS()->getSubPicFromPos(pos);
+    // padding/restore at slice level
+    if (curSubPic.getTreatedAsPicFlag() && ctuIdx == 0)
+    {
+      int subPicX = (int)curSubPic.getSubPicLeft();
+      int subPicY = (int)curSubPic.getSubPicTop();
+      int subPicWidth = (int)curSubPic.getSubPicWidthInLumaSample();
+      int subPicHeight = (int)curSubPic.getSubPicHeightInLumaSample();
+
+      for (int rlist = REF_PIC_LIST_0; rlist < NUM_REF_PIC_LIST_01; rlist++) 
+      {
+        int n = pcSlice->getNumRefIdx((RefPicList)rlist);
+        for (int idx = 0; idx < n; idx++) 
+        {
+          Picture *refPic = pcSlice->getRefPic((RefPicList)rlist, idx);
+
+          refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
+          refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
 
+          if (!refPic->getSubPicSaved()) 
+          {
+            refPic->setSubPicSaved(true);
+          }
+          // Save only at the beginning of the tile          
+          // refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);          
+        }
+      }
+    }
+#endif
     if (cs.pps->ctuIsTileColBd( ctuXPosInCtus ) && cs.pps->ctuIsTileRowBd( ctuYPosInCtus ))
     {
       pCABACWriter->initCtxModels( *pcSlice );
@@ -1649,6 +1678,31 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
 
     m_uiPicTotalBits += actualBits;
     m_uiPicDist       = cs.dist;
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+    // for last Ctu in the slice    
+    if (curSubPic.getTreatedAsPicFlag() && ctuIdx == (pcSlice->getNumCtuInSlice() - 1))
+    {
+
+      int subPicX = (int)curSubPic.getSubPicLeft();
+      int subPicY = (int)curSubPic.getSubPicTop();
+      int subPicWidth = (int)curSubPic.getSubPicWidthInLumaSample();
+      int subPicHeight = (int)curSubPic.getSubPicHeightInLumaSample();
+
+      for (int rlist = REF_PIC_LIST_0; rlist < NUM_REF_PIC_LIST_01; rlist++) 
+      {
+        int n = pcSlice->getNumRefIdx((RefPicList)rlist);
+        for (int idx = 0; idx < n; idx++) 
+        {
+          Picture *refPic = pcSlice->getRefPic((RefPicList)rlist, idx);
+          refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
+          if (refPic->getSubPicSaved()) 
+          {
+            refPic->setSubPicSaved(false);
+          }
+        }
+      }
+    }
+#endif
   }
 
   // this is wpp exclusive section
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index 51ff99a786..91fcfd1333 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -7984,7 +7984,17 @@ 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;
+#if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
+  SubPic curSubPic = pps.getSubPicFromPos(pos);
+  if (curSubPic.getTreatedAsPicFlag()) 
+  {
+    horMax = (curSubPic.getSubPicWidthInLumaSample() + offset - (int)pos.x - 1) << mvShift;
+    horMin = (-(int)sps.getMaxCUWidth()  - offset - ((int)pos.x - curSubPic.getSubPicLeft()) + 1) << mvShift;
 
+    verMax = (curSubPic.getSubPicHeightInLumaSample()+ offset -  (int)pos.y - 1) << mvShift;
+    verMin = (-(int)sps.getMaxCUHeight() - offset - ((int)pos.y - curSubPic.getSubPicTop()) + 1) << mvShift;
+  }
+#endif
   if( sps.getWrapAroundEnabledFlag() )
   {
     int horMax = ( pps.getPicWidthInLumaSamples() + sps.getMaxCUWidth() - size.width + offset - (int)pos.x - 1 ) << mvShift;
-- 
GitLab


From fbfebee1be692161b6ebb9766bdbca74d599ceda Mon Sep 17 00:00:00 2001
From: biaowang <biao.wang@huawei.com>
Date: Sat, 1 Feb 2020 11:04:27 +0100
Subject: [PATCH 2/5] JVET-O1143: motion and in-loop filter operations
 adaptation when subpic boundaries are treated as pic boundaries, check
 disabled

---
 source/Lib/CommonLib/TypeDef.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 82b938fe38..01db04b185 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -92,7 +92,7 @@
 
 #define JVET_O1143_SUBPIC_BOUNDARY                        1 // treat subpicture boundary as piucture boundary
 #if JVET_O1143_SUBPIC_BOUNDARY
-#define JVET_O1143_SUBPIC_DECCHECK                        1
+#define JVET_O1143_SUBPIC_DECCHECK                        0
 #define JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY             1 
 #define JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY              1
 #endif
-- 
GitLab


From ceb8ecbd5496c041e18f59d3f6b2ca93c9b8af70 Mon Sep 17 00:00:00 2001
From: biaowang <biao.wang@huawei.com>
Date: Wed, 5 Feb 2020 14:58:10 +0100
Subject: [PATCH 3/5] improve variable namings and code clean to address
 software coordinates concerns

---
 source/Lib/CommonLib/LoopFilter.cpp |  55 ++++----
 source/Lib/CommonLib/Picture.cpp    | 212 ++++++++++------------------
 source/Lib/CommonLib/Picture.h      |   6 +-
 source/Lib/CommonLib/Slice.h        |   6 +-
 4 files changed, 104 insertions(+), 175 deletions(-)

diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/LoopFilter.cpp
index 7541b5de90..ba4ff56166 100644
--- a/source/Lib/CommonLib/LoopFilter.cpp
+++ b/source/Lib/CommonLib/LoopFilter.cpp
@@ -81,31 +81,30 @@ inline static uint32_t getRasterIdx(const Position& pos, const PreCalcValues& pc
 // ====================================================================================================================
 // utility functions
 // ====================================================================================================================
-
-static bool isAvailableLeft( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction 
 #if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
-  , const bool bEnforceSubPicRestriction
+static bool isAvailableLeft( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction, const bool bEnforceSubPicRestriction)
+#else
+static bool isAvailableLeft( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction)
 #endif
-)
 {
-  return ( ( !bEnforceSliceRestriction || CU::isSameSlice( cu, cu2 ) ) && ( !bEnforceTileRestriction || CU::isSameTile( cu, cu2 ) ) 
 #if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
-    && (!bEnforceSubPicRestriction || CU::isSameSubPic(cu, cu2))
-#endif
-    );
+  return ((!bEnforceSliceRestriction || CU::isSameSlice(cu, cu2)) && (!bEnforceTileRestriction || CU::isSameTile(cu, cu2)) && (!bEnforceSubPicRestriction || CU::isSameSubPic(cu, cu2)));
+#else
+  return ((!bEnforceSliceRestriction || CU::isSameSlice(cu, cu2)) && (!bEnforceTileRestriction || CU::isSameTile(cu, cu2)));
+#endif    
 }
 
-static bool isAvailableAbove( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction
 #if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
-  , const bool bEnforceSubPicRestriction
+static bool isAvailableAbove( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction, const bool bEnforceSubPicRestriction)
+#else
+static bool isAvailableAbove( const CodingUnit& cu, const CodingUnit& cu2, const bool bEnforceSliceRestriction, const bool bEnforceTileRestriction)
 #endif
-)
 {
-  return ( !bEnforceSliceRestriction || CU::isSameSlice( cu, cu2 ) ) && ( !bEnforceTileRestriction || CU::isSameTile( cu, cu2 ) )
 #if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
-  && (!bEnforceSubPicRestriction || CU::isSameSubPic(cu, cu2))
+  return ( !bEnforceSliceRestriction || CU::isSameSlice( cu, cu2 ) ) && ( !bEnforceTileRestriction || CU::isSameTile( cu, cu2 ) ) && (!bEnforceSubPicRestriction || CU::isSameSubPic(cu, cu2));
+#else
+  return ( !bEnforceSliceRestriction || CU::isSameSlice( cu, cu2 ) ) && ( !bEnforceTileRestriction || CU::isSameTile( cu, cu2 ) ) ;
 #endif
-  ;
 }
 
 
@@ -697,16 +696,18 @@ void LoopFilter::xSetLoopfilterParam( const CodingUnit& cu )
 
   m_stLFCUParam.internalEdge = true;
 
-  m_stLFCUParam.leftEdge     = ( 0 < pos.x ) && isAvailableLeft ( cu, *cu.cs->getCU( pos.offset( -1,  0 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag() 
 #if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
-    , !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()
+  m_stLFCUParam.leftEdge     = ( 0 < pos.x ) && isAvailableLeft ( cu, *cu.cs->getCU( pos.offset( -1,  0 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag(), !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag() );
+#else
+  m_stLFCUParam.leftEdge     = ( 0 < pos.x ) && isAvailableLeft ( cu, *cu.cs->getCU( pos.offset( -1,  0 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag());  
 #endif
-  );
-  m_stLFCUParam.topEdge      = ( 0 < pos.y ) && isAvailableAbove( cu, *cu.cs->getCU( pos.offset(  0, -1 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag() 
+
 #if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
-    , !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()
+  m_stLFCUParam.topEdge      = ( 0 < pos.y ) && isAvailableAbove( cu, *cu.cs->getCU( pos.offset(  0, -1 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag(), !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag() );
+#else
+  m_stLFCUParam.topEdge      = ( 0 < pos.y ) && isAvailableAbove( cu, *cu.cs->getCU( pos.offset(  0, -1 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag());  
 #endif
-  );
+
 }
 
 unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const Position& localPos ) const
@@ -962,11 +963,11 @@ void LoopFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edg
       // Derive neighboring PU index
       if (edgeDir == EDGE_VER)
       {
-        if (!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()
 #if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
-          , !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()
-#endif
-        ))
+        if (!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag(), !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()))
+#else
+        if (!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()))
+#endif        
         {
           m_aapucBS[edgeDir][uiBsAbsIdx] = uiBs = 0;
           continue;
@@ -974,11 +975,11 @@ void LoopFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edg
       }
       else  // (iDir == EDGE_HOR)
       {
-        if (!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()
 #if JVET_O1143_LPF_ACROSS_SUBPIC_BOUNDARY
-          , !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()
+        if (!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag(), !pps.getSubPicFromCU(cu).getloopFilterAcrossEnabledFlag()))
+#else
+        if (!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossTilesEnabledFlag()))
 #endif
-        ))
         {
           m_aapucBS[edgeDir][uiBsAbsIdx] = uiBs = 0;
           continue;
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index f69d5bd64b..40e26ba561 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -174,7 +174,7 @@ Picture::Picture()
 {
   cs                   = nullptr;
 #if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
-  m_bIsSubPicBorderSaved = false;
+  m_isSubPicBorderSaved = false;
 #endif
   m_bIsBorderExtended  = false;
   usedByCurr           = false;
@@ -762,12 +762,6 @@ void Picture::saveSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWi
   m_bufSubPicLeft.create(unitAreaLeftRight);
   m_bufSubPicRight.create(unitAreaLeftRight);
 
-  Pel *ss0;
-  Pel *ss1;
-  Pel *dd0;
-  Pel *dd1;
-  int copylen;
-
   for (int comp = 0; comp < getNumberValidComponents(cs->area.chromaFormat); comp++) 
   {
     ComponentID compID = ComponentID(comp);
@@ -777,71 +771,51 @@ void Picture::saveSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWi
     int ymargin = margin >> getComponentScaleY(compID, cs->area.chromaFormat);
 
     // 2.2 calculate the origin of the subpicture
-    int tx0 = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
-    int ty0 = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
+    int left = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int top = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
 
     // 2.3 calculate the width/height of the subPic
-    int tww = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
-    int thh = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
+    int width = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int height = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
 
 
     // 3.1.1 set reconstructed picture
     PelBuf s = M_BUFS(0, PIC_RECONSTRUCTION).get(compID);
-    Pel *siTxt = s.bufAt(tx0, ty0);
-    Pel*  si = siTxt;
+    Pel *src = s.bufAt(left, top);
 
     // 3.2.1 set back up buffer for left
-    PelBuf d0 = m_bufSubPicLeft.getBuf(compID);
-    Pel *diTxt0 = d0.bufAt(0, 0);
-    Pel *di0 = diTxt0;
+    PelBuf dBufLeft   = m_bufSubPicLeft.getBuf(compID);
+    Pel    *dstLeft   = dBufLeft.bufAt(0, 0);
 
-    // 3.2.2 set back up buffer for right
-    PelBuf d1 = m_bufSubPicRight.getBuf(compID);
-    Pel *diTxt1 = d1.bufAt(0, 0);
-    Pel *di1 = diTxt1;
 
+    // 3.2.2 set back up buffer for right
+    PelBuf dBufRight  = m_bufSubPicRight.getBuf(compID);
+    Pel    *dstRight  = dBufRight.bufAt(0, 0);
 
     // 3.2.3 copy to recon picture to back up buffer
-    ss0 = si - xmargin;
-    ss1 = si + tww;
-    dd0 = di0;
-    dd1 = di1;
-    copylen = sizeof(Pel) * xmargin;
-    for (int y = 0; y < thh; y++) 
+    Pel *srcLeft  = src - xmargin;
+    Pel *srcRight = src + width;
+    for (int y = 0; y < height; y++) 
     {
-      ::memcpy(dd0, ss0, copylen);
-      ::memcpy(dd1, ss1, copylen);
-      ss0 += s.stride;
-      ss1 += s.stride;
-      dd0 += d0.stride;
-      dd1 += d1.stride;
+      ::memcpy(dstLeft  + y *  dBufLeft.stride, srcLeft  + y * s.stride, sizeof(Pel) * xmargin);
+      ::memcpy(dstRight + y * dBufRight.stride, srcRight + y * s.stride, sizeof(Pel) * xmargin);
     }
 
-
     // 3.3.1 set back up buffer for above
-    d0 = m_bufSubPicAbove.getBuf(compID);
-    diTxt0 = d0.bufAt(0, 0);
-    di0 = diTxt0;
+    PelBuf dBufTop = m_bufSubPicAbove.getBuf(compID);
+    Pel    *dstTop = dBufTop.bufAt(0, 0);
 
     // 3.3.2 set back up buffer for below
-    d1 = m_bufSubPicBelow.getBuf(compID);
-    diTxt1 = d1.bufAt(0, 0);
-    di1 = diTxt1;
+    PelBuf dBufBottom = m_bufSubPicBelow.getBuf(compID);
+    Pel    *dstBottom = dBufBottom.bufAt(0, 0);
 
     // 3.3.3 copy to recon picture to back up buffer
-    ss0 = si - xmargin - ymargin * s.stride;
-    ss1 = si - xmargin + thh * s.stride;
-    dd0 = di0;
-    dd1 = di1;
-    copylen = sizeof(Pel) * (2 * xmargin + tww);
+    Pel *srcTop    = src - xmargin - ymargin * s.stride;
+    Pel *srcBottom = src - xmargin +  height * s.stride;
     for (int y = 0; y < ymargin; y++) 
     {
-      ::memcpy(dd0, ss0, copylen);
-      ::memcpy(dd1, ss1, copylen);
-      ss0 += s.stride;
-      ss1 += s.stride;
-      dd0 += d0.stride;
-      dd1 += d1.stride;
+      ::memcpy(dstTop    + y *    dBufTop.stride, srcTop    + y * s.stride, sizeof(Pel) * (2 * xmargin + width));
+      ::memcpy(dstBottom + y * dBufBottom.stride, srcBottom + y * s.stride, sizeof(Pel) * (2 * xmargin + width));
     }
   }
 }
@@ -854,12 +828,6 @@ void Picture::extendSubPicBorder(int POC, int subPicX0, int subPicY0, int subPic
     return;
   }
 
-  Pel *ss0 = 0;
-  Pel *ss1 = 0;
-  Pel *dd0 = 0;
-  Pel *dd1 = 0;
-  int copylen;
-
   for (int comp = 0; comp < getNumberValidComponents(cs->area.chromaFormat); comp++) 
   {
     ComponentID compID = ComponentID(comp);
@@ -869,67 +837,56 @@ void Picture::extendSubPicBorder(int POC, int subPicX0, int subPicY0, int subPic
     int ymargin = margin >> getComponentScaleY(compID, cs->area.chromaFormat);
 
     // 2.2 calculate the origin of the Subpicture
-    int tx0 = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
-    int ty0 = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
+    int left = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int top = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
 
     // 2.3 calculate the width/height of the Subpicture
-    int tww = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
-    int thh = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
+    int width = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int height = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
 
     // 3.1 set reconstructed picture
     PelBuf s = M_BUFS(0, PIC_RECONSTRUCTION).get(compID);
-    Pel *siTxt = s.bufAt(tx0, ty0);
-    Pel*  si = siTxt;
+    Pel *src = s.bufAt(left, top);
 
     // 4.1 apply padding for left and right
     {
-      Pel *xx0, *xx1;
-      ss0 = si - xmargin;
-      ss1 = si + tww;
-      xx0 = si + 0;
-      xx1 = si + tww - 1;
+      Pel *dstLeft  = src - xmargin;
+      Pel *dstRight = src + width;
+      Pel *srcLeft  = src + 0;
+      Pel *srcRight = src + width - 1;
 
-      for (int y = 0; y < thh; y++) 
+      for (int y = 0; y < height; y++) 
       {
-        dd0 = ss0;
-        dd1 = ss1;
         for (int x = 0; x < xmargin; x++) 
         {
-          *dd0++ = *xx0;
-          *dd1++ = *xx1;
+          dstLeft[x]  = *srcLeft;
+          dstRight[x] = *srcRight;
         }
-
-        ss0 += s.stride;
-        ss1 += s.stride;
-        xx0 += s.stride;
-        xx1 += s.stride;
+        dstLeft += s.stride;
+        dstRight += s.stride;
+        srcLeft += s.stride;
+        srcRight += s.stride;
       }
     }
 
     // 4.2 apply padding on bottom 
-    // si is now the (0, SubpictureHeight) (bottom left of image within bigger picture
-    si += s.stride * (thh - 1) - xmargin;
-
-    // si is now the (-marginX, SubpictureHeight-1)
-    ss0 = si + s.stride;
-    copylen = sizeof(Pel)*(tww + (xmargin << 1));
+    Pel *srcBottom = src + s.stride * (height - 1) - xmargin;
+    Pel *dstBottom = srcBottom + s.stride;
     for (int y = 0; y < ymargin; y++)
     {
-      ::memcpy(ss0, si, copylen);
-      ss0 += s.stride;
+      ::memcpy(dstBottom, srcBottom, sizeof(Pel)*(2 * xmargin + width));
+      dstBottom += s.stride;
     }
 
     // 4.3 apply padding for top
     // si is still (-marginX, SubpictureHeight-1)
-    si -= ((thh - 1) * s.stride);
-
+    Pel *srcTop = src - xmargin;
+    Pel *dstTop = srcTop - s.stride;
     // si is now (-marginX, 0)
-    ss0 = si - s.stride;
-    copylen = sizeof(Pel)*(tww + (xmargin << 1));
     for (int y = 0; y < ymargin; y++)
     {
-      ::memcpy(ss0, si, copylen);
-      ss0 -= s.stride;
+      ::memcpy(dstTop, srcTop, sizeof(Pel)*(2 * xmargin + width));
+      dstTop -= s.stride;
     }
   } // end of for  
 }
@@ -942,12 +899,6 @@ void Picture::restoreSubPicBorder(int POC, int subPicX0, int subPicY0, int subPi
     return;
   }
 
-  Pel *ss0;
-  Pel *ss1;
-  Pel *dd0;
-  Pel *dd1;
-  int copylen;
-
   for (int comp = 0; comp < getNumberValidComponents(cs->area.chromaFormat); comp++) 
   {
     ComponentID compID = ComponentID(comp);
@@ -957,72 +908,53 @@ void Picture::restoreSubPicBorder(int POC, int subPicX0, int subPicY0, int subPi
     int ymargin = margin >> getComponentScaleY(compID, cs->area.chromaFormat);
 
     // 2.2 calculate the origin of the subpicture
-    int tx0 = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
-    int ty0 = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
+    int left = subPicX0 >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int top = subPicY0 >> getComponentScaleY(compID, cs->area.chromaFormat);
 
     // 2.3 calculate the width/height of the subpicture
-    int tww = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
-    int thh = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
+    int width = subPicWidth >> getComponentScaleX(compID, cs->area.chromaFormat);
+    int height = subPicHeight >> getComponentScaleY(compID, cs->area.chromaFormat);
 
     // 3.1 set reconstructed picture
     PelBuf s = M_BUFS(0, PIC_RECONSTRUCTION).get(compID);
-    Pel *siTxt = s.bufAt(tx0, ty0);
-    Pel*  si = siTxt;
-
+    Pel *src = s.bufAt(left, top);
 
     // 4.2.1 copy from back up buffer to recon picture
-    PelBuf d0 = m_bufSubPicLeft.getBuf(compID);
-    Pel *diTxt0 = d0.bufAt(0, 0);
-    Pel *di0 = diTxt0;
+    PelBuf dBufLeft = m_bufSubPicLeft.getBuf(compID);
+    Pel    *dstLeft = dBufLeft.bufAt(0, 0);
 
     // 4.2.2 set back up buffer for right
-    PelBuf d1 = m_bufSubPicRight.getBuf(compID);
-    Pel *diTxt1 = d1.bufAt(0, 0);
-    Pel *di1 = diTxt1;
+    PelBuf dBufRight = m_bufSubPicRight.getBuf(compID);
+    Pel    *dstRight = dBufRight.bufAt(0, 0);
 
     // 4.2.3 copy to recon picture to back up buffer
-    ss0 = si - xmargin;
-    ss1 = si + tww;
-    dd0 = di0;
-    dd1 = di1;
-    copylen = sizeof(Pel) * xmargin;
+    Pel *srcLeft  = src - xmargin;
+    Pel *srcRight = src + width;
 
-    for (int y = 0; y < thh; y++) 
+    for (int y = 0; y < height; y++) 
     {
-      ::memcpy(ss0, dd0, copylen);
-      ::memcpy(ss1, dd1, copylen);
-      ss0 += s.stride;
-      ss1 += s.stride;
-      dd0 += d0.stride;
-      dd1 += d1.stride;
+      // the destination and source position is reversed on purpose
+      ::memcpy(srcLeft  + y * s.stride,  dstLeft + y *  dBufLeft.stride, sizeof(Pel) * xmargin);
+      ::memcpy(srcRight + y * s.stride, dstRight + y * dBufRight.stride, sizeof(Pel) * xmargin);
     }
 
 
-    // 4.3.1 copy from back up buffer to recon picture
-    d0 = m_bufSubPicAbove.getBuf(compID);
-    diTxt0 = d0.bufAt(0, 0);
-    di0 = diTxt0;
+    // 4.3.1 set back up buffer for above
+    PelBuf dBufTop = m_bufSubPicAbove.getBuf(compID);
+    Pel    *dstTop = dBufTop.bufAt(0, 0);
 
     // 4.3.2 set back up buffer for below
-    d1 = m_bufSubPicBelow.getBuf(compID);
-    diTxt1 = d1.bufAt(0, 0);
-    di1 = diTxt1;
+    PelBuf dBufBottom = m_bufSubPicBelow.getBuf(compID);
+    Pel    *dstBottom = dBufBottom.bufAt(0, 0);
 
     // 4.3.3 copy to recon picture to back up buffer
-    ss0 = si - xmargin - ymargin * s.stride;
-    ss1 = si - xmargin + thh * s.stride;
-    dd0 = di0;
-    dd1 = di1;
-    copylen = sizeof(Pel) * (2 * xmargin + tww);
+    Pel *srcTop = src - xmargin - ymargin * s.stride;
+    Pel *srcBottom = src - xmargin + height * s.stride;
 
     for (int y = 0; y < ymargin; y++) 
     {
-      ::memcpy(ss0, dd0, copylen);
-      ::memcpy(ss1, dd1, copylen);
-      ss0 += s.stride;
-      ss1 += s.stride;
-      dd0 += d0.stride;
-      dd1 += d1.stride;
+      ::memcpy(srcTop    + y * s.stride, dstTop    + y *    dBufTop.stride, sizeof(Pel) * (2 * xmargin + width));
+      ::memcpy(srcBottom + y * s.stride, dstBottom + y * dBufBottom.stride, sizeof(Pel) * (2 * xmargin + width));
     }
   }
 
diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h
index b1d8ca6f45..5cc6a41611 100644
--- a/source/Lib/CommonLib/Picture.h
+++ b/source/Lib/CommonLib/Picture.h
@@ -173,7 +173,7 @@ private:
 
 public:
 #if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY  
-  bool m_bIsSubPicBorderSaved;
+  bool m_isSubPicBorderSaved;
 
   PelStorage m_bufSubPicAbove;
   PelStorage m_bufSubPicBelow;
@@ -184,8 +184,8 @@ public:
   void  extendSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight);
   void restoreSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight);
 
-  bool getSubPicSaved()          { return m_bIsSubPicBorderSaved; }
-  void setSubPicSaved(bool bVal) { m_bIsSubPicBorderSaved = bVal; }
+  bool getSubPicSaved()          { return m_isSubPicBorderSaved; }
+  void setSubPicSaved(bool bVal) { m_isSubPicBorderSaved = bVal; }
 #endif
   bool m_bIsBorderExtended;
   bool referenced;
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index fc1f1aa271..ce6efa00c3 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -752,11 +752,7 @@ public:
   }
   bool                 isContainingPos(const Position& pos) const
   {
-    if (pos.x >= m_subPicLeft && pos.x <= m_subPicRight &&
-      pos.y >= m_subPicTop  && pos.y <= m_subPicBottom)
-      return true;
-    else
-      return false;
+    return pos.x >= m_subPicLeft && pos.x <= m_subPicRight && pos.y >= m_subPicTop  && pos.y <= m_subPicBottom;
   }
   void             setTreatedAsPicFlag           (bool u)  {         m_treatedAsPicFlag = u;   }
   bool             getTreatedAsPicFlag           ()  const { return  m_treatedAsPicFlag;       }
-- 
GitLab


From 3d074ac6766a3c3a9f0ceba61e3e1c123335017e Mon Sep 17 00:00:00 2001
From: biaowang <biao.wang@huawei.com>
Date: Wed, 5 Feb 2020 18:55:44 +0100
Subject: [PATCH 4/5] improve readability of save and restore subpicture
 boundaries functionality

---
 source/Lib/CommonLib/Picture.cpp   | 16 ----------------
 source/Lib/DecoderLib/DecSlice.cpp |  7 +++----
 source/Lib/EncoderLib/EncSlice.cpp | 10 +++-------
 3 files changed, 6 insertions(+), 27 deletions(-)

diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index 40e26ba561..a74e5ed1e1 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -740,11 +740,6 @@ void Picture::rescalePicture( const std::pair<int, int> scalingRatio,
 #if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY
 void Picture::saveSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight)
 {
-  // 1.0 check border was extended
-  if (getSubPicSaved()) 
-  {
-    return;
-  }
 
   // 1.1 set up margin for back up memory allocation
   int xMargin = margin >> getComponentScaleX(COMPONENT_Y, cs->area.chromaFormat);
@@ -822,11 +817,6 @@ void Picture::saveSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWi
 
 void Picture::extendSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight)
 {
-  // 1.0 check border was extended
-  if (getSubPicSaved()) 
-  {
-    return;
-  }
 
   for (int comp = 0; comp < getNumberValidComponents(cs->area.chromaFormat); comp++) 
   {
@@ -893,12 +883,6 @@ void Picture::extendSubPicBorder(int POC, int subPicX0, int subPicY0, int subPic
 
 void Picture::restoreSubPicBorder(int POC, int subPicX0, int subPicY0, int subPicWidth, int subPicHeight)
 {
-  // 1.0 check border was extended
-  if (!getSubPicSaved()) 
-  {
-    return;
-  }
-
   for (int comp = 0; comp < getNumberValidComponents(cs->area.chromaFormat); comp++) 
   {
     ComponentID compID = ComponentID(comp);
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index 5393538dd4..762ddf16bc 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -158,10 +158,10 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
         for (int idx = 0; idx < n; idx++) 
         {
           Picture *refPic = slice->getRefPic((RefPicList)rlist, idx);
-          refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
-          refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
           if (!refPic->getSubPicSaved()) 
           {
+            refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
+            refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
             refPic->setSubPicSaved(true);
           }
         }
@@ -271,10 +271,9 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
         for (int idx = 0; idx < n; idx++) 
         {
           Picture *refPic = slice->getRefPic((RefPicList)rlist, idx);
-          refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
-
           if (refPic->getSubPicSaved()) 
           {
+            refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
             refPic->setSubPicSaved(false);
           }
         }
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index cb0d820903..98c5bd9ec2 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1468,16 +1468,12 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
         for (int idx = 0; idx < n; idx++) 
         {
           Picture *refPic = pcSlice->getRefPic((RefPicList)rlist, idx);
-
-          refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
-          refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
-
           if (!refPic->getSubPicSaved()) 
           {
+            refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
+            refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
             refPic->setSubPicSaved(true);
           }
-          // Save only at the beginning of the tile          
-          // refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);          
         }
       }
     }
@@ -1694,9 +1690,9 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
         for (int idx = 0; idx < n; idx++) 
         {
           Picture *refPic = pcSlice->getRefPic((RefPicList)rlist, idx);
-          refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
           if (refPic->getSubPicSaved()) 
           {
+            refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
             refPic->setSubPicSaved(false);
           }
         }
-- 
GitLab


From 6a371ffdc796e31e79b5c5c39345f33b478f1cde Mon Sep 17 00:00:00 2001
From: biaowang <biao.wang@huawei.com>
Date: Wed, 5 Feb 2020 21:56:09 +0100
Subject: [PATCH 5/5] remove debug code

---
 source/Lib/DecoderLib/DecLib.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 7c6721fe3f..66ea5461a2 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -605,7 +605,6 @@ void DecLib::executeLoopFilters()
       uint32_t right = SubPicNoUse.getSubPicRight();
       uint32_t top   = SubPicNoUse.getSubPicTop();
       uint32_t bottom= SubPicNoUse.getSubPicBottom();
-      printf("left %d right %d, top %d bottom %d\n", left, right, top, bottom);
       for (uint32_t row = top; row <= bottom; row++)
       {
         for (uint32_t col = left; col <= right; col++)
-- 
GitLab