diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index a74311fde631c0f6b3ea67131e91670ea0b3f60c..79bed41558a6f7099bba441060c7663fffbd06ec 100644
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -1965,6 +1965,11 @@ beginning of each line of CTBs in order to produce a bitstream that can
 be encoded or decoded using one or more cores.
 \\
 
+\Option{WaveFrontEntryPointsPresent} &
+%\ShortOption{\None} &
+\Default{false} &
+Allow signalling of entry points for WPP in slice header.
+\\
 
 \end{OptionTableNoShorthand}
 
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 3fa5065a9ae66b35ba2365657c20b9e6b981412e..6efcb035b5c8e16721400d03625fd82687d3d567 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -747,6 +747,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setCcvSEIMaxLuminanceValue                           (m_ccvSEIMaxLuminanceValue);
   m_cEncLib.setCcvSEIAvgLuminanceValue                           (m_ccvSEIAvgLuminanceValue);
   m_cEncLib.setEntropyCodingSyncEnabledFlag                      ( m_entropyCodingSyncEnabledFlag );
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  m_cEncLib.setEntropyCodingSyncEntryPointPresentFlag            ( m_entropyCodingSyncEntryPointPresentFlag );
+#endif
   m_cEncLib.setTMVPModeId                                        ( m_TMVPModeId );
   m_cEncLib.setSliceLevelRpl                                     ( m_sliceLevelRpl  );
   m_cEncLib.setSliceLevelDblk                                    ( m_sliceLevelDblk );
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 929dcd0b5dd673f8f7699197b4591185a7e358d7..dc7b5a3d1572db6e361bc6000b35d45d43c8e758 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1188,6 +1188,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("Log2ParallelMergeLevel",                          m_log2ParallelMergeLevel,                            2u, "Parallel merge estimation region")
 #endif
   ("WaveFrontSynchro",                                m_entropyCodingSyncEnabledFlag,                   false, "0: entropy coding sync disabled; 1 entropy coding sync enabled")
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  ("WaveFrontEntryPointsPresent",                     m_entropyCodingSyncEntryPointPresentFlag,         false, "0: entry points for WPP is not present; 1 entry points for WPP may be present in slice header")
+#endif
   ("ScalingList",                                     m_useScalingListId,                    SCALING_LIST_OFF, "0/off: no scaling list, 1/default: default scaling lists, 2/file: scaling lists specified in ScalingListFile")
   ("ScalingListFile",                                 m_scalingListFileName,                       string(""), "Scaling list file name. Use an empty string to produce help.")
   ("DisableScalingMatrixForLFNST",                    m_disableScalingMatrixForLfnstBlks,                true, "Disable scaling matrices, when enabled, for LFNST-coded blocks")
@@ -1739,6 +1742,13 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
     m_outputBitDepth     [CHANNEL_TYPE_CHROMA] = m_outputBitDepth     [CHANNEL_TYPE_LUMA  ];
   }
 
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  if( !m_entropyCodingSyncEnabledFlag ) 
+  {
+    m_entropyCodingSyncEntryPointPresentFlag = false;
+  }
+#endif
+
   m_InputChromaFormatIDC = numberToChromaFormat(tmpInputChromaFormat);
   m_chromaFormatIDC      = ((tmpChromaFormat == 0) ? (m_InputChromaFormatIDC) : (numberToChromaFormat(tmpChromaFormat)));
 #if EXTENSION_360_VIDEO
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 198a5bc67a08df9db5e868fb9127d383c69e66a6..e6c8ee61f90df63d37780a05f157ecbf62da3958 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -488,7 +488,9 @@ protected:
   bool      m_subPicPartitionFlag;
   bool      m_singleSlicePerSubPicFlag;
   bool      m_entropyCodingSyncEnabledFlag;
-
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  bool      m_entropyCodingSyncEntryPointPresentFlag;         ///< flag for the presence of entry points for WPP
+#endif
 
   bool      m_bFastUDIUseMPMEnabled;
   bool      m_bFastMEForGenBLowDelayEnabled;
diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp
index 3246480c9c5bbb28f946820137c7b809765db88d..88f82c69430d78dd240fccfc9fb3fe57641a26dc 100644
--- a/source/Lib/CommonLib/CodingStructure.cpp
+++ b/source/Lib/CommonLib/CodingStructure.cpp
@@ -1536,7 +1536,11 @@ const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const C
   const CodingUnit* cu = getCU( pos, _chType );
   // exists       same slice and tile                  cu precedes curCu in encoding order
   //                                                  (thus, is either from parent CS in RD-search or its index is lower)
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  const bool wavefrontsEnabled = curCu.slice->getSPS()->getEntropyCodingSyncEnabledFlag();
+#else
   const bool wavefrontsEnabled = curCu.slice->getPPS()->getEntropyCodingSyncEnabledFlag();
+#endif
   int ctuSizeBit = floorLog2(curCu.cs->sps->getMaxCUWidth());
   int xNbY  = pos.x << getChannelTypeScaleX( _chType, curCu.chromaFormat );
   int xCurr = curCu.blocks[_chType].x << getChannelTypeScaleX( _chType, curCu.chromaFormat );
@@ -1554,7 +1558,11 @@ const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const C
 const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType ) const
 {
   const CodingUnit* cu = getCU( pos, _chType );
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  const bool wavefrontsEnabled = this->slice->getSPS()->getEntropyCodingSyncEnabledFlag();
+#else
   const bool wavefrontsEnabled = this->slice->getPPS()->getEntropyCodingSyncEnabledFlag();
+#endif
   int ctuSizeBit = floorLog2(this->sps->getMaxCUWidth());
   int xNbY  = pos.x << getChannelTypeScaleX( _chType, this->area.chromaFormat );
   int xCurr = curPos.x << getChannelTypeScaleX( _chType, this->area.chromaFormat );
@@ -1567,7 +1575,11 @@ const PredictionUnit* CodingStructure::getPURestricted( const Position &pos, con
   const PredictionUnit* pu = getPU( pos, _chType );
   // exists       same slice and tile                  pu precedes curPu in encoding order
   //                                                  (thus, is either from parent CS in RD-search or its index is lower)
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  const bool wavefrontsEnabled = curPu.cu->slice->getSPS()->getEntropyCodingSyncEnabledFlag();
+#else
   const bool wavefrontsEnabled = curPu.cu->slice->getPPS()->getEntropyCodingSyncEnabledFlag();
+#endif
   int ctuSizeBit = floorLog2(curPu.cs->sps->getMaxCUWidth());
   int xNbY  = pos.x << getChannelTypeScaleX( _chType, curPu.chromaFormat );
   int xCurr = curPu.blocks[_chType].x << getChannelTypeScaleX( _chType, curPu.chromaFormat );
@@ -1587,7 +1599,11 @@ const TransformUnit* CodingStructure::getTURestricted( const Position &pos, cons
   const TransformUnit* tu = getTU( pos, _chType );
   // exists       same slice and tile                  tu precedes curTu in encoding order
   //                                                  (thus, is either from parent CS in RD-search or its index is lower)
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  const bool wavefrontsEnabled = curTu.cu->slice->getSPS()->getEntropyCodingSyncEnabledFlag();
+#else
   const bool wavefrontsEnabled = curTu.cu->slice->getPPS()->getEntropyCodingSyncEnabledFlag();
+#endif
   int ctuSizeBit = floorLog2(curTu.cs->sps->getMaxCUWidth());
   int xNbY  = pos.x << getChannelTypeScaleX( _chType, curTu.chromaFormat );
   int xCurr = curTu.blocks[_chType].x << getChannelTypeScaleX( _chType, curTu.chromaFormat );
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index a0c5ad62daf2eb12ba5b6c5984a393f4f321001d..4e2d809432cde96ff763f42019a569b72baa60b2 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -263,9 +263,36 @@ void Slice::inheritFromPicHeader( PicHeader *picHeader, const PPS *pps, const SP
 #endif
 }
 
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+void Slice::setNumSubstream(const SPS* sps, const PPS* pps) 
+{
+  uint32_t ctuAddr, ctuX, ctuY;
+  m_numSubstream = 0;
+
+  // count the number of CTUs that align with either the start of a tile, or with an entropy coding sync point
+  // ignore the first CTU since it doesn't count as an entry point
+  for (uint32_t i = 1; i < m_sliceMap.getNumCtuInSlice(); i++)
+  {
+    ctuAddr = m_sliceMap.getCtuAddrInSlice(i);
+    ctuX    = (ctuAddr % pps->getPicWidthInCtu());
+    ctuY    = (ctuAddr / pps->getPicWidthInCtu());
+
+    if (pps->ctuIsTileColBd(ctuX) && (pps->ctuIsTileRowBd(ctuY) || sps->getEntropyCodingSyncEnabledFlag()))
+    {
+      m_numSubstream++;
+    }
+  }
+}
+
+void Slice::setNumEntryPoints(const SPS *sps, const PPS *pps)
+#else
 void  Slice::setNumEntryPoints( const PPS *pps ) 
+#endif
 {
   uint32_t ctuAddr, ctuX, ctuY;
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  uint32_t prevCtuAddr, prevCtuX, prevCtuY;
+#endif
   m_numEntryPoints = 0;
 
   // count the number of CTUs that align with either the start of a tile, or with an entropy coding sync point
@@ -275,7 +302,15 @@ void  Slice::setNumEntryPoints( const PPS *pps )
     ctuAddr = m_sliceMap.getCtuAddrInSlice( i );
     ctuX = ( ctuAddr % pps->getPicWidthInCtu() );
     ctuY = ( ctuAddr / pps->getPicWidthInCtu() );
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+    prevCtuAddr = m_sliceMap.getCtuAddrInSlice(i - 1);
+    prevCtuX    = (prevCtuAddr % pps->getPicWidthInCtu());
+    prevCtuY    = (prevCtuAddr / pps->getPicWidthInCtu());
+
+    if (pps->ctuToTileRowBd(ctuY) != pps->ctuToTileRowBd(prevCtuY) || pps->ctuToTileColBd(ctuX) != pps->ctuToTileColBd(prevCtuX) || (ctuY != prevCtuY && sps->getEntropyCodingSyncEntryPointsPresentFlag()))
+#else
     if( pps->ctuIsTileColBd( ctuX ) && (pps->ctuIsTileRowBd( ctuY ) || pps->getEntropyCodingSyncEnabledFlag() ) ) 
+#endif
     {
       m_numEntryPoints++;
     }
@@ -2098,6 +2133,10 @@ SPS::SPS()
 , m_BDPCMEnabled              (0)
 #endif
 , m_JointCbCrEnabledFlag      (false)
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+, m_entropyCodingSyncEnabledFlag(false)
+, m_entropyCodingSyncEntryPointPresentFlag(false)
+#endif
 , m_sbtmvpEnabledFlag         (false)
 , m_bdofEnabledFlag           (false)
 , m_fpelMmvdEnabledFlag       ( false )
@@ -2357,7 +2396,9 @@ PPS::PPS()
 #if !JVET_Q0183_SPS_TRANSFORM_SKIP_MODE_CONTROL
   , m_log2MaxTransformSkipBlockSize    (2)
 #endif
+#if !JVET_Q0151_Q0205_ENTRYPOINTS
 , m_entropyCodingSyncEnabledFlag     (false)
+#endif
 , m_constantSliceHeaderParamsEnabledFlag (false)
 , m_PPSDepQuantEnabledIdc            (0)
 , m_PPSRefPicListSPSIdc0             (0)
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index 374d6be31194e0e722cf7c020970470e1db8b7be..ad3d25ea07904399484ed3ecb0c3c6037936a247 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1236,6 +1236,10 @@ private:
   bool              m_JointCbCrEnabledFlag;
   // Parameter
   BitDepths         m_bitDepths;
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  bool              m_entropyCodingSyncEnabledFlag;                    //!< Flag for enabling WPP
+  bool              m_entropyCodingSyncEntryPointPresentFlag;          //!< Flag for indicating the presence of WPP entry points
+ #endif
   int               m_qpBDOffset[MAX_NUM_CHANNEL_TYPE];
   int               m_minQpMinus4[MAX_NUM_CHANNEL_TYPE]; //  QP_internal - QP_input;
 
@@ -1501,6 +1505,13 @@ public:
   int                     getBitDepth(ChannelType type) const                                             { return m_bitDepths.recon[type];                                      }
   void                    setBitDepth(ChannelType type, int u )                                           { m_bitDepths.recon[type] = u;                                         }
   const BitDepths&        getBitDepths() const                                                            { return m_bitDepths;                                                  }
+
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  bool                    getEntropyCodingSyncEnabledFlag() const                                         { return m_entropyCodingSyncEnabledFlag;                               }
+  void                    setEntropyCodingSyncEnabledFlag(bool val)                                       { m_entropyCodingSyncEnabledFlag = val;                                }
+  bool                    getEntropyCodingSyncEntryPointsPresentFlag() const                              { return m_entropyCodingSyncEntryPointPresentFlag;                     }
+  void                    setEntropyCodingSyncEntryPointsPresentFlag(bool val)                            { m_entropyCodingSyncEntryPointPresentFlag = val;                      }
+#endif
   int                     getMaxLog2TrDynamicRange(ChannelType channelType) const                         { return getSpsRangeExtension().getExtendedPrecisionProcessingFlag() ? std::max<int>(15, int(m_bitDepths.recon[channelType] + 6)) : 15; }
 
   int                     getDifferentialLumaChromaBitDepth() const                                       { return int(m_bitDepths.recon[CHANNEL_TYPE_LUMA]) - int(m_bitDepths.recon[CHANNEL_TYPE_CHROMA]); }
@@ -1791,7 +1802,9 @@ private:
 #if !JVET_Q0183_SPS_TRANSFORM_SKIP_MODE_CONTROL
   int              m_log2MaxTransformSkipBlockSize;
 #endif
+#if !JVET_Q0151_Q0205_ENTRYPOINTS
   bool             m_entropyCodingSyncEnabledFlag;      //!< Indicates the presence of wavefronts
+#endif
 
   bool              m_constantSliceHeaderParamsEnabledFlag;
   int               m_PPSDepQuantEnabledIdc;
@@ -2021,8 +2034,10 @@ public:
   uint32_t               getLog2MaxTransformSkipBlockSize() const                         { return m_log2MaxTransformSkipBlockSize; }
   void                   setLog2MaxTransformSkipBlockSize(uint32_t u)                     { m_log2MaxTransformSkipBlockSize = u; }
 #endif
+#if !JVET_Q0151_Q0205_ENTRYPOINTS
   bool                   getEntropyCodingSyncEnabledFlag() const                          { return m_entropyCodingSyncEnabledFlag;        }
   void                   setEntropyCodingSyncEnabledFlag(bool val)                        { m_entropyCodingSyncEnabledFlag = val;         }
+#endif
 
 
   bool                    getConstantSliceHeaderParamsEnabledFlag() const                 { return m_constantSliceHeaderParamsEnabledFlag; }
@@ -2620,6 +2635,9 @@ private:
   ClpRngs                    m_clpRngs;
   std::vector<uint32_t>          m_substreamSizes;
   uint32_t                   m_numEntryPoints;
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  uint32_t                   m_numSubstream;
+#endif
 
   bool                       m_cabacInitFlag;
 
@@ -2886,6 +2904,11 @@ public:
   uint32_t                        getNumberOfSubstreamSizes( )                           { return (uint32_t) m_substreamSizes.size();                        }
   void                        addSubstreamSize( uint32_t size )                          { m_substreamSizes.push_back(size);                             }
   uint32_t                        getSubstreamSize( uint32_t idx )                           { CHECK(idx>=getNumberOfSubstreamSizes(),"Invalid index"); return m_substreamSizes[idx]; }
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  void                        resetNumberOfSubstream()                               { m_numSubstream = 0;                                           }
+  uint32_t                    getNumberOfSubstream()                                 { return (uint32_t) m_numSubstream;                             }
+  void                        increaseNumberOfSubstream()                            { m_numSubstream++;                                             }
+#endif
 
   void                        setCabacInitFlag( bool val )                           { m_cabacInitFlag = val;                                        } //!< set CABAC initial flag
   bool                        getCabacInitFlag()                               const { return m_cabacInitFlag;                                       } //!< get CABAC initial flag
@@ -2943,7 +2966,12 @@ public:
   void                        freeScaledRefPicList( Picture *scaledRefPic[] );
   bool                        checkRPR();
   const std::pair<int, int>&  getScalingRatio( const RefPicList refPicList, const int refIdx )  const { CHECK( refIdx < 0, "Invalid reference index" ); return m_scalingRatio[refPicList][refIdx]; }
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  void                        setNumSubstream( const SPS *sps, const PPS *pps );
+  void                        setNumEntryPoints( const SPS *sps, const PPS *pps );
+#else
   void                        setNumEntryPoints( const PPS *pps );
+#endif
   uint32_t                    getNumEntryPoints( ) const { return m_numEntryPoints;  }
 
 #if JVET_Q0795_CCALF
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 209f4f6a4833c0f005e8d485ea2a239296c5e4db..7037686803b8287bf78f86db013a05a8704ef8ae 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -147,6 +147,8 @@
 
 #define JVET_Q0517_RPR_AFFINE_DS                          1 // JVET-Q0517: affine down-sampling filters for RPR
 
+#define JVET_Q0151_Q0205_ENTRYPOINTS                      1 // JVET-Q0151 & JVET-Q0205: Make mandatory the tile offsets signalling and move the entropy_coding_sync_enabled_flag entry_point_offsets_present_flag syntax elements to the SPS from the PPS
+
 #define JVET_O1143_SUBPIC_BOUNDARY                        0 // treat subpicture boundary as picture boundary
 #if JVET_O1143_SUBPIC_BOUNDARY
 #define JVET_O1143_SUBPIC_DECCHECK                        0
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index 762ddf16bca5d86ccdbebbc7df5b389a339a2021..429995835d7c6ee8dcd87db37646478fd2499467 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -48,49 +48,41 @@
 // Construction/Destruction
 //////////////////////////////////////////////////////////////////////
 
-DecSlice::DecSlice()
-{
-}
+DecSlice::DecSlice() {}
 
-DecSlice::~DecSlice()
-{
-}
+DecSlice::~DecSlice() {}
 
-void DecSlice::create()
-{
-}
+void DecSlice::create() {}
 
-void DecSlice::destroy()
-{
-}
+void DecSlice::destroy() {}
 
-void DecSlice::init( CABACDecoder* cabacDecoder, DecCu* pcCuDecoder )
+void DecSlice::init(CABACDecoder *cabacDecoder, DecCu *pcCuDecoder)
 {
-  m_CABACDecoder    = cabacDecoder;
-  m_pcCuDecoder     = pcCuDecoder;
+  m_CABACDecoder = cabacDecoder;
+  m_pcCuDecoder  = pcCuDecoder;
 }
 
-void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int debugCTU )
+void DecSlice::decompressSlice(Slice *slice, InputBitstream *bitstream, int debugCTU)
 {
   //-- For time output for each slice
   slice->startProcessingTimer();
 
-  const SPS*     sps          = slice->getSPS();
-  Picture*       pic          = slice->getPic();
-  CABACReader&   cabacReader  = *m_CABACDecoder->getCABACReader( 0 );
+  const SPS *  sps         = slice->getSPS();
+  Picture *    pic         = slice->getPic();
+  CABACReader &cabacReader = *m_CABACDecoder->getCABACReader(0);
 
   // setup coding structure
-  CodingStructure& cs = *pic->cs;
+  CodingStructure &cs = *pic->cs;
   cs.slice            = slice;
   cs.sps              = sps;
   cs.pps              = slice->getPPS();
   memcpy(cs.alfApss, slice->getAlfAPSs(), sizeof(cs.alfApss));
 
-  cs.lmcsAps          = slice->getPicHeader()->getLmcsAPS();
-  cs.scalinglistAps   = slice->getPicHeader()->getScalingListAPS();
+  cs.lmcsAps        = slice->getPicHeader()->getLmcsAPS();
+  cs.scalinglistAps = slice->getPicHeader()->getScalingListAPS();
 
-  cs.pcv              = slice->getPPS()->pcv;
-  cs.chromaQpAdj      = 0;
+  cs.pcv         = slice->getPPS()->pcv;
+  cs.chromaQpAdj = 0;
 
   cs.picture->resizeSAO(cs.pcv->sizeInCtus, 0);
 
@@ -98,67 +90,72 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
 
   if (slice->getFirstCtuRsAddrInSlice() == 0)
   {
-    cs.picture->resizeAlfCtuEnableFlag( cs.pcv->sizeInCtus );
+    cs.picture->resizeAlfCtuEnableFlag(cs.pcv->sizeInCtus);
     cs.picture->resizeAlfCtbFilterIndex(cs.pcv->sizeInCtus);
-    cs.picture->resizeAlfCtuAlternative( cs.pcv->sizeInCtus );
+    cs.picture->resizeAlfCtuAlternative(cs.pcv->sizeInCtus);
   }
 
-  const unsigned numSubstreams = slice->getNumberOfSubstreamSizes() + 1;
+  const unsigned numSubstreams     = slice->getNumberOfSubstreamSizes() + 1;
 
   // init each couple {EntropyDecoder, Substream}
   // Table of extracted substreams.
-  std::vector<InputBitstream*> ppcSubstreams( numSubstreams );
-  for( unsigned idx = 0; idx < numSubstreams; idx++ )
+  std::vector<InputBitstream *> ppcSubstreams(numSubstreams);
+  for (unsigned idx = 0; idx < numSubstreams; idx++)
   {
-    ppcSubstreams[idx] = bitstream->extractSubstream( idx+1 < numSubstreams ? ( slice->getSubstreamSize(idx) << 3 ) : bitstream->getNumBitsLeft() );
+    ppcSubstreams[idx] = bitstream->extractSubstream(idx + 1 < numSubstreams ? (slice->getSubstreamSize(idx) << 3)
+                                                                             : bitstream->getNumBitsLeft());
   }
 
-  const unsigned  widthInCtus             = cs.pcv->widthInCtus;
-  const bool      wavefrontsEnabled       = cs.pps->getEntropyCodingSyncEnabledFlag();
+  const unsigned widthInCtus = cs.pcv->widthInCtus;
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  const bool     wavefrontsEnabled           = cs.sps->getEntropyCodingSyncEnabledFlag();
+  const bool     wavefrontsEntryPointPresent = cs.sps->getEntropyCodingSyncEntryPointsPresentFlag();
+#else
+  const bool     wavefrontsEnabled = cs.pps->getEntropyCodingSyncEnabledFlag();
+#endif
 
-  cabacReader.initBitstream( ppcSubstreams[0] );
-  cabacReader.initCtxModels( *slice );
+  cabacReader.initBitstream(ppcSubstreams[0]);
+  cabacReader.initCtxModels(*slice);
 
   // Quantization parameter
-    pic->m_prevQP[0] = pic->m_prevQP[1] = slice->getSliceQp();
-  CHECK( pic->m_prevQP[0] == std::numeric_limits<int>::max(), "Invalid previous QP" );
-
-  DTRACE( g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", slice->getPOC() );
+  pic->m_prevQP[0] = pic->m_prevQP[1] = slice->getSliceQp();
+  CHECK(pic->m_prevQP[0] == std::numeric_limits<int>::max(), "Invalid previous QP");
 
+  DTRACE(g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", slice->getPOC());
 
   // for every CTU in the slice segment...
   unsigned subStrmId = 0;
-  for( unsigned ctuIdx = 0; ctuIdx < slice->getNumCtuInSlice(); ctuIdx++ )
+  for (unsigned ctuIdx = 0; ctuIdx < slice->getNumCtuInSlice(); ctuIdx++)
   {
-    const unsigned  ctuRsAddr       = slice->getCtuAddrInSlice(ctuIdx);
-    const unsigned  ctuXPosInCtus   = ctuRsAddr % widthInCtus;
-    const unsigned  ctuYPosInCtus   = ctuRsAddr / widthInCtus;    
-    const unsigned  tileColIdx      = slice->getPPS()->ctuToTileCol( ctuXPosInCtus );
-    const unsigned  tileRowIdx      = slice->getPPS()->ctuToTileRow( ctuYPosInCtus );
-    const unsigned  tileXPosInCtus  = slice->getPPS()->getTileColumnBd( tileColIdx );
-    const unsigned  tileYPosInCtus  = slice->getPPS()->getTileRowBd( tileRowIdx );
-    const unsigned  tileColWidth    = slice->getPPS()->getTileColumnWidth( tileColIdx );
-    const unsigned  tileRowHeight   = slice->getPPS()->getTileRowHeight( tileRowIdx );
-    const unsigned  tileIdx         = slice->getPPS()->getTileIdx( ctuXPosInCtus, ctuYPosInCtus);
-    const unsigned  maxCUSize             = sps->getMaxCUWidth();
-    Position pos( ctuXPosInCtus*maxCUSize, ctuYPosInCtus*maxCUSize) ;
-    UnitArea ctuArea(cs.area.chromaFormat, Area( pos.x, pos.y, maxCUSize, maxCUSize ) );
+    const unsigned ctuRsAddr      = slice->getCtuAddrInSlice(ctuIdx);
+    const unsigned ctuXPosInCtus  = ctuRsAddr % widthInCtus;
+    const unsigned ctuYPosInCtus  = ctuRsAddr / widthInCtus;
+    const unsigned tileColIdx     = slice->getPPS()->ctuToTileCol(ctuXPosInCtus);
+    const unsigned tileRowIdx     = slice->getPPS()->ctuToTileRow(ctuYPosInCtus);
+    const unsigned tileXPosInCtus = slice->getPPS()->getTileColumnBd(tileColIdx);
+    const unsigned tileYPosInCtus = slice->getPPS()->getTileRowBd(tileRowIdx);
+    const unsigned tileColWidth   = slice->getPPS()->getTileColumnWidth(tileColIdx);
+    const unsigned tileRowHeight  = slice->getPPS()->getTileRowHeight(tileRowIdx);
+    const unsigned tileIdx        = slice->getPPS()->getTileIdx(ctuXPosInCtus, ctuYPosInCtus);
+    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)
+    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 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++) 
+        int n = slice->getNumRefIdx((RefPicList) rlist);
+        for (int idx = 0; idx < n; idx++)
         {
-          Picture *refPic = slice->getRefPic((RefPicList)rlist, idx);
-          if (!refPic->getSubPicSaved()) 
+          Picture *refPic = slice->getRefPic((RefPicList) rlist, idx);
+          if (!refPic->getSubPicSaved())
           {
             refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
             refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
@@ -169,29 +166,29 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
     }
 #endif
 
-    DTRACE_UPDATE( g_trace_ctx, std::make_pair( "ctu", ctuRsAddr ) );
+    DTRACE_UPDATE(g_trace_ctx, std::make_pair("ctu", ctuRsAddr));
 
-    cabacReader.initBitstream( ppcSubstreams[subStrmId] );
+    cabacReader.initBitstream(ppcSubstreams[subStrmId]);
 
     // set up CABAC contexts' state for this CTU
-    if( ctuXPosInCtus == tileXPosInCtus && ctuYPosInCtus == tileYPosInCtus )
+    if (ctuXPosInCtus == tileXPosInCtus && ctuYPosInCtus == tileYPosInCtus)
     {
-      if( ctuIdx != 0 ) // if it is the first CTU, then the entropy coder has already been reset
+      if (ctuIdx != 0)   // if it is the first CTU, then the entropy coder has already been reset
       {
-        cabacReader.initCtxModels( *slice );
+        cabacReader.initCtxModels(*slice);
         cs.resetPrevPLT(cs.prevPLT);
       }
       pic->m_prevQP[0] = pic->m_prevQP[1] = slice->getSliceQp();
     }
-    else if( ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled )
+    else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
     {
       // Synchronize cabac probabilities with top CTU if it's available and at the start of a line.
-      if( ctuIdx != 0 ) // if it is the first CTU, then the entropy coder has already been reset
+      if (ctuIdx != 0)   // if it is the first CTU, then the entropy coder has already been reset
       {
-        cabacReader.initCtxModels( *slice );
+        cabacReader.initCtxModels(*slice);
         cs.resetPrevPLT(cs.prevPLT);
       }
-      if( cs.getCURestricted( pos.offset(0, -1), pos, slice->getIndependentSliceIdx(), tileIdx, CH_L ) )
+      if (cs.getCURestricted(pos.offset(0, -1), pos, slice->getIndependentSliceIdx(), tileIdx, CH_L))
       {
         // Top is available, so use it.
         cabacReader.getCtx() = m_entropyCodingSyncContextState;
@@ -203,7 +200,7 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
     }
 
     bool updateBcwCodingOrder = cs.slice->getSliceType() == B_SLICE && ctuIdx == 0;
-    if(updateBcwCodingOrder)
+    if (updateBcwCodingOrder)
     {
       resetBcwCodingOrder(true, cs);
     }
@@ -215,20 +212,20 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
       cs.resetIBCBuffer = true;
     }
 
-    if( !cs.slice->isIntra() )
+    if (!cs.slice->isIntra())
     {
-      pic->mctsInfo.init( &cs, getCtuAddr( ctuArea.lumaPos(), *( cs.pcv ) ) );
+      pic->mctsInfo.init(&cs, getCtuAddr(ctuArea.lumaPos(), *(cs.pcv)));
     }
 
-    if( ctuRsAddr == debugCTU )
+    if (ctuRsAddr == debugCTU)
     {
       break;
     }
-    cabacReader.coding_tree_unit( cs, ctuArea, pic->m_prevQP, ctuRsAddr );
+    cabacReader.coding_tree_unit(cs, ctuArea, pic->m_prevQP, ctuRsAddr);
 
-    m_pcCuDecoder->decompressCtu( cs, ctuArea );
+    m_pcCuDecoder->decompressCtu(cs, ctuArea);
 
-    if( ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled )
+    if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled)
     {
       m_entropyCodingSyncContextState = cabacReader.getCtx();
 #if JVET_Q0501_PALETTE_WPP_INIT_ABOVECTU
@@ -236,42 +233,52 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
 #endif
     }
 
-
-    if( ctuIdx == slice->getNumCtuInSlice()-1 )
+    if (ctuIdx == slice->getNumCtuInSlice() - 1)
     {
       unsigned binVal = cabacReader.terminating_bit();
-      CHECK( !binVal, "Expecting a terminating bit" );
+      CHECK(!binVal, "Expecting a terminating bit");
 #if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES
-      cabacReader.remaining_bytes( false );
+      cabacReader.remaining_bytes(false);
 #endif
     }
-    else if( ( ctuXPosInCtus + 1 == tileXPosInCtus + tileColWidth ) &&
-             ( ctuYPosInCtus + 1 == tileYPosInCtus + tileRowHeight || wavefrontsEnabled ) )
+    else if ((ctuXPosInCtus + 1 == tileXPosInCtus + tileColWidth)
+             && (ctuYPosInCtus + 1 == tileYPosInCtus + tileRowHeight || wavefrontsEnabled))
     {
       // The sub-stream/stream should be terminated after this CTU.
       // (end of slice-segment, end of tile, end of wavefront-CTU-row)
       unsigned binVal = cabacReader.terminating_bit();
-      CHECK( !binVal, "Expecting a terminating bit" );
+      CHECK(!binVal, "Expecting a terminating bit");
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+      bool isLastTileCtu = (ctuXPosInCtus + 1 == tileXPosInCtus + tileColWidth) && (ctuYPosInCtus + 1 == tileYPosInCtus + tileRowHeight);
+      if (isLastTileCtu || wavefrontsEntryPointPresent) 
+      {
+#if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES
+        cabacReader.remaining_bytes( true );
+#endif
+        subStrmId++;
+      }
+#else
 #if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES
       cabacReader.remaining_bytes( true );
 #endif
       subStrmId++;
+#endif
     }
 #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 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++) 
+        int n = slice->getNumRefIdx((RefPicList) rlist);
+        for (int idx = 0; idx < n; idx++)
         {
-          Picture *refPic = slice->getRefPic((RefPicList)rlist, idx);
-          if (refPic->getSubPicSaved()) 
+          Picture *refPic = slice->getRefPic((RefPicList) rlist, idx);
+          if (refPic->getSubPicSaved())
           {
             refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight);
             refPic->setSubPicSaved(false);
@@ -283,7 +290,7 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
   }
 
   // deallocate all created substreams, including internal buffers.
-  for( auto substr: ppcSubstreams )
+  for (auto substr: ppcSubstreams)
   {
     delete substr;
   }
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 08ed54f5ebdff357c4b67a50ab8743532ebd1a5c..fd86a2852aff70790a9483336d3f6b1096d9d4a2 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -616,7 +616,9 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana
     READ_CODE(1, uiCode, "loop_filter_across_slices_enabled_flag");   pcPPS->setLoopFilterAcrossSlicesEnabledFlag( uiCode == 1 );
   }
 
+#if !JVET_Q0151_Q0205_ENTRYPOINTS
   READ_FLAG(uiCode, "entropy_coding_sync_enabled_flag");       pcPPS->setEntropyCodingSyncEnabledFlag(uiCode == 1);
+#endif
   READ_FLAG( uiCode,   "cabac_init_present_flag" );            pcPPS->setCabacInitPresentFlag( uiCode ? true : false );
 
   READ_UVLC(uiCode, "num_ref_idx_l0_default_active_minus1");
@@ -1518,6 +1520,15 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   CHECK(uiCode > 48, "Invalid min_qp_prime_ts_minus4 signalled");
 #endif
   pcSPS->setMinQpPrimeTsMinus4(CHANNEL_TYPE_CHROMA, uiCode);
+
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  READ_FLAG( uiCode, "sps_entropy_coding_sync_enabled_flag" );       pcSPS->setEntropyCodingSyncEnabledFlag(uiCode == 1);
+  if (pcSPS->getEntropyCodingSyncEnabledFlag()) 
+  {
+    READ_FLAG(uiCode, "sps_wpp_entry_point_offsets_present_flag");   pcSPS->setEntropyCodingSyncEntryPointsPresentFlag(uiCode == 1);
+  }
+#endif
+
   READ_FLAG( uiCode, "sps_weighted_pred_flag" );                    pcSPS->setUseWP( uiCode ? true : false );
   READ_FLAG( uiCode, "sps_weighted_bipred_flag" );                  pcSPS->setUseWPBiPred( uiCode ? true : false );
 
@@ -3980,7 +3991,14 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
 
   std::vector<uint32_t> entryPointOffset;
 
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  pcSlice->resetNumberOfSubstream();
+  pcSlice->setNumSubstream(sps, pps);
+
+  pcSlice->setNumEntryPoints( sps, pps );
+#else
   pcSlice->setNumEntryPoints( pps );
+#endif
   if( pcSlice->getNumEntryPoints() > 0 )
   {
     uint32_t offsetLenMinus1;
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index f38c05ff486cf3f98ffb08f81336be5eb06119b5..7451a788e99b99c3727be9bb90801a49eb998871 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -519,6 +519,9 @@ protected:
   //====== Sub-picture and Slices ========
   bool      m_singleSlicePerSubPicFlag;
   bool      m_entropyCodingSyncEnabledFlag;
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  bool      m_entropyCodingSyncEntryPointPresentFlag;          ///< flag for the presence of entry points for WPP
+#endif
 
 
   HashType  m_decodedPictureHashSEIType;
@@ -1473,6 +1476,9 @@ public:
   bool  getSaoGreedyMergeEnc           ()                            { return m_saoGreedyMergeEnc; }
   void  setEntropyCodingSyncEnabledFlag(bool b)                      { m_entropyCodingSyncEnabledFlag = b; }
   bool  getEntropyCodingSyncEnabledFlag() const                      { return m_entropyCodingSyncEnabledFlag; }
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  void  setEntropyCodingSyncEntryPointPresentFlag(bool b)            { m_entropyCodingSyncEntryPointPresentFlag = b; }
+#endif
   void  setDecodedPictureHashSEIType(HashType m)                     { m_decodedPictureHashSEIType = m; }
   HashType getDecodedPictureHashSEIType() const                      { return m_decodedPictureHashSEIType; }
   void  setBufferingPeriodSEIEnabled(bool b)                         { m_bufferingPeriodSEIEnabled = b; }
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index e415c7d6a883945e4c164f9ad7bb0caef966e66b..c3b16b06562ff90f2b489e1e3cc9acfd194e1027 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -2702,7 +2702,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     // Allocate some coders, now the number of tiles are known.
     const uint32_t numberOfCtusInFrame = pcPic->cs->pcv->sizeInCtus;
     const int numSubstreamsColumns = pcSlice->getPPS()->getNumTileColumns();
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+    const int numSubstreamRows     = pcSlice->getSPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->cs->pcv->heightInCtus : (pcSlice->getPPS()->getNumTileRows());
+#else
     const int numSubstreamRows     = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->cs->pcv->heightInCtus : (pcSlice->getPPS()->getNumTileRows());
+#endif
     const int numSubstreams        = std::max<int> (numSubstreamRows * numSubstreamsColumns, (int) pcPic->cs->pps->getNumSlicesInPic());
     std::vector<OutputBitstream> substreamsOut(numSubstreams);
 
@@ -3285,6 +3289,10 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
         pcSlice->setFinalized(true);
 
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+        pcSlice->resetNumberOfSubstream( );
+        pcSlice->setNumSubstream( pcSlice->getSPS(), pcSlice->getPPS() );
+#endif
         pcSlice->clearSubstreamSizes(  );
         {
           uint32_t numBinsCoded = 0;
@@ -3300,7 +3308,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
           // Append substreams...
           OutputBitstream *pcOut = pcBitstreamRedirect;
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+          const int numSubstreamsToCode = pcSlice->getNumberOfSubstream() + 1;
+#else
           const int numSubstreamsToCode  = pcSlice->getNumberOfSubstreamSizes()+1;
+#endif
+
           for ( uint32_t ui = 0 ; ui < numSubstreamsToCode; ui++ )
           {
             pcOut->addSubstream(&(substreamsOut[ui]));
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index f5661cb03418b4d232f368e60bb9de417edb5245..60db1a5a5a7f589ea211d7da0f7c31d0cdbbc8a7 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -1347,6 +1347,11 @@ void EncLib::xInitSPS( SPS& sps, VPS& vps )
     sps.setMinQpPrimeTsMinus4(ChannelType(channelType), (6 * (m_bitDepth[channelType] - m_inputBitDepth[channelType])));
   }
 
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  sps.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag );
+  sps.setEntropyCodingSyncEntryPointsPresentFlag( m_entropyCodingSyncEntryPointPresentFlag );
+#endif
+
   sps.setUseWP( m_useWeightedPred );
   sps.setUseWPBiPred( m_useWeightedBiPred );
 
@@ -1719,7 +1724,9 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
     pps.setSliceChromaQpFlag(m_chromaCbQpOffsetDualTree != 0 || m_chromaCrQpOffsetDualTree != 0 || m_chromaCbCrQpOffsetDualTree != 0);
   }
 
-  pps.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag );
+#if !JVET_Q0151_Q0205_ENTRYPOINTS
+  pps.setEntropyCodingSyncEnabledFlag(m_entropyCodingSyncEnabledFlag);
+#endif
 
   pps.setNoPicPartitionFlag( m_noPicPartitionFlag );
   if( m_noPicPartitionFlag == false )
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index 449ba3af1d9f82708e8c138b0e5abecb2f179312..101589a50705d0665fe31d79b5bd46eeed5a0e7c 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1722,7 +1722,14 @@ void EncSlice::encodeSlice   ( Picture* pcPic, OutputBitstream* pcSubstreams, ui
 {
 
   Slice *const pcSlice               = pcPic->slices[getSliceSegmentIdx()];
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  const bool wavefrontsEnabled         = pcSlice->getSPS()->getEntropyCodingSyncEnabledFlag();
+  const bool wavefrontsEntryPointsFlag = (wavefrontsEnabled) ? pcSlice->getSPS()->getEntropyCodingSyncEntryPointsPresentFlag() : false;
+  uint32_t substreamSize               = 0;
+  pcSlice->resetNumberOfSubstream();
+#else
   const bool wavefrontsEnabled       = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag();
+#endif
 
 
   // setup coding structure
@@ -1810,7 +1817,17 @@ void EncSlice::encodeSlice   ( Picture* pcPic, OutputBitstream* pcSubstreams, ui
       if (!isLastCTUsinSlice) //Byte alignment only when it is not the last substream in the slice
       {
         // write sub-stream size
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+        substreamSize += (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations();
+        pcSlice->increaseNumberOfSubstream();
+        if( isLastCTUinTile || (isLastCTUinWPP && wavefrontsEntryPointsFlag) )
+        {
+          pcSlice->addSubstreamSize(substreamSize);
+          substreamSize = 0;
+        }
+#else
         pcSlice->addSubstreamSize((pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations());
+#endif
       }
       uiSubStrm++;
     }
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 1f0f1b672f8f246bd7d4cd543f477c0374fc3d5f..5348353d26504acbac954a986171e9096d48d361 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -376,7 +376,9 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS )
     WRITE_FLAG( pcPPS->getLoopFilterAcrossSlicesEnabledFlag(), "loop_filter_across_slices_enabled_flag");
   }
 
+#if !JVET_Q0151_Q0205_ENTRYPOINTS
   WRITE_FLAG( pcPPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "entropy_coding_sync_enabled_flag" );
+#endif
   WRITE_FLAG( pcPPS->getCabacInitPresentFlag() ? 1 : 0,   "cabac_init_present_flag" );
   WRITE_UVLC( pcPPS->getNumRefIdxL0DefaultActive()-1,     "num_ref_idx_l0_default_active_minus1");
   WRITE_UVLC( pcPPS->getNumRefIdxL1DefaultActive()-1,     "num_ref_idx_l1_default_active_minus1");
@@ -986,7 +988,15 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   WRITE_UVLC( pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8,                      "bit_depth_minus8" );
 #if !JVET_Q0183_SPS_TRANSFORM_SKIP_MODE_CONTROL
   WRITE_UVLC( pcSPS->getMinQpPrimeTsMinus4(CHANNEL_TYPE_LUMA),                      "min_qp_prime_ts_minus4" );
-#endif  
+#endif
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  WRITE_FLAG( pcSPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "sps_entropy_coding_sync_enabled_flag" );
+  if (pcSPS->getEntropyCodingSyncEnabledFlag()) 
+  {
+    WRITE_FLAG( pcSPS->getEntropyCodingSyncEntryPointsPresentFlag() ? 1 : 0, "sps_wpp_entry_point_offsets_present_flag" );
+  }
+#endif
+
   WRITE_FLAG( pcSPS->getUseWP() ? 1 : 0, "sps_weighted_pred_flag" );   // Use of Weighting Prediction (P_SLICE)
   WRITE_FLAG( pcSPS->getUseWPBiPred() ? 1 : 0, "sps_weighted_bipred_flag" );  // Use of Weighting Bi-Prediction (B_SLICE)
 
@@ -2862,7 +2872,11 @@ void  HLSWriter::codeProfileTierLevel    ( const ProfileTierLevel* ptl, int maxN
 */
 void  HLSWriter::codeTilesWPPEntryPoint( Slice* pSlice )
 {
+#if JVET_Q0151_Q0205_ENTRYPOINTS
+  pSlice->setNumEntryPoints( pSlice->getSPS(), pSlice->getPPS() );
+#else
   pSlice->setNumEntryPoints( pSlice->getPPS() );
+#endif
   if( pSlice->getNumEntryPoints() == 0 )
   {
     return;