From ffe2c6a7760e9a34624399713853a95055a7e6e5 Mon Sep 17 00:00:00 2001
From: Brian Heng <brian.heng@broadcom.com>
Date: Thu, 21 Nov 2019 14:40:05 +0100
Subject: [PATCH] JVET-P1006: Picture Header

  - Add picture header and related syntax changes.
---
 doc/software-manual.tex                       |  24 +
 source/App/DecoderApp/DecApp.cpp              | 166 ++++
 source/App/DecoderApp/DecApp.h                |   3 +
 source/App/EncoderApp/EncApp.cpp              |   9 +
 source/App/EncoderApp/EncAppCfg.cpp           |  12 +
 source/App/EncoderApp/EncAppCfg.h             |   6 +
 source/App/Parcat/parcat.cpp                  |  47 +-
 source/Lib/CommonLib/AdaptiveLoopFilter.cpp   |  81 ++
 source/Lib/CommonLib/AdaptiveLoopFilter.h     |   4 +
 source/Lib/CommonLib/CodingStructure.cpp      |   3 +
 source/Lib/CommonLib/CodingStructure.h        |   3 +
 source/Lib/CommonLib/CommonDef.h              |   3 +
 source/Lib/CommonLib/ContextModelling.cpp     |   4 +
 source/Lib/CommonLib/DepQuant.cpp             |  24 +
 source/Lib/CommonLib/InterPrediction.cpp      |   8 +
 source/Lib/CommonLib/LoopFilter.cpp           |  50 +
 source/Lib/CommonLib/LoopFilter.h             |   4 +
 source/Lib/CommonLib/Picture.cpp              |  15 +
 source/Lib/CommonLib/Picture.h                |   4 +
 source/Lib/CommonLib/Quant.cpp                |  28 +-
 source/Lib/CommonLib/QuantRDOQ.cpp            |  16 +
 source/Lib/CommonLib/SampleAdaptiveOffset.cpp |  59 ++
 source/Lib/CommonLib/SampleAdaptiveOffset.h   |   4 +
 source/Lib/CommonLib/Slice.cpp                | 322 +++++++
 source/Lib/CommonLib/Slice.h                  | 403 +++++++-
 source/Lib/CommonLib/TypeDef.h                |   2 +
 source/Lib/CommonLib/UnitPartitioner.cpp      |   5 +
 source/Lib/CommonLib/UnitTools.cpp            |  56 ++
 source/Lib/DecoderLib/CABACReader.cpp         |  60 ++
 source/Lib/DecoderLib/DecCu.cpp               |  46 +
 source/Lib/DecoderLib/DecLib.cpp              | 176 ++++
 source/Lib/DecoderLib/DecLib.h                |  11 +-
 source/Lib/DecoderLib/DecSlice.cpp            |   5 +
 source/Lib/DecoderLib/VLCReader.cpp           | 866 +++++++++++++++++-
 source/Lib/DecoderLib/VLCReader.h             |   5 +
 source/Lib/EncoderLib/CABACWriter.cpp         |  60 ++
 .../Lib/EncoderLib/EncAdaptiveLoopFilter.cpp  |  12 +
 source/Lib/EncoderLib/EncCfg.h                |  16 +
 source/Lib/EncoderLib/EncCu.cpp               |  80 ++
 source/Lib/EncoderLib/EncGOP.cpp              | 269 ++++++
 source/Lib/EncoderLib/EncGOP.h                |   7 +
 source/Lib/EncoderLib/EncLib.cpp              | 185 +++-
 source/Lib/EncoderLib/EncLib.h                |   6 +
 source/Lib/EncoderLib/EncModeCtrl.cpp         |   8 +
 .../EncoderLib/EncSampleAdaptiveOffset.cpp    |  22 +
 source/Lib/EncoderLib/EncSlice.cpp            |  49 +
 source/Lib/EncoderLib/EncSlice.h              |   3 +
 source/Lib/EncoderLib/InterSearch.cpp         | 100 ++
 source/Lib/EncoderLib/IntraSearch.cpp         |  52 ++
 source/Lib/EncoderLib/VLCWriter.cpp           | 666 ++++++++++++++
 source/Lib/EncoderLib/VLCWriter.h             |   3 +
 51 files changed, 4061 insertions(+), 11 deletions(-)

diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index 2f10b24f5..6f687cfb4 100755
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -2220,6 +2220,30 @@ Enables signaling the below parameters either in PPS or for each slice according
 \end{tabular}
 \\
 
+\Option{SliceLevelRpl} &
+%\ShortOption{\None} &
+\Default{true} &
+Code reference picture lists in slice headers rather than picture header.
+\\
+
+\Option{SliceLevelDblk} &
+%\ShortOption{\None} &
+\Default{true} &
+Code deblocking filter parameters in slice headers rather than picture header.
+\\
+
+\Option{SliceLevelSao} &
+%\ShortOption{\None} &
+\Default{true} &
+Code SAO parameters in slice headers rather than picture header.
+\\
+
+\Option{SliceLevelAlf} &
+%\ShortOption{\None} &
+\Default{true} &
+Code ALF parameters in slice headers rather than picture header.
+\\
+
 \Option{TransformSkip} &
 %\ShortOption{\None} &
 \Default{false} &
diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp
index 25f95b3a6..c5ec40de6 100644
--- a/source/App/DecoderApp/DecApp.cpp
+++ b/source/App/DecoderApp/DecApp.cpp
@@ -118,6 +118,48 @@ uint32_t DecApp::decode()
 
   while (!!bitstreamFile)
   {
+#if JVET_P1006_PICTURE_HEADER
+    InputNALUnit nalu;
+    nalu.m_nalUnitType = NAL_UNIT_INVALID;
+
+    // determine if next NAL unit will be the first one from a new picture
+    bool bNewPicture = isNewPicture(&bitstreamFile, &bytestream);
+    if(!bNewPicture) 
+    { 
+      AnnexBStats stats = AnnexBStats();
+
+      // find next NAL unit in stream
+      byteStreamNALUnit(bytestream, nalu.getBitstream().getFifo(), stats);
+      if (nalu.getBitstream().getFifo().empty())
+      {
+        /* this can happen if the following occur:
+         *  - empty input file
+         *  - two back-to-back start_code_prefixes
+         *  - start_code_prefix immediately followed by EOF
+         */
+        msg( ERROR, "Warning: Attempt to decode an empty NAL unit\n");
+      }
+      else
+      {
+        // read NAL unit header
+        read(nalu);
+
+        // flush output for first slice of an IDR picture
+        if(m_cDecLib.getFirstSliceInPicture() &&
+            (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
+             nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP))
+        {
+          xFlushOutput(pcListPic);
+        }
+
+        // parse NAL unit syntax if within target decoding layer
+        if ((m_iMaxTemporalLayer < 0 || nalu.m_temporalId <= m_iMaxTemporalLayer) && isNaluWithinTargetDecLayerIdSet(&nalu) && isNaluTheTargetLayer(&nalu))
+        {
+          m_cDecLib.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);
+        }
+      }
+    }
+#else 
     /* location serves to work around a design fault in the decoder, whereby
      * the process of reading a new slice that is the first slice of a new frame
      * requires the DecApp::decode() method to be called again with the same
@@ -199,6 +241,7 @@ uint32_t DecApp::decode()
       }
     }
 
+#endif
 
 
     if( ( bNewPicture || !bitstreamFile || nalu.m_nalUnitType == NAL_UNIT_EOS ) && !m_cDecLib.getFirstSliceInSequence() )
@@ -207,8 +250,10 @@ uint32_t DecApp::decode()
       {
         m_cDecLib.executeLoopFilters();
         m_cDecLib.finishPicture( poc, pcListPic );
+#if !JVET_P1006_PICTURE_HEADER
 #if RExt__DECODER_DEBUG_TOOL_MAX_FRAME_STATS
         CodingStatistics::UpdateMaxStat(backupStats);
+#endif
 #endif
       }
       loopFiltered = (nalu.m_nalUnitType == NAL_UNIT_EOS);
@@ -287,8 +332,17 @@ uint32_t DecApp::decode()
         xWriteOutput( pcListPic, nalu.m_temporalId );
       }
     }
+#if JVET_P1006_PICTURE_HEADER
+    if(bNewPicture) 
+    {
+        m_cDecLib.resetAccessUnitNals();
+        m_cDecLib.resetAccessUnitApsNals();
+    }
+#endif
+#if !JVET_P1006_PICTURE_HEADER
 #if RExt__DECODER_DEBUG_STATISTICS
     delete backupStats;
+#endif
 #endif
   }
 
@@ -311,6 +365,118 @@ uint32_t DecApp::decode()
   return nRet;
 }
 
+#if JVET_P1006_PICTURE_HEADER
+/**
+ - lookahead through next NAL units to determine if current NAL unit is the first NAL unit in a new picture
+ */
+bool DecApp::isNewPicture(ifstream *bitstreamFile, class InputByteStream *bytestream)
+{
+  bool ret = false;
+  bool finished = false;
+
+  // cannot be a new picture if there haven't been any slices yet
+  if(m_cDecLib.getFirstSliceInPicture())
+  {
+    return false;
+  }
+
+  // save stream position for backup
+#if RExt__DECODER_DEBUG_STATISTICS
+  CodingStatistics::CodingStatisticsData* backupStats = new CodingStatistics::CodingStatisticsData(CodingStatistics::GetStatistics());
+  streampos location = bitstreamFile->tellg() - streampos(bytestream->GetNumBufferedBytes());
+#else
+  streampos location = bitstreamFile->tellg();
+#endif
+
+  // look ahead until picture start location is determined
+  while (!finished && !!(*bitstreamFile))
+  {
+    AnnexBStats stats = AnnexBStats();
+    InputNALUnit nalu;
+    byteStreamNALUnit(*bytestream, nalu.getBitstream().getFifo(), stats);
+    if (nalu.getBitstream().getFifo().empty())
+    {
+      msg( ERROR, "Warning: Attempt to decode an empty NAL unit\n");
+    }
+    else
+    {
+      // get next NAL unit type
+      read(nalu);
+      switch( nalu.m_nalUnitType ) {
+
+        // NUT that indicate the start of a new picture
+        case NAL_UNIT_ACCESS_UNIT_DELIMITER:
+        case NAL_UNIT_DPS:
+        case NAL_UNIT_VPS:
+        case NAL_UNIT_SPS:
+        case NAL_UNIT_PPS:
+        case NAL_UNIT_PH:
+          ret = true;
+          finished = true;
+          break;
+        
+        // NUT that are not the start of a new picture
+        case NAL_UNIT_CODED_SLICE_TRAIL:
+        case NAL_UNIT_CODED_SLICE_STSA:
+        case NAL_UNIT_CODED_SLICE_RASL:
+        case NAL_UNIT_CODED_SLICE_RADL:
+        case NAL_UNIT_RESERVED_VCL_4:
+        case NAL_UNIT_RESERVED_VCL_5:
+        case NAL_UNIT_RESERVED_VCL_6:
+        case NAL_UNIT_CODED_SLICE_IDR_W_RADL:
+        case NAL_UNIT_CODED_SLICE_IDR_N_LP:
+        case NAL_UNIT_CODED_SLICE_CRA:
+        case NAL_UNIT_CODED_SLICE_GDR:
+        case NAL_UNIT_RESERVED_IRAP_VCL_11:
+        case NAL_UNIT_RESERVED_IRAP_VCL_12:
+        case NAL_UNIT_EOS:
+        case NAL_UNIT_EOB:
+#if JVET_P0588_SUFFIX_APS
+        case NAL_UNIT_SUFFIX_APS:
+#endif
+        case NAL_UNIT_SUFFIX_SEI:
+        case NAL_UNIT_FD:
+          ret = false;
+          finished = true;
+          break;
+        
+        // NUT that might indicate the start of a new picture - keep looking
+#if JVET_P0588_SUFFIX_APS
+        case NAL_UNIT_PREFIX_APS:
+#else
+        case NAL_UNIT_APS:
+#endif
+        case NAL_UNIT_PREFIX_SEI:
+        case NAL_UNIT_RESERVED_NVCL_26:
+        case NAL_UNIT_RESERVED_NVCL_27:
+        case NAL_UNIT_UNSPECIFIED_28:
+        case NAL_UNIT_UNSPECIFIED_29:
+        case NAL_UNIT_UNSPECIFIED_30:
+        case NAL_UNIT_UNSPECIFIED_31:
+        default:
+          break;
+      }
+    }
+  }
+  
+  // restore previous stream location - minus 3 due to the need for the annexB parser to read three extra bytes
+#if RExt__DECODER_DEBUG_BIT_STATISTICS
+  bitstreamFile->clear();
+  bitstreamFile->seekg(location);
+  bytestream->reset();
+  CodingStatistics::SetStatistics(*backupStats);
+  delete backupStats;
+#else
+  bitstreamFile->clear();
+  bitstreamFile->seekg(location-streamoff(3));
+  bytestream->reset();
+#endif
+
+  // return TRUE if next NAL unit is the start of a new picture
+  return ret;
+}
+#endif
+
 // ====================================================================================================================
 // Protected member functions
 // ====================================================================================================================
diff --git a/source/App/DecoderApp/DecApp.h b/source/App/DecoderApp/DecApp.h
index a912738ca..f3108e7c7 100644
--- a/source/App/DecoderApp/DecApp.h
+++ b/source/App/DecoderApp/DecApp.h
@@ -91,6 +91,9 @@ private:
 #endif
   bool  isNaluWithinTargetDecLayerIdSet ( InputNALUnit* nalu ); ///< check whether given Nalu is within targetDecLayerIdSet
   bool  isNaluTheTargetLayer(InputNALUnit* nalu); ///< check whether given Nalu is within targetDecLayerIdSet
+#if JVET_P1006_PICTURE_HEADER
+  bool  isNewPicture(ifstream *bitstreamFile, class InputByteStream *bytestream);  ///< check if next NAL unit will be the first NAL unit from a new picture
+#endif
 };
 
 //! \}
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 8023735a7..a4fd3fbf1 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -572,6 +572,12 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setLFCrossTileBoundaryFlag                           ( m_bLFCrossTileBoundaryFlag );
   m_cEncLib.setEntropyCodingSyncEnabledFlag                      ( m_entropyCodingSyncEnabledFlag );
   m_cEncLib.setTMVPModeId                                        ( m_TMVPModeId );
+#if JVET_P1006_PICTURE_HEADER
+  m_cEncLib.setSliceLevelRpl                                     ( m_sliceLevelRpl  );
+  m_cEncLib.setSliceLevelDblk                                    ( m_sliceLevelDblk );
+  m_cEncLib.setSliceLevelSao                                     ( m_sliceLevelSao  );
+  m_cEncLib.setSliceLevelAlf                                     ( m_sliceLevelAlf  );
+#endif
   m_cEncLib.setConstantSliceHeaderParamsEnabledFlag              ( m_constantSliceHeaderParamsEnabledFlag );
   m_cEncLib.setPPSDepQuantEnabledIdc                             ( m_PPSDepQuantEnabledIdc );
   m_cEncLib.setPPSRefPicListSPSIdc0                              ( m_PPSRefPicListSPSIdc0 );
@@ -1181,6 +1187,9 @@ void EncApp::rateStatsAccum(const AccessUnit& au, const std::vector<uint32_t>& a
     case NAL_UNIT_VPS:
     case NAL_UNIT_SPS:
     case NAL_UNIT_PPS:
+#if JVET_P1006_PICTURE_HEADER
+    case NAL_UNIT_PH:
+#endif
 #if JVET_P0588_SUFFIX_APS
     case NAL_UNIT_PREFIX_APS:
     case NAL_UNIT_SUFFIX_APS:
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index d2fdacf3b..0164f4c63 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -855,7 +855,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("ConfWinRight",                                    m_confWinRight,                                       0, "Right offset for window conformance mode 3")
   ("ConfWinTop",                                      m_confWinTop,                                         0, "Top offset for window conformance mode 3")
   ("ConfWinBottom",                                   m_confWinBottom,                                      0, "Bottom offset for window conformance mode 3")
+#if JVET_P1006_PICTURE_HEADER
+  ("AccessUnitDelimiter",                             m_AccessUnitDelimiter,                            false, "Enable Access Unit Delimiter NALUs")
+#else
   ("AccessUnitDelimiter",                             m_AccessUnitDelimiter,                             true, "Enable Access Unit Delimiter NALUs")
+#endif
   ("FrameRate,-fr",                                   m_iFrameRate,                                         0, "Frame rate")
   ("FrameSkip,-fs",                                   m_FrameSkip,                                         0u, "Number of frames to skip at start of input YUV")
   ("TemporalSubsampleRatio,-ts",                      m_temporalSubsampleRatio,                            1u, "Temporal sub-sample ratio when reading input YUV")
@@ -1217,6 +1221,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("TMVPMode",                                        m_TMVPModeId,                                         1, "TMVP mode 0: TMVP disable for all slices. 1: TMVP enable for all slices (default) 2: TMVP enable for certain slices only")
   ("PPSorSliceMode",                                  m_PPSorSliceMode,                                     0, "Enable signalling certain parameters either in PPS or per slice\n"
                                                                                                                 "\tmode 0: Always per slice (default), 1: RA settings, 2: LDB settings, 3: LDP settings")
+#if JVET_P1006_PICTURE_HEADER
+  ("SliceLevelRpl",                                   m_sliceLevelRpl,                                   true, "Code reference picture lists in slice headers rather than picture header.")
+  ("SliceLevelDblk",                                  m_sliceLevelDblk,                                  true, "Code deblocking filter parameters in slice headers rather than picture header.")
+  ("SliceLevelSao",                                   m_sliceLevelSao,                                   true, "Code SAO parameters in slice headers rather than picture header.")
+  ("SliceLevelAlf",                                   m_sliceLevelAlf,                                   true, "Code ALF parameters in slice headers rather than picture header.")
+#endif
   ("FEN",                                             tmpFastInterSearchMode,   int(FASTINTERSEARCH_DISABLED), "fast encoder setting")
   ("ECU",                                             m_bUseEarlyCU,                                    false, "Early CU setting")
   ("FDM",                                             m_useFastDecisionForMerge,                         true, "Fast decision for Merge RD Cost")
@@ -2189,10 +2199,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   }
 #endif
 
+#if !JVET_P1006_PICTURE_HEADER
   if (m_AccessUnitDelimiter == false)
   {
     printf ("Warning: Access unit delimiters are disabled. VVC requires the presence of access unit delimiters\n");
   }
+#endif
 
 #if JVET_O0756_CONFIG_HDRMETRICS && !JVET_O0756_CALCULATE_HDRMETRICS
   if ( m_calculateHdrMetrics == true)
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index db0b21c07..69e59f2f1 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -542,6 +542,12 @@ protected:
   uint32_t      m_maxNumTriangleCand;
   uint32_t      m_maxNumIBCMergeCand;                             ///< Max number of IBC merge candidates
 
+#if JVET_P1006_PICTURE_HEADER
+  bool      m_sliceLevelRpl;                                      ///< code reference picture lists in slice headers rather than picture header
+  bool      m_sliceLevelDblk;                                     ///< code deblocking filter parameters in slice headers rather than picture header
+  bool      m_sliceLevelSao;                                      ///< code SAO parameters in slice headers rather than picture header
+  bool      m_sliceLevelAlf;                                      ///< code ALF parameters in slice headers rather than picture header
+#endif
   int       m_TMVPModeId;
   int       m_PPSorSliceMode;
   bool      m_constantSliceHeaderParamsEnabledFlag;
diff --git a/source/App/Parcat/parcat.cpp b/source/App/Parcat/parcat.cpp
index f614dcc1a..4c2136582 100644
--- a/source/App/Parcat/parcat.cpp
+++ b/source/App/Parcat/parcat.cpp
@@ -48,9 +48,20 @@
 class ParcatHLSyntaxReader : public VLCReader
 {
   public:
+#if JVET_P1006_PICTURE_HEADER
+    void  parseSliceHeaderUpToPoc ( ParameterSetManager *parameterSetManager );
+#else
     bool  parseSliceHeaderUpToPoc ( ParameterSetManager *parameterSetManager, bool isRapPic );
+#endif
 };
 
+#if JVET_P1006_PICTURE_HEADER
+void ParcatHLSyntaxReader::parseSliceHeaderUpToPoc ( ParameterSetManager *parameterSetManager )
+{
+  // POC is first syntax element in slice header
+  return;
+}
+#else
 bool ParcatHLSyntaxReader::parseSliceHeaderUpToPoc ( ParameterSetManager *parameterSetManager, bool isRapPic )
 {
   uint32_t  uiCode;
@@ -120,6 +131,7 @@ bool ParcatHLSyntaxReader::parseSliceHeaderUpToPoc ( ParameterSetManager *parame
 
   return firstSliceSegmentInPic;
 }
+#endif
 
 /**
  Find the beginning and end of a NAL (Network Abstraction Layer) unit in a byte buffer containing H264 bitstream data.
@@ -296,6 +308,9 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
 
   int bits_for_poc = 8;
   bool skip_next_sei = false;
+#if JVET_P1006_PICTURE_HEADER
+  bool first_slice_segment_in_pic_flag = false;
+#endif
 
   while(find_nal_unit(p, sz, &nal_start, &nal_end) > 0)
   {
@@ -342,19 +357,33 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
       HLSReader.parsePPS( pps, &parameterSetManager );
       parameterSetManager.storePPS( pps, inp_nalu.getBitstream().getFifo() );
     }
+#if JVET_P1006_PICTURE_HEADER
+    if( inp_nalu.m_nalUnitType == NAL_UNIT_PH )
+    {
+      first_slice_segment_in_pic_flag = true;
+    }
+#endif
 
     if(nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP)
     {
       poc = 0;
       new_poc = *poc_base + poc;
+#if JVET_P1006_PICTURE_HEADER
+      first_slice_segment_in_pic_flag = false;
+#endif
     }
 #if JVET_P0363_CLEANUP_NUT_TABLE
-    if((nalu_type < NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (nalu_type > NAL_UNIT_CODED_SLICE_IDR_N_LP && nalu_type < NAL_UNIT_RESERVED_IRAP_VCL_12) )
+    if((nalu_type < NAL_UNIT_CODED_SLICE_IDR_W_RADL) || (nalu_type > NAL_UNIT_CODED_SLICE_IDR_N_LP && nalu_type <= NAL_UNIT_RESERVED_IRAP_VCL_12) )
 #else
     if((nalu_type < 7) || (nalu_type > 9 && nalu_type < 15) )
 #endif
     {
       parcatHLSReader.setBitstream( &inp_nalu.getBitstream() );
+#if JVET_P1006_PICTURE_HEADER
+      
+      // beginning of slice header parsing, taken from VLCReader
+      parcatHLSReader.parseSliceHeaderUpToPoc( &parameterSetManager );
+#else
       bool isRapPic =
         inp_nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL
         || inp_nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP
@@ -362,6 +391,7 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
 
       // beginning of slice header parsing, taken from VLCReader
       bool first_slice_segment_in_pic_flag = parcatHLSReader.parseSliceHeaderUpToPoc( &parameterSetManager, isRapPic);
+#endif
       int num_bits_up_to_poc_lsb = parcatHLSReader.getBitstream()->getNumBitsRead();
       int offset = num_bits_up_to_poc_lsb;
 
@@ -376,7 +406,11 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
       // int picOrderCntLSB = (pcSlice->getPOC()-pcSlice->getLastIDR()+(1<<pcSlice->getSPS()->getBitsForPOC())) & ((1<<pcSlice->getSPS()->getBitsForPOC())-1);
       unsigned picOrderCntLSB = (new_poc - *last_idr_poc +(1 << bits_for_poc)) & ((1<<bits_for_poc)-1);
 
+#if JVET_P1006_PICTURE_HEADER
+      int low = data & ((1 << low_bits) - 1);
+#else
       int low = data & ((1 << (low_bits + 1)) - 1);
+#endif
       int hi = data >> (16 - hi_bits);
       data = (hi << (16 - hi_bits)) | (picOrderCntLSB << low_bits) | low;
 
@@ -389,6 +423,9 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
         std::cout << "Changed poc " << poc << " to " << new_poc << std::endl;
 #endif
         ++cnt;
+#if JVET_P1006_PICTURE_HEADER
+        first_slice_segment_in_pic_flag = false;
+#endif
       }
     }
 
@@ -398,10 +435,18 @@ std::vector<uint8_t> filter_segment(const std::vector<uint8_t> & v, int idx, int
       idr_found = true;
     }
 
+#if JVET_P1006_PICTURE_HEADER
+#if JVET_P0588_SUFFIX_APS
+    if( ( idx > 1 && ( nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP ) ) || ( ( idx > 1 && !idr_found ) && ( nalu_type == NAL_UNIT_DPS || nalu_type == NAL_UNIT_VPS || nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_PREFIX_APS || nalu_type == NAL_UNIT_SUFFIX_APS || nalu_type == NAL_UNIT_PH || nalu_type == NAL_UNIT_ACCESS_UNIT_DELIMITER ) )
+#else
+    if((idx > 1 && (nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP)) || ((idx > 1 && !idr_found) && (nalu_type == NAL_UNIT_DPS || nalu_type == NAL_UNIT_VPS ||nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_APS || nalu_type == NAL_UNIT_PH || nalu_type == NAL_UNIT_ACCESS_UNIT_DELIMITER))
+#endif
+#else
 #if JVET_P0588_SUFFIX_APS
     if( ( idx > 1 && ( nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP ) ) || ( ( idx > 1 && !idr_found ) && ( nalu_type == NAL_UNIT_DPS || nalu_type == NAL_UNIT_VPS || nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_PREFIX_APS || nalu_type == NAL_UNIT_SUFFIX_APS || nalu_type == NAL_UNIT_ACCESS_UNIT_DELIMITER ) )
 #else
     if((idx > 1 && (nalu_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalu_type == NAL_UNIT_CODED_SLICE_IDR_N_LP)) || ((idx > 1 && !idr_found) && (nalu_type == NAL_UNIT_DPS || nalu_type == NAL_UNIT_VPS ||nalu_type == NAL_UNIT_SPS || nalu_type == NAL_UNIT_PPS || nalu_type == NAL_UNIT_APS || nalu_type == NAL_UNIT_ACCESS_UNIT_DELIMITER))
+#endif
 #endif
       || (nalu_type == NAL_UNIT_SUFFIX_SEI && skip_next_sei))
     {
diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
index 9c4659257..d8294c312 100644
--- a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
+++ b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp
@@ -78,6 +78,9 @@ void AdaptiveLoopFilter::getAlfBoundary( const CodingStructure& cs, int posX, in
 {
   const Slice& slice = *( cs.slice );
   const PPS&   pps   = *( cs.pps );
+#if JVET_P1006_PICTURE_HEADER
+  const PicHeader& picHeader = *( cs.picHeader );
+#endif
   int   ctuSize = slice.getSPS()->getCTUSize();
   const Position currCtuPos( posX, posY );
   const CodingUnit *currCtu = cs.getCU( currCtuPos, CHANNEL_TYPE_LUMA );
@@ -91,7 +94,11 @@ void AdaptiveLoopFilter::getAlfBoundary( const CodingStructure& cs, int posX, in
     const Position prevCtuPos( posX, posY - ctuSize );
     const CodingUnit *prevCtu = cs.getCU( prevCtuPos, CHANNEL_TYPE_LUMA );
 
+#if JVET_P1006_PICTURE_HEADER
+    if ( !pps.getLoopFilterAcrossSlicesEnabledFlag() && !CU::isSameSlice( *currCtu, *prevCtu ) )
+#else
     if ( !slice.getLFCrossSliceBoundaryFlag() && !CU::isSameSlice( *currCtu, *prevCtu ) )
+#endif
     {
       topBry = posY;
     }
@@ -108,7 +115,11 @@ void AdaptiveLoopFilter::getAlfBoundary( const CodingStructure& cs, int posX, in
     const Position nextCtuPos( posX, posY + ctuSize );
     const CodingUnit *nextCtu = cs.getCU( nextCtuPos, CHANNEL_TYPE_LUMA );
 
+#if JVET_P1006_PICTURE_HEADER
+    if ( !pps.getLoopFilterAcrossSlicesEnabledFlag() && !CU::isSameSlice( *currCtu, *nextCtu ) )
+#else
     if ( !slice.getLFCrossSliceBoundaryFlag() && !CU::isSameSlice( *currCtu, *nextCtu ) )
+#endif
     {
       botBry = posY + ctuSize;
     }
@@ -125,7 +136,11 @@ void AdaptiveLoopFilter::getAlfBoundary( const CodingStructure& cs, int posX, in
     const Position prevCtuPos( posX - ctuSize, posY );
     const CodingUnit *prevCtu = cs.getCU( prevCtuPos, CHANNEL_TYPE_LUMA );
 
+#if JVET_P1006_PICTURE_HEADER
+    if ( !pps.getLoopFilterAcrossSlicesEnabledFlag() && !CU::isSameSlice( *currCtu, *prevCtu ) )
+#else
     if ( !slice.getLFCrossSliceBoundaryFlag() && !CU::isSameSlice( *currCtu, *prevCtu ) )
+#endif
     {
       leftBry = posX;
     }
@@ -142,7 +157,11 @@ void AdaptiveLoopFilter::getAlfBoundary( const CodingStructure& cs, int posX, in
     const Position nextCtuPos( posX + ctuSize, posY );
     const CodingUnit *nextCtu = cs.getCU( nextCtuPos, CHANNEL_TYPE_LUMA );
 
+#if JVET_P1006_PICTURE_HEADER
+    if ( !pps.getLoopFilterAcrossSlicesEnabledFlag() && !CU::isSameSlice( *currCtu, *nextCtu ) )
+#else
     if ( !slice.getLFCrossSliceBoundaryFlag() && !CU::isSameSlice( *currCtu, *nextCtu ) )
+#endif
     {
       rightBry = posX + ctuSize;
     }
@@ -153,6 +172,34 @@ void AdaptiveLoopFilter::getAlfBoundary( const CodingStructure& cs, int posX, in
     }
   }
 
+#if JVET_P1006_PICTURE_HEADER
+  if( picHeader.getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
+  {
+    for( int i = 0; i < picHeader.getNumHorVirtualBoundaries(); i++ )
+    {
+      if( picHeader.getVirtualBoundariesPosY( i ) == posY )
+      {
+        topBry = posY;
+      }
+      else if( picHeader.getVirtualBoundariesPosY( i ) == posY + ctuSize )
+      {
+        botBry = posY + ctuSize;
+      }
+    }
+
+    for( int i = 0; i < picHeader.getNumVerVirtualBoundaries(); i++ )
+    {
+      if( picHeader.getVirtualBoundariesPosX( i ) == posX )
+      {
+        leftBry = posX;
+      }
+      else if( picHeader.getVirtualBoundariesPosX( i ) == posX + ctuSize )
+      {
+        rightBry = posX + ctuSize;
+      }
+    }
+  }
+#else
   if( pps.getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
   {
     for( int i = 0; i < pps.getNumHorVirtualBoundaries(); i++ )
@@ -179,8 +226,37 @@ void AdaptiveLoopFilter::getAlfBoundary( const CodingStructure& cs, int posX, in
       }
     }
   }
+#endif
 }
 
+#if JVET_P1006_PICTURE_HEADER
+bool AdaptiveLoopFilter::isCrossedByVirtualBoundaries( const CodingStructure& cs, const int xPos, const int yPos, const int width, const int height, int &topBry, int &botBry, int &leftBry, int &rightBry, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PicHeader* picHeader)
+{
+  numHorVirBndry = 0; numVerVirBndry = 0;
+  
+  if( picHeader->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
+  {
+    for( int i = 0; i < picHeader->getNumHorVirtualBoundaries(); i++ )
+    {
+      if( yPos < picHeader->getVirtualBoundariesPosY(i) && picHeader->getVirtualBoundariesPosY(i) < yPos + height )
+      {
+        horVirBndryPos[numHorVirBndry++] = picHeader->getVirtualBoundariesPosY(i);
+      }
+    }
+    for( int i = 0; i < picHeader->getNumVerVirtualBoundaries(); i++ )
+    {
+      if( xPos < picHeader->getVirtualBoundariesPosX(i) && picHeader->getVirtualBoundariesPosX(i) < xPos + width )
+      {
+        verVirBndryPos[numVerVirBndry++] = picHeader->getVirtualBoundariesPosX(i);
+      }
+    }
+  }
+
+  getAlfBoundary( cs, xPos, yPos, topBry, botBry, leftBry, rightBry );
+
+  return numHorVirBndry > 0 || numVerVirBndry > 0 || ( topBry != ALF_NONE_BOUNDARY ) || ( botBry != ALF_NONE_BOUNDARY ) || ( leftBry != ALF_NONE_BOUNDARY ) || ( rightBry != ALF_NONE_BOUNDARY );
+}
+#else
 bool AdaptiveLoopFilter::isCrossedByVirtualBoundaries( const CodingStructure& cs, const int xPos, const int yPos, const int width, const int height, int &topBry, int &botBry, int &leftBry, int &rightBry, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PPS* pps)
 {
   numHorVirBndry = 0; numVerVirBndry = 0;
@@ -207,6 +283,7 @@ bool AdaptiveLoopFilter::isCrossedByVirtualBoundaries( const CodingStructure& cs
 
   return numHorVirBndry > 0 || numVerVirBndry > 0 || ( topBry != ALF_NONE_BOUNDARY ) || ( botBry != ALF_NONE_BOUNDARY ) || ( leftBry != ALF_NONE_BOUNDARY ) || ( rightBry != ALF_NONE_BOUNDARY );
 }
+#endif
 #else
 bool AdaptiveLoopFilter::isCrossedByVirtualBoundaries( const int xPos, const int yPos, const int width, const int height, bool& clipTop, bool& clipBottom, bool& clipLeft, bool& clipRight, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PPS* pps)
 {
@@ -386,7 +463,11 @@ void AdaptiveLoopFilter::ALFProcess(CodingStructure& cs)
         ctuEnableFlag |= m_ctuEnableFlag[compIdx][ctuIdx] > 0;
       }
 #if JVET_O0625_ALF_PADDING
+#if JVET_P1006_PICTURE_HEADER
+      if( ctuEnableFlag && isCrossedByVirtualBoundaries( cs, xPos, yPos, width, height, alfBryList[0], alfBryList[1], alfBryList[2], alfBryList[3], numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.picHeader ) )
+#else
       if( ctuEnableFlag && isCrossedByVirtualBoundaries( cs, xPos, yPos, width, height, alfBryList[0], alfBryList[1], alfBryList[2], alfBryList[3], numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS() ) )
+#endif
 #else
       if( ctuEnableFlag && isCrossedByVirtualBoundaries( xPos, yPos, width, height, clipTop, clipBottom, clipLeft, clipRight, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS() ) )
 #endif
diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.h b/source/Lib/CommonLib/AdaptiveLoopFilter.h
index 42ab5bf3d..71d114520 100644
--- a/source/Lib/CommonLib/AdaptiveLoopFilter.h
+++ b/source/Lib/CommonLib/AdaptiveLoopFilter.h
@@ -145,10 +145,14 @@ public:
 #endif
 
 protected:
+#if JVET_P1006_PICTURE_HEADER
+  bool isCrossedByVirtualBoundaries( const CodingStructure& cs, const int xPos, const int yPos, const int width, const int height, int &topBry, int &botBry, int &leftBry, int &rightBry, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PicHeader* picHeader );
+#else
 #if JVET_O0625_ALF_PADDING
   bool isCrossedByVirtualBoundaries( const CodingStructure& cs, const int xPos, const int yPos, const int width, const int height, int &topBry, int &botBry, int &leftBry, int &rightBry, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PPS* pps );
 #else
   bool isCrossedByVirtualBoundaries( const int xPos, const int yPos, const int width, const int height, bool& clipTop, bool& clipBottom, bool& clipLeft, bool& clipRight, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PPS* pps );
+#endif
 #endif
   static const int             m_classToFilterMapping[NUM_FIXED_FILTER_SETS][MAX_NUM_ALF_CLASSES];
   static const int             m_fixedFilterSetCoeff[ALF_FIXED_FILTER_NUM][MAX_NUM_ALF_LUMA_COEFF];
diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp
index 93eb94142..c942c5828 100644
--- a/source/Lib/CommonLib/CodingStructure.cpp
+++ b/source/Lib/CommonLib/CodingStructure.cpp
@@ -1015,6 +1015,9 @@ void CodingStructure::initSubStructure( CodingStructure& subStruct, const Channe
   subStruct.sps       = sps;
   subStruct.vps       = vps;
   subStruct.pps       = pps;
+#if JVET_P1006_PICTURE_HEADER
+  subStruct.picHeader = picHeader;
+#endif
   memcpy(subStruct.alfApss, alfApss, sizeof(alfApss));
 
   subStruct.lmcsAps = lmcsAps;
diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h
index 643b0b8d3..d017a250b 100644
--- a/source/Lib/CommonLib/CodingStructure.h
+++ b/source/Lib/CommonLib/CodingStructure.h
@@ -92,6 +92,9 @@ public:
   bool        isLossless;
   const SPS *sps;
   const PPS *pps;
+#if JVET_P1006_PICTURE_HEADER
+  PicHeader *picHeader;
+#endif
   APS*       alfApss[ALF_CTB_MAX_NUM_APS];
   APS *      lmcsAps;
   APS *      scalinglistAps;
diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index 1732b46ea..365e8f6d2 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -285,6 +285,9 @@ static const int LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS_SIGNAL = 1 << MV
 static const int LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS = 1 << MV_FRACTIONAL_BITS_INTERNAL;
 static const int CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS = 1 << (MV_FRACTIONAL_BITS_INTERNAL + 1);
 
+#if JVET_P1006_PICTURE_HEADER
+static const int MAX_NUM_SUB_PICS =                               255;
+#endif
 static const int MAX_NUM_LONG_TERM_REF_PICS =                      33;
 static const int NUM_LONG_TERM_REF_PIC_SPS =                        0;
 
diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp
index 5a54b4bf7..f1cad5688 100644
--- a/source/Lib/CommonLib/ContextModelling.cpp
+++ b/source/Lib/CommonLib/ContextModelling.cpp
@@ -372,7 +372,11 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx)
   fPosStep = tempIdx / 4;
   fPosPosition = tempIdx - fPosStep * (4);
   int offset = refMvdCands[fPosStep];
+#if JVET_P1006_PICTURE_HEADER
+  if ( pu.cu->slice->getPicHeader()->getDisFracMMVD() )
+#else
   if ( pu.cu->slice->getDisFracMMVD() )
+#endif
   {
     offset <<= 2;
   }
diff --git a/source/Lib/CommonLib/DepQuant.cpp b/source/Lib/CommonLib/DepQuant.cpp
index c63ef3adf..9c30646d4 100644
--- a/source/Lib/CommonLib/DepQuant.cpp
+++ b/source/Lib/CommonLib/DepQuant.cpp
@@ -1618,7 +1618,11 @@ DepQuant::~DepQuant()
 void DepQuant::quant( TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &pSrc, TCoeff &uiAbsSum, const QpParam &cQP, const Ctx& ctx )
 {
 #if JVET_P0058_CHROMA_TS
+#if JVET_P1006_PICTURE_HEADER
+  if ( tu.cs->picHeader->getDepQuantEnabledFlag() && (tu.mtsIdx[compID] != MTS_SKIP) )
+#else
   if ( tu.cs->slice->getDepQuantEnabledFlag() && (tu.mtsIdx[compID] != MTS_SKIP) )
+#endif
 #else
 #if JVET_P0059_CHROMA_BDPCM
   if ((tu.cs->slice->getDepQuantEnabledFlag() && (tu.mtsIdx != MTS_SKIP || !isLuma(compID))) && 
@@ -1650,14 +1654,22 @@ void DepQuant::quant( TransformUnit &tu, const ComponentID &compID, const CCoeff
     const uint32_t    log2TrHeight    = floorLog2(height);
 #if JVET_P0058_CHROMA_TS
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+    const bool        disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
     const bool        disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
     const bool        enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx[compID] == MTS_SKIP), tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
     const bool        enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx[compID] == MTS_SKIP));
 #endif
 #else
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+    const bool        disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
     const bool        disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
     const bool        enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx == MTS_SKIP && isLuma(compID)), tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
     const bool        enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx == MTS_SKIP && isLuma(compID)));
@@ -1674,7 +1686,11 @@ void DepQuant::quant( TransformUnit &tu, const ComponentID &compID, const CCoeff
 void DepQuant::dequant( const TransformUnit &tu, CoeffBuf &dstCoeff, const ComponentID &compID, const QpParam &cQP )
 {
 #if JVET_P0058_CHROMA_TS
+#if JVET_P1006_PICTURE_HEADER
+  if( tu.cs->picHeader->getDepQuantEnabledFlag() && (tu.mtsIdx[compID] != MTS_SKIP))
+#else
   if( tu.cs->slice->getDepQuantEnabledFlag() && (tu.mtsIdx[compID] != MTS_SKIP))
+#endif
 #else
 #if JVET_P0059_CHROMA_BDPCM
   if ((tu.cs->slice->getDepQuantEnabledFlag() && (tu.mtsIdx != MTS_SKIP || !isLuma(compID))) && 
@@ -1705,14 +1721,22 @@ void DepQuant::dequant( const TransformUnit &tu, CoeffBuf &dstCoeff, const Compo
     const uint32_t    log2TrHeight = floorLog2(height);
 #if JVET_P0058_CHROMA_TS
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+    const bool disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
     const bool disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
     const bool enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx[compID] == MTS_SKIP), tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
     const bool enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx[compID] == MTS_SKIP));
 #endif
 #else
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+    const bool disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
     const bool disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
     const bool enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx == MTS_SKIP && isLuma(compID)), tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
     const bool enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx == MTS_SKIP && isLuma(compID)));
diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index e5f4322c9..da35d1054 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -492,7 +492,11 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred, Pe
   pu.cs->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
 
   bool bioApplied = false;
+#if JVET_P1006_PICTURE_HEADER
+  if (pu.cs->sps->getBDOFEnabledFlag() && (!pu.cs->picHeader->getDisBdofDmvrFlag()))
+#else
   if (pu.cs->sps->getBDOFEnabledFlag() && (!pu.cs->slice->getDisBdofDmvrFlag()))
+#endif
   {
     if (pu.cu->affine || m_subPuMC)
     {
@@ -1812,7 +1816,11 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
     pu.cs->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
     bool bioApplied = false;
     const Slice &slice = *pu.cs->slice;
+#if JVET_P1006_PICTURE_HEADER
+    if (pu.cs->sps->getBDOFEnabledFlag() && (!pu.cs->picHeader->getDisBdofDmvrFlag()))
+#else
     if (pu.cs->sps->getBDOFEnabledFlag() && (!pu.cs->slice->getDisBdofDmvrFlag()))
+#endif
     {
 
       if (pu.cu->affine || m_subPuMC)
diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/LoopFilter.cpp
index 64966452b..c75c3dff8 100644
--- a/source/Lib/CommonLib/LoopFilter.cpp
+++ b/source/Lib/CommonLib/LoopFilter.cpp
@@ -268,7 +268,11 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
   int  horVirBndryPos[] = { 0, 0, 0 };
   int  verVirBndryPos[] = { 0, 0, 0 };
 
+#if JVET_P1006_PICTURE_HEADER
+  bool isCuCrossedByVirtualBoundaries = isCrossedByVirtualBoundaries( area.x, area.y, area.width, area.height, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cu.cs->picHeader );
+#else
   bool isCuCrossedByVirtualBoundaries = isCrossedByVirtualBoundaries( area.x, area.y, area.width, area.height, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cu.cs->slice->getPPS() );
+#endif
 
   xSetLoopfilterParam( cu );
   static_vector<int, 2*MAX_CU_SIZE> edgeIdx;
@@ -407,6 +411,30 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
   }
 }
 
+#if JVET_P1006_PICTURE_HEADER
+inline bool LoopFilter::isCrossedByVirtualBoundaries(const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PicHeader* picHeader )
+{
+  numHorVirBndry = 0; numVerVirBndry = 0;
+  if (picHeader->getLoopFilterAcrossVirtualBoundariesDisabledFlag())
+  {
+    for (int i = 0; i < picHeader->getNumHorVirtualBoundaries(); i++)
+    {
+      if (yPos <= picHeader->getVirtualBoundariesPosY(i) && picHeader->getVirtualBoundariesPosY(i) < yPos + height)
+      {
+        horVirBndryPos[numHorVirBndry++] = picHeader->getVirtualBoundariesPosY(i);
+      }
+    }
+    for (int i = 0; i < picHeader->getNumVerVirtualBoundaries(); i++)
+    {
+      if (xPos <= picHeader->getVirtualBoundariesPosX(i) && picHeader->getVirtualBoundariesPosX(i) < xPos + width)
+      {
+        verVirBndryPos[numVerVirBndry++] = picHeader->getVirtualBoundariesPosX(i);
+      }
+    }
+  }
+  return numHorVirBndry > 0 || numVerVirBndry > 0;
+}
+#else
 inline bool LoopFilter::isCrossedByVirtualBoundaries(const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PPS* pps)
 {
   numHorVirBndry = 0; numVerVirBndry = 0;
@@ -429,6 +457,7 @@ inline bool LoopFilter::isCrossedByVirtualBoundaries(const int xPos, const int y
   }
   return numHorVirBndry > 0 || numVerVirBndry > 0;
 }
+#endif
 
 inline void LoopFilter::xDeriveEdgefilterParam( const int xPos, const int yPos, const int numVerVirBndry, const int numHorVirBndry, const int verVirBndryPos[], const int horVirBndryPos[], bool &verEdgeFilter, bool &horEdgeFilter )
 {
@@ -671,8 +700,13 @@ void LoopFilter::xSetLoopfilterParam( const CodingUnit& cu )
   const Position& pos = cu.blocks[cu.chType].pos();
 
   m_stLFCUParam.internalEdge = true;
+#if JVET_P1006_PICTURE_HEADER
+  m_stLFCUParam.leftEdge     = ( 0 < pos.x ) && isAvailableLeft ( cu, *cu.cs->getCU( pos.offset( -1,  0 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag() );
+  m_stLFCUParam.topEdge      = ( 0 < pos.y ) && isAvailableAbove( cu, *cu.cs->getCU( pos.offset(  0, -1 ), cu.chType ), !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag() );
+#else
   m_stLFCUParam.leftEdge     = ( 0 < pos.x ) && isAvailableLeft ( cu, *cu.cs->getCU( pos.offset( -1,  0 ), cu.chType ), !slice.getLFCrossSliceBoundaryFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag() );
   m_stLFCUParam.topEdge      = ( 0 < pos.y ) && isAvailableAbove( cu, *cu.cs->getCU( pos.offset(  0, -1 ), cu.chType ), !slice.getLFCrossSliceBoundaryFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag() );
+#endif
 }
 
 unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const DeblockEdgeDir edgeDir, const Position& localPos ) const
@@ -938,7 +972,11 @@ void LoopFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edg
       // Derive neighboring PU index
       if (edgeDir == EDGE_VER)
       {
+#if JVET_P1006_PICTURE_HEADER
+        if (!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag()))
+#else
         if (!isAvailableLeft(cu, cuP, !slice.getLFCrossSliceBoundaryFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag()))
+#endif
         {
           m_aapucBS[edgeDir][uiBsAbsIdx] = uiBs = 0;
           continue;
@@ -946,7 +984,11 @@ void LoopFilter::xEdgeFilterLuma( const CodingUnit& cu, const DeblockEdgeDir edg
       }
       else  // (iDir == EDGE_HOR)
       {
+#if JVET_P1006_PICTURE_HEADER
+        if (!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag()))
+#else
         if (!isAvailableAbove(cu, cuP, !slice.getLFCrossSliceBoundaryFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag()))
+#endif
         {
           m_aapucBS[edgeDir][uiBsAbsIdx] = uiBs = 0;
           continue;
@@ -1213,11 +1255,19 @@ void LoopFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir ed
 
       if (edgeDir == EDGE_VER)
       {
+#if JVET_P1006_PICTURE_HEADER
+        CHECK(!isAvailableLeft(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag()), "Neighbour not available");
+#else
         CHECK(!isAvailableLeft(cu, cuP, !slice.getLFCrossSliceBoundaryFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag()), "Neighbour not available");
+#endif
       }
       else  // (iDir == EDGE_HOR)
       {
+#if JVET_P1006_PICTURE_HEADER
+        CHECK(!isAvailableAbove(cu, cuP, !pps.getLoopFilterAcrossSlicesEnabledFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag()), "Neighbour not available");
+#else
         CHECK(!isAvailableAbove(cu, cuP, !slice.getLFCrossSliceBoundaryFlag(), !pps.getLoopFilterAcrossBricksEnabledFlag()), "Neighbour not available");
+#endif
       }
 
       bPartPNoFilter = bPartQNoFilter = false;
diff --git a/source/Lib/CommonLib/LoopFilter.h b/source/Lib/CommonLib/LoopFilter.h
index 4191d7146..ed88c34bb 100644
--- a/source/Lib/CommonLib/LoopFilter.h
+++ b/source/Lib/CommonLib/LoopFilter.h
@@ -104,7 +104,11 @@ private:
   inline unsigned BsSet(unsigned val, const ComponentID compIdx) const;
   inline unsigned BsGet(unsigned val, const ComponentID compIdx) const;
 
+#if JVET_P1006_PICTURE_HEADER
+  inline bool isCrossedByVirtualBoundaries ( const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PicHeader* picHeader );
+#else
   inline bool isCrossedByVirtualBoundaries ( const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PPS* pps );
+#endif
   inline void xDeriveEdgefilterParam       ( const int xPos, const int yPos, const int numVerVirBndry, const int numHorVirBndry, const int verVirBndryPos[], const int horVirBndryPos[], bool &verEdgeFilter, bool &horEdgeFilter );
 
 #if  JVET_P0081_CHROMA_LONG_DEBLOCKING_FIX
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index b362b378c..8fbb337ca 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -953,7 +953,11 @@ const CPelUnitBuf Picture::getRecoBuf(const UnitArea &unit, bool wrap)     const
        PelUnitBuf Picture::getRecoBuf(bool wrap)                                 { return M_BUFS(scheduler.getSplitPicId(), wrap ? PIC_RECON_WRAP : PIC_RECONSTRUCTION); }
 const CPelUnitBuf Picture::getRecoBuf(bool wrap)                           const { return M_BUFS(scheduler.getSplitPicId(), wrap ? PIC_RECON_WRAP : PIC_RECONSTRUCTION); }
 
+#if JVET_P1006_PICTURE_HEADER
+void Picture::finalInit( const SPS& sps, const PPS& pps, PicHeader* picHeader, APS** alfApss, APS* lmcsAps, APS* scalingListAps )
+#else
 void Picture::finalInit( const SPS& sps, const PPS& pps, APS** alfApss, APS* lmcsAps, APS* scalingListAps )
+#endif
 {
   for( auto &sei : SEIs )
   {
@@ -987,6 +991,11 @@ void Picture::finalInit( const SPS& sps, const PPS& pps, APS** alfApss, APS* lmc
   cs->picture = this;
   cs->slice   = nullptr;  // the slices for this picture have not been set at this point. update cs->slice after swapSliceObject()
   cs->pps     = &pps;
+#if JVET_P1006_PICTURE_HEADER
+  picHeader->setSPSId( sps.getSPSId() );
+  picHeader->setPPSId( pps.getPPSId() );
+  cs->picHeader = picHeader;
+#endif
   memcpy(cs->alfApss, alfApss, sizeof(cs->alfApss));
   cs->lmcsAps = lmcsAps;
   cs->scalinglistAps = scalingListAps;
@@ -1009,8 +1018,10 @@ void Picture::allocateNewSlice()
   Slice& slice = *slices.back();
   memcpy(slice.getAlfAPSs(), cs->alfApss, sizeof(cs->alfApss));
 
+#if !JVET_P1006_PICTURE_HEADER
   slice.setLmcsAPS(cs->lmcsAps);
   slice.setscalingListAPS( cs->scalinglistAps );
+#endif
 
   slice.setPPS( cs->pps);
   slice.setSPS( cs->sps);
@@ -1027,10 +1038,12 @@ Slice *Picture::swapSliceObject(Slice * p, uint32_t i)
   p->setPPS(cs->pps);
   p->setAlfAPSs(cs->alfApss);
 
+#if !JVET_P1006_PICTURE_HEADER
   if(cs->lmcsAps != nullptr)
     p->setLmcsAPS(cs->lmcsAps);
   if(cs->scalinglistAps != nullptr)
     p->setscalingListAPS( cs->scalinglistAps );
+#endif
 
   Slice * pTmp = slices[i];
   slices[i] = p;
@@ -1038,8 +1051,10 @@ Slice *Picture::swapSliceObject(Slice * p, uint32_t i)
   pTmp->setPPS(0);
   memset(pTmp->getAlfAPSs(), 0, sizeof(*pTmp->getAlfAPSs())*ALF_CTB_MAX_NUM_APS);
 
+#if !JVET_P1006_PICTURE_HEADER
   pTmp->setLmcsAPS(0);
   pTmp->setscalingListAPS( 0 );
+#endif
   return pTmp;
 }
 
diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h
index 57c1c4282..b9ad71b07 100644
--- a/source/Lib/CommonLib/Picture.h
+++ b/source/Lib/CommonLib/Picture.h
@@ -247,7 +247,11 @@ struct Picture : public UnitArea
   const CPelUnitBuf getBuf(const UnitArea &unit,     const PictureType &type) const;
 
   void extendPicBorder();
+#if JVET_P1006_PICTURE_HEADER
+  void finalInit( const SPS& sps, const PPS& pps, PicHeader *picHeader, APS** alfApss, APS* lmcsAps, APS* scalingListAps );
+#else
   void finalInit( const SPS& sps, const PPS& pps, APS** alfApss, APS* lmcsAps, APS* scalingListAps );
+#endif
 
   int  getPOC()                               const { return poc; }
   void setBorderExtension( bool bFlag)              { m_bIsBorderExtended = bFlag;}
diff --git a/source/Lib/CommonLib/Quant.cpp b/source/Lib/CommonLib/Quant.cpp
index 1693a64be..27eb90af5 100644
--- a/source/Lib/CommonLib/Quant.cpp
+++ b/source/Lib/CommonLib/Quant.cpp
@@ -384,7 +384,11 @@ void Quant::dequant(const TransformUnit &tu,
 #endif
 
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+  const bool            disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
   const bool            disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
   const bool            enableScalingLists = getUseScalingList(uiWidth, uiHeight, isTransformSkip, tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
   const bool            enableScalingLists = getUseScalingList(uiWidth, uiHeight, isTransformSkip);
@@ -1074,7 +1078,11 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
   const int  maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange(toChannelType(compID));
 
   {
+#if JVET_P1006_PICTURE_HEADER
+    CoeffCodingContext cctx(tu, compID, tu.cs->picHeader->getSignDataHidingEnabledFlag());
+#else
     CoeffCodingContext cctx(tu, compID, tu.cs->slice->getSignDataHidingEnabledFlag());
+#endif
 
     const TCoeff entropyCodingMinimum = -(1 << maxLog2TrDynamicRange);
     const TCoeff entropyCodingMaximum =  (1 << maxLog2TrDynamicRange) - 1;
@@ -1085,9 +1093,13 @@ void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf
     const uint32_t uiLog2TrWidth = floorLog2(uiWidth);
     const uint32_t uiLog2TrHeight = floorLog2(uiHeight);
     int *piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem(useTransformSkip), uiLog2TrWidth, uiLog2TrHeight);
-    
+
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+    const bool disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
     const bool disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
     const bool enableScalingLists = getUseScalingList(uiWidth, uiHeight, useTransformSkip, tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
     const bool enableScalingLists             = getUseScalingList(uiWidth, uiHeight, useTransformSkip);
@@ -1175,9 +1187,13 @@ bool Quant::xNeedRDOQ(TransformUnit &tu, const ComponentID &compID, const CCoeff
   const uint32_t uiLog2TrWidth  = floorLog2(uiWidth);
   const uint32_t uiLog2TrHeight = floorLog2(uiHeight);
   int *piQuantCoeff         = getQuantCoeff(scalingListType, cQP.rem(useTransformSkip), uiLog2TrWidth, uiLog2TrHeight);
-  
+
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+  const bool disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
   const bool disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
   const bool enableScalingLists = getUseScalingList(uiWidth, uiHeight, (useTransformSkip != 0), tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
   const bool enableScalingLists             = getUseScalingList(uiWidth, uiHeight, (useTransformSkip != 0));
@@ -1231,7 +1247,11 @@ void Quant::transformSkipQuantOneSample(TransformUnit &tu, const ComponentID &co
   const int            iTransformShift                = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange);
   const int            scalingListType                = getScalingListType(tu.cu->predMode, compID);
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+  const bool           disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
   const bool           disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
   const bool           enableScalingLists = getUseScalingList(uiWidth, uiHeight, true, tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
   const bool           enableScalingLists             = getUseScalingList(uiWidth, uiHeight, true);
@@ -1313,7 +1333,11 @@ void Quant::invTrSkipDeQuantOneSample(TransformUnit &tu, const ComponentID &comp
   const int            iTransformShift        = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange);
   const int            scalingListType        = getScalingListType(tu.cu->predMode, compID);
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+  const bool           disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
   const bool           disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
   const bool           enableScalingLists = getUseScalingList(uiWidth, uiHeight, true, tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
   const bool           enableScalingLists     = getUseScalingList(uiWidth, uiHeight, true);
diff --git a/source/Lib/CommonLib/QuantRDOQ.cpp b/source/Lib/CommonLib/QuantRDOQ.cpp
index cc4c8ae6c..bc60e540b 100644
--- a/source/Lib/CommonLib/QuantRDOQ.cpp
+++ b/source/Lib/CommonLib/QuantRDOQ.cpp
@@ -668,7 +668,11 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
   const double *const pdErrScale = xGetErrScaleCoeffSL(scalingListType, uiLog2BlockWidth, uiLog2BlockHeight, cQP.rem(isTransformSkip));
   const int    *const piQCoef    = getQuantCoeff(scalingListType, cQP.rem(isTransformSkip), uiLog2BlockWidth, uiLog2BlockHeight);
 #if JVET_P0365_SCALING_MATRIX_LFNST
+#if JVET_P1006_PICTURE_HEADER
+  const bool   disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->picHeader->getScalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#else
   const bool   disableSMForLFNST = tu.cs->sps->getScalingListFlag() ? tu.cs->slice->getscalingListAPS()->getScalingList().getDisableScalingMatrixForLfnstBlks() : false;
+#endif
   const bool   enableScalingLists = getUseScalingList(uiWidth, uiHeight, isTransformSkip, tu.cu->lfnstIdx > 0, disableSMForLFNST);
 #else
   const bool   enableScalingLists             = getUseScalingList(uiWidth, uiHeight, isTransformSkip);
@@ -681,7 +685,11 @@ void QuantRDOQ::xRateDistOptQuant(TransformUnit &tu, const ComponentID &compID,
   const TCoeff entropyCodingMinimum = -(1 << maxLog2TrDynamicRange);
   const TCoeff entropyCodingMaximum =  (1 << maxLog2TrDynamicRange) - 1;
 
+#if JVET_P1006_PICTURE_HEADER
+  CoeffCodingContext cctx(tu, compID, tu.cs->picHeader->getSignDataHidingEnabledFlag());
+#else
   CoeffCodingContext cctx(tu, compID, tu.cs->slice->getSignDataHidingEnabledFlag());
+#endif
   const int    iCGSizeM1      = (1 << cctx.log2CGSize()) - 1;
 
   int     iCGLastScanPos      = -1;
@@ -1286,7 +1294,11 @@ void QuantRDOQ::xRateDistOptQuantTS( TransformUnit &tu, const ComponentID &compI
   uint32_t coeffLevels[3];
   double   coeffLevelError[4];
 
+#if JVET_P1006_PICTURE_HEADER
+  CoeffCodingContext cctx( tu, compID, tu.cs->picHeader->getSignDataHidingEnabledFlag() );
+#else
   CoeffCodingContext cctx( tu, compID, tu.cs->slice->getSignDataHidingEnabledFlag() );
+#endif
   const int sbSizeM1    = ( 1 << cctx.log2CGSize() ) - 1;
   double    baseCost    = 0;
   uint32_t  goRiceParam = 0;
@@ -1548,7 +1560,11 @@ void QuantRDOQ::forwardRDPCM( TransformUnit &tu, const ComponentID &compID, cons
   uint32_t coeffLevels[3];
   double   coeffLevelError[4];
 
+#if JVET_P1006_PICTURE_HEADER
+  CoeffCodingContext cctx(tu, compID, tu.cs->picHeader->getSignDataHidingEnabledFlag());
+#else
   CoeffCodingContext cctx(tu, compID, tu.cs->slice->getSignDataHidingEnabledFlag());
+#endif
   const int sbSizeM1 = (1 << cctx.log2CGSize()) - 1;
   double    baseCost = 0;
   uint32_t  goRiceParam = 0;
diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
index ee5d84fbb..eb5a89edc 100644
--- a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
+++ b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp
@@ -579,7 +579,11 @@ void SampleAdaptiveOffset::offsetCTU( const UnitArea& area, const CPelUnitBuf& s
   int verVirBndryPos[] = { -1,-1,-1 };
   int horVirBndryPosComp[] = { -1,-1,-1 };
   int verVirBndryPosComp[] = { -1,-1,-1 };
+#if JVET_P1006_PICTURE_HEADER
+  bool isCtuCrossedByVirtualBoundaries = isCrossedByVirtualBoundaries(area.Y().x, area.Y().y, area.Y().width, area.Y().height, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.picHeader );
+#else
   bool isCtuCrossedByVirtualBoundaries = isCrossedByVirtualBoundaries(area.Y().x, area.Y().y, area.Y().width, area.Y().height, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS());
+#endif
   for(int compIdx = 0; compIdx < numberOfComponents; compIdx++)
   {
     const ComponentID compID = ComponentID(compIdx);
@@ -733,7 +737,11 @@ void SampleAdaptiveOffset::xLosslessSampleRestoration(CodingUnit& cu, const Comp
              PelBuf dstBuf  = cu.cs->getRecoBuf( currTU.block(compID) );
 
       dstBuf.copyFrom( pcmBuf );
+#if JVET_P1006_PICTURE_HEADER
+      if (cu.slice->getPicHeader()->getLmcsEnabledFlag() && isLuma(compID))
+#else
       if (cu.slice->getLmcsEnabledFlag() && isLuma(compID))
+#endif
       {
         dstBuf.rspSignal(m_pcReshape->getInvLUT());
       }
@@ -768,6 +776,31 @@ void SampleAdaptiveOffset::deriveLoopFilterBoundaryAvailibility(CodingStructure&
   const CodingUnit* cuBelowRight = cs.getCU(pos.offset(width, height), CH_L);
 
   // check cross slice flags
+#if JVET_P1006_PICTURE_HEADER
+  const bool isLoopFilterAcrossSlicePPS = cs.pps->getLoopFilterAcrossSlicesEnabledFlag();
+  if (!isLoopFilterAcrossSlicePPS)
+  {
+    isLeftAvail       = (cuLeft == NULL)       ? false : CU::isSameSlice(*cuCurr, *cuLeft);
+    isAboveAvail      = (cuAbove == NULL)      ? false : CU::isSameSlice(*cuCurr, *cuAbove);
+    isRightAvail      = (cuRight == NULL)      ? false : CU::isSameSlice(*cuCurr, *cuRight);
+    isBelowAvail      = (cuBelow == NULL)      ? false : CU::isSameSlice(*cuCurr, *cuBelow);
+    isAboveLeftAvail  = (cuAboveLeft == NULL)  ? false : CU::isSameSlice(*cuCurr, *cuAboveLeft);
+    isAboveRightAvail = (cuAboveRight == NULL) ? false : CU::isSameSlice(*cuCurr, *cuAboveRight);
+    isBelowLeftAvail  = (cuBelowLeft == NULL)  ? false : CU::isSameSlice(*cuCurr, *cuBelowLeft);
+    isBelowRightAvail = (cuBelowRight == NULL) ? false : CU::isSameSlice(*cuCurr, *cuBelowRight);
+  }
+  else
+  {
+    isLeftAvail       = (cuLeft != NULL);
+    isAboveAvail      = (cuAbove != NULL);
+    isRightAvail      = (cuRight != NULL);
+    isBelowAvail      = (cuBelow != NULL);
+    isAboveLeftAvail  = (cuAboveLeft != NULL);
+    isAboveRightAvail = (cuAboveRight != NULL);
+    isBelowLeftAvail  = (cuBelowLeft != NULL);
+    isBelowRightAvail = (cuBelowRight != NULL);
+  }
+#else
   {
     //left
     isLeftAvail       = (cuLeft != NULL)       ? ( !CU::isSameSlice(*cuCurr, *cuLeft)       ? cuCurr->slice->getLFCrossSliceBoundaryFlag()       : true ) : false;
@@ -803,6 +836,7 @@ void SampleAdaptiveOffset::deriveLoopFilterBoundaryAvailibility(CodingStructure&
       isBelowLeftAvail = ( !CU::isSameSlice(*cuCurr, *cuBelowLeft) ) ? bLFCrossSliceBoundaryFlag : true;
     }
   }
+#endif
 
   // check cross tile flags
   const bool isLoopFilterAcrossTilePPS = cs.pps->getLoopFilterAcrossBricksEnabledFlag();
@@ -819,6 +853,30 @@ void SampleAdaptiveOffset::deriveLoopFilterBoundaryAvailibility(CodingStructure&
   }
 }
 
+#if JVET_P1006_PICTURE_HEADER
+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 )
+{
+  numHorVirBndry = 0; numVerVirBndry = 0;
+  if (picHeader->getLoopFilterAcrossVirtualBoundariesDisabledFlag())
+  {
+    for (int i = 0; i < picHeader->getNumHorVirtualBoundaries(); i++)
+    {
+     if (yPos <= picHeader->getVirtualBoundariesPosY(i) && picHeader->getVirtualBoundariesPosY(i) <= yPos + height)
+      {
+        horVirBndryPos[numHorVirBndry++] = picHeader->getVirtualBoundariesPosY(i);
+      }
+    }
+    for (int i = 0; i < picHeader->getNumVerVirtualBoundaries(); i++)
+    {
+      if (xPos <= picHeader->getVirtualBoundariesPosX(i) && picHeader->getVirtualBoundariesPosX(i) <= xPos + width)
+      {
+        verVirBndryPos[numVerVirBndry++] = picHeader->getVirtualBoundariesPosX(i);
+      }
+    }
+  }
+  return numHorVirBndry > 0 || numVerVirBndry > 0 ;
+}
+#else
 bool SampleAdaptiveOffset::isCrossedByVirtualBoundaries(const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PPS* pps)
 {
   numHorVirBndry = 0; numVerVirBndry = 0;
@@ -841,4 +899,5 @@ bool SampleAdaptiveOffset::isCrossedByVirtualBoundaries(const int xPos, const in
   }
   return numHorVirBndry > 0 || numVerVirBndry > 0 ;
 }
+#endif
 //! \}
diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.h b/source/Lib/CommonLib/SampleAdaptiveOffset.h
index e3e75f399..93b6fc384 100644
--- a/source/Lib/CommonLib/SampleAdaptiveOffset.h
+++ b/source/Lib/CommonLib/SampleAdaptiveOffset.h
@@ -95,7 +95,11 @@ protected:
   void xLosslessCURestoration(CodingStructure& cs, const UnitArea &ctuArea);
   void xLosslessSampleRestoration(CodingUnit& cu, const ComponentID compID);
   void xReconstructBlkSAOParams(CodingStructure& cs, SAOBlkParam* saoBlkParams);
+#if JVET_P1006_PICTURE_HEADER
+  bool isCrossedByVirtualBoundaries(const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PicHeader* picHeader);
+#else
   bool isCrossedByVirtualBoundaries(const int xPos, const int yPos, const int width, const int height, int& numHorVirBndry, int& numVerVirBndry, int horVirBndryPos[], int verVirBndryPos[], const PPS* pps);
+#endif
   inline bool isProcessDisabled(int xPos, int yPos, int numVerVirBndry, int numHorVirBndry, int verVirBndryPos[], int horVirBndryPos[])
   {
     bool bDisabledFlag = false;
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 8629d4c1d..a09e25920 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -47,9 +47,13 @@
 //! \{
 
 Slice::Slice()
+#if !JVET_P1006_PICTURE_HEADER
 : m_iPPSId                        ( -1 )
 , m_PicOutputFlag                 ( true )
 , m_iPOC                          ( 0 )
+#else
+: m_iPOC                          ( 0 )
+#endif
 , m_iLastIDR                      ( 0 )
 , m_iAssociatedIRAP               ( 0 )
 , m_iAssociatedIRAPType           ( NAL_UNIT_INVALID )
@@ -58,14 +62,18 @@ Slice::Slice()
 , m_eNalUnitType                  ( NAL_UNIT_CODED_SLICE_IDR_W_RADL )
 , m_eSliceType                    ( I_SLICE )
 , m_iSliceQp                      ( 0 )
+#if !JVET_P1006_PICTURE_HEADER
 , m_ChromaQpAdjEnabled            ( false )
+#endif
 , m_deblockingFilterDisable       ( false )
 , m_deblockingFilterOverrideFlag  ( false )
 , m_deblockingFilterBetaOffsetDiv2( 0 )
 , m_deblockingFilterTcOffsetDiv2  ( 0 )
 , m_pendingRasInit                ( false )
+#if !JVET_P1006_PICTURE_HEADER
 , m_depQuantEnabledFlag           ( false )
 , m_signDataHidingEnabledFlag     ( false )
+#endif
 , m_bCheckLDC                     ( false )
 , m_biDirPred                    ( false )
 , m_iSliceQpDelta                 ( 0 )
@@ -75,16 +83,20 @@ Slice::Slice()
 , m_pcPPS                         ( NULL )
 , m_pcPic                         ( NULL )
 , m_colFromL0Flag                 ( true )
+#if !JVET_P1006_PICTURE_HEADER
 , m_noOutputPriorPicsFlag         ( false )
+#endif
 , m_noIncorrectPicOutputFlag      ( false )
 , m_handleCraAsCvsStartFlag            ( false )
 , m_colRefIdx                     ( 0 )
+#if !JVET_P1006_PICTURE_HEADER
 , m_maxNumMergeCand               ( 0 )
 , m_maxNumAffineMergeCand         ( 0 )
 , m_maxNumTriangleCand            ( 0 )
 , m_maxNumIBCMergeCand            ( 0 )
 , m_disFracMMVD                   ( false )
 , m_disBdofDmvrFlag               ( false )
+#endif
 , m_uiTLayer                      ( 0 )
 , m_bTLayerSwitchingFlag          ( false )
 , m_sliceMode                     ( NO_SLICES )
@@ -103,13 +115,16 @@ Slice::Slice()
 , m_bTestWeightBiPred             ( false )
 , m_substreamSizes                ( )
 , m_cabacInitFlag                 ( false )
+#if !JVET_P1006_PICTURE_HEADER
 , m_jointCbCrSignFlag             ( false )
 , m_bLMvdL1Zero                   ( false )
 , m_LFCrossSliceBoundaryFlag      ( false )
 , m_enableTMVPFlag                ( true )
+#endif
 , m_encCABACTableIdx              (I_SLICE)
 , m_iProcessingStartTime          ( 0 )
 , m_dProcessingTime               ( 0 )
+#if !JVET_P1006_PICTURE_HEADER
 , m_splitConsOverrideFlag         ( false )
 , m_uiMinQTSize                   ( 0 )
 , m_uiMaxMTTHierarchyDepth                  ( 0 )
@@ -127,6 +142,7 @@ Slice::Slice()
 , m_scalingListAps               ( nullptr )
 , m_tileGroupscalingListPresentFlag ( false )
 , m_nonReferencePicFlag          ( 0 )
+#endif
 {
   for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
   {
@@ -195,18 +211,24 @@ void Slice::initSlice()
   }
   m_iSliceChromaQpDelta[JOINT_CbCr] = 0;
 
+#if !JVET_P1006_PICTURE_HEADER
   m_maxNumMergeCand = MRG_MAX_NUM_CANDS;
   m_maxNumAffineMergeCand = AFFINE_MRG_MAX_NUM_CANDS;
   m_maxNumIBCMergeCand = IBC_MRG_MAX_NUM_CANDS;
+#endif
 
   m_bFinalized=false;
 
+#if !JVET_P1006_PICTURE_HEADER
   m_disFracMMVD          = false;
   m_disBdofDmvrFlag      = false;
+#endif
   m_substreamSizes.clear();
   m_cabacInitFlag        = false;
+#if !JVET_P1006_PICTURE_HEADER
   m_jointCbCrSignFlag    = false;
   m_enableTMVPFlag       = true;
+#endif
   m_enableDRAPSEI        = false;
   m_useLTforDRAP         = false;
   m_isDRAP               = false;
@@ -214,6 +236,50 @@ void Slice::initSlice()
   resetTileGroupAlfEnabledFlag();
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void Slice::inheritFromPicHeader( PicHeader *picHeader, const PPS *pps, const SPS *sps )
+{ 
+  if(picHeader->getPicRplPresentFlag())
+  {
+    setRPL0idx( picHeader->getRPL0idx() );
+    *getLocalRPL0() = *picHeader->getLocalRPL0();
+    if(getRPL0idx() != -1)
+    {
+      setRPL0(sps->getRPLList0()->getReferencePictureList(getRPL0idx()));
+    }
+    else
+    {
+      setRPL0(getLocalRPL0());
+    }
+    
+    setRPL1idx( picHeader->getRPL1idx() );
+    *getLocalRPL1() = *picHeader->getLocalRPL1();
+    if(getRPL1idx() != -1)
+    {
+      setRPL1(sps->getRPLList1()->getReferencePictureList(getRPL1idx()));
+    }
+    else
+    {
+      setRPL1(getLocalRPL1());
+    }
+  }
+
+  setDeblockingFilterDisable( picHeader->getDeblockingFilterDisable() );
+  setDeblockingFilterBetaOffsetDiv2( picHeader->getDeblockingFilterBetaOffsetDiv2() );
+  setDeblockingFilterTcOffsetDiv2( picHeader->getDeblockingFilterTcOffsetDiv2() );
+
+  setSaoEnabledFlag(CHANNEL_TYPE_LUMA,     picHeader->getSaoEnabledFlag(CHANNEL_TYPE_LUMA));
+  setSaoEnabledFlag(CHANNEL_TYPE_CHROMA,   picHeader->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA));
+
+  setTileGroupAlfEnabledFlag(COMPONENT_Y,  picHeader->getAlfEnabledFlag(COMPONENT_Y));
+  setTileGroupAlfEnabledFlag(COMPONENT_Cb, picHeader->getAlfEnabledFlag(COMPONENT_Cb));
+  setTileGroupAlfEnabledFlag(COMPONENT_Cr, picHeader->getAlfEnabledFlag(COMPONENT_Cr));
+  setTileGroupNumAps(picHeader->getNumAlfAps());
+  setAlfAPSs(picHeader->getAlfAPSs());
+  setTileGroupApsIdChroma(picHeader->getAlfApsIdChroma());   
+}
+
+#endif
 void Slice::setDefaultClpRng( const SPS& sps )
 {
   m_clpRngs.comp[COMPONENT_Y].min = m_clpRngs.comp[COMPONENT_Cb].min  = m_clpRngs.comp[COMPONENT_Cr].min = 0;
@@ -703,7 +769,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   m_eSliceType           = pSrc->m_eSliceType;
   m_iSliceQp             = pSrc->m_iSliceQp;
   m_iSliceQpBase         = pSrc->m_iSliceQpBase;
+#if !JVET_P1006_PICTURE_HEADER
   m_ChromaQpAdjEnabled              = pSrc->m_ChromaQpAdjEnabled;
+#endif
   m_deblockingFilterDisable         = pSrc->m_deblockingFilterDisable;
   m_deblockingFilterOverrideFlag    = pSrc->m_deblockingFilterOverrideFlag;
   m_deblockingFilterBetaOffsetDiv2  = pSrc->m_deblockingFilterBetaOffsetDiv2;
@@ -793,7 +861,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   }
 
   m_cabacInitFlag                 = pSrc->m_cabacInitFlag;
+#if !JVET_P1006_PICTURE_HEADER
   m_jointCbCrSignFlag             = pSrc->m_jointCbCrSignFlag;
+#endif
   memcpy(m_alfApss, pSrc->m_alfApss, sizeof(m_alfApss)); // this might be quite unsafe
   memcpy( m_tileGroupAlfEnabledFlag, pSrc->m_tileGroupAlfEnabledFlag, sizeof(m_tileGroupAlfEnabledFlag));
   m_tileGroupNumAps               = pSrc->m_tileGroupNumAps;
@@ -801,6 +871,7 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   m_tileGroupChromaApsId          = pSrc->m_tileGroupChromaApsId;
   m_disableSATDForRd              = pSrc->m_disableSATDForRd;
 
+#if !JVET_P1006_PICTURE_HEADER
   m_bLMvdL1Zero                   = pSrc->m_bLMvdL1Zero;
   m_LFCrossSliceBoundaryFlag      = pSrc->m_LFCrossSliceBoundaryFlag;
   m_enableTMVPFlag                = pSrc->m_enableTMVPFlag;
@@ -810,7 +881,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   m_maxNumIBCMergeCand            = pSrc->m_maxNumIBCMergeCand;
   m_disFracMMVD                   = pSrc->m_disFracMMVD;
   m_disBdofDmvrFlag               = pSrc->m_disBdofDmvrFlag;
+#endif
   if( cpyAlmostAll ) m_encCABACTableIdx  = pSrc->m_encCABACTableIdx;
+#if !JVET_P1006_PICTURE_HEADER
   m_splitConsOverrideFlag         = pSrc->m_splitConsOverrideFlag;
   m_uiMinQTSize                   = pSrc->m_uiMinQTSize;
   m_uiMaxMTTHierarchyDepth                  = pSrc->m_uiMaxMTTHierarchyDepth;
@@ -832,6 +905,7 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   m_tileGroupscalingListPresentFlag = pSrc->m_tileGroupscalingListPresentFlag;
   m_scalingListAps                  = pSrc->m_scalingListAps;
   m_scalingListApsId                = pSrc->m_scalingListApsId;
+#endif
   for( int i = 0; i < NUM_REF_PIC_LIST_01; i ++ )
   {
     for (int j = 0; j < MAX_NUM_REF_PICS; j ++ )
@@ -941,7 +1015,11 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic) const
     // Any picture that has PicOutputFlag equal to 1 that precedes an IRAP picture
     // in decoding order shall precede the IRAP picture in output order.
     // (Note that any picture following in output order would be present in the DPB)
+#if JVET_P1006_PICTURE_HEADER
+    if(pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getPicHeader()->getNoOutputOfPriorPicsFlag())
+#else
     if(pcSlice->getPicOutputFlag() == 1 && !this->getNoOutputPriorPicsFlag())
+#endif
     {
       if (nalUnitType == NAL_UNIT_CODED_SLICE_CRA ||
           nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP ||
@@ -954,7 +1032,11 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic) const
     // Any picture that has PicOutputFlag equal to 1 that precedes an IRAP picture
     // in decoding order shall precede any RADL picture associated with the IRAP
     // picture in output order.
+#if JVET_P1006_PICTURE_HEADER
+    if(pcSlice->getPicHeader()->getPicOutputFlag() == 1)
+#else
     if(pcSlice->getPicOutputFlag() == 1)
+#endif
     {
       if (nalUnitType == NAL_UNIT_CODED_SLICE_RADL)
       {
@@ -1681,6 +1763,173 @@ VPS::~VPS()
 {
 }
 
+#if JVET_P1006_PICTURE_HEADER
+// ------------------------------------------------------------------------------------------------
+// Picture Header
+// ------------------------------------------------------------------------------------------------
+
+PicHeader::PicHeader()
+: m_valid                                         ( 0 )
+, m_nonReferencePictureFlag                       ( 0 )
+, m_gdrPicFlag                                    ( 0 )
+, m_noOutputOfPriorPicsFlag                       ( 0 )
+, m_recoveryPocCnt                                ( 0 )
+, m_spsId                                         ( -1 )
+, m_ppsId                                         ( -1 )
+, m_subPicIdSignallingPresentFlag                 ( 0 )
+, m_subPicIdLen                                   ( 0 )
+, m_loopFilterAcrossVirtualBoundariesDisabledFlag ( 0 )
+, m_numVerVirtualBoundaries                       ( 0 )
+, m_numHorVirtualBoundaries                       ( 0 )
+, m_colourPlaneId                                 ( 0 )
+, m_picOutputFlag                                 ( true )
+, m_picRplPresentFlag                             ( 0 )
+, m_pRPL0                                         ( 0 )
+, m_pRPL1                                         ( 0 )
+, m_rpl0Idx                                       ( 0 )
+, m_rpl1Idx                                       ( 0 )
+, m_splitConsOverrideFlag                         ( 0 )
+, m_cuQpDeltaSubdivIntra                          ( 0 )
+, m_cuQpDeltaSubdivInter                          ( 0 )
+, m_cuChromaQpOffsetSubdivIntra                   ( 0 )
+, m_cuChromaQpOffsetSubdivInter                   ( 0 )
+, m_enableTMVPFlag                                ( true )
+, m_mvdL1ZeroFlag                                 ( 0 )
+, m_maxNumMergeCand                               ( MRG_MAX_NUM_CANDS )
+, m_maxNumAffineMergeCand                         ( AFFINE_MRG_MAX_NUM_CANDS )
+, m_disFracMMVD                                   ( 0 )
+, m_disBdofDmvrFlag                               ( 0 )
+, m_maxNumTriangleCand                            ( 0 )
+, m_maxNumIBCMergeCand                            ( IBC_MRG_MAX_NUM_CANDS )
+, m_jointCbCrSignFlag                             ( 0 )
+, m_saoEnabledPresentFlag                         ( 0 )
+, m_alfEnabledPresentFlag                         ( 0 )
+, m_numAlfAps                                     ( 0 )
+, m_alfApsId                                      ( 0 )
+, m_alfChromaApsId                                ( 0 )
+, m_depQuantEnabledFlag                           ( 0 )
+, m_signDataHidingEnabledFlag                     ( 0 )
+, m_deblockingFilterOverridePresentFlag           ( 0 )
+, m_deblockingFilterOverrideFlag                  ( 0 )
+, m_deblockingFilterDisable                       ( 0 )
+, m_deblockingFilterBetaOffsetDiv2                ( 0 )
+, m_deblockingFilterTcOffsetDiv2                  ( 0 )
+, m_lmcsEnabledFlag                               ( 0 )
+, m_lmcsApsId                                     ( -1 )
+, m_lmcsAps                                       ( nullptr )
+, m_lmcsChromaResidualScaleFlag                   ( 0 )
+, m_scalingListPresentFlag                        ( 0 )
+, m_scalingListApsId                              ( -1 )
+, m_scalingListAps                                ( nullptr )
+{
+  memset(m_subPicId,                                0,    sizeof(m_subPicId));
+  memset(m_virtualBoundariesPosX,                   0,    sizeof(m_virtualBoundariesPosX));
+  memset(m_virtualBoundariesPosY,                   0,    sizeof(m_virtualBoundariesPosY));
+  memset(m_saoEnabledFlag,                          0,    sizeof(m_saoEnabledFlag));
+  memset(m_alfEnabledFlag,                          0,    sizeof(m_alfEnabledFlag));
+  memset(m_minQT,                                   0,    sizeof(m_minQT));
+  memset(m_maxMTTHierarchyDepth,                    0,    sizeof(m_maxMTTHierarchyDepth));
+  memset(m_maxBTSize,                               0,    sizeof(m_maxBTSize));
+  memset(m_maxTTSize,                               0,    sizeof(m_maxTTSize));
+
+  m_localRPL0.setNumberOfActivePictures(0);
+  m_localRPL0.setNumberOfShorttermPictures(0);
+  m_localRPL0.setNumberOfLongtermPictures(0);
+  m_localRPL0.setLtrpInSliceHeaderFlag(0);
+
+  m_localRPL1.setNumberOfActivePictures(0);
+  m_localRPL1.setNumberOfShorttermPictures(0);
+  m_localRPL1.setNumberOfLongtermPictures(0);
+  m_localRPL1.setLtrpInSliceHeaderFlag(0);
+
+  m_alfApsId.resize(0);
+}
+
+PicHeader::~PicHeader()
+{
+  m_alfApsId.resize(0);
+}
+
+/**
+ - initialize picture header to defaut state
+ */
+void PicHeader::initPicHeader()
+{
+  m_valid                                         = 0;
+  m_nonReferencePictureFlag                       = 0;
+  m_gdrPicFlag                                    = 0;
+  m_noOutputOfPriorPicsFlag                       = 0;
+  m_recoveryPocCnt                                = 0;
+  m_spsId                                         = -1;
+  m_ppsId                                         = -1;
+  m_subPicIdSignallingPresentFlag                 = 0;
+  m_subPicIdLen                                   = 0;
+  m_loopFilterAcrossVirtualBoundariesDisabledFlag = 0;
+  m_numVerVirtualBoundaries                       = 0;
+  m_numHorVirtualBoundaries                       = 0;
+  m_colourPlaneId                                 = 0;
+  m_picOutputFlag                                 = true;
+  m_picRplPresentFlag                             = 0;
+  m_pRPL0                                         = 0;
+  m_pRPL1                                         = 0;
+  m_rpl0Idx                                       = 0;
+  m_rpl1Idx                                       = 0;
+  m_splitConsOverrideFlag                         = 0;
+  m_cuQpDeltaSubdivIntra                          = 0;
+  m_cuQpDeltaSubdivInter                          = 0;
+  m_cuChromaQpOffsetSubdivIntra                   = 0;
+  m_cuChromaQpOffsetSubdivInter                   = 0;
+  m_enableTMVPFlag                                = true;
+  m_mvdL1ZeroFlag                                 = 0;
+  m_maxNumMergeCand                               = MRG_MAX_NUM_CANDS;
+  m_maxNumAffineMergeCand                         = AFFINE_MRG_MAX_NUM_CANDS;
+  m_disFracMMVD                                   = 0;
+  m_disBdofDmvrFlag                               = 0;
+  m_maxNumTriangleCand                            = 0;
+  m_maxNumIBCMergeCand                            = IBC_MRG_MAX_NUM_CANDS;
+  m_jointCbCrSignFlag                             = 0;
+  m_saoEnabledPresentFlag                         = 0;
+  m_alfEnabledPresentFlag                         = 0;
+  m_numAlfAps                                     = 0;
+  m_alfChromaApsId                                = 0;
+  m_depQuantEnabledFlag                           = 0;
+  m_signDataHidingEnabledFlag                     = 0;
+  m_deblockingFilterOverridePresentFlag           = 0;
+  m_deblockingFilterOverrideFlag                  = 0;
+  m_deblockingFilterDisable                       = 0;
+  m_deblockingFilterBetaOffsetDiv2                = 0;
+  m_deblockingFilterTcOffsetDiv2                  = 0;
+  m_lmcsEnabledFlag                               = 0;
+  m_lmcsApsId                                     = -1;
+  m_lmcsAps                                       = nullptr;
+  m_lmcsChromaResidualScaleFlag                   = 0;
+  m_scalingListPresentFlag                        = 0;
+  m_scalingListApsId                              = -1;
+  m_scalingListAps                                = nullptr;
+  memset(m_subPicId,                                0,    sizeof(m_subPicId));
+  memset(m_virtualBoundariesPosX,                   0,    sizeof(m_virtualBoundariesPosX));
+  memset(m_virtualBoundariesPosY,                   0,    sizeof(m_virtualBoundariesPosY));
+  memset(m_saoEnabledFlag,                          0,    sizeof(m_saoEnabledFlag));
+  memset(m_alfEnabledFlag,                          0,    sizeof(m_alfEnabledFlag));
+  memset(m_minQT,                                   0,    sizeof(m_minQT));
+  memset(m_maxMTTHierarchyDepth,                    0,    sizeof(m_maxMTTHierarchyDepth));
+  memset(m_maxBTSize,                               0,    sizeof(m_maxBTSize));
+  memset(m_maxTTSize,                               0,    sizeof(m_maxTTSize));
+
+  m_localRPL0.setNumberOfActivePictures(0);
+  m_localRPL0.setNumberOfShorttermPictures(0);
+  m_localRPL0.setNumberOfLongtermPictures(0);
+  m_localRPL0.setLtrpInSliceHeaderFlag(0);
+
+  m_localRPL1.setNumberOfActivePictures(0);
+  m_localRPL1.setNumberOfShorttermPictures(0);
+  m_localRPL1.setNumberOfLongtermPictures(0);
+  m_localRPL1.setLtrpInSliceHeaderFlag(0);
+
+  m_alfApsId.resize(0);
+}
+
+#endif
 // ------------------------------------------------------------------------------------------------
 // Sequence parameter set (SPS)
 // ------------------------------------------------------------------------------------------------
@@ -1713,10 +1962,19 @@ SPS::SPS()
 #endif
 , m_ISP                       ( false )
 , m_chromaFormatIdc           (CHROMA_420)
+#if JVET_P1006_PICTURE_HEADER
+, m_separateColourPlaneFlag(0)
+#endif
 , m_uiMaxTLayers              (  1)
 // Structure
 , m_maxWidthInLumaSamples     (352)
 , m_maxHeightInLumaSamples    (288)
+#if JVET_P1006_PICTURE_HEADER
+, m_numSubPics(1)
+, m_subPicIdPresentFlag(0)
+, m_subPicIdSignallingPresentFlag(0)
+, m_subPicIdLen(16)
+#endif
 , m_log2MinCodingBlockSize    (  0)
 , m_log2DiffMaxMinCodingBlockSize(0)
 , m_CTUSize(0)
@@ -1753,6 +2011,11 @@ SPS::SPS()
 , m_saoEnabledFlag            (false)
 , m_bTemporalIdNestingFlag    (false)
 , m_scalingListEnabledFlag    (false)
+#if JVET_P1006_PICTURE_HEADER
+, m_loopFilterAcrossVirtualBoundariesDisabledFlag(0)
+, m_numVerVirtualBoundaries(0)
+, m_numHorVirtualBoundaries(0)
+#endif
 , m_hrdParametersPresentFlag  (false)
 , m_vuiParametersPresentFlag  (false)
 , m_vuiParameters             ()
@@ -1798,6 +2061,10 @@ SPS::SPS()
 
   ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
   ::memset(m_usedByCurrPicLtSPSFlag, 0, sizeof(m_usedByCurrPicLtSPSFlag));
+#if JVET_P1006_PICTURE_HEADER
+  ::memset(m_virtualBoundariesPosX, 0, sizeof(m_virtualBoundariesPosX));
+  ::memset(m_virtualBoundariesPosY, 0, sizeof(m_virtualBoundariesPosY));
+#endif
 }
 
 SPS::~SPS()
@@ -1935,15 +2202,24 @@ PPS::PPS()
 , m_useDQP                           (false)
 , m_bConstrainedIntraPred            (false)
 , m_bSliceChromaQpFlag               (false)
+#if !JVET_P1006_PICTURE_HEADER
 , m_cuQpDeltaSubdiv                  (0)
+#endif
 , m_chromaCbQpOffset                 (0)
 , m_chromaCrQpOffset                 (0)
 , m_chromaCbCrQpOffset               (0)
+#if !JVET_P1006_PICTURE_HEADER
 , m_cuChromaQpOffsetSubdiv             (0)
+#endif
 , m_chromaQpOffsetListLen              (0)
 , m_numRefIdxL0DefaultActive         (1)
 , m_numRefIdxL1DefaultActive         (1)
 , m_rpl1IdxPresentFlag               (false)
+#if JVET_P1006_PICTURE_HEADER
+, m_numSubPics                       (1)
+, m_subPicIdSignallingPresentFlag    (0)
+, m_subPicIdLen                      (16)
+#endif
 , m_TransquantBypassEnabledFlag      (false)
 , m_log2MaxTransformSkipBlockSize    (2)
 , m_entropyCodingSyncEnabledFlag     (false)
@@ -1977,13 +2253,18 @@ PPS::PPS()
 #endif
 , m_PPSMaxNumMergeCandMinusMaxNumTriangleCandPlus1 (0)
 , m_cabacInitPresentFlag             (false)
+#if JVET_P1006_PICTURE_HEADER
+, m_pictureHeaderExtensionPresentFlag(0)
+#endif
 , m_sliceHeaderExtensionPresentFlag  (false)
 , m_loopFilterAcrossSlicesEnabledFlag(false)
 , m_listsModificationPresentFlag     (0)
 , m_numExtraSliceHeaderBits          (0)
+#if !JVET_P1006_PICTURE_HEADER
 , m_loopFilterAcrossVirtualBoundariesDisabledFlag(false)
 , m_numVerVirtualBoundaries          (0)
 , m_numHorVirtualBoundaries          (0)
+#endif
 , m_picWidthInLumaSamples( 352 )
 , m_picHeightInLumaSamples( 288 )
 , m_ppsRangeExtension                ()
@@ -1992,8 +2273,10 @@ PPS::PPS()
   m_ChromaQpAdjTableIncludingNullEntry[0].u.comp.CbOffset = 0; // Array includes entry [0] for the null offset used when cu_chroma_qp_offset_flag=0. This is initialised here and never subsequently changed.
   m_ChromaQpAdjTableIncludingNullEntry[0].u.comp.CrOffset = 0;
   m_ChromaQpAdjTableIncludingNullEntry[0].u.comp.JointCbCrOffset = 0;
+#if !JVET_P1006_PICTURE_HEADER
   ::memset(m_virtualBoundariesPosX, 0, sizeof(m_virtualBoundariesPosX));
   ::memset(m_virtualBoundariesPosY, 0, sizeof(m_virtualBoundariesPosY));
+#endif
 }
 
 PPS::~PPS()
@@ -2902,8 +3185,13 @@ uint32_t PreCalcValues::getValIdx( const Slice &slice, const ChannelType chType
 
 uint32_t PreCalcValues::getMaxBtDepth( const Slice &slice, const ChannelType chType ) const
 {
+#if JVET_P1006_PICTURE_HEADER
+  if ( slice.getPicHeader()->getSplitConsOverrideFlag() )    
+    return slice.getPicHeader()->getMaxMTTHierarchyDepth( slice.getSliceType(), ISingleTree ? CHANNEL_TYPE_LUMA : chType);
+#else
   if ( slice.getSplitConsOverrideFlag() )
     return (!slice.isIntra() || isLuma(chType) || ISingleTree) ? slice.getMaxMTTHierarchyDepth() : slice.getMaxMTTHierarchyDepthIChroma();
+#endif
   else
   return maxBtDepth[getValIdx( slice, chType )];
 }
@@ -2915,8 +3203,13 @@ uint32_t PreCalcValues::getMinBtSize( const Slice &slice, const ChannelType chTy
 
 uint32_t PreCalcValues::getMaxBtSize( const Slice &slice, const ChannelType chType ) const
 {
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getSplitConsOverrideFlag())
+    return slice.getPicHeader()->getMaxBTSize( slice.getSliceType(), ISingleTree ? CHANNEL_TYPE_LUMA : chType);
+#else
   if (slice.getSplitConsOverrideFlag())
     return (!slice.isIntra() || isLuma(chType) || ISingleTree) ? slice.getMaxBTSize() : slice.getMaxBTSizeIChroma();
+#endif
   else
     return maxBtSize[getValIdx(slice, chType)];
 }
@@ -2928,20 +3221,34 @@ uint32_t PreCalcValues::getMinTtSize( const Slice &slice, const ChannelType chTy
 
 uint32_t PreCalcValues::getMaxTtSize( const Slice &slice, const ChannelType chType ) const
 {
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getSplitConsOverrideFlag())
+    return slice.getPicHeader()->getMaxTTSize( slice.getSliceType(), ISingleTree ? CHANNEL_TYPE_LUMA : chType);
+#else
   if ( slice.getSplitConsOverrideFlag() )
     return (!slice.isIntra() || isLuma(chType) || ISingleTree) ? slice.getMaxTTSize() : slice.getMaxTTSizeIChroma();
+#endif
   else
   return maxTtSize[getValIdx( slice, chType )];
 }
 uint32_t PreCalcValues::getMinQtSize( const Slice &slice, const ChannelType chType ) const
 {
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getSplitConsOverrideFlag())
+    return slice.getPicHeader()->getMinQTSize( slice.getSliceType(), ISingleTree ? CHANNEL_TYPE_LUMA : chType);
+#else
   if ( slice.getSplitConsOverrideFlag() )
     return (!slice.isIntra() || isLuma(chType) || ISingleTree) ? slice.getMinQTSize() : slice.getMinQTSizeIChroma();
+#endif
   else
   return minQtSize[getValIdx( slice, chType )];
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void Slice::scaleRefPicList( Picture *scaledRefPic[ ], PicHeader *picHeader, APS** apss, APS* lmcsAps, APS* scalingListAps, const bool isDecoder )
+#else
 void Slice::scaleRefPicList( Picture *scaledRefPic[ ], APS** apss, APS* lmcsAps, APS* scalingListAps, const bool isDecoder )
+#endif
 {
   int i;
   const SPS* sps = getSPS();
@@ -3027,7 +3334,11 @@ void Slice::scaleRefPicList( Picture *scaledRefPic[ ], APS** apss, APS* lmcsAps,
             scaledRefPic[j]->reconstructed = false;
             scaledRefPic[j]->referenced = true;
 
+#if JVET_P1006_PICTURE_HEADER
+            scaledRefPic[ j ]->finalInit( *sps, *pps, picHeader, apss, lmcsAps, scalingListAps );
+#else
             scaledRefPic[ j ]->finalInit( *sps, *pps, apss, lmcsAps, scalingListAps );
+#endif
 
             scaledRefPic[j]->poc = -1;
 
@@ -3078,7 +3389,11 @@ void Slice::scaleRefPicList( Picture *scaledRefPic[ ], APS** apss, APS* lmcsAps,
   //Make sure that TMVP is disabled when there are no reference pictures with the same resolution
   if(!refPicIsSameRes)
   {
+#if JVET_P1006_PICTURE_HEADER
+    CHECK(getPicHeader()->getEnableTMVPFlag() != 0, "TMVP cannot be enabled in pictures that have no reference pictures with the same resolution")
+#else
     CHECK(m_enableTMVPFlag != 0, "TMVP cannot be enabled in slices that have no reference pictures with the same resolution")
+#endif
   }
 #endif
 }
@@ -3149,6 +3464,13 @@ void xTraceAPSHeader()
   DTRACE(g_trace_ctx, D_HEADER, "=========== Adaptation Parameter Set  ===========\n");
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void xTracePictureHeader()
+{
+  DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Header ===========\n" );
+}
+
+#endif
 void xTraceSliceHeader()
 {
   DTRACE( g_trace_ctx, D_HEADER, "=========== Slice ===========\n" );
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index 83f12218c..358278cec 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -855,12 +855,22 @@ private:
 #endif
   bool              m_ISP;
   ChromaFormat      m_chromaFormatIdc;
+#if JVET_P1006_PICTURE_HEADER
+  bool              m_separateColourPlaneFlag;     //!< separate colour plane flag
+#endif
 
   uint32_t              m_uiMaxTLayers;           // maximum number of temporal layers
 
   // Structure
   uint32_t              m_maxWidthInLumaSamples;
   uint32_t              m_maxHeightInLumaSamples;
+#if JVET_P1006_PICTURE_HEADER
+  uint8_t               m_numSubPics;                        //!< number of sub-pictures used
+  bool                  m_subPicIdPresentFlag;               //!< indicates the presence of sub-picture IDs
+  bool                  m_subPicIdSignallingPresentFlag;     //!< indicates the presence of sub-picture ID signalling in the SPS
+  uint32_t              m_subPicIdLen;                       //!< sub-picture ID length in bits
+  uint8_t               m_subPicId[MAX_NUM_SUB_PICS];        //!< sub-picture ID for each sub-picture in the sequence
+#endif
 
   int               m_log2MinCodingBlockSize;
   int               m_log2DiffMaxMinCodingBlockSize;
@@ -919,6 +929,13 @@ private:
   bool              m_bTemporalIdNestingFlag; // temporal_id_nesting_flag
 
   bool              m_scalingListEnabledFlag;
+#if JVET_P1006_PICTURE_HEADER
+  bool              m_loopFilterAcrossVirtualBoundariesDisabledFlag;   //!< disable loop filtering across virtual boundaries
+  unsigned          m_numVerVirtualBoundaries;                         //!< number of vertical virtual boundaries
+  unsigned          m_numHorVirtualBoundaries;                         //!< number of horizontal virtual boundaries
+  unsigned          m_virtualBoundariesPosX[3];                        //!< horizontal position of each vertical virtual boundary
+  unsigned          m_virtualBoundariesPosY[3];                        //!< vertical position of each horizontal virtual boundary
+#endif
   uint32_t              m_uiMaxDecPicBuffering[MAX_TLAYER];
   uint32_t              m_uiMaxLatencyIncreasePlus1[MAX_TLAYER];
 
@@ -980,6 +997,10 @@ public:
   int                     getDecodingParameterSetId() const                                               { return m_decodingParameterSetId; }
   ChromaFormat            getChromaFormatIdc () const                                                     { return m_chromaFormatIdc;                                            }
   void                    setChromaFormatIdc (ChromaFormat i)                                             { m_chromaFormatIdc = i;                                               }
+ #if JVET_P1006_PICTURE_HEADER
+  void                    setSeparateColourPlaneFlag ( bool b )                                           { m_separateColourPlaneFlag = b;                                       }
+  bool                    getSeparateColourPlaneFlag () const                                             { return m_separateColourPlaneFlag;                                    }
+#endif
 
   static int              getWinUnitX (int chromaFormatIdc)                                               { CHECK(chromaFormatIdc < 0 || chromaFormatIdc >= NUM_CHROMA_FORMAT, "Invalid chroma format parameter"); return m_winUnitX[chromaFormatIdc]; }
   static int              getWinUnitY (int chromaFormatIdc)                                               { CHECK(chromaFormatIdc < 0 || chromaFormatIdc >= NUM_CHROMA_FORMAT, "Invalid chroma format parameter"); return m_winUnitY[chromaFormatIdc]; }
@@ -989,6 +1010,18 @@ public:
   uint32_t                getMaxPicWidthInLumaSamples() const                                             { return  m_maxWidthInLumaSamples; }
   void                    setMaxPicHeightInLumaSamples( uint32_t u )                                      { m_maxHeightInLumaSamples = u; }
   uint32_t                getMaxPicHeightInLumaSamples() const                                            { return  m_maxHeightInLumaSamples; }
+#if JVET_P1006_PICTURE_HEADER
+  void                    setNumSubPics( uint8_t u )                                                      { m_numSubPics = u;                        }
+  uint8_t                 getNumSubPics( ) const                                                          { return  m_numSubPics;                    }
+  void                    setSubPicIdPresentFlag( bool b )                                                { m_subPicIdPresentFlag = b;               }
+  bool                    getSubPicIdPresentFlag() const                                                  { return  m_subPicIdPresentFlag;           }
+  void                    setSubPicIdSignallingPresentFlag( bool b )                                      { m_subPicIdSignallingPresentFlag = b;     }
+  bool                    getSubPicIdSignallingPresentFlag() const                                        { return  m_subPicIdSignallingPresentFlag; }
+  void                    setSubPicIdLen( uint32_t u )                                                    { m_subPicIdLen = u;                       }
+  uint32_t                getSubPicIdLen() const                                                          { return  m_subPicIdLen;                   }
+  void                    setSubPicId( int i, uint8_t u )                                                 { CHECK( i >= MAX_NUM_SUB_PICS, "Sub-picture index exceeds valid range" ); m_subPicId[i] = u;     }
+  uint8_t                 getSubPicId( int i ) const                                                      { CHECK( i >= MAX_NUM_SUB_PICS, "Sub-picture index exceeds valid range" ); return  m_subPicId[i]; }
+#endif
 
   uint32_t                    getNumLongTermRefPicSPS() const                                                 { return m_numLongTermRefPicSPS;                                       }
   void                    setNumLongTermRefPicSPS(uint32_t val)                                               { m_numLongTermRefPicSPS = val;                                        }
@@ -1032,6 +1065,12 @@ public:
   unsigned                getMaxTTSize()                                                            const { return m_maxTTSize[1]; }
   unsigned                getMaxTTSizeI()                                                           const { return m_maxTTSize[0]; }
   unsigned                getMaxTTSizeIChroma()                                                     const { return m_maxTTSize[2]; }
+#if JVET_P1006_PICTURE_HEADER
+  unsigned*               getMinQTSizes()                                                          const { return (unsigned *)m_minQT;                }
+  unsigned*               getMaxMTTHierarchyDepths()                                               const { return (unsigned *)m_maxMTTHierarchyDepth; }
+  unsigned*               getMaxBTSizes()                                                          const { return (unsigned *)m_maxBTSize;            }
+  unsigned*               getMaxTTSizes()                                                          const { return (unsigned *)m_maxTTSize;            }
+#endif
   void                    setIDRRefParamListPresent(bool b)                             { m_idrRefParamList = b; }
   bool                    getIDRRefParamListPresent()                             const { return m_idrRefParamList; }
   void                    setUseDualITree(bool b) { m_dualITree = b; }
@@ -1058,6 +1097,11 @@ public:
   int                     getNumReorderPics(uint32_t tlayer) const                                            { return m_numReorderPics[tlayer];                                     }
   void                    createRPLList0(int numRPL);
   void                    createRPLList1(int numRPL);
+#if JVET_P1006_PICTURE_HEADER
+  const RPLList*          getRPLList( bool b ) const                                                          { return b==1 ? &m_RPLList1 : &m_RPLList0;                             }
+  RPLList*                getRPLList( bool b )                                                                { return b==1 ? &m_RPLList1 : &m_RPLList0;                             }
+  uint32_t                getNumRPL( bool b ) const                                                           { return b==1 ? m_numRPL1   : m_numRPL0;                               }
+#endif
   const RPLList*          getRPLList0() const                                                                 { return &m_RPLList0;                                                  }
   RPLList*                getRPLList0()                                                                       { return &m_RPLList0;                                                  }
   const RPLList*          getRPLList1() const                                                                 { return &m_RPLList1;                                                  }
@@ -1118,6 +1162,18 @@ public:
 
   bool                    getScalingListFlag() const                                                      { return m_scalingListEnabledFlag;                                     }
   void                    setScalingListFlag( bool b )                                                    { m_scalingListEnabledFlag  = b;                                       }
+#if JVET_P1006_PICTURE_HEADER
+  void                    setLoopFilterAcrossVirtualBoundariesDisabledFlag(bool b)                        { m_loopFilterAcrossVirtualBoundariesDisabledFlag = b;                 }
+  bool                    getLoopFilterAcrossVirtualBoundariesDisabledFlag() const                        { return m_loopFilterAcrossVirtualBoundariesDisabledFlag;              }
+  void                    setNumVerVirtualBoundaries(unsigned u)                                          { m_numVerVirtualBoundaries = u;                                       }
+  unsigned                getNumVerVirtualBoundaries() const                                              { return m_numVerVirtualBoundaries;                                    }
+  void                    setNumHorVirtualBoundaries(unsigned u)                                          { m_numHorVirtualBoundaries = u;                                       }
+  unsigned                getNumHorVirtualBoundaries() const                                              { return m_numHorVirtualBoundaries;                                    }
+  void                    setVirtualBoundariesPosX(unsigned u, unsigned idx)                              { CHECK( idx >= 3, "vitrual boundary index exceeds valid range" ); m_virtualBoundariesPosX[idx] = u;    }
+  unsigned                getVirtualBoundariesPosX(unsigned idx) const                                    { CHECK( idx >= 3, "vitrual boundary index exceeds valid range" ); return m_virtualBoundariesPosX[idx]; }
+  void                    setVirtualBoundariesPosY(unsigned u, unsigned idx)                              { CHECK( idx >= 3, "vitrual boundary index exceeds valid range" ); m_virtualBoundariesPosY[idx] = u;    }
+  unsigned                getVirtualBoundariesPosY(unsigned idx) const                                    { CHECK( idx >= 3, "vitrual boundary index exceeds valid range" ); return m_virtualBoundariesPosY[idx]; }
+#endif
   uint32_t                    getMaxDecPicBuffering(uint32_t tlayer) const                                        { return m_uiMaxDecPicBuffering[tlayer];                               }
   void                    setMaxDecPicBuffering( uint32_t ui, uint32_t tlayer )                                   { CHECK(tlayer >= MAX_TLAYER, "Invalid T-layer"); m_uiMaxDecPicBuffering[tlayer] = ui;    }
   uint32_t                    getMaxLatencyIncreasePlus1(uint32_t tlayer) const                                   { return m_uiMaxLatencyIncreasePlus1[tlayer];                          }
@@ -1264,7 +1320,9 @@ private:
   int              m_temporalId;
 
   // access channel
+#if !JVET_P1006_PICTURE_HEADER
   uint32_t         m_cuQpDeltaSubdiv;           // cu_qp_delta_subdiv
+#endif
 
   int              m_chromaCbQpOffset;
   int              m_chromaCrQpOffset;
@@ -1274,7 +1332,9 @@ private:
   int              m_chromaCbCrQpOffset;
 
   // Chroma QP Adjustments
+#if !JVET_P1006_PICTURE_HEADER
   int              m_cuChromaQpOffsetSubdiv;
+#endif
   int              m_chromaQpOffsetListLen; // size (excludes the null entry used in the following array).
   ChromaQpAdj      m_ChromaQpAdjTableIncludingNullEntry[1+MAX_QP_OFFSET_LIST_SIZE]; //!< Array includes entry [0] for the null offset used when cu_chroma_qp_offset_flag=0, and entries [cu_chroma_qp_offset_idx+1...] otherwise
 
@@ -1286,6 +1346,12 @@ private:
   bool             m_bUseWeightPred;                    //!< Use of Weighting Prediction (P_SLICE)
   bool             m_useWeightedBiPred;                 //!< Use of Weighting Bi-Prediction (B_SLICE)
   bool             m_OutputFlagPresentFlag;             //!< Indicates the presence of output_flag in slice header
+#if JVET_P1006_PICTURE_HEADER 
+  uint8_t          m_numSubPics;                        //!< number of sub-pictures used - must match SPS
+  bool             m_subPicIdSignallingPresentFlag;     //!< indicates the presence of sub-picture ID signalling in the PPS
+  uint32_t         m_subPicIdLen;                       //!< sub-picture ID length in bits
+  uint8_t          m_subPicId[MAX_NUM_SUB_PICS];        //!< sub-picture ID for each sub-picture in the sequence
+#endif
   bool             m_TransquantBypassEnabledFlag;       //!< Indicates presence of cu_transquant_bypass_flag in CUs.
   int              m_log2MaxTransformSkipBlockSize;
   bool             m_entropyCodingSyncEnabledFlag;      //!< Indicates the presence of wavefronts
@@ -1336,6 +1402,9 @@ private:
 
   bool             m_cabacInitPresentFlag;
 
+#if JVET_P1006_PICTURE_HEADER
+  bool             m_pictureHeaderExtensionPresentFlag;   //< picture header extension flags present in picture headers or not
+#endif
   bool             m_sliceHeaderExtensionPresentFlag;
   bool             m_loopFilterAcrossSlicesEnabledFlag;
   bool             m_deblockingFilterControlPresentFlag;
@@ -1347,11 +1416,13 @@ private:
   uint32_t             m_log2ParallelMergeLevelMinus2;
   int              m_numExtraSliceHeaderBits;
 
+#if !JVET_P1006_PICTURE_HEADER
   bool             m_loopFilterAcrossVirtualBoundariesDisabledFlag;
   unsigned         m_numVerVirtualBoundaries;
   unsigned         m_numHorVirtualBoundaries;
   unsigned         m_virtualBoundariesPosX[3];
   unsigned         m_virtualBoundariesPosY[3];
+#endif
 
   uint32_t         m_picWidthInLumaSamples;
   uint32_t         m_picHeightInLumaSamples;
@@ -1385,8 +1456,10 @@ public:
   bool                   getSliceChromaQpFlag() const                                     { return  m_bSliceChromaQpFlag;                 }
   void                   setSliceChromaQpFlag( bool b )                                   { m_bSliceChromaQpFlag = b;                     }
 
+#if !JVET_P1006_PICTURE_HEADER
   void                   setCuQpDeltaSubdiv( uint32_t u )                                 { m_cuQpDeltaSubdiv = u;                         }
   uint32_t               getCuQpDeltaSubdiv() const                                       { return m_cuQpDeltaSubdiv;                      }
+#endif
 
 #if JVET_P0667_QP_OFFSET_TABLE_SIGNALING_JCCR
   bool                   getJointCbCrQpOffsetPresentFlag() const                          { return m_chromaJointCbCrQpOffsetPresentFlag;   }
@@ -1417,9 +1490,11 @@ public:
     return (compID==COMPONENT_Y) ? 0 : (compID==COMPONENT_Cb ? m_chromaCbQpOffset : compID==COMPONENT_Cr ? m_chromaCrQpOffset : m_chromaCbCrQpOffset );
   }
 
+#if !JVET_P1006_PICTURE_HEADER
   uint32_t               getCuChromaQpOffsetSubdiv () const                               { return m_cuChromaQpOffsetSubdiv;                }
   void                   setCuChromaQpOffsetSubdiv ( uint32_t u )                         { m_cuChromaQpOffsetSubdiv = u;                   }
 
+#endif
   bool                   getCuChromaQpOffsetEnabledFlag() const                           { return getChromaQpOffsetListLen()>0;            }
   int                    getChromaQpOffsetListLen() const                                 { return m_chromaQpOffsetListLen;                 }
   void                   clearChromaQpOffsetList()                                        { m_chromaQpOffsetListLen = 0;                    }
@@ -1454,6 +1529,16 @@ public:
 
   void                   setOutputFlagPresentFlag( bool b )                               { m_OutputFlagPresentFlag = b;                  }
   bool                   getOutputFlagPresentFlag() const                                 { return m_OutputFlagPresentFlag;               }
+#if JVET_P1006_PICTURE_HEADER
+  void                   setNumSubPics( uint8_t u )                                       { m_numSubPics = u;                             }
+  uint8_t                getNumSubPics( ) const                                           { return  m_numSubPics;                         }
+  void                   setSubPicIdSignallingPresentFlag( bool b )                       { m_subPicIdSignallingPresentFlag = b;          }
+  bool                   getSubPicIdSignallingPresentFlag() const                         { return  m_subPicIdSignallingPresentFlag;      }
+  void                   setSubPicIdLen( uint32_t u )                                     { m_subPicIdLen = u;                            }
+  uint32_t               getSubPicIdLen() const                                           { return  m_subPicIdLen;                        }
+  void                   setSubPicId( int i, uint8_t u )                                  { CHECK( i >= MAX_NUM_SUB_PICS, "Sub-picture index exceeds valid range" ); m_subPicId[i] = u;     }
+  uint8_t                getSubPicId( int i ) const                                       { CHECK( i >= MAX_NUM_SUB_PICS, "Sub-picture index exceeds valid range" ); return  m_subPicId[i]; }
+#endif
   void                   setTransquantBypassEnabledFlag( bool b )                         { m_TransquantBypassEnabledFlag = b;            }
   bool                   getTransquantBypassEnabledFlag() const                           { return m_TransquantBypassEnabledFlag;         }
 
@@ -1523,6 +1608,9 @@ public:
   void                    setConstantSliceHeaderParamsEnabledFlag(bool b)                 { m_constantSliceHeaderParamsEnabledFlag = b;   }
   int                     getPPSDepQuantEnabledIdc() const                                { return m_PPSDepQuantEnabledIdc;               }
   void                    setPPSDepQuantEnabledIdc(int u)                                 { m_PPSDepQuantEnabledIdc = u;                  }
+#if JVET_P1006_PICTURE_HEADER
+  int                     getPPSRefPicListSPSIdc( bool b ) const                          { return b==1 ? m_PPSRefPicListSPSIdc1: m_PPSRefPicListSPSIdc0; }
+#endif
   int                     getPPSRefPicListSPSIdc0() const                                 { return m_PPSRefPicListSPSIdc0;                }
   void                    setPPSRefPicListSPSIdc0(int u)                                  { m_PPSRefPicListSPSIdc0 = u;                   }
   int                     getPPSRefPicListSPSIdc1() const                                 { return m_PPSRefPicListSPSIdc1;                }
@@ -1564,9 +1652,14 @@ public:
   void                   setNumExtraSliceHeaderBits(int i)                                { m_numExtraSliceHeaderBits = i;                }
   void                   setLoopFilterAcrossSlicesEnabledFlag( bool bValue )              { m_loopFilterAcrossSlicesEnabledFlag = bValue; }
   bool                   getLoopFilterAcrossSlicesEnabledFlag() const                     { return m_loopFilterAcrossSlicesEnabledFlag;   }
+#if JVET_P1006_PICTURE_HEADER
+  bool                   getPictureHeaderExtensionPresentFlag() const                     { return m_pictureHeaderExtensionPresentFlag;     }
+  void                   setPictureHeaderExtensionPresentFlag(bool val)                   { m_pictureHeaderExtensionPresentFlag = val;      }
+#endif
   bool                   getSliceHeaderExtensionPresentFlag() const                       { return m_sliceHeaderExtensionPresentFlag;     }
   void                   setSliceHeaderExtensionPresentFlag(bool val)                     { m_sliceHeaderExtensionPresentFlag = val;      }
 
+#if !JVET_P1006_PICTURE_HEADER
   void                   setLoopFilterAcrossVirtualBoundariesDisabledFlag(bool b)         { m_loopFilterAcrossVirtualBoundariesDisabledFlag = b; }
   bool                   getLoopFilterAcrossVirtualBoundariesDisabledFlag() const         { return m_loopFilterAcrossVirtualBoundariesDisabledFlag; }
   void                   setNumVerVirtualBoundaries(unsigned u)                           { m_numVerVirtualBoundaries = u;                }
@@ -1577,6 +1670,7 @@ public:
   unsigned               getVirtualBoundariesPosX(unsigned idx) const                     { return m_virtualBoundariesPosX[idx];          }
   void                   setVirtualBoundariesPosY(unsigned u, unsigned idx)               { m_virtualBoundariesPosY[idx] = u;             }
   unsigned               getVirtualBoundariesPosY(unsigned idx) const                     { return m_virtualBoundariesPosY[idx];          }
+#endif
 
   const PPSRExt&         getPpsRangeExtension() const                                     { return m_ppsRangeExtension;                   }
   PPSRExt&               getPpsRangeExtension()                                           { return m_ppsRangeExtension;                   }
@@ -1647,6 +1741,242 @@ struct WPACDCParam
   int64_t iDC;
 };
 
+#if JVET_P1006_PICTURE_HEADER
+// picture header class
+class PicHeader
+{
+private:
+  bool                        m_valid;                                                  //!< picture header is valid yet or not
+  Picture*                    m_pcPic;                                                  //!< pointer to picture structure
+  bool                        m_nonReferencePictureFlag;                                //!< non-reference picture flag
+  bool                        m_gdrPicFlag;                                             //!< gradual decoding refresh picture flag
+  bool                        m_noOutputOfPriorPicsFlag;                                //!< no output of prior pictures flag
+  uint32_t                    m_recoveryPocCnt;                                         //!< recovery POC count
+  int                         m_spsId;                                                  //!< sequence parameter set ID
+  int                         m_ppsId;                                                  //!< picture parameter set ID
+  bool                        m_subPicIdSignallingPresentFlag;                          //!< indicates the presence of sub-picture ID signalling in the SPS
+  uint32_t                    m_subPicIdLen;                                            //!< sub-picture ID length in bits
+  uint8_t                     m_subPicId[MAX_NUM_SUB_PICS];                             //!< sub-picture ID for each sub-picture in the sequence
+  bool                        m_loopFilterAcrossVirtualBoundariesDisabledFlag;          //!< loop filtering across virtual boundaries disabled
+  unsigned                    m_numVerVirtualBoundaries;                                //!< number of vertical virtual boundaries
+  unsigned                    m_numHorVirtualBoundaries;                                //!< number of horizontal virtual boundaries
+  unsigned                    m_virtualBoundariesPosX[3];                               //!< horizontal virtual boundary positions
+  unsigned                    m_virtualBoundariesPosY[3];                               //!< vertical virtual boundary positions
+  unsigned                    m_colourPlaneId;                                          //!< 4:4:4 colour plane ID
+  bool                        m_picOutputFlag;                                          //!< picture output flag
+  bool                        m_picRplPresentFlag;                                      //!< reference lists present in picture header or not
+  const ReferencePictureList* m_pRPL0;                                                  //!< pointer to RPL for L0, either in the SPS or the local RPS in the picture header
+  const ReferencePictureList* m_pRPL1;                                                  //!< pointer to RPL for L1, either in the SPS or the local RPS in the picture header
+  ReferencePictureList        m_localRPL0;                                              //!< RPL for L0 when present in picture header
+  ReferencePictureList        m_localRPL1;                                              //!< RPL for L1 when present in picture header
+  int                         m_rpl0Idx;                                                //!< index of used RPL in the SPS or -1 for local RPL in the picture header
+  int                         m_rpl1Idx;                                                //!< index of used RPL in the SPS or -1 for local RPL in the picture header
+  bool                        m_splitConsOverrideFlag;                                  //!< partitioning constraint override flag  
+  uint32_t                    m_cuQpDeltaSubdivIntra;                                   //!< CU QP delta maximum subdivision for intra slices
+  uint32_t                    m_cuQpDeltaSubdivInter;                                   //!< CU QP delta maximum subdivision for inter slices 
+  uint32_t                    m_cuChromaQpOffsetSubdivIntra;                            //!< CU chroma QP offset maximum subdivision for intra slices 
+  uint32_t                    m_cuChromaQpOffsetSubdivInter;                            //!< CU chroma QP offset maximum subdivision for inter slices 
+  bool                        m_enableTMVPFlag;                                         //!< enable temporal motion vector prediction
+  bool                        m_mvdL1ZeroFlag;                                          //!< L1 MVD set to zero flag  
+  uint32_t                    m_maxNumMergeCand;                                        //!< max number of merge candidates
+  uint32_t                    m_maxNumAffineMergeCand;                                  //!< max number of sub-block merge candidates
+  bool                        m_disFracMMVD;                                            //!< fractional MMVD offsets disabled flag
+  bool                        m_disBdofDmvrFlag;                                        //!< picture level BDOF/DMVR disable flag
+  uint32_t                    m_maxNumTriangleCand;                                     //!< max number of triangle merge candidates
+  uint32_t                    m_maxNumIBCMergeCand;                                     //!< max number of IBC merge candidates
+  bool                        m_jointCbCrSignFlag;                                      //!< joint Cb/Cr residual sign flag  
+  bool                        m_saoEnabledPresentFlag;                                  //!< sao enabled flags present in the picture header
+  bool                        m_saoEnabledFlag[MAX_NUM_CHANNEL_TYPE];                   //!< sao enabled flags for each channel
+  bool                        m_alfEnabledPresentFlag;                                  //!< alf enabled flags present in the picture header
+  bool                        m_alfEnabledFlag[MAX_NUM_COMPONENT];                      //!< alf enabled flags for each component
+  int                         m_numAlfAps;                                              //!< number of alf aps active for the picture
+  std::vector<int>            m_alfApsId;                                               //!< list of alf aps for the picture
+  int                         m_alfChromaApsId;                                         //!< chroma alf aps ID
+  bool                        m_depQuantEnabledFlag;                                    //!< dependent quantization enabled flag
+  bool                        m_signDataHidingEnabledFlag;                              //!< sign data hiding enabled flag
+  bool                        m_deblockingFilterOverridePresentFlag;                    //!< deblocking filter override controls present in picture header
+  bool                        m_deblockingFilterOverrideFlag;                           //!< deblocking filter override controls enabled
+  bool                        m_deblockingFilterDisable;                                //!< deblocking filter disabled flag
+  int                         m_deblockingFilterBetaOffsetDiv2;                         //!< beta offset for deblocking filter
+  int                         m_deblockingFilterTcOffsetDiv2;                           //!< tc offset for deblocking filter
+  bool                        m_lmcsEnabledFlag;                                        //!< lmcs enabled flag
+  int                         m_lmcsApsId;                                              //!< lmcs APS ID
+  APS*                        m_lmcsAps;                                                //!< lmcs APS
+  bool                        m_lmcsChromaResidualScaleFlag;                            //!< lmcs chroma residual scale flag  
+  bool                        m_scalingListPresentFlag;                                 //!< quantization scaling lists present
+  int                         m_scalingListApsId;                                       //!< quantization scaling list APS ID
+  APS*                        m_scalingListAps;                                         //!< quantization scaling list APS
+  unsigned                    m_minQT[3];                                               //!< minimum quad-tree size  0: I slice luma; 1: P/B slice; 2: I slice chroma
+  unsigned                    m_maxMTTHierarchyDepth[3];                                //!< maximum MTT depth
+  unsigned                    m_maxBTSize[3];                                           //!< maximum BT size
+  unsigned                    m_maxTTSize[3];                                           //!< maximum TT size
+
+public:
+                              PicHeader();
+  virtual                     ~PicHeader();
+  void                        initPicHeader();
+  bool                        isValid()                                                 { return m_valid;                                                                              }
+  void                        setValid()                                                { m_valid = true;                                                                              }
+  void                        setPic( Picture* p )                                      { m_pcPic = p;                                                                                 }
+  Picture*                    getPic()                                                  { return m_pcPic;                                                                              }
+  const Picture*              getPic() const                                            { return m_pcPic;                                                                              }
+  void                        setNonReferencePictureFlag( bool b )                      { m_nonReferencePictureFlag = b;                                                               }
+  bool                        getNonReferencePictureFlag() const                        { return m_nonReferencePictureFlag;                                                            }
+  void                        setGdrPicFlag( bool b )                                   { m_gdrPicFlag = b;                                                                            }
+  bool                        getGdrPicFlag() const                                     { return m_gdrPicFlag;                                                                         }
+  void                        setNoOutputOfPriorPicsFlag( bool b )                      { m_noOutputOfPriorPicsFlag = b;                                                               }
+  bool                        getNoOutputOfPriorPicsFlag() const                        { return m_noOutputOfPriorPicsFlag;                                                            }
+  void                        setRecoveryPocCnt( uint32_t u )                           { m_recoveryPocCnt = u;                                                                        }
+  bool                        getRecoveryPocCnt() const                                 { return m_recoveryPocCnt;                                                                     }
+  void                        setSPSId( uint32_t u )                                    { m_spsId = u;                                                                                 }
+  uint32_t                    getSPSId() const                                          { return m_spsId;                                                                              }
+  void                        setPPSId( uint32_t u )                                    { m_ppsId = u;                                                                                 }
+  uint32_t                    getPPSId() const                                          { return m_ppsId;                                                                              }
+  void                        setSubPicIdSignallingPresentFlag( bool b )                { m_subPicIdSignallingPresentFlag = b;                                                         }
+  bool                        getSubPicIdSignallingPresentFlag() const                  { return  m_subPicIdSignallingPresentFlag;                                                     }
+  void                        setSubPicIdLen( uint32_t u )                              { m_subPicIdLen = u;                                                                           }
+  uint32_t                    getSubPicIdLen() const                                    { return  m_subPicIdLen;                                                                       }
+  void                        setSubPicId( int i, uint8_t u )                           { CHECK( i >= MAX_NUM_SUB_PICS, "Sub-pic index exceeds valid range" ); m_subPicId[i] = u;      }
+  uint8_t                     getSubPicId( int i ) const                                { CHECK( i >= MAX_NUM_SUB_PICS, "Sub-pic index exceeds valid range" ); return  m_subPicId[i];  }
+  void                        setLoopFilterAcrossVirtualBoundariesDisabledFlag(bool b)  { m_loopFilterAcrossVirtualBoundariesDisabledFlag = b;                                         }
+  bool                        getLoopFilterAcrossVirtualBoundariesDisabledFlag() const  { return m_loopFilterAcrossVirtualBoundariesDisabledFlag;                                      }
+  void                        setNumVerVirtualBoundaries(unsigned u)                    { m_numVerVirtualBoundaries = u;                                                               }
+  unsigned                    getNumVerVirtualBoundaries() const                        { return m_numVerVirtualBoundaries;                                                            }
+  void                        setNumHorVirtualBoundaries(unsigned u)                    { m_numHorVirtualBoundaries = u;                                                               }
+  unsigned                    getNumHorVirtualBoundaries() const                        { return m_numHorVirtualBoundaries;                                                            }
+  void                        setVirtualBoundariesPosX(unsigned u, unsigned idx)        { CHECK( idx >= 3, "boundary index exceeds valid range" ); m_virtualBoundariesPosX[idx] = u;   }
+  unsigned                    getVirtualBoundariesPosX(unsigned idx) const              { CHECK( idx >= 3, "boundary index exceeds valid range" ); return m_virtualBoundariesPosX[idx];}
+  void                        setVirtualBoundariesPosY(unsigned u, unsigned idx)        { CHECK( idx >= 3, "boundary index exceeds valid range" ); m_virtualBoundariesPosY[idx] = u;   }
+  unsigned                    getVirtualBoundariesPosY(unsigned idx) const              { CHECK( idx >= 3, "boundary index exceeds valid range" ); return m_virtualBoundariesPosY[idx];}
+  void                        setColourPlaneId(unsigned u)                              { m_colourPlaneId = u;                                                                         }
+  unsigned                    getColourPlaneId() const                                  { return m_colourPlaneId;                                                                      }
+  void                        setPicOutputFlag( bool b )                                { m_picOutputFlag = b;                                                                         }
+  bool                        getPicOutputFlag() const                                  { return m_picOutputFlag;                                                                      }
+  void                        setPicRplPresentFlag( bool b )                            { m_picRplPresentFlag = b;                                                                     }
+  bool                        getPicRplPresentFlag() const                              { return m_picRplPresentFlag;                                                                  }
+  void                        setRPL( bool b, const ReferencePictureList *pcRPL)        { if(b==1) { m_pRPL1 = pcRPL; } else { m_pRPL0 = pcRPL; }                                      }
+  const ReferencePictureList* getRPL( bool b )                                          { return b==1 ? m_pRPL1 : m_pRPL0;                                                             }
+  ReferencePictureList*       getLocalRPL( bool b )                                     { return b==1 ? &m_localRPL1 : &m_localRPL0;                                                   }
+  void                        setRPLIdx( bool b, int rplIdx)                            { if(b==1) { m_rpl1Idx = rplIdx; } else { m_rpl0Idx = rplIdx; }                                }
+  int                         getRPLIdx( bool b ) const                                 { return b==1 ? m_rpl1Idx : m_rpl0Idx;                                                         }
+  void                        setRPL0(const ReferencePictureList *pcRPL)                { m_pRPL0 = pcRPL;                                                                             }
+  void                        setRPL1(const ReferencePictureList *pcRPL)                { m_pRPL1 = pcRPL;                                                                             }
+  const ReferencePictureList* getRPL0()                                                 { return m_pRPL0;                                                                              }
+  const ReferencePictureList* getRPL1()                                                 { return m_pRPL1;                                                                              }
+  ReferencePictureList*       getLocalRPL0()                                            { return &m_localRPL0;                                                                         }
+  ReferencePictureList*       getLocalRPL1()                                            { return &m_localRPL1;                                                                         }
+  void                        setRPL0idx(int rplIdx)                                    { m_rpl0Idx = rplIdx;                                                                          }
+  void                        setRPL1idx(int rplIdx)                                    { m_rpl1Idx = rplIdx;                                                                          }
+  int                         getRPL0idx() const                                        { return m_rpl0Idx;                                                                            }
+  int                         getRPL1idx() const                                        { return m_rpl1Idx;                                                                            }
+  void                        setSplitConsOverrideFlag( bool b )                        { m_splitConsOverrideFlag = b;                                                                 }
+  bool                        getSplitConsOverrideFlag() const                          { return m_splitConsOverrideFlag;                                                              }  
+  void                        setCuQpDeltaSubdivIntra( uint32_t u )                     { m_cuQpDeltaSubdivIntra = u;                                                                  }
+  uint32_t                    getCuQpDeltaSubdivIntra() const                           { return m_cuQpDeltaSubdivIntra;                                                               }
+  void                        setCuQpDeltaSubdivInter( uint32_t u )                     { m_cuQpDeltaSubdivInter = u;                                                                  }
+  uint32_t                    getCuQpDeltaSubdivInter() const                           { return m_cuQpDeltaSubdivInter;                                                               }
+  void                        setCuChromaQpOffsetSubdivIntra( uint32_t u )              { m_cuChromaQpOffsetSubdivIntra = u;                                                           }
+  uint32_t                    getCuChromaQpOffsetSubdivIntra() const                    { return m_cuChromaQpOffsetSubdivIntra;                                                        }
+  void                        setCuChromaQpOffsetSubdivInter( uint32_t u )              { m_cuChromaQpOffsetSubdivInter = u;                                                           }
+  uint32_t                    getCuChromaQpOffsetSubdivInter() const                    { return m_cuChromaQpOffsetSubdivInter;                                                        }
+  void                        setEnableTMVPFlag( bool b )                               { m_enableTMVPFlag = b;                                                                        }
+  bool                        getEnableTMVPFlag() const                                 { return m_enableTMVPFlag;                                                                     }
+  void                        setMvdL1ZeroFlag( bool b )                                { m_mvdL1ZeroFlag = b;                                                                         }
+  bool                        getMvdL1ZeroFlag() const                                  { return m_mvdL1ZeroFlag;                                                                      }  
+  void                        setMaxNumMergeCand(uint32_t val )                         { m_maxNumMergeCand = val;                                                                     }
+  uint32_t                    getMaxNumMergeCand() const                                { return m_maxNumMergeCand;                                                                    }  
+  void                        setMaxNumAffineMergeCand( uint32_t val )                  { m_maxNumAffineMergeCand = val;                                                               }
+  uint32_t                    getMaxNumAffineMergeCand() const                          { return m_maxNumAffineMergeCand;                                                              }
+  void                        setDisFracMMVD( bool val )                                { m_disFracMMVD = val;                                                                         }
+  bool                        getDisFracMMVD() const                                    { return m_disFracMMVD;                                                                        }  
+  void                        setDisBdofDmvrFlag(bool val)                              { m_disBdofDmvrFlag = val;                                                                     }
+  bool                        getDisBdofDmvrFlag() const                                { return m_disBdofDmvrFlag;                                                                    }
+  void                        setMaxNumTriangleCand(uint32_t b)                         { m_maxNumTriangleCand = b;                                                                    }
+  uint32_t                    getMaxNumTriangleCand() const                             { return m_maxNumTriangleCand;                                                                 }
+  void                        setMaxNumIBCMergeCand( uint32_t b )                       { m_maxNumIBCMergeCand = b;                                                                    }
+  uint32_t                    getMaxNumIBCMergeCand() const                             { return m_maxNumIBCMergeCand;                                                                 } 
+  void                        setJointCbCrSignFlag( bool b )                            { m_jointCbCrSignFlag = b;                                                                     }
+  bool                        getJointCbCrSignFlag() const                              { return m_jointCbCrSignFlag;                                                                  }
+  void                        setSaoEnabledPresentFlag( bool b )                        { m_saoEnabledPresentFlag = b;                                                                 }
+  bool                        getSaoEnabledPresentFlag() const                          { return m_saoEnabledPresentFlag;                                                              }
+  void                        setSaoEnabledFlag(ChannelType chType, bool b)             { m_saoEnabledFlag[chType] = b;                                                                }
+  bool                        getSaoEnabledFlag(ChannelType chType) const               { return m_saoEnabledFlag[chType];                                                             }  
+  void                        setAlfEnabledPresentFlag( bool b )                        { m_alfEnabledPresentFlag = b;                                                                 }
+  bool                        getAlfEnabledPresentFlag() const                          { return m_alfEnabledPresentFlag;                                                              }
+  void                        setAlfEnabledFlag(ComponentID compId, bool b)             { m_alfEnabledFlag[compId] = b;                                                                }
+  bool                        getAlfEnabledFlag(ComponentID compId) const               { return m_alfEnabledFlag[compId];                                                             }
+  void                        setNumAlfAps(int i)                                       { m_numAlfAps = i;                                                                             }
+  int                         getNumAlfAps() const                                      { return m_numAlfAps;                                                                          }
+  void                        setAlfApsIdChroma(int i)                                  { m_alfChromaApsId = i;                                                                        }
+  int                         getAlfApsIdChroma() const                                 { return m_alfChromaApsId;                                                                     }  
+  void                        setDepQuantEnabledFlag( bool b )                          { m_depQuantEnabledFlag = b;                                                                   }
+  bool                        getDepQuantEnabledFlag() const                            { return m_depQuantEnabledFlag;                                                                }  
+  void                        setSignDataHidingEnabledFlag( bool b )                    { m_signDataHidingEnabledFlag = b;                                                             }
+  bool                        getSignDataHidingEnabledFlag() const                      { return m_signDataHidingEnabledFlag;                                                          }  
+  void                        setDeblockingFilterOverridePresentFlag( bool b )          { m_deblockingFilterOverridePresentFlag = b;                                                   }
+  bool                        getDeblockingFilterOverridePresentFlag() const            { return m_deblockingFilterOverridePresentFlag;                                                }
+  void                        setDeblockingFilterOverrideFlag( bool b )                 { m_deblockingFilterOverrideFlag = b;                                                          }
+  bool                        getDeblockingFilterOverrideFlag() const                   { return m_deblockingFilterOverrideFlag;                                                       }    
+  void                        setDeblockingFilterDisable( bool b )                      { m_deblockingFilterDisable= b;                                                                }  
+  bool                        getDeblockingFilterDisable() const                        { return m_deblockingFilterDisable;                                                            }
+  void                        setDeblockingFilterBetaOffsetDiv2( int i )                { m_deblockingFilterBetaOffsetDiv2 = i;                                                        }  
+  int                         getDeblockingFilterBetaOffsetDiv2()const                  { return m_deblockingFilterBetaOffsetDiv2;                                                     }
+  void                        setDeblockingFilterTcOffsetDiv2( int i )                  { m_deblockingFilterTcOffsetDiv2 = i;                                                          }  
+  int                         getDeblockingFilterTcOffsetDiv2() const                   { return m_deblockingFilterTcOffsetDiv2;                                                       }    
+  void                        setLmcsEnabledFlag(bool b)                                { m_lmcsEnabledFlag = b;                                                                       }
+  bool                        getLmcsEnabledFlag()                                      { return m_lmcsEnabledFlag;                                                                    }
+  const bool                  getLmcsEnabledFlag() const                                { return m_lmcsEnabledFlag;                                                                    }
+  void                        setLmcsAPS(APS* aps)                                      { m_lmcsAps = aps; m_lmcsApsId = (aps) ? aps->getAPSId() : -1;                                 }
+  APS*                        getLmcsAPS() const                                        { return m_lmcsAps;                                                                            }
+  void                        setLmcsAPSId(int id)                                      { m_lmcsApsId = id;                                                                            }
+  int                         getLmcsAPSId() const                                      { return m_lmcsApsId;                                                                          }
+  void                        setLmcsChromaResidualScaleFlag(bool b)                    { m_lmcsChromaResidualScaleFlag = b;                                                           }
+  bool                        getLmcsChromaResidualScaleFlag()                          { return m_lmcsChromaResidualScaleFlag;                                                        }
+  const bool                  getLmcsChromaResidualScaleFlag() const                    { return m_lmcsChromaResidualScaleFlag;                                                        }
+  void                        setScalingListAPS( APS* aps )                             { m_scalingListAps = aps; m_scalingListApsId = ( aps ) ? aps->getAPSId() : -1;                 }
+  APS*                        getScalingListAPS() const                                 { return m_scalingListAps;                                                                     }
+  void                        setScalingListAPSId( int id )                             { m_scalingListApsId = id;                                                                     }
+  int                         getScalingListAPSId() const                               { return m_scalingListApsId;                                                                   }
+  void                        setScalingListPresentFlag( bool b )                       { m_scalingListPresentFlag = b;                                                                }
+  bool                        getScalingListPresentFlag()                               { return m_scalingListPresentFlag;                                                             }
+  const bool                  getScalingListPresentFlag() const                         { return m_scalingListPresentFlag;                                                             }
+  
+  unsigned*                   getMinQTSizes() const                                     { return (unsigned *)m_minQT;                                                                  }
+  unsigned*                   getMaxMTTHierarchyDepths() const                          { return (unsigned *)m_maxMTTHierarchyDepth;                                                   }
+  unsigned*                   getMaxBTSizes() const                                     { return (unsigned *)m_maxBTSize;                                                              }
+  unsigned*                   getMaxTTSizes() const                                     { return (unsigned *)m_maxTTSize;                                                              }
+  
+  void                        setMinQTSize(unsigned idx, unsigned minQT)                { m_minQT[idx] = minQT;                                                                        }
+  void                        setMaxMTTHierarchyDepth(unsigned idx, unsigned maxMTT)    { m_maxMTTHierarchyDepth[idx] = maxMTT;                                                        }
+  void                        setMaxBTSize(unsigned idx, unsigned maxBT)                { m_maxBTSize[idx] = maxBT;                                                                    }
+  void                        setMaxTTSize(unsigned idx, unsigned maxTT)                { m_maxTTSize[idx] = maxTT;                                                                    }
+
+  void                        setMinQTSizes(unsigned*   minQT)                          { m_minQT[0] = minQT[0]; m_minQT[1] = minQT[1]; m_minQT[2] = minQT[2];                                                 }
+  void                        setMaxMTTHierarchyDepths(unsigned*   maxMTT)              { m_maxMTTHierarchyDepth[0] = maxMTT[0]; m_maxMTTHierarchyDepth[1] = maxMTT[1]; m_maxMTTHierarchyDepth[2] = maxMTT[2]; }
+  void                        setMaxBTSizes(unsigned*   maxBT)                          { m_maxBTSize[0] = maxBT[0]; m_maxBTSize[1] = maxBT[1]; m_maxBTSize[2] = maxBT[2];                                     }
+  void                        setMaxTTSizes(unsigned*   maxTT)                          { m_maxTTSize[0] = maxTT[0]; m_maxTTSize[1] = maxTT[1]; m_maxTTSize[2] = maxTT[2];                                     }
+    
+  unsigned                    getMinQTSize(SliceType   slicetype,
+                                       ChannelType chType = CHANNEL_TYPE_LUMA) const    { return slicetype == I_SLICE ? (chType == CHANNEL_TYPE_LUMA ? m_minQT[0] : m_minQT[2]) : m_minQT[1];                                              }
+  unsigned                    getMaxMTTHierarchyDepth(SliceType   slicetype,
+                                       ChannelType chType = CHANNEL_TYPE_LUMA) const    { return slicetype == I_SLICE ? (chType == CHANNEL_TYPE_LUMA ? m_maxMTTHierarchyDepth[0] : m_maxMTTHierarchyDepth[2]) : m_maxMTTHierarchyDepth[1]; }
+  unsigned                    getMaxBTSize(SliceType   slicetype,
+                                       ChannelType chType = CHANNEL_TYPE_LUMA) const    { return slicetype == I_SLICE ? (chType == CHANNEL_TYPE_LUMA ? m_maxBTSize[0] : m_maxBTSize[2]) : m_maxBTSize[1];                                  }
+  unsigned                    getMaxTTSize(SliceType   slicetype,
+                                       ChannelType chType = CHANNEL_TYPE_LUMA) const    { return slicetype == I_SLICE ? (chType == CHANNEL_TYPE_LUMA ? m_maxTTSize[0] : m_maxTTSize[2]) : m_maxTTSize[1];                                  }
+  
+  void                        setAlfAPSs(std::vector<int> apsIDs)                       { m_alfApsId.resize(m_numAlfAps);
+                                                                                          for (int i = 0; i < m_numAlfAps; i++)
+                                                                                          {
+                                                                                            m_alfApsId[i] = apsIDs[i];
+                                                                                          }
+                                                                                        }
+
+  std::vector<int>            getAlfAPSs() const                                        { return m_alfApsId; }
+
+};
+
+#endif
 /// slice header class
 class Slice
 {
@@ -1654,8 +1984,10 @@ class Slice
 private:
   //  Bitstream writing
   bool                       m_saoEnabledFlag[MAX_NUM_CHANNEL_TYPE];
+#if !JVET_P1006_PICTURE_HEADER
   int                        m_iPPSId;               ///< picture parameter set ID
   bool                       m_PicOutputFlag;        ///< pic_output_flag
+#endif
   int                        m_iPOC;
   int                        m_iLastIDR;
   int                        m_iAssociatedIRAP;
@@ -1674,7 +2006,9 @@ private:
   SliceType                  m_eSliceType;
   int                        m_iSliceQp;
   int                        m_iSliceQpBase;
+#if !JVET_P1006_PICTURE_HEADER
   bool                       m_ChromaQpAdjEnabled;
+#endif
   bool                       m_deblockingFilterDisable;
   bool                       m_deblockingFilterOverrideFlag;      //< offsets for deblocking filter inherit from PPS
   int                        m_deblockingFilterBetaOffsetDiv2;    //< beta offset for deblocking filter
@@ -1683,8 +2017,10 @@ private:
   int                        m_aiNumRefIdx   [NUM_REF_PIC_LIST_01];    //  for multiple reference of current slice
   bool                       m_pendingRasInit;
 
+#if !JVET_P1006_PICTURE_HEADER
   bool                       m_depQuantEnabledFlag;
   bool                       m_signDataHidingEnabledFlag;
+#endif
   bool                       m_bCheckLDC;
 
   bool                       m_biDirPred;
@@ -1707,19 +2043,26 @@ private:
   const SPS*                 m_pcSPS;
   const PPS*                 m_pcPPS;
   Picture*                   m_pcPic;
+#if JVET_P1006_PICTURE_HEADER
+  const PicHeader*           m_pcPicHeader;    //!< pointer to picture header structure
+#endif
   bool                       m_colFromL0Flag;  // collocated picture from List0 flag
 
+#if !JVET_P1006_PICTURE_HEADER
   bool                       m_noOutputPriorPicsFlag;
+#endif
   bool                       m_noIncorrectPicOutputFlag;
   bool                       m_handleCraAsCvsStartFlag;
 
   uint32_t                       m_colRefIdx;
+#if !JVET_P1006_PICTURE_HEADER
   uint32_t                       m_maxNumMergeCand;
   uint32_t                   m_maxNumAffineMergeCand;
   uint32_t                   m_maxNumTriangleCand;
   uint32_t                   m_maxNumIBCMergeCand;
   bool                       m_disFracMMVD;
   bool                       m_disBdofDmvrFlag;
+#endif
   double                     m_lambdas[MAX_NUM_COMPONENT];
 
   bool                       m_abEqualRef  [NUM_REF_PIC_LIST_01][MAX_NUM_REF][MAX_NUM_REF];
@@ -1749,18 +2092,25 @@ private:
 
   bool                       m_cabacInitFlag;
 
+#if !JVET_P1006_PICTURE_HEADER
   bool                       m_jointCbCrSignFlag;
-
+#endif
+  
+#if !JVET_P1006_PICTURE_HEADER
   bool                       m_bLMvdL1Zero;
   bool                       m_LFCrossSliceBoundaryFlag;
-
+#endif
+  
+#if !JVET_P1006_PICTURE_HEADER
   bool                       m_enableTMVPFlag;
+#endif
 
 
   SliceType                  m_encCABACTableIdx;           // Used to transmit table selection across slices.
 
   clock_t                    m_iProcessingStartTime;
   double                     m_dProcessingTime;
+#if !JVET_P1006_PICTURE_HEADER
   bool                       m_splitConsOverrideFlag;
   uint32_t                   m_uiMinQTSize;
   uint32_t                   m_uiMaxMTTHierarchyDepth;
@@ -1771,8 +2121,11 @@ private:
   uint32_t                   m_uiMaxBTSizeIChroma;
   uint32_t                   m_uiMaxTTSizeIChroma;
   uint32_t                   m_uiMaxBTSize;
-
+#endif
+  
+#if !JVET_P1006_PICTURE_HEADER
   int                        m_recoveryPocCnt;
+#endif
   int                        m_rpPicOrderCntVal;
   APS*                       m_alfApss[ALF_CTB_MAX_NUM_APS];
   bool                       m_tileGroupAlfEnabledFlag[MAX_NUM_COMPONENT];
@@ -1780,6 +2133,7 @@ private:
   std::vector<int>           m_tileGroupLumaApsId;
   int                        m_tileGroupChromaApsId;
   bool                       m_disableSATDForRd;
+#if !JVET_P1006_PICTURE_HEADER
   int                        m_lmcsApsId;
   APS*                       m_lmcsAps;
   bool                       m_tileGroupLmcsEnabledFlag;
@@ -1788,10 +2142,16 @@ private:
   APS*                       m_scalingListAps;
   bool                       m_tileGroupscalingListPresentFlag;
   bool                       m_nonReferencePicFlag;
+#endif
 public:
                               Slice();
   virtual                     ~Slice();
   void                        initSlice();
+#if JVET_P1006_PICTURE_HEADER
+  void                        inheritFromPicHeader( PicHeader *picHeader, const PPS *pps, const SPS *sps );
+  void                        setPicHeader( const PicHeader* pcPicHeader )           { m_pcPicHeader = pcPicHeader;                                  }
+  const PicHeader*            getPicHeader() const                                   { return m_pcPicHeader;                                         }
+#endif
   int                         getRefIdx4MVPair( RefPicList eCurRefPicList, int nCurRefIdx );
   void                        setDPS( DPS* dps )                                     { m_dps = dps;                                              }
   const DPS*                  getDPS() const                                         { return m_dps;                                               }
@@ -1799,13 +2159,20 @@ public:
   void                        setSPS( const SPS* pcSPS )                             { m_pcSPS = pcSPS;                                              }
   const SPS*                  getSPS() const                                         { return m_pcSPS;                                               }
 
+#if JVET_P1006_PICTURE_HEADER
+  void                        setPPS( const PPS* pcPPS )                             { m_pcPPS = pcPPS;                                              }
+#else
   void                        setPPS( const PPS* pcPPS )                             { m_pcPPS = pcPPS; m_iPPSId = (pcPPS) ? pcPPS->getPPSId() : -1; }
+#endif
   const PPS*                  getPPS() const                                         { return m_pcPPS;                                               }
 
+#if !JVET_P1006_PICTURE_HEADER
   void                        setPPSId( int PPSId )                                  { m_iPPSId = PPSId;                                             }
   int                         getPPSId() const                                       { return m_iPPSId;                                              }
+#endif
   void                        setAlfAPSs(APS** apss)                                 { memcpy(m_alfApss, apss, sizeof(m_alfApss));                   }
   APS**                       getAlfAPSs()                                           { return m_alfApss;                                             }
+#if !JVET_P1006_PICTURE_HEADER
   void                        setLmcsAPS(APS* lmcsAps)                               { m_lmcsAps = lmcsAps; m_lmcsApsId = (lmcsAps) ? lmcsAps->getAPSId() : -1; }
   APS*                        getLmcsAPS()                                           { return m_lmcsAps;                                            }
   void                        setLmcsAPSId(int lmcsApsId)                            { m_lmcsApsId = lmcsApsId;                                     }
@@ -1825,6 +2192,7 @@ public:
   const bool                  getscalingListPresentFlag()                      const { return m_tileGroupscalingListPresentFlag;                    }
   void                        setPicOutputFlag( bool b   )                           { m_PicOutputFlag = b;                                          }
   bool                        getPicOutputFlag() const                               { return m_PicOutputFlag;                                       }
+#endif
   void                        setSaoEnabledFlag(ChannelType chType, bool s)          {m_saoEnabledFlag[chType] =s;                                   }
   bool                        getSaoEnabledFlag(ChannelType chType) const            { return m_saoEnabledFlag[chType];                              }
   void                        setRPL0(const ReferencePictureList *pcRPL)             { m_pRPL0 = pcRPL;                                             }
@@ -1849,7 +2217,9 @@ public:
   bool                        getUseWeightedPrediction() const                       { return( (m_eSliceType==P_SLICE && testWeightPred()) || (m_eSliceType==B_SLICE && testWeightBiPred()) ); }
   int                         getSliceQpDelta() const                                { return m_iSliceQpDelta;                                       }
   int                         getSliceChromaQpDelta(ComponentID compID) const        { return isLuma(compID) ? 0 : m_iSliceChromaQpDelta[compID];    }
+#if !JVET_P1006_PICTURE_HEADER
   bool                        getUseChromaQpAdj() const                              { return m_ChromaQpAdjEnabled;                                  }
+#endif
   bool                        getDeblockingFilterDisable() const                     { return m_deblockingFilterDisable;                             }
   bool                        getDeblockingFilterOverrideFlag() const                { return m_deblockingFilterOverrideFlag;                        }
   int                         getDeblockingFilterBetaOffsetDiv2()const               { return m_deblockingFilterBetaOffsetDiv2;                      }
@@ -1869,7 +2239,9 @@ public:
   bool                        getIsUsedAsLongTerm(int i, int j) const                { return m_bIsUsedAsLongTerm[i][j];                             }
   void                        setIsUsedAsLongTerm(int i, int j, bool value)          { m_bIsUsedAsLongTerm[i][j] = value;                            }
   bool                        getCheckLDC() const                                    { return m_bCheckLDC;                                           }
+#if !JVET_P1006_PICTURE_HEADER
   bool                        getMvdL1ZeroFlag() const                               { return m_bLMvdL1Zero;                                         }
+#endif
   int                         getList1IdxToList0Idx( int list1Idx ) const            { return m_list1IdxToList0Idx[list1Idx];                        }
   void                        setPOC( int i )                                        { m_iPOC              = i;                                      }
   void                        setNalUnitType( NalUnitType e )                        { m_eNalUnitType      = e;                                      }
@@ -1887,7 +2259,9 @@ public:
   void                        setSliceQp( int i )                                    { m_iSliceQp          = i;                                      }
   void                        setSliceQpDelta( int i )                               { m_iSliceQpDelta     = i;                                      }
   void                        setSliceChromaQpDelta( ComponentID compID, int i )     { m_iSliceChromaQpDelta[compID] = isLuma(compID) ? 0 : i;       }
+#if !JVET_P1006_PICTURE_HEADER
   void                        setUseChromaQpAdj( bool b )                            { m_ChromaQpAdjEnabled = b;                                     }
+#endif
   void                        setDeblockingFilterDisable( bool b )                   { m_deblockingFilterDisable= b;                                 }
   void                        setDeblockingFilterOverrideFlag( bool b )              { m_deblockingFilterOverrideFlag = b;                           }
   void                        setDeblockingFilterBetaOffsetDiv2( int i )             { m_deblockingFilterBetaOffsetDiv2 = i;                         }
@@ -1903,7 +2277,9 @@ public:
   void                        setColFromL0Flag( bool colFromL0 )                     { m_colFromL0Flag = colFromL0;                                  }
   void                        setColRefIdx( uint32_t refIdx)                             { m_colRefIdx = refIdx;                                         }
   void                        setCheckLDC( bool b )                                  { m_bCheckLDC = b;                                              }
+#if !JVET_P1006_PICTURE_HEADER
   void                        setMvdL1ZeroFlag( bool b)                              { m_bLMvdL1Zero = b;                                            }
+#endif
 
   void                        setBiDirPred( bool b, int refIdx0, int refIdx1 ) { m_biDirPred = b; m_symRefIdx[0] = refIdx0; m_symRefIdx[1] = refIdx1; }
   bool                        getBiDirPred() const { return m_biDirPred; }
@@ -1929,6 +2305,7 @@ public:
   void                        setLambdas( const double lambdas[MAX_NUM_COMPONENT] )  { for (int component = 0; component < MAX_NUM_COMPONENT; component++) m_lambdas[component] = lambdas[component]; }
   const double*               getLambdas() const                                     { return m_lambdas;                                             }
 
+#if !JVET_P1006_PICTURE_HEADER
   void                        setSplitConsOverrideFlag(bool b)                       { m_splitConsOverrideFlag = b; }
   bool                        getSplitConsOverrideFlag() const                       { return m_splitConsOverrideFlag; }
   void                        setMinQTSize(int i)                                    { m_uiMinQTSize = i; }
@@ -1953,7 +2330,12 @@ public:
   bool                        getDepQuantEnabledFlag() const                         { return m_depQuantEnabledFlag; }
   void                        setSignDataHidingEnabledFlag( bool b )                 { m_signDataHidingEnabledFlag = b;              }
   bool                        getSignDataHidingEnabledFlag() const                   { return m_signDataHidingEnabledFlag;           }
+#endif
 
+#if JVET_P1006_PICTURE_HEADER
+  uint32_t                    getCuQpDeltaSubdiv() const                             { return this->isIntra() ? m_pcPicHeader->getCuQpDeltaSubdivIntra() : m_pcPicHeader->getCuQpDeltaSubdivInter(); }
+  uint32_t                    getCuChromaQpOffsetSubdiv() const                      { return this->isIntra() ? m_pcPicHeader->getCuChromaQpOffsetSubdivIntra() : m_pcPicHeader->getCuChromaQpOffsetSubdivInter(); }
+#endif
   void                        initEqualRef();
   bool                        isEqualRef( RefPicList e, int iRefIdx1, int iRefIdx2 )
   {
@@ -1987,6 +2369,7 @@ public:
   bool                        isStepwiseTemporalLayerSwitchingPointCandidate( PicList& rcListPic )                          const;
   int                         checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePictureList *pRPL, int rplIdx, bool printErrors)                const;
   void                        createExplicitReferencePictureSetFromReference(PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1);
+#if !JVET_P1006_PICTURE_HEADER
   void                        setMaxNumMergeCand(uint32_t val )                          { m_maxNumMergeCand = val;                                      }
   uint32_t                    getMaxNumMergeCand() const                             { return m_maxNumMergeCand;                                     }
   void                        setMaxNumAffineMergeCand( uint32_t val )               { m_maxNumAffineMergeCand = val;  }
@@ -2001,7 +2384,7 @@ public:
   bool                        getDisBdofDmvrFlag() const                             { return m_disBdofDmvrFlag;                                         }
   void                        setNoOutputPriorPicsFlag( bool val )                   { m_noOutputPriorPicsFlag = val;                                }
   bool                        getNoOutputPriorPicsFlag() const                       { return m_noOutputPriorPicsFlag;                               }
-
+#endif
   void                        setNoIncorrectPicOutputFlag(bool val)                  { m_noIncorrectPicOutputFlag = val;                             }
   bool                        getNoIncorrectPicOutputFlag() const                    { return m_noIncorrectPicOutputFlag;                                    }
 
@@ -2058,6 +2441,7 @@ public:
   void                        setCabacInitFlag( bool val )                           { m_cabacInitFlag = val;                                        } //!< set CABAC initial flag
   bool                        getCabacInitFlag()                               const { return m_cabacInitFlag;                                       } //!< get CABAC initial flag
 
+#if !JVET_P1006_PICTURE_HEADER
   void                        setJointCbCrSignFlag( bool b )                         { m_jointCbCrSignFlag = b; }
   bool                        getJointCbCrSignFlag()                           const { return m_jointCbCrSignFlag; }
 
@@ -2066,7 +2450,7 @@ public:
 
   void                        setEnableTMVPFlag( bool   b )                          { m_enableTMVPFlag = b;                                         }
   bool                        getEnableTMVPFlag() const                              { return m_enableTMVPFlag;                                      }
-
+#endif
   void                        setEncCABACTableIdx( SliceType idx )                   { m_encCABACTableIdx = idx;                                     }
   SliceType                   getEncCABACTableIdx() const                            { return m_encCABACTableIdx;                                    }
 
@@ -2102,16 +2486,22 @@ public:
   }
   void                        setDisableSATDForRD(bool b) { m_disableSATDForRd = b; }
   bool                        getDisableSATDForRD() { return m_disableSATDForRd; }
+#if JVET_P1006_PICTURE_HEADER
+  void                        scaleRefPicList( Picture *scaledRefPic[ ], PicHeader *picHeader, APS** apss, APS* lmcsAps, APS* scalingListAps, const bool isDecoder );
+#else
   void                        scaleRefPicList( Picture *scaledRefPic[ ], APS** apss, APS* lmcsAps, APS* scalingListAps, const bool isDecoder );
+#endif
   void                        freeScaledRefPicList( Picture *scaledRefPic[] );
   bool                        checkRPR();
   const std::pair<int, int>&  getScalingRatio( const RefPicList refPicList, const int refIdx )  const { return m_scalingRatio[refPicList][refIdx]; }
+#if !JVET_P1006_PICTURE_HEADER
   void                        setRecoveryPocCnt(int value) { m_recoveryPocCnt = value; }
   int                         getRecoveryPocCnt() const { return m_recoveryPocCnt; }
   void                        setRpPicOrderCntVal(int value) { m_rpPicOrderCntVal = value; }
   int                         getRpPicOrderCntVal() const { return m_rpPicOrderCntVal; }
   void                        setNonRefPictFlag(bool value) { m_nonReferencePicFlag = value; }
   bool                        getNonRefPictFlag() const { return m_nonReferencePicFlag;  }
+#endif
 
 protected:
 #if JVET_N0278_FIXES
@@ -2451,6 +2841,9 @@ void xTraceDPSHeader();
 void xTraceSPSHeader();
 void xTracePPSHeader();
 void xTraceAPSHeader();
+#if JVET_P1006_PICTURE_HEADER
+void xTracePictureHeader();
+#endif
 void xTraceSliceHeader();
 void xTraceAccessUnitDelimiter();
 #endif
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index a9ae67945..ff2d0db3b 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,8 @@
 #include <assert.h>
 #include <cassert>
 
+#define JVET_P1006_PICTURE_HEADER                         1 // JVET-P1006: Add picture header and related syntax changes
+
 #define JVET_P0365_SCALING_MATRIX_LFNST                   1 // JVET-P0365: Signal flag to indicate whether scaling matrices are used for LFNST-coded blocks
 
 #define JVET_P0243_SINGLE_BIT_DEPTH                       1 // JVET-P0243: Single bitdepth for luma and chroma
diff --git a/source/Lib/CommonLib/UnitPartitioner.cpp b/source/Lib/CommonLib/UnitPartitioner.cpp
index 68bf1fda1..7714d436e 100644
--- a/source/Lib/CommonLib/UnitPartitioner.cpp
+++ b/source/Lib/CommonLib/UnitPartitioner.cpp
@@ -348,8 +348,13 @@ void QTBTPartitioner::splitCurrArea( const PartSplit split, const CodingStructur
     currQtDepth++;
     currSubdiv++;
   }
+#if JVET_P1006_PICTURE_HEADER
+  qgEnable       &= (currSubdiv <= cs.slice->getCuQpDeltaSubdiv());
+  qgChromaEnable &= (currSubdiv <= cs.slice->getCuChromaQpOffsetSubdiv());
+#else
   qgEnable       &= (currSubdiv <= cs.pps->getCuQpDeltaSubdiv());
   qgChromaEnable &= (currSubdiv <= cs.pps->getCuChromaQpOffsetSubdiv());
+#endif
   m_partStack.back().qgEnable       = qgEnable;
   m_partStack.back().qgChromaEnable = qgChromaEnable;
   if (qgEnable)
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 9b8d09b8a..cfd51e71e 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -726,7 +726,11 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
 {
   const CodingStructure &cs = *pu.cs;
   const Slice &slice = *pu.cs->slice;
+#if JVET_P1006_PICTURE_HEADER
+  const uint32_t maxNumMergeCand = slice.getPicHeader()->getMaxNumIBCMergeCand();
+#else
   const uint32_t maxNumMergeCand = slice.getMaxNumIBCMergeCand();
+#endif
   const bool canFastExit = pu.cs->pps->getLog2ParallelMergeLevelMinus2() == 0;
 
   for (uint32_t ui = 0; ui < maxNumMergeCand; ++ui)
@@ -859,7 +863,11 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
 {
   const CodingStructure &cs  = *pu.cs;
   const Slice &slice         = *pu.cs->slice;
+#if JVET_P1006_PICTURE_HEADER
+  const uint32_t maxNumMergeCand = slice.getPicHeader()->getMaxNumMergeCand();
+#else
   const uint32_t maxNumMergeCand = slice.getMaxNumMergeCand();
+#endif
   const bool canFastExit     = pu.cs->pps->getLog2ParallelMergeLevelMinus2() == 0;
 
 
@@ -1142,7 +1150,11 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
     return;
   }
 
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getEnableTMVPFlag() && (pu.lumaSize().width + pu.lumaSize().height > 12))
+#else
   if (slice.getEnableTMVPFlag() && (pu.lumaSize().width + pu.lumaSize().height > 12))
+#endif
   {
     //>> MTK colocated-RightBottom
     // offset the pos to be sure to "point" to the same position the uiAbsPartIdx would've pointed to
@@ -1347,7 +1359,11 @@ bool PU::checkDMVRCondition(const PredictionUnit& pu)
   int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
   pu.cu->slice->getWpScaling(REF_PIC_LIST_0, refIdx0, wp0);
   pu.cu->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
+#if JVET_P1006_PICTURE_HEADER
+  if (pu.cs->sps->getUseDMVR() && (!pu.cs->picHeader->getDisBdofDmvrFlag()))
+#else
   if (pu.cs->sps->getUseDMVR() && (!pu.cs->slice->getDisBdofDmvrFlag()))
+#endif
   {
     return pu.mergeFlag
       && pu.mergeType == MRG_TYPE_DEFAULT_N
@@ -1830,7 +1846,11 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
     }
   }
 
+#if JVET_P1006_PICTURE_HEADER
+  if (cs.picHeader->getEnableTMVPFlag() && pInfo->numCand < AMVP_MAX_NUM_CANDS && (pu.lumaSize().width + pu.lumaSize().height > 12))
+#else
   if (cs.slice->getEnableTMVPFlag() && pInfo->numCand < AMVP_MAX_NUM_CANDS && (pu.lumaSize().width + pu.lumaSize().height > 12))
+#endif
   {
     // Get Temporal Motion Predictor
     const int refIdx_Col = refIdx;
@@ -2147,7 +2167,11 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
     }
 
     // Get Temporal Motion Predictor
+#if JVET_P1006_PICTURE_HEADER
+    if ( affiAMVPInfo.numCand < 2 && pu.cs->picHeader->getEnableTMVPFlag() )
+#else
     if ( affiAMVPInfo.numCand < 2 && pu.cs->slice->getEnableTMVPFlag() )
+#endif
     {
       const int refIdxCol = refIdx;
 
@@ -2513,7 +2537,11 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
 {
   const CodingStructure &cs = *pu.cs;
   const Slice &slice = *pu.cs->slice;
+#if JVET_P1006_PICTURE_HEADER
+  const uint32_t maxNumAffineMergeCand = slice.getPicHeader()->getMaxNumAffineMergeCand();
+#else
   const uint32_t maxNumAffineMergeCand = slice.getMaxNumAffineMergeCand();
+#endif
 
   for ( int i = 0; i < maxNumAffineMergeCand; i++ )
   {
@@ -2533,7 +2561,11 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
 
   bool enableSubPuMvp = slice.getSPS()->getSBTMVPEnabledFlag() && !(slice.getPOC() == slice.getRefPic(REF_PIC_LIST_0, 0)->getPOC() && slice.isIRAP());
   bool isAvailableSubPu = false;
+#if JVET_P1006_PICTURE_HEADER
+  if ( enableSubPuMvp && slice.getPicHeader()->getEnableTMVPFlag() )
+#else
   if ( enableSubPuMvp && slice.getEnableTMVPFlag() )
+#endif
   {
     MergeCtx mrgCtx = *affMrgCtx.mrgCtx;
     bool tmpLICFlag = false;
@@ -2702,7 +2734,11 @@ void PU::getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx
       }
 
       // control point: RB
+#if JVET_P1006_PICTURE_HEADER
+      if ( slice.getPicHeader()->getEnableTMVPFlag() )
+#else
       if ( slice.getEnableTMVPFlag() )
+#endif
       {
         //>> MTK colocated-RightBottom
         // offset the pos to be sure to "point" to the same position the uiAbsPartIdx would've pointed to
@@ -3181,7 +3217,11 @@ void PU::applyImv( PredictionUnit& pu, MergeCtx &mrgCtx, InterPrediction *interP
 
     if (pu.interDir != 1 /* PRED_L0 */)
     {
+#if JVET_P1006_PICTURE_HEADER
+      if( !( pu.cu->cs->picHeader->getMvdL1ZeroFlag() && pu.interDir == 3 ) && pu.cu->imv )/* PRED_BI */
+#else
       if( !( pu.cu->cs->slice->getMvdL1ZeroFlag() && pu.interDir == 3 ) && pu.cu->imv )/* PRED_BI */
+#endif
       {
         pu.mvd[1].changeTransPrecAmvr2Internal(pu.cu->imv);
       }
@@ -3270,7 +3310,11 @@ void PU::getTriangleMergeCandidates( const PredictionUnit &pu, MergeCtx& triangl
   MergeCtx tmpMergeCtx;
 
   const Slice &slice = *pu.cs->slice;
+#if JVET_P1006_PICTURE_HEADER
+  const uint32_t maxNumMergeCand = slice.getPicHeader()->getMaxNumMergeCand();
+#else
   const uint32_t maxNumMergeCand = slice.getMaxNumMergeCand();
+#endif
 
   triangleMrgCtx.numValidMergeCand = 0;
 
@@ -3437,7 +3481,11 @@ bool CU::hasSubCUNonZeroMVd( const CodingUnit& cu )
       }
       if( pu.interDir != 1 /* PRED_L0 */ )
       {
+#if JVET_P1006_PICTURE_HEADER
+        if( !pu.cu->cs->picHeader->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
+#else
         if( !pu.cu->cs->slice->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
+#endif
         {
           bNonZeroMvd |= pu.mvd[REF_PIC_LIST_1].getHor() != 0;
           bNonZeroMvd |= pu.mvd[REF_PIC_LIST_1].getVer() != 0;
@@ -3473,7 +3521,11 @@ bool CU::hasSubCUNonZeroAffineMVd( const CodingUnit& cu )
 
       if ( pu.interDir != 1 /* PRED_L0 */ )
       {
+#if JVET_P1006_PICTURE_HEADER
+        if ( !pu.cu->cs->picHeader->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
+#else
         if ( !pu.cu->cs->slice->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
+#endif
         {
           for ( int i = 0; i < ( cu.affineType == AFFINEMODEL_6PARAM ? 3 : 2 ); i++ )
           {
@@ -3867,7 +3919,11 @@ int TU::getICTMode( const TransformUnit& tu, int jointCbCr )
   {
     jointCbCr = tu.jointCbCr;
   }
+#if JVET_P1006_PICTURE_HEADER
+  return g_ictModes[ tu.cs->picHeader->getJointCbCrSignFlag() ][ jointCbCr ];
+#else
   return g_ictModes[ tu.cs->slice->getJointCbCrSignFlag() ][ jointCbCr ];
+#endif
 }
 
 bool TU::hasCrossCompPredInfo( const TransformUnit &tu, const ComponentID &compID )
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 265930594..3c22783a1 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -454,7 +454,11 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
     cuCtx.qgStart    = true;
     cuCtx.isDQPCoded = false;
   }
+#if JVET_P1006_PICTURE_HEADER
+  if( pps.getCuChromaQpOffsetEnabledFlag() && partitioner.currQgChromaEnable() )
+#else
   if( cs.slice->getUseChromaQpAdj() && partitioner.currQgChromaEnable() )
+#endif
   {
     cuCtx.isChromaQpAdjCoded  = false;
   }
@@ -467,7 +471,11 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
       pCuCtxChroma->qgStart    = true;
       pCuCtxChroma->isDQPCoded = false;
     }
+#if JVET_P1006_PICTURE_HEADER
+    if (pps.getCuChromaQpOffsetEnabledFlag() && pPartitionerChroma->currQgChromaEnable())
+#else
     if (cs.slice->getUseChromaQpAdj() && pPartitionerChroma->currQgChromaEnable())
+#endif
     {
       pCuCtxChroma->isChromaQpAdjCoded = false;
     }
@@ -1752,7 +1760,11 @@ void CABACReader::cu_palette_info(CodingUnit& cu, ComponentID compBegin, uint32_
       cuCtx.isDQPCoded = true;
     }
   }
+#if JVET_P1006_PICTURE_HEADER
+  if (cu.useEscape[compBegin] && cu.cs->pps->getCuChromaQpOffsetEnabledFlag() && !cuCtx.isChromaQpAdjCoded)
+#else
   if (cu.useEscape[compBegin] && cu.cs->slice->getUseChromaQpAdj() && !cuCtx.isChromaQpAdjCoded)
+#endif
   {
     if (!cu.isSepTree() || isChroma(tu.chType))
     {
@@ -2295,7 +2307,11 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx )
     pu.cu->affine = false;
     pu.refIdx[REF_PIC_LIST_0] = MAX_NUM_REF;
     mvd_coding(pu.mvd[REF_PIC_LIST_0]);
+#if JVET_P1006_PICTURE_HEADER
+    if ( pu.cu->slice->getPicHeader()->getMaxNumIBCMergeCand() == 1 )
+#else
     if ( pu.cu->slice->getMaxNumIBCMergeCand() == 1 )
+#endif
     {
       pu.mvpIdx[REF_PIC_LIST_0] = 0;
     }
@@ -2332,7 +2348,11 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx )
       if ( pu.cu->smvdMode != 1 )
       {
       ref_idx     ( pu, REF_PIC_LIST_1 );
+#if JVET_P1006_PICTURE_HEADER
+      if( pu.cu->cs->picHeader->getMvdL1ZeroFlag() && pu.interDir == 3 /* PRED_BI */ )
+#else
       if( pu.cu->cs->slice->getMvdL1ZeroFlag() && pu.interDir == 3 /* PRED_BI */ )
+#endif
       {
         pu.mvd[ REF_PIC_LIST_1 ] = Mv();
         pu.mvdAffi[REF_PIC_LIST_1][0] = Mv();
@@ -2399,7 +2419,11 @@ void CABACReader::subblock_merge_flag( CodingUnit& cu )
 {
   cu.affine = false;
 
+#if JVET_P1006_PICTURE_HEADER
+  if ( !cu.cs->slice->isIntra() && (cu.slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
+#else
   if ( !cu.cs->slice->isIntra() && (cu.slice->getMaxNumAffineMergeCand() > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
+#endif
   {
     RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__AFFINE_FLAG );
 
@@ -2468,7 +2492,11 @@ void CABACReader::merge_data( PredictionUnit& pu )
     }
 
     RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__MERGE_FLAG );
+#if JVET_P1006_PICTURE_HEADER
+    const bool triangleAvailable = pu.cu->cs->slice->getSPS()->getUseTriangle() && pu.cu->cs->slice->isInterB() && pu.cu->cs->picHeader->getMaxNumTriangleCand() > 1;
+#else
     const bool triangleAvailable = pu.cu->cs->slice->getSPS()->getUseTriangle() && pu.cu->cs->slice->isInterB() && pu.cu->cs->slice->getMaxNumTriangleCand() > 1;
+#endif
     const bool ciipAvailable = pu.cs->sps->getUseMHIntra() && !pu.cu->skip && pu.cu->lwidth() < MAX_CU_SIZE && pu.cu->lheight() < MAX_CU_SIZE;
     if (pu.cu->lwidth() * pu.cu->lheight() >= 64
       && (triangleAvailable || ciipAvailable))
@@ -2538,7 +2566,11 @@ void CABACReader::merge_idx( PredictionUnit& pu )
 
   if ( pu.cu->affine )
   {
+#if JVET_P1006_PICTURE_HEADER
+    int numCandminus1 = int( pu.cs->picHeader->getMaxNumAffineMergeCand() ) - 1;
+#else
     int numCandminus1 = int( pu.cs->slice->getMaxNumAffineMergeCand() ) - 1;
+#endif
     pu.mergeIdx = 0;
     if ( numCandminus1 > 0 )
     {
@@ -2558,7 +2590,11 @@ void CABACReader::merge_idx( PredictionUnit& pu )
   }
   else
   {
+#if JVET_P1006_PICTURE_HEADER
+  int numCandminus1 = int( pu.cs->picHeader->getMaxNumMergeCand() ) - 1;
+#else
   int numCandminus1 = int( pu.cs->slice->getMaxNumMergeCand() ) - 1;
+#endif
   pu.mergeIdx       = 0;
 
   if( pu.cu->triangle )
@@ -2585,7 +2621,11 @@ void CABACReader::merge_idx( PredictionUnit& pu )
       }
       return decIdx;
     };
+#if JVET_P1006_PICTURE_HEADER
+    const int maxNumTriangleCand = pu.cs->picHeader->getMaxNumTriangleCand();
+#else
     const int maxNumTriangleCand = pu.cs->slice->getMaxNumTriangleCand();
+#endif
     CHECK(maxNumTriangleCand < 2, "Incorrect max number of triangle candidates");
     candIdx0 = decodeOneIdx(maxNumTriangleCand - 1);
     candIdx1 = decodeOneIdx(maxNumTriangleCand - 2);
@@ -2601,7 +2641,11 @@ void CABACReader::merge_idx( PredictionUnit& pu )
 
   if (pu.cu->predMode == MODE_IBC)
   {
+#if JVET_P1006_PICTURE_HEADER
+    numCandminus1 = int(pu.cs->picHeader->getMaxNumIBCMergeCand()) - 1;
+#else
     numCandminus1 = int(pu.cs->slice->getMaxNumIBCMergeCand()) - 1;
+#endif
   }
   if( numCandminus1 > 0 )
   {
@@ -2626,7 +2670,11 @@ void CABACReader::mmvd_merge_idx(PredictionUnit& pu)
   RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET(STATS__CABAC_BITS__MERGE_INDEX);
 
   int var0 = 0;
+#if JVET_P1006_PICTURE_HEADER
+  if (pu.cs->picHeader->getMaxNumMergeCand() > 1)
+#else
   if (pu.cs->slice->getMaxNumMergeCand() > 1)
+#endif
   {
     static_assert(MMVD_BASE_MV_NUM == 2, "");
     var0 = m_BinDecoder.decodeBin(Ctx::MmvdMergeIdx());
@@ -3081,7 +3129,11 @@ void CABACReader::transform_unit( TransformUnit& tu, CUCtx& cuCtx, Partitioner&
     SizeType channelWidth = !cu.isSepTree() ? cu.lwidth() : cu.chromaSize().width;
     SizeType channelHeight = !cu.isSepTree() ? cu.lheight() : cu.chromaSize().height;
 
+#if JVET_P1006_PICTURE_HEADER
+    if (cu.cs->pps->getCuChromaQpOffsetEnabledFlag() && (channelWidth > 64 || channelHeight > 64 || cbfChroma) && !cuCtx.isChromaQpAdjCoded)
+#else
     if (cu.cs->slice->getUseChromaQpAdj() && (channelWidth > 64 || channelHeight > 64 || cbfChroma) && !cuCtx.isChromaQpAdjCoded)
+#endif
     {
       cu_chroma_qp_offset(cu);
       cuCtx.isChromaQpAdjCoded = true;
@@ -3223,7 +3275,11 @@ void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID, CUCtx&
   }
 
   // determine sign hiding
+#if JVET_P1006_PICTURE_HEADER
+  bool signHiding  = ( cu.cs->picHeader->getSignDataHidingEnabledFlag() && !cu.transQuantBypass && tu.rdpcm[compID] == RDPCM_OFF );
+#else
   bool signHiding  = ( cu.cs->slice->getSignDataHidingEnabledFlag() && !cu.transQuantBypass && tu.rdpcm[compID] == RDPCM_OFF );
+#endif
 #if JVET_P0058_CHROMA_TS
   if(  signHiding && CU::isIntra(cu) && CU::isRDPCMEnabled(cu) && tu.mtsIdx[compID] == MTS_SKIP )
 #else
@@ -3270,7 +3326,11 @@ void CABACReader::residual_coding( TransformUnit& tu, ComponentID compID, CUCtx&
 #endif
 
   // parse subblocks
+#if JVET_P1006_PICTURE_HEADER
+  const int stateTransTab = ( tu.cs->picHeader->getDepQuantEnabledFlag() ? 32040 : 0 );
+#else
   const int stateTransTab = ( tu.cs->slice->getDepQuantEnabledFlag() ? 32040 : 0 );
+#endif
   int       state         = 0;
 
   int ctxBinSampleRatio = (compID == COMPONENT_Y) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA;
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index 5876716f4..59e452134 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -263,8 +263,13 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
     }
   }
   const Slice           &slice = *cs.slice;
+#if JVET_P1006_PICTURE_HEADER
+  bool flag = slice.getPicHeader()->getLmcsEnabledFlag() && (slice.isIntra() || (!slice.isIntra() && m_pcReshape->getCTUFlag()));
+  if (flag && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() && (compID != COMPONENT_Y) && (tu.cbf[COMPONENT_Cb] || tu.cbf[COMPONENT_Cr]))
+#else
   bool flag = slice.getLmcsEnabledFlag() && (slice.isIntra() || (!slice.isIntra() && m_pcReshape->getCTUFlag()));
   if (flag && slice.getLmcsChromaResidualScaleFlag() && (compID != COMPONENT_Y) && (tu.cbf[COMPONENT_Cb] || tu.cbf[COMPONENT_Cr]))
+#endif
   {
     const Area area = tu.Y().valid() ? tu.Y() : Area(recalcPosition(tu.chromaFormat, tu.chType, CHANNEL_TYPE_LUMA, tu.blocks[tu.chType].pos()), recalcSize(tu.chromaFormat, tu.chType, CHANNEL_TYPE_LUMA, tu.blocks[tu.chType].size()));
     const CompArea &areaY = CompArea(COMPONENT_Y, tu.chromaFormat, area);
@@ -305,7 +310,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
 
   //===== reconstruction =====
   flag = flag && (tu.blocks[compID].width*tu.blocks[compID].height > 4);
+#if JVET_P1006_PICTURE_HEADER
+  if (flag && (TU::getCbf(tu, compID) || tu.jointCbCr) && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag())
+#else
   if (flag && (TU::getCbf(tu, compID) || tu.jointCbCr) && isChroma(compID) && slice.getLmcsChromaResidualScaleFlag())
+#endif
   {
     piResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(compID));
   }
@@ -328,7 +337,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
   CompArea    tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
   PelBuf tmpPred;
 #endif
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || slice.isIntra()) && compID == COMPONENT_Y)
+#else
   if (slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || slice.isIntra()) && compID == COMPONENT_Y)
+#endif
   {
 #if REUSE_CU_RESULTS
     {
@@ -345,7 +358,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID )
 #if !KEEP_PRED_AND_RESI_SIGNALS
   pReco.copyFrom( piPred );
 #endif
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || slice.isIntra()) && compID == COMPONENT_Y)
+#else
   if (slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || slice.isIntra()) && compID == COMPONENT_Y)
+#endif
   {
 #if REUSE_CU_RESULTS
     {
@@ -571,7 +588,11 @@ void DecCu::xReconInter(CodingUnit &cu)
 
   if (cu.firstPU->mhIntraFlag)
   {
+#if JVET_P1006_PICTURE_HEADER
+    if (cu.cs->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
     if (cu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
     {
       cu.cs->getPredBuf(*cu.firstPU).Y().rspSignal(m_pcReshape->getFwdLUT());
     }
@@ -603,7 +624,11 @@ void DecCu::xReconInter(CodingUnit &cu)
     CompArea    tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
     PelBuf tmpPred;
 #endif
+#if JVET_P1006_PICTURE_HEADER
+    if (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
     if (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
     {
 #if REUSE_CU_RESULTS
       if (cs.pcv->isEncoder)
@@ -621,7 +646,11 @@ void DecCu::xReconInter(CodingUnit &cu)
     cs.getResiBuf( cu ).reconstruct( cs.getPredBuf( cu ), cs.getResiBuf( cu ), cs.slice->clpRngs() );
     cs.getRecoBuf( cu ).copyFrom   (                      cs.getResiBuf( cu ) );
 #endif
+#if JVET_P1006_PICTURE_HEADER
+    if (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
     if (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
     {
 #if REUSE_CU_RESULTS
       if (cs.pcv->isEncoder)
@@ -634,7 +663,11 @@ void DecCu::xReconInter(CodingUnit &cu)
   else
   {
     cs.getRecoBuf(cu).copyClip(cs.getPredBuf(cu), cs.slice->clpRngs());
+#if JVET_P1006_PICTURE_HEADER
+    if (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && !cu.firstPU->mhIntraFlag && !CU::isIBC(cu))
+#else
     if (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && !cu.firstPU->mhIntraFlag && !CU::isIBC(cu))
+#endif
     {
       cs.getRecoBuf(cu).get(COMPONENT_Y).rspSignal(m_pcReshape->getFwdLUT());
     }
@@ -688,8 +721,13 @@ void DecCu::xDecodeInterTU( TransformUnit & currTU, const ComponentID compID )
 
   //===== reconstruction =====
   const Slice           &slice = *cs.slice;
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getLmcsEnabledFlag() && isChroma(compID) && (TU::getCbf(currTU, compID) || currTU.jointCbCr)
+   && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() && currTU.blocks[compID].width * currTU.blocks[compID].height > 4)
+#else
   if (slice.getLmcsEnabledFlag() && isChroma(compID) && (TU::getCbf(currTU, compID) || currTU.jointCbCr)
    && slice.getLmcsChromaResidualScaleFlag() && currTU.blocks[compID].width * currTU.blocks[compID].height > 4)
+#endif
   {
     resiBuf.scaleSignal(currTU.getChromaAdj(), 0, currTU.cu->cs->slice->clpRng(compID));
   }
@@ -716,7 +754,11 @@ void DecCu::xDecodeInterTexture(CodingUnit &cu)
     {
       CodingStructure  &cs = *cu.cs;
       const Slice &slice = *cs.slice;
+#if JVET_P1006_PICTURE_HEADER
+      if (slice.getPicHeader()->getLmcsEnabledFlag() && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() && (compID == COMPONENT_Y) && (currTU.cbf[COMPONENT_Cb] || currTU.cbf[COMPONENT_Cr]))
+#else
       if (slice.getLmcsEnabledFlag() && slice.getLmcsChromaResidualScaleFlag() && (compID == COMPONENT_Y) && (currTU.cbf[COMPONENT_Cb] || currTU.cbf[COMPONENT_Cr]))
+#endif
       {
         const CompArea &areaY = currTU.blocks[COMPONENT_Y];
         int adj = m_pcReshape->calculateChromaAdjVpduNei(currTU, areaY);
@@ -895,7 +937,11 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
           {
             mvd.changeIbcPrecAmvr2Internal(pu.cu->imv);
           }
+#if JVET_P1006_PICTURE_HEADER
+          if ( pu.cu->slice->getPicHeader()->getMaxNumIBCMergeCand() == 1 )
+#else
           if ( pu.cu->slice->getMaxNumIBCMergeCand() == 1 )
+#endif
           {
             CHECK( pu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" );
           }
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 473455a21..ab2ac638d 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -615,7 +615,11 @@ void DecLib::finishPictureLight(int& poc, PicList*& rpcListPic )
 {
   Slice*  pcSlice = m_pcPic->cs->slice;
 
+#if JVET_P1006_PICTURE_HEADER
+  m_pcPic->neededForOutput = (pcSlice->getPicHeader()->getPicOutputFlag() ? true : false);
+#else
   m_pcPic->neededForOutput = (pcSlice->getPicOutputFlag() ? true : false);
+#endif
   m_pcPic->reconstructed = true;
 
   Slice::sortPicList( m_cListPic ); // sorting for application output
@@ -659,7 +663,11 @@ void DecLib::finishPicture(int& poc, PicList*& rpcListPic, MsgLevel msgl )
     {
       const std::pair<int, int>& scaleRatio = pcSlice->getScalingRatio( RefPicList( iRefList ), iRefIndex );
 
+#if JVET_P1006_PICTURE_HEADER
+      if( pcSlice->getPicHeader()->getEnableTMVPFlag() && pcSlice->getColFromL0Flag() == bool(1 - iRefList) && pcSlice->getColRefIdx() == iRefIndex )
+#else
       if( pcSlice->getEnableTMVPFlag() && pcSlice->getColFromL0Flag() == bool(1 - iRefList) && pcSlice->getColRefIdx() == iRefIndex )
+#endif
       {
         if ( scaleRatio.first != 1 << SCALE_RATIO_BITS || scaleRatio.second != 1 << SCALE_RATIO_BITS )
           msg( msgl, "%dc(%1.2lfx, %1.2lfx) ", pcSlice->getRefPOC( RefPicList( iRefList ), iRefIndex ), double( scaleRatio.first ) / ( 1 << SCALE_RATIO_BITS ), double( scaleRatio.second ) / ( 1 << SCALE_RATIO_BITS ) );
@@ -689,7 +697,11 @@ void DecLib::finishPicture(int& poc, PicList*& rpcListPic, MsgLevel msgl )
 
   msg( msgl, "\n");
 
+#if JVET_P1006_PICTURE_HEADER
+  m_pcPic->neededForOutput = (pcSlice->getPicHeader()->getPicOutputFlag() ? true : false);
+#else
   m_pcPic->neededForOutput = (pcSlice->getPicOutputFlag() ? true : false);
+#endif
   m_pcPic->reconstructed = true;
 
 
@@ -701,6 +713,9 @@ void DecLib::finishPicture(int& poc, PicList*& rpcListPic, MsgLevel msgl )
   m_pcPic->destroyTempBuffers();
   m_pcPic->cs->destroyCoeffs();
   m_pcPic->cs->releaseIntermediateData();
+#if JVET_P1006_PICTURE_HEADER
+  m_pcPic->cs->picHeader->initPicHeader();
+#endif
 }
 
 void DecLib::checkNoOutputPriorPics (PicList* pcListPic)
@@ -815,10 +830,16 @@ void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag)
   cFillPic->referenced = true;
   cFillPic->longTerm = longTermFlag;
   cFillPic->slices[0]->setPOC(iUnavailablePoc);
+#if !JVET_P1006_PICTURE_HEADER
   cFillPic->slices[0]->setPicOutputFlag(false);
+#endif
   xUpdatePreviousTid0POC(cFillPic->slices[0]);
   cFillPic->reconstructed = true;
+#if JVET_P1006_PICTURE_HEADER
+  cFillPic->neededForOutput = false;
+#else
   cFillPic->neededForOutput = true;
+#endif
   if (m_pocRandomAccess == MAX_INT)
   {
     m_pocRandomAccess = iUnavailablePoc;
@@ -826,7 +847,11 @@ void DecLib::xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag)
 
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void activateAPS(PicHeader* picHeader, Slice* pSlice, ParameterSetManager& parameterSetManager, APS** apss, APS* lmcsAPS, APS* scalingListAPS)
+#else
 void activateAPS(Slice* pSlice, ParameterSetManager& parameterSetManager, APS** apss, APS* lmcsAPS, APS* scalingListAPS)
+#endif
 {
   //luma APSs
   if (pSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y))
@@ -867,14 +892,27 @@ void activateAPS(Slice* pSlice, ParameterSetManager& parameterSetManager, APS**
     }
   }
 
+#if JVET_P1006_PICTURE_HEADER
+  if (picHeader->getLmcsEnabledFlag() && lmcsAPS == nullptr)
+#else
   if (pSlice->getLmcsEnabledFlag() && lmcsAPS == nullptr)
+#endif
   {
+#if JVET_P1006_PICTURE_HEADER
+    lmcsAPS = parameterSetManager.getAPS(picHeader->getLmcsAPSId(), LMCS_APS);
+#else
     lmcsAPS = parameterSetManager.getAPS(pSlice->getLmcsAPSId(), LMCS_APS);
+#endif
     CHECK(lmcsAPS == nullptr, "No LMCS APS present");
     if (lmcsAPS)
     {
+#if JVET_P1006_PICTURE_HEADER
+      parameterSetManager.clearAPSChangedFlag(picHeader->getLmcsAPSId(), LMCS_APS);
+      if (false == parameterSetManager.activateAPS(picHeader->getLmcsAPSId(), LMCS_APS))
+#else
       parameterSetManager.clearAPSChangedFlag(pSlice->getLmcsAPSId(), LMCS_APS);
       if (false == parameterSetManager.activateAPS(pSlice->getLmcsAPSId(), LMCS_APS))
+#endif
       {
         THROW("LMCS APS activation failed!");
       }
@@ -883,16 +921,33 @@ void activateAPS(Slice* pSlice, ParameterSetManager& parameterSetManager, APS**
       //ToDO: APS NAL unit containing the APS RBSP shall have nuh_layer_id either equal to the nuh_layer_id of a coded slice NAL unit that referrs it, or equal to the nuh_layer_id of a direct dependent layer of the layer containing a coded slice NAL unit that referrs it.
     }
   }
+#if JVET_P1006_PICTURE_HEADER
+  picHeader->setLmcsAPS(lmcsAPS);
+#else
   pSlice->setLmcsAPS(lmcsAPS);
+#endif
 
+#if JVET_P1006_PICTURE_HEADER
+  if( picHeader->getScalingListPresentFlag() && scalingListAPS == nullptr)
+#else
   if( pSlice->getscalingListPresentFlag() && scalingListAPS == nullptr)
+#endif
   {
+#if JVET_P1006_PICTURE_HEADER
+    scalingListAPS = parameterSetManager.getAPS( picHeader->getScalingListAPSId(), SCALING_LIST_APS );
+#else
     scalingListAPS = parameterSetManager.getAPS( pSlice->getscalingListAPSId(), SCALING_LIST_APS );
+#endif
     CHECK( scalingListAPS == nullptr, "No SCALING LIST APS present" );
     if( scalingListAPS )
     {
+#if JVET_P1006_PICTURE_HEADER
+      parameterSetManager.clearAPSChangedFlag( picHeader->getScalingListAPSId(), SCALING_LIST_APS );
+      if( false == parameterSetManager.activateAPS( picHeader->getScalingListAPSId(), SCALING_LIST_APS ) )
+#else
       parameterSetManager.clearAPSChangedFlag( pSlice->getscalingListAPSId(), SCALING_LIST_APS );
       if( false == parameterSetManager.activateAPS( pSlice->getscalingListAPSId(), SCALING_LIST_APS ) )
+#endif
       {
         THROW( "SCALING LIST APS activation failed!" );
       }
@@ -901,7 +956,11 @@ void activateAPS(Slice* pSlice, ParameterSetManager& parameterSetManager, APS**
       //ToDO: APS NAL unit containing the APS RBSP shall have nuh_layer_id either equal to the nuh_layer_id of a coded slice NAL unit that referrs it, or equal to the nuh_layer_id of a direct dependent layer of the layer containing a coded slice NAL unit that referrs it.
     }
   }
+#if JVET_P1006_PICTURE_HEADER
+  picHeader->setScalingListAPS(scalingListAPS);
+#else
   pSlice->setscalingListAPS(scalingListAPS);
+#endif
 }
 
 #if JVET_N0278_FIXES
@@ -914,7 +973,11 @@ void DecLib::xActivateParameterSets()
   {
     APS** apss = m_parameterSetManager.getAPSs();
     memset(apss, 0, sizeof(*apss) * ALF_CTB_MAX_NUM_APS);
+#if JVET_P1006_PICTURE_HEADER
+    const PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId()); // this is a temporary PPS object. Do not store this value
+#else
     const PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId()); // this is a temporary PPS object. Do not store this value
+#endif
     CHECK(pps == 0, "No PPS present");
 
     const SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());             // this is a temporary SPS object. Do not store this value
@@ -922,12 +985,20 @@ void DecLib::xActivateParameterSets()
 
     if (NULL == pps->pcv)
     {
+#if JVET_P1006_PICTURE_HEADER
+      m_parameterSetManager.getPPS( m_picHeader.getPPSId() )->pcv = new PreCalcValues( *sps, *pps, false );
+#else
       m_parameterSetManager.getPPS( m_apcSlicePilot->getPPSId() )->pcv = new PreCalcValues( *sps, *pps, false );
+#endif
     }
     m_parameterSetManager.clearSPSChangedFlag(sps->getSPSId());
     m_parameterSetManager.clearPPSChangedFlag(pps->getPPSId());
 
+#if JVET_P1006_PICTURE_HEADER
+    if (false == m_parameterSetManager.activatePPS(m_picHeader.getPPSId(),m_apcSlicePilot->isIRAP()))
+#else
     if (false == m_parameterSetManager.activatePPS(m_apcSlicePilot->getPPSId(),m_apcSlicePilot->isIRAP()))
+#endif
     {
       THROW("Parameter set activation failed!");
     }
@@ -942,7 +1013,11 @@ void DecLib::xActivateParameterSets()
     }
     APS* lmcsAPS = nullptr;
     APS* scalinglistAPS = nullptr;
+#if JVET_P1006_PICTURE_HEADER
+    activateAPS(&m_picHeader, m_apcSlicePilot, m_parameterSetManager, apss, lmcsAPS, scalinglistAPS);
+#else
     activateAPS(m_apcSlicePilot, m_parameterSetManager, apss, lmcsAPS, scalinglistAPS);
+#endif
 
     xParsePrefixSEImessages();
 
@@ -961,8 +1036,16 @@ void DecLib::xActivateParameterSets()
 #endif
 
     m_apcSlicePilot->applyReferencePictureListBasedMarking(m_cListPic, m_apcSlicePilot->getRPL0(), m_apcSlicePilot->getRPL1());
+#if JVET_P1006_PICTURE_HEADER
+    m_pcPic->finalInit( *sps, *pps, &m_picHeader, apss, lmcsAPS, scalinglistAPS );
+#else
     m_pcPic->finalInit( *sps, *pps, apss, lmcsAPS, scalinglistAPS );
+#endif
+#if JVET_P1006_PICTURE_HEADER
+    m_parameterSetManager.getPPS(m_picHeader.getPPSId())->setNumBricksInPic((int)m_pcPic->brickMap->bricks.size());
+#else
     m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId())->setNumBricksInPic((int)m_pcPic->brickMap->bricks.size());
+#endif
     m_pcPic->createTempBuffers( m_pcPic->cs->pps->pcv->maxCUWidth );
     m_pcPic->cs->createCoeffs();
 
@@ -1052,8 +1135,13 @@ void DecLib::xActivateParameterSets()
     const SPS *sps = pSlice->getSPS();
     const PPS *pps = pSlice->getPPS();
     APS** apss = pSlice->getAlfAPSs();
+#if JVET_P1006_PICTURE_HEADER
+    APS *lmcsAPS = m_picHeader.getLmcsAPS();
+    APS *scalinglistAPS = m_picHeader.getScalingListAPS();
+#else
     APS *lmcsAPS = pSlice->getLmcsAPS();
     APS *scalinglistAPS = pSlice->getscalingListAPS();
+#endif
 
     // fix Parameter Sets, now that we have the real slice
     m_pcPic->cs->slice = pSlice;
@@ -1092,7 +1180,11 @@ void DecLib::xActivateParameterSets()
       EXIT( "Error - a new SCALING LIST APS has been decoded while processing a picture" );
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    activateAPS(&m_picHeader, pSlice, m_parameterSetManager, apss, lmcsAPS, scalinglistAPS);
+#else
     activateAPS(pSlice, m_parameterSetManager, apss, lmcsAPS, scalinglistAPS);
+#endif
 
     m_pcPic->cs->lmcsAps = lmcsAPS;
     m_pcPic->cs->scalinglistAps = scalinglistAPS;
@@ -1158,9 +1250,23 @@ void DecLib::xParsePrefixSEImessages()
   }
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void DecLib::xDecodePicHeader( InputNALUnit& nalu )
+{
+  m_HLSReader.setBitstream( &nalu.getBitstream() );
+  m_HLSReader.parsePictureHeader( &m_picHeader, &m_parameterSetManager);
+  m_picHeader.setValid();
+}
+#endif
 
 bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay )
 {
+#if JVET_P1006_PICTURE_HEADER
+  if(m_picHeader.isValid() == false) {
+    return false;
+  }
+  m_apcSlicePilot->setPicHeader( &m_picHeader );
+#endif
   m_apcSlicePilot->initSlice(); // the slice pilot is an object to prepare for a new slice
                                 // it is not associated with picture, sps or pps structures.
 
@@ -1201,7 +1307,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     CHECK(nalu.m_temporalId != 0, "Current GDR picture has TemporalId not equal to 0");
 
   m_HLSReader.setBitstream( &nalu.getBitstream() );
+#if JVET_P1006_PICTURE_HEADER
+  m_HLSReader.parseSliceHeader( m_apcSlicePilot, &m_picHeader, &m_parameterSetManager, m_prevTid0POC );
+#else
   m_HLSReader.parseSliceHeader( m_apcSlicePilot, &m_parameterSetManager, m_prevTid0POC );
+#endif
 
   // update independent slice index
   uint32_t uiIndependentSliceIdx = 0;
@@ -1213,7 +1323,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   m_apcSlicePilot->setIndependentSliceIdx(uiIndependentSliceIdx);
 
 #if K0149_BLOCK_STATISTICS
+#if JVET_P1006_PICTURE_HEADER
+  PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId());
+#else
   PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId());
+#endif
   CHECK(pps == 0, "No PPS present");
   SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
   CHECK(sps == 0, "No SPS present");
@@ -1253,12 +1367,20 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     {
       if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
       {
+#if JVET_P1006_PICTURE_HEADER
+        m_picHeader.setNoOutputOfPriorPicsFlag(true);
+#else
         m_apcSlicePilot->setNoOutputPriorPicsFlag(true);
+#endif
       }
     }
     else
     {
+#if JVET_P1006_PICTURE_HEADER
+      m_picHeader.setNoOutputOfPriorPicsFlag(false);
+#else
       m_apcSlicePilot->setNoOutputPriorPicsFlag(false);
+#endif
     }
 
     if (m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR)
@@ -1266,7 +1388,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
       m_lastNoIncorrectPicOutputFlag = m_apcSlicePilot->getNoIncorrectPicOutputFlag();
     }
   }
+#if JVET_P1006_PICTURE_HEADER
+  if ((m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) && m_picHeader.getNoOutputOfPriorPicsFlag())
+#else
   if ((m_apcSlicePilot->getRapPicFlag() || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) && m_apcSlicePilot->getNoOutputPriorPicsFlag())
+#endif
   {
     m_lastPOCNoOutputPriorPics = m_apcSlicePilot->getPOC();
     m_isNoOutputPriorPics = true;
@@ -1281,14 +1407,22 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   {
     if (m_lastNoIncorrectPicOutputFlag)
     {
+#if JVET_P1006_PICTURE_HEADER
+      m_picHeader.setPicOutputFlag(false);
+#else
       m_apcSlicePilot->setPicOutputFlag(false);
+#endif
     }
   }
 
   if ((m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || m_apcSlicePilot->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) &&
       m_lastNoIncorrectPicOutputFlag)                     //Reset POC MSB when CRA or GDR has NoIncorrectPicOutputFlag equal to 1
   {
+#if JVET_P1006_PICTURE_HEADER
+    PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId());
+#else
     PPS *pps = m_parameterSetManager.getPPS(m_apcSlicePilot->getPPSId());
+#endif
     CHECK(pps == 0, "No PPS present");
     SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
     CHECK(sps == 0, "No SPS present");
@@ -1452,7 +1586,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   pcSlice->checkSTSA(m_cListPic);
 #endif
 
+#if JVET_P1006_PICTURE_HEADER
+  pcSlice->scaleRefPicList( scaledRefPic, m_pcPic->cs->picHeader, m_parameterSetManager.getAPSs(), m_picHeader.getLmcsAPS(), m_picHeader.getScalingListAPS(), true );
+#else
   pcSlice->scaleRefPicList( scaledRefPic, m_parameterSetManager.getAPSs(), pcSlice->getLmcsAPS(), pcSlice->getscalingListAPS(), true );
+#endif
 
     if (!pcSlice->isIntra())
     {
@@ -1482,7 +1620,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     }
 
     if (pcSlice->getSPS()->getUseSMVD() && pcSlice->getCheckLDC() == false
+#if JVET_P1006_PICTURE_HEADER
+      && pcSlice->getPicHeader()->getMvdL1ZeroFlag() == false
+#else
       && pcSlice->getMvdL1ZeroFlag() == false
+#endif
       )
     {
       int currPOC = pcSlice->getPOC();
@@ -1580,9 +1722,17 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   if( pcSlice->getSPS()->getScalingListFlag() )
   {
     ScalingList scalingList;
+#if JVET_P1006_PICTURE_HEADER
+    if( pcSlice->getPicHeader()->getScalingListPresentFlag() )
+#else
     if( pcSlice->getscalingListPresentFlag() )
+#endif
     {
+#if JVET_P1006_PICTURE_HEADER
+      APS* scalingListAPS = pcSlice->getPicHeader()->getScalingListAPS();
+#else
       APS* scalingListAPS = pcSlice->getscalingListAPS();
+#endif
       scalingList = scalingListAPS->getScalingList();
     }
     else
@@ -1602,9 +1752,17 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
   {
     if (m_bFirstSliceInPicture)
       m_sliceLmcsApsId = -1;
+#if JVET_P1006_PICTURE_HEADER
+    if (pcSlice->getPicHeader()->getLmcsEnabledFlag())
+#else
     if (pcSlice->getLmcsEnabledFlag())
+#endif
     {
+#if JVET_P1006_PICTURE_HEADER
+      APS* lmcsAPS = pcSlice->getPicHeader()->getLmcsAPS();
+#else
       APS* lmcsAPS = pcSlice->getLmcsAPS();
+#endif
       if (m_sliceLmcsApsId == -1)
       {
         m_sliceLmcsApsId = lmcsAPS->getAPSId();
@@ -1622,8 +1780,13 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
 #if JVET_P0371_CHROMA_SCALING_OFFSET
       tInfo.chrResScalingOffset = sInfo.chrResScalingOffset;
 #endif
+#if JVET_P1006_PICTURE_HEADER
+      tInfo.setUseSliceReshaper(pcSlice->getPicHeader()->getLmcsEnabledFlag());
+      tInfo.setSliceReshapeChromaAdj(pcSlice->getPicHeader()->getLmcsChromaResidualScaleFlag());
+#else
       tInfo.setUseSliceReshaper(pcSlice->getLmcsEnabledFlag());
       tInfo.setSliceReshapeChromaAdj(pcSlice->getLmcsChromaResidualScaleFlag());
+#endif
       tInfo.setSliceReshapeModelPresentFlag(true);
     }
     else
@@ -1633,7 +1796,11 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
       tInfo.setSliceReshapeChromaAdj(false);
       tInfo.setSliceReshapeModelPresentFlag(false);
     }
+#if JVET_P1006_PICTURE_HEADER
+    if (pcSlice->getPicHeader()->getLmcsEnabledFlag())
+#else
     if (pcSlice->getLmcsEnabledFlag())
+#endif
     {
       m_cReshaper.constructReshaper();
     }
@@ -1773,6 +1940,13 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
     case NAL_UNIT_PPS:
       xDecodePPS( nalu );
       return false;
+#if JVET_P1006_PICTURE_HEADER
+
+    case NAL_UNIT_PH:
+      xDecodePicHeader(nalu);
+      return !m_bFirstSliceInPicture;
+#endif
+
 #if JVET_P0588_SUFFIX_APS
     case NAL_UNIT_PREFIX_APS:
     case NAL_UNIT_SUFFIX_APS:
@@ -1831,10 +2005,12 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay)
         AUDReader audReader;
         uint32_t picType;
         audReader.parseAccessUnitDelimiter(&(nalu.getBitstream()),picType);
+#if !JVET_P1006_PICTURE_HEADER
         // vectors clearing shall be moved to the right place if mandatory AUD starting an AU is removed
         m_accessUnitNals.clear();
         m_accessUnitApsNals.clear();
         m_accessUnitNals.push_back( std::pair<NalUnitType, int>( NAL_UNIT_ACCESS_UNIT_DELIMITER, nalu.m_temporalId ) );
+#endif
         return !m_bFirstSliceInPicture;
       }
 
diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h
index 7e8cc5e0b..32d3a1d42 100644
--- a/source/Lib/DecoderLib/DecLib.h
+++ b/source/Lib/DecoderLib/DecLib.h
@@ -77,6 +77,9 @@ private:
 
   PicList                 m_cListPic;         //  Dynamic buffer
   ParameterSetManager     m_parameterSetManager;  // storage for parameter sets
+#if JVET_P1006_PICTURE_HEADER
+  PicHeader               m_picHeader;            // picture header
+#endif
   Slice*                  m_apcSlicePilot;
 
 
@@ -173,6 +176,10 @@ public:
   void setDebugCTU( int debugCTU )        { m_debugCTU = debugCTU; }
   int  getDebugPOC( )               const { return m_debugPOC; };
   void setDebugPOC( int debugPOC )        { m_debugPOC = debugPOC; };
+#if JVET_P1006_PICTURE_HEADER
+  void resetAccessUnitNals()              { m_accessUnitNals.clear();    }
+  void resetAccessUnitApsNals()           { m_accessUnitApsNals.clear(); }
+#endif
 
 #if JVET_N0278_FIXES
   const VPS* getVPS()                     { return m_vps; }
@@ -192,7 +199,9 @@ protected:
   void  xCreateUnavailablePicture(int iUnavailablePoc, bool longTermFlag);
   void      xActivateParameterSets();
 #endif
-
+#if JVET_P1006_PICTURE_HEADER
+  void      xDecodePicHeader( InputNALUnit& nalu );
+#endif
   bool      xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay);
   void      xDecodeVPS( InputNALUnit& nalu );
   void      xDecodeDPS( InputNALUnit& nalu );
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index b4a5da395..ff0b2c915 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -87,8 +87,13 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
   cs.pps              = slice->getPPS();
   memcpy(cs.alfApss, slice->getAlfAPSs(), sizeof(cs.alfApss));
 
+ #if JVET_P1006_PICTURE_HEADER
+  cs.lmcsAps          = slice->getPicHeader()->getLmcsAPS();
+  cs.scalinglistAps   = slice->getPicHeader()->getScalingListAPS();
+#else
   cs.lmcsAps = slice->getLmcsAPS();
   cs.scalinglistAps   = slice->getscalingListAPS();
+#endif
 
   cs.pcv              = slice->getPPS()->pcv;
   cs.chromaQpAdj      = 0;
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index dd2dddafa..d4fc96565 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -388,6 +388,30 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana
 
   READ_FLAG( uiCode, "output_flag_present_flag" );                    pcPPS->setOutputFlagPresentFlag( uiCode==1 );
 
+#if JVET_P1006_PICTURE_HEADER 
+  READ_FLAG(uiCode, "pps_subpic_id_signalling_present_flag");              pcPPS->setSubPicIdSignallingPresentFlag( uiCode != 0 );
+  if( pcPPS->getSubPicIdSignallingPresentFlag() )
+  {
+    READ_UVLC( uiCode, "pps_num_subpics_minus1" );                         pcPPS->setNumSubPics( uiCode + 1 );
+    CHECK( uiCode > MAX_NUM_SUB_PICS-1,  "Number of sub-pictures exceeds limit");
+
+    READ_UVLC( uiCode, "pps_subpic_id_len_minus1" );                       pcPPS->setSubPicIdLen( uiCode + 1 );
+    CHECK( uiCode > 15, "Invalid pps_subpic_id_len_minus1 signalled");
+
+    for( int picIdx = 0; picIdx < pcPPS->getNumSubPics( ); picIdx++ )
+    {
+      READ_CODE( pcPPS->getSubPicIdLen( ), uiCode, "pps_subpic_id[i]" );   pcPPS->setSubPicId( picIdx, uiCode );
+    }
+  }
+  else 
+  {
+    for( int picIdx = 0; picIdx < MAX_NUM_SUB_PICS; picIdx++ )
+    {
+      pcPPS->setSubPicId( picIdx, picIdx );
+    }
+  }
+
+#endif
   READ_CODE(3, uiCode, "num_extra_slice_header_bits");                pcPPS->setNumExtraSliceHeaderBits(uiCode);
 
 
@@ -446,6 +470,7 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana
   }
 
   READ_FLAG( uiCode, "cu_qp_delta_enabled_flag" );            pcPPS->setUseDQP( uiCode ? true : false );
+#if !JVET_P1006_PICTURE_HEADER 
   if( pcPPS->getUseDQP() )
   {
     READ_UVLC( uiCode, "cu_qp_delta_subdiv" );
@@ -455,6 +480,7 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana
   {
     pcPPS->setCuQpDeltaSubdiv( 0 );
   }
+#endif
   READ_SVLC( iCode, "pps_cb_qp_offset");
   pcPPS->setQpOffset(COMPONENT_Cb, iCode);
   CHECK( pcPPS->getQpOffset(COMPONENT_Cb) < -12, "Invalid Cb QP offset" );
@@ -494,11 +520,15 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana
   if (uiCode == 0)
   {
     pcPPS->clearChromaQpOffsetList();
+#if !JVET_P1006_PICTURE_HEADER
     pcPPS->setCuChromaQpOffsetSubdiv(0);
+#endif
   }
   else
   {
+#if !JVET_P1006_PICTURE_HEADER
     READ_UVLC(uiCode, "cu_chroma_qp_offset_subdiv"); pcPPS->setCuChromaQpOffsetSubdiv(uiCode);
+#endif
     uint32_t tableSizeMinus1 = 0;
     READ_UVLC(tableSizeMinus1, "chroma_qp_offset_list_len_minus1");
     CHECK(tableSizeMinus1 >= MAX_QP_OFFSET_LIST_SIZE, "Table size exceeds maximum");
@@ -813,6 +843,7 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana
     }
   }
 
+#if !JVET_P1006_PICTURE_HEADER 
   READ_FLAG( uiCode, "pps_loop_filter_across_virtual_boundaries_disabled_flag" ); pcPPS->setLoopFilterAcrossVirtualBoundariesDisabledFlag( uiCode != 0 );
   if( pcPPS->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
   {
@@ -827,12 +858,17 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana
       READ_CODE(13, uiCode, "pps_virtual_boundaries_pos_y");        pcPPS->setVirtualBoundariesPosY(uiCode << 3, i);
     }
   }
+#endif
 
 
 
   READ_UVLC( uiCode, "log2_parallel_merge_level_minus2");
   pcPPS->setLog2ParallelMergeLevelMinus2 (uiCode);
 
+#if JVET_P1006_PICTURE_HEADER 
+  READ_FLAG( uiCode, "picture_header_extension_present_flag");
+  pcPPS->setPictureHeaderExtensionPresentFlag(uiCode);
+#endif
   READ_FLAG( uiCode, "slice_segment_header_extension_present_flag");
   pcPPS->setSliceHeaderExtensionPresentFlag(uiCode);
 
@@ -1206,11 +1242,39 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   if( pcSPS->getChromaFormatIdc() == CHROMA_444 )
   {
     READ_FLAG(     uiCode, "separate_colour_plane_flag");        CHECK(uiCode != 0, "Invalid code");
+#if JVET_P1006_PICTURE_HEADER
+    pcSPS->setSeparateColourPlaneFlag( uiCode != 0 );
+#endif
   }
 
   READ_UVLC( uiCode, "pic_width_max_in_luma_samples" );          pcSPS->setMaxPicWidthInLumaSamples( uiCode );
   READ_UVLC( uiCode, "pic_height_max_in_luma_samples" );         pcSPS->setMaxPicHeightInLumaSamples( uiCode );
 
+#if JVET_P1006_PICTURE_HEADER
+  pcSPS->setNumSubPics( 1 );  // TODO - need sub-picture syntax
+  READ_FLAG(uiCode, "sps_subpic_id_present_flag");                           pcSPS->setSubPicIdPresentFlag( uiCode != 0 );
+  if( pcSPS->getSubPicIdPresentFlag() )
+  {
+    READ_FLAG(uiCode, "sps_subpic_id_signalling_present_flag");              pcSPS->setSubPicIdSignallingPresentFlag( uiCode != 0 );
+    if( pcSPS->getSubPicIdSignallingPresentFlag() )
+    {
+      READ_UVLC( uiCode, "sps_subpic_id_len_minus1" );                       pcSPS->setSubPicIdLen( uiCode + 1 );
+      CHECK( uiCode > 15, "Invalid sps_subpic_id_len_minus1 signalled");
+      for( int picIdx = 0; picIdx < pcSPS->getNumSubPics( ); picIdx++ )
+      {
+        READ_CODE( pcSPS->getSubPicIdLen( ), uiCode, "sps_subpic_id[i]" );   pcSPS->setSubPicId( picIdx, uiCode );
+      }
+    }
+  }
+  if( pcSPS->getSubPicIdPresentFlag() == false || pcSPS->getSubPicIdSignallingPresentFlag() == false )
+  {
+    for( int picIdx = 0; picIdx < pcSPS->getNumSubPics( ); picIdx++ )
+    {
+      pcSPS->setSubPicId( picIdx, picIdx );
+    }
+  }
+#endif
+
 #if JVET_P0243_SINGLE_BIT_DEPTH
   READ_UVLC(     uiCode, "bit_depth_minus8" );
   CHECK(uiCode > 8, "Invalid bit depth signalled");
@@ -1570,6 +1634,28 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   // KJS: remove scaling lists?
   READ_FLAG( uiCode, "scaling_list_enabled_flag" );                 pcSPS->setScalingListFlag ( uiCode );
 
+#if JVET_P1006_PICTURE_HEADER
+  READ_FLAG( uiCode, "sps_loop_filter_across_virtual_boundaries_disabled_present_flag" ); pcSPS->setLoopFilterAcrossVirtualBoundariesDisabledFlag( uiCode != 0 );
+  if( pcSPS->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
+  {
+    READ_CODE( 2, uiCode, "sps_num_ver_virtual_boundaries");        pcSPS->setNumVerVirtualBoundaries( uiCode );
+    for( unsigned i = 0; i < pcSPS->getNumVerVirtualBoundaries(); i++ )
+    {
+      READ_CODE(13, uiCode, "sps_virtual_boundaries_pos_x");        pcSPS->setVirtualBoundariesPosX(uiCode << 3, i);
+    }
+    READ_CODE( 2, uiCode, "sps_num_hor_virtual_boundaries");        pcSPS->setNumHorVirtualBoundaries( uiCode );
+    for( unsigned i = 0; i < pcSPS->getNumHorVirtualBoundaries(); i++ )
+    {
+      READ_CODE(13, uiCode, "sps_virtual_boundaries_pos_y");        pcSPS->setVirtualBoundariesPosY(uiCode << 3, i);
+    }
+  }
+  else
+  {
+    pcSPS->setNumVerVirtualBoundaries( 0 );
+    pcSPS->setNumHorVirtualBoundaries( 0 );
+  }
+
+#endif
   TimingInfo *timingInfo = pcSPS->getTimingInfo();
   READ_FLAG(     uiCode, "general_hrd_parameters_present_flag");        pcSPS->setHrdParametersPresentFlag(uiCode);
   if( pcSPS->getHrdParametersPresentFlag() )
@@ -1713,7 +1799,676 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
   xReadRbspTrailingBits();
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, ParameterSetManager *parameterSetManager )
+{
+  uint32_t  uiCode; 
+  int       iCode;
+  PPS*      pps = NULL;
+  SPS*      sps = NULL;
+  
+#if ENABLE_TRACING
+  xTracePictureHeader();
+#endif
+
+  READ_FLAG(uiCode, "non_reference_picture_flag");       picHeader->setNonReferencePictureFlag( uiCode != 0 );
+  READ_FLAG(uiCode, "gdr_pic_flag");                     picHeader->setGdrPicFlag( uiCode != 0 );
+  READ_FLAG(uiCode, "no_output_of_prior_pics_flag");     picHeader->setNoOutputOfPriorPicsFlag( uiCode != 0 );
+  if( picHeader->getGdrPicFlag() ) 
+  {
+    READ_UVLC(uiCode, "recovery_poc_cnt");               picHeader->setRecoveryPocCnt( uiCode );
+  }
+  else 
+  {
+    picHeader->setRecoveryPocCnt( 0 );
+  }
+  
+  // parameter sets
+  READ_UVLC(uiCode, "ph_pic_parameter_set_id");
+  picHeader->setPPSId( uiCode );
+  pps = parameterSetManager->getPPS(picHeader->getPPSId());
+  CHECK(pps==0, "Invalid PPS");  
+  picHeader->setSPSId( pps->getSPSId() );
+  sps = parameterSetManager->getSPS(picHeader->getSPSId());
+  CHECK(sps==0, "Invalid SPS");
+  
+  // sub-picture IDs
+  if( sps->getSubPicIdPresentFlag() ) 
+  {
+    if( sps->getSubPicIdSignallingPresentFlag() ) 
+    {
+      for( int picIdx = 0; picIdx < sps->getNumSubPics( ); picIdx++ )
+      {
+        picHeader->setSubPicId( picIdx, sps->getSubPicId( picIdx ) );
+      }
+    }
+    else 
+    {
+      READ_FLAG(uiCode, "ph_subpic_id_signalling_present_flag");                 picHeader->setSubPicIdSignallingPresentFlag( uiCode != 0 );
+      if( picHeader->getSubPicIdSignallingPresentFlag() )
+      {
+        READ_UVLC( uiCode, "ph_subpic_id_len_minus1" );                          picHeader->setSubPicIdLen( uiCode + 1 );
+        CHECK( uiCode > 15, "Invalid ph_subpic_id_len_minus1 signalled");
+        for( int picIdx = 0; picIdx < sps->getNumSubPics( ); picIdx++ )
+        {
+          READ_CODE( picHeader->getSubPicIdLen( ), uiCode, "ph_subpic_id[i]" );   picHeader->setSubPicId( picIdx, uiCode );
+        }
+      }
+      else 
+      {
+        for( int picIdx = 0; picIdx < sps->getNumSubPics( ); picIdx++ )
+        {
+          picHeader->setSubPicId( picIdx, pps->getSubPicId( picIdx ) );
+        }
+      }
+    }
+  }
+  else 
+  {
+    for( int picIdx = 0; picIdx < sps->getNumSubPics( ); picIdx++ )
+    {
+      picHeader->setSubPicId( picIdx, picIdx );
+    }
+  }
+
+  // virtual boundaries
+  if( !sps->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
+  {
+    READ_FLAG( uiCode, "ph_loop_filter_across_virtual_boundaries_disabled_present_flag" ); picHeader->setLoopFilterAcrossVirtualBoundariesDisabledFlag( uiCode != 0 );
+    if( picHeader->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
+    {
+      READ_CODE( 2, uiCode, "ph_num_ver_virtual_boundaries");        picHeader->setNumVerVirtualBoundaries( uiCode );
+      for( unsigned i = 0; i < picHeader->getNumVerVirtualBoundaries(); i++ )
+      {
+        READ_CODE(13, uiCode, "ph_virtual_boundaries_pos_x");        picHeader->setVirtualBoundariesPosX(uiCode << 3, i);
+      }
+      READ_CODE( 2, uiCode, "ph_num_hor_virtual_boundaries");        picHeader->setNumHorVirtualBoundaries( uiCode );
+      for( unsigned i = 0; i < picHeader->getNumHorVirtualBoundaries(); i++ )
+      {
+        READ_CODE(13, uiCode, "ph_virtual_boundaries_pos_y");        picHeader->setVirtualBoundariesPosY(uiCode << 3, i);
+      }
+    }
+    else
+    {
+      picHeader->setNumVerVirtualBoundaries( 0 );
+      picHeader->setNumHorVirtualBoundaries( 0 );
+    }
+  }
+  else
+  {
+    picHeader->setLoopFilterAcrossVirtualBoundariesDisabledFlag( sps->getLoopFilterAcrossVirtualBoundariesDisabledFlag() );
+    picHeader->setNumVerVirtualBoundaries( sps->getNumVerVirtualBoundaries() );
+    picHeader->setNumHorVirtualBoundaries( sps->getNumHorVirtualBoundaries() );
+    for( unsigned i = 0; i < 3; i++ ) 
+    {
+      picHeader->setVirtualBoundariesPosX( sps->getVirtualBoundariesPosX(i), i );
+      picHeader->setVirtualBoundariesPosY( sps->getVirtualBoundariesPosY(i), i );
+    }
+  }
+  
+  // 4:4:4 colour plane ID
+  if( sps->getSeparateColourPlaneFlag() )	
+  {
+    READ_CODE( 2, uiCode, "colour_plane_id" ); picHeader->setColourPlaneId( uiCode );
+    CHECK(uiCode > 2, "colour_plane_id exceeds valid range");
+  }
+  else 
+  {
+    picHeader->setColourPlaneId( 0 );
+  }
+
+  // picture output flag
+  if( pps->getOutputFlagPresentFlag() )	
+  {
+    READ_FLAG( uiCode, "pic_output_flag" ); picHeader->setPicOutputFlag( uiCode != 0 );
+  }
+  else 
+  {
+    picHeader->setPicOutputFlag( true );
+  }
+
+  // reference picture lists
+  READ_FLAG( uiCode, "pic_rpl_present_flag" ); picHeader->setPicRplPresentFlag( uiCode != 0 );
+  if( picHeader->getPicRplPresentFlag() )
+  {	
+    // List0 and List1
+    for(int listIdx = 0; listIdx < 2; listIdx++) 
+    {                 
+      // copy L1 index from L0 index
+      if (listIdx == 1 && !pps->getRpl1IdxPresentFlag())
+      {
+        picHeader->setRPL1idx(picHeader->getRPL0idx());
+        uiCode = (picHeader->getRPL0idx() != -1);
+      }
+      // RPL in picture header or SPS
+      else if (sps->getNumRPL( listIdx ) == 0)
+      {
+        uiCode = 0;
+      }
+      else if (!pps->getPPSRefPicListSPSIdc( listIdx ))
+      {
+        READ_FLAG(uiCode, "pic_rpl_sps_flag[i]");
+      }
+      else
+      {
+        uiCode = pps->getPPSRefPicListSPSIdc( listIdx ) - 1;
+      }
+
+      // explicit RPL in picture header
+      if (!uiCode)
+      {
+        ReferencePictureList* rpl = picHeader->getLocalRPL( listIdx );
+        (*rpl) = ReferencePictureList();
+        parseRefPicList(sps, rpl);
+        picHeader->setRPLIdx(listIdx, -1);
+        picHeader->setRPL(listIdx, rpl);
+      }
+      // use list from SPS
+      else 
+      { 
+        if (listIdx == 1 && !pps->getRpl1IdxPresentFlag())
+        {
+          picHeader->setRPL( listIdx, sps->getRPLList( listIdx )->getReferencePictureList(picHeader->getRPLIdx( listIdx )));
+        }
+        else if (sps->getNumRPL( listIdx ) > 1)
+        {
+          int numBits = ceilLog2(sps->getNumRPL( listIdx ));
+          READ_CODE(numBits, uiCode, "pic_rpl_idx[i]");
+          picHeader->setRPLIdx( listIdx, uiCode );
+          picHeader->setRPL( listIdx, sps->getRPLList( listIdx )->getReferencePictureList(uiCode));
+        }
+        else
+        {
+          picHeader->setRPLIdx( listIdx, 0 );
+          picHeader->setRPL( listIdx, sps->getRPLList( listIdx )->getReferencePictureList(0));
+        }
+      }
+
+      // POC MSB cycle signalling for LTRP
+      for (int i = 0; i < picHeader->getRPL( listIdx )->getNumberOfLongtermPictures() + picHeader->getRPL( listIdx )->getNumberOfShorttermPictures(); i++)
+      {
+        picHeader->getLocalRPL( listIdx )->setDeltaPocMSBPresentFlag(i, false);
+        picHeader->getLocalRPL( listIdx )->setDeltaPocMSBCycleLT(i, 0);
+      }
+      if (picHeader->getRPL( listIdx )->getNumberOfLongtermPictures())
+      {
+        for (int i = 0; i < picHeader->getRPL( listIdx )->getNumberOfLongtermPictures() + picHeader->getRPL( listIdx )->getNumberOfShorttermPictures(); i++)
+        {
+          if (picHeader->getRPL( listIdx )->isRefPicLongterm(i))
+          {
+            if (picHeader->getRPL( listIdx )->getLtrpInSliceHeaderFlag())
+            {
+              READ_CODE(sps->getBitsForPOC(), uiCode, "pic_poc_lsb_lt[i][j]");
+              picHeader->getLocalRPL( listIdx )->setRefPicIdentifier(i, uiCode, true);
+            }
+            READ_FLAG(uiCode, "pic_delta_poc_msb_present_flag[i][j]");
+            picHeader->getLocalRPL( listIdx )->setDeltaPocMSBPresentFlag(i, uiCode ? true : false);
+            if (uiCode)
+            {
+              READ_UVLC(uiCode, "pic_delta_poc_msb_cycle_lt[i][j]");
+              picHeader->getLocalRPL( listIdx )->setDeltaPocMSBCycleLT(i, uiCode);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // partitioning constraint overrides
+  if (sps->getSplitConsOverrideEnabledFlag())
+  {
+    READ_FLAG(uiCode, "partition_constraints_override_flag");  picHeader->setSplitConsOverrideFlag( uiCode != 0 );
+    if (picHeader->getSplitConsOverrideFlag())
+    {
+      unsigned  minQT[3]     = { 0, 0, 0 };
+      unsigned  maxBTD[3]    = { 0, 0, 0 };
+      unsigned  maxBTSize[3] = { 0, 0, 0 };
+      unsigned  maxTTSize[3] = { 0, 0, 0 };
+      unsigned  ctbLog2SizeY = floorLog2(sps->getCTUSize());
+
+      READ_UVLC(uiCode, "pic_log2_diff_min_qt_min_cb_intra_slice_luma");
+      unsigned minQtLog2SizeIntraY = uiCode + sps->getLog2MinCodingBlockSize();
+      minQT[0] = 1 << minQtLog2SizeIntraY;
+      READ_UVLC(uiCode, "pic_log2_diff_min_qt_min_cb_inter_slice");
+      unsigned minQtLog2SizeInterY = uiCode + sps->getLog2MinCodingBlockSize();
+      minQT[1] = 1 << minQtLog2SizeInterY;
+      READ_UVLC(uiCode, "pic_max_mtt_hierarchy_depth_inter_slice");              maxBTD[1] = uiCode;
+      READ_UVLC(uiCode, "pic_max_mtt_hierarchy_depth_intra_slice_luma");         maxBTD[0] = uiCode;
+
+      maxTTSize[0] = maxBTSize[0] = minQT[0];
+      if (maxBTD[0] != 0)
+      {
+        READ_UVLC(uiCode, "pic_log2_diff_max_bt_min_qt_intra_slice_luma");       maxBTSize[0] <<= uiCode;
+        CHECK(uiCode > ctbLog2SizeY - minQtLog2SizeIntraY, "Invalid code");
+        READ_UVLC(uiCode, "pic_log2_diff_max_tt_min_qt_intra_slice_luma");       maxTTSize[0] <<= uiCode;
+        CHECK(uiCode > ctbLog2SizeY - minQtLog2SizeIntraY, "Invalid code");
+      }
+      maxTTSize[1] = maxBTSize[1] = minQT[1];
+      if (maxBTD[1] != 0)
+      {
+        READ_UVLC(uiCode, "pic_log2_diff_max_bt_min_qt_inter_slice");            maxBTSize[1] <<= uiCode;
+        CHECK(uiCode > ctbLog2SizeY - minQtLog2SizeInterY, "Invalid code");
+        READ_UVLC(uiCode, "pic_log2_diff_max_tt_min_qt_inter_slice");            maxTTSize[1] <<= uiCode;
+        CHECK(uiCode > ctbLog2SizeY - minQtLog2SizeInterY, "Invalid code");
+      }
+      if (sps->getUseDualITree())
+      {
+        READ_UVLC(uiCode, "pic_log2_diff_min_qt_min_cb_intra_slice_chroma");     minQT[2] = 1 << (uiCode + sps->getLog2MinCodingBlockSize());
+        READ_UVLC(uiCode, "pic_max_mtt_hierarchy_depth_intra_slice_chroma");     maxBTD[2] = uiCode;
+        maxTTSize[2] = maxBTSize[2] = minQT[2];
+        if (maxBTD[2] != 0)
+        {
+          READ_UVLC(uiCode, "pic_log2_diff_max_bt_min_qt_intra_slice_chroma");   maxBTSize[2] <<= uiCode;
+          READ_UVLC(uiCode, "pic_log2_diff_max_tt_min_qt_intra_slice_chroma");   maxTTSize[2] <<= uiCode;
+        }
+      }
+
+      picHeader->setMinQTSizes(minQT);
+      picHeader->setMaxMTTHierarchyDepths(maxBTD);
+      picHeader->setMaxBTSizes(maxBTSize);
+      picHeader->setMaxTTSizes(maxTTSize);
+    }
+  }
+  else
+  {
+    picHeader->setSplitConsOverrideFlag(0);
+  }
+
+  // inherit constraint values from SPS
+  if (!sps->getSplitConsOverrideEnabledFlag() || !picHeader->getSplitConsOverrideFlag()) 
+  {
+    picHeader->setMinQTSizes(sps->getMinQTSizes());
+    picHeader->setMaxMTTHierarchyDepths(sps->getMaxMTTHierarchyDepths());
+    picHeader->setMaxBTSizes(sps->getMaxBTSizes());
+    picHeader->setMaxTTSizes(sps->getMaxTTSizes());
+  }
+
+  // delta quantization and chrom and chroma offset
+  if (pps->getUseDQP())
+  {
+    READ_UVLC( uiCode, "pic_cu_qp_delta_subdiv_intra_slice" );   picHeader->setCuQpDeltaSubdivIntra( uiCode );
+    READ_UVLC( uiCode, "pic_cu_qp_delta_subdiv_inter_slice" );   picHeader->setCuQpDeltaSubdivInter( uiCode );
+  }
+  else 
+  {
+    picHeader->setCuQpDeltaSubdivIntra( 0 );
+    picHeader->setCuQpDeltaSubdivInter( 0 );
+  }
+  if (pps->getCuChromaQpOffsetEnabledFlag())
+  {
+    READ_UVLC( uiCode, "pic_cu_chroma_qp_offset_subdiv_intra_slice" );   picHeader->setCuChromaQpOffsetSubdivIntra( uiCode );
+    READ_UVLC( uiCode, "pic_cu_chroma_qp_offset_subdiv_inter_slice" );   picHeader->setCuChromaQpOffsetSubdivInter( uiCode );
+  }
+  else 
+  {
+    picHeader->setCuChromaQpOffsetSubdivIntra( 0 );
+    picHeader->setCuChromaQpOffsetSubdivInter( 0 );
+  }
+  
+  // temporal motion vector prediction
+  if (sps->getSPSTemporalMVPEnabledFlag())
+  {
+#if JVET_P0206_TMVP_flags
+    READ_FLAG( uiCode, "pic_temporal_mvp_enabled_flag" );
+    picHeader->setEnableTMVPFlag( uiCode != 0 );
+#else
+    if (!pps->getPPSTemporalMVPEnabledIdc()) 
+    {
+      READ_FLAG( uiCode, "pic_temporal_mvp_enabled_flag" );
+      picHeader->setEnableTMVPFlag( uiCode != 0 );
+    }
+    else 
+    {
+      pcSlice->setEnableTMVPFlag((pps->getPPSTemporalMVPEnabledIdc() - 1) == 1 ? true : false);
+    }
+#endif
+  }
+  else
+  {
+    picHeader->setEnableTMVPFlag(false);
+  }
+
+  // mvd L1 zero flag
+  if (!pps->getPPSMvdL1ZeroIdc())
+  {
+    READ_FLAG(uiCode, "pic_mvd_l1_zero_flag");
+  }
+  else
+  {
+    uiCode = pps->getPPSMvdL1ZeroIdc() - 1;
+  }
+  picHeader->setMvdL1ZeroFlag( uiCode != 0 );
+     
+  // merge candidate list size
+  if (!pps->getPPSSixMinusMaxNumMergeCandPlus1())
+  {
+    READ_UVLC(uiCode, "pic_six_minus_max_num_merge_cand");
+  }
+  else
+  {
+    uiCode = pps->getPPSSixMinusMaxNumMergeCandPlus1() - 1;
+  }
+  CHECK(MRG_MAX_NUM_CANDS <= uiCode, "Incorrrect max number of merge candidates!");
+  picHeader->setMaxNumMergeCand(MRG_MAX_NUM_CANDS - uiCode);
+
+  // subblock merge candidate list size
+  if ( sps->getUseAffine() )
+  {
+#if JVET_P0152_REMOVE_PPS_NUM_SUBBLOCK_MERGE_CAND
+    READ_UVLC(uiCode, "pic_five_minus_max_num_subblock_merge_cand");
+#else
+    if (!pps->getPPSFiveMinusMaxNumSubblockMergeCandPlus1())
+    {
+      READ_UVLC(uiCode, "five_minus_max_num_subblock_merge_cand");
+    }
+    else
+    {
+      uiCode = pps->getPPSFiveMinusMaxNumSubblockMergeCandPlus1() - 1;
+    }
+#endif
+    CHECK(AFFINE_MRG_MAX_NUM_CANDS < uiCode, "Incorrrect max number of affine merge candidates!");
+    picHeader->setMaxNumAffineMergeCand( AFFINE_MRG_MAX_NUM_CANDS - uiCode );
+  }
+  else
+  {
+    picHeader->setMaxNumAffineMergeCand( sps->getSBTMVPEnabledFlag() && picHeader->getEnableTMVPFlag() );
+  }
+
+  // full-pel MMVD flag
+  if (sps->getFpelMmvdEnabledFlag())
+  {
+    READ_FLAG( uiCode, "pic_fpel_mmvd_enabled_flag" );
+    picHeader->setDisFracMMVD( uiCode != 0 );
+  }
+  else
+  {
+    picHeader->setDisFracMMVD(false);
+  }
+  
+  // picture level BDOF/DMVR/PROF disable flags
+  if (sps->getBdofDmvrSlicePresentFlag())
+  {
+    READ_FLAG(uiCode, "pic_disable_bdof_dmvr_flag");  picHeader->setDisBdofDmvrFlag( uiCode != 0 );
+  }
+  else
+  {
+    picHeader->setDisBdofDmvrFlag(0);
+  }
+
+  // triangle merge candidate list size
+  if (sps->getUseTriangle() && picHeader->getMaxNumMergeCand() >= 2)
+  {
+    if (!pps->getPPSMaxNumMergeCandMinusMaxNumTriangleCandPlus1())
+    {
+      READ_UVLC(uiCode, "pic_max_num_merge_cand_minus_max_num_triangle_cand");
+    }
+    else
+    {
+      uiCode = pps->getPPSMaxNumMergeCandMinusMaxNumTriangleCandPlus1() - 1;
+    }
+    CHECK(picHeader->getMaxNumMergeCand() < uiCode, "Incorrrect max number of triangle candidates!");
+    picHeader->setMaxNumTriangleCand((uint32_t)(picHeader->getMaxNumMergeCand() - uiCode));
+  }
+  else
+  {
+    picHeader->setMaxNumTriangleCand(0);
+  }
+
+  // ibc merge candidate list size
+  if (sps->getIBCFlag())
+  {
+    READ_UVLC(uiCode, "pic_six_minus_max_num_ibc_merge_cand");
+    CHECK(IBC_MRG_MAX_NUM_CANDS <= uiCode, "Incorrrect max number of IBC merge candidates!");
+    picHeader->setMaxNumIBCMergeCand(IBC_MRG_MAX_NUM_CANDS - uiCode);
+  }
+  else 
+   {
+    picHeader->setMaxNumIBCMergeCand(0);
+  }
+
+  // joint Cb/Cr sign flag
+  if (sps->getJointCbCrEnabledFlag())
+  {
+    READ_FLAG( uiCode, "pic_joint_cbcr_sign_flag" ); 
+    picHeader->setJointCbCrSignFlag(uiCode != 0);
+  }
+  else
+  {
+    picHeader->setJointCbCrSignFlag(false);
+  }
+
+  // sao enable flags
+  if(sps->getSAOEnabledFlag())
+  {
+    READ_FLAG(uiCode, "pic_sao_enabled_present_flag");  
+    picHeader->setSaoEnabledPresentFlag(uiCode != 0);
+
+    if (picHeader->getSaoEnabledPresentFlag())
+    {    
+      READ_FLAG(uiCode, "slice_sao_luma_flag");  
+      picHeader->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, uiCode != 0);
+
+      if (sps->getChromaFormatIdc() != CHROMA_400)
+      {
+        READ_FLAG(uiCode, "slice_sao_chroma_flag");  
+        picHeader->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, uiCode != 0);
+      }
+    }
+    else 
+    {
+      picHeader->setSaoEnabledFlag(CHANNEL_TYPE_LUMA,   true);
+      picHeader->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() != CHROMA_400);
+    }
+  }
+  else 
+  {
+    picHeader->setSaoEnabledFlag(CHANNEL_TYPE_LUMA,   false);
+    picHeader->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, false);
+  }
+  
+  // alf enable flags and aps IDs
+  if( sps->getALFEnabledFlag() )
+  {
+    READ_FLAG(uiCode, "pic_alf_enabled_present_flag");  
+    picHeader->setAlfEnabledPresentFlag(uiCode != 0);
+
+    if (picHeader->getAlfEnabledPresentFlag()) 
+    {
+      READ_FLAG(uiCode, "pic_alf_enabled_flag");
+      picHeader->setAlfEnabledFlag(COMPONENT_Y, uiCode);
+
+      int alfChromaIdc = 0;
+      if (uiCode)
+      {
+        READ_CODE(3, uiCode, "pic_num_alf_aps_ids_luma");
+        int numAps = uiCode;
+        picHeader->setNumAlfAps(numAps);
+
+        std::vector<int> apsId(numAps, -1);
+        for (int i = 0; i < numAps; i++)
+        {
+          READ_CODE(3, uiCode, "pic_alf_aps_id_luma");
+          apsId[i] = uiCode;
+        }
+        picHeader->setAlfAPSs(apsId);
+
+        if (sps->getChromaFormatIdc() != CHROMA_400)
+        {
+          READ_CODE(2, uiCode, "pic_alf_chroma_idc");
+          alfChromaIdc = uiCode;
+        }
+        else
+        {
+          alfChromaIdc = 0;
+        }
+        if (alfChromaIdc)
+        {
+          READ_CODE(3, uiCode, "pic_alf_aps_id_chroma");
+          picHeader->setAlfApsIdChroma(uiCode);
+        }
+      }
+      else
+      {
+        picHeader->setNumAlfAps(0);
+      }
+      picHeader->setAlfEnabledFlag(COMPONENT_Cb, alfChromaIdc & 1);
+      picHeader->setAlfEnabledFlag(COMPONENT_Cr, alfChromaIdc >> 1);
+    }
+    else 
+    {
+      picHeader->setAlfEnabledFlag(COMPONENT_Y,  true);
+      picHeader->setAlfEnabledFlag(COMPONENT_Cb, true);
+      picHeader->setAlfEnabledFlag(COMPONENT_Cr, true);
+    }
+  }
+  else 
+  {
+    picHeader->setAlfEnabledFlag(COMPONENT_Y,  false);
+    picHeader->setAlfEnabledFlag(COMPONENT_Cb, false);
+    picHeader->setAlfEnabledFlag(COMPONENT_Cr, false);
+  }
+
+  // dependent quantization
+  if (!pps->getPPSDepQuantEnabledIdc())
+  {
+    READ_FLAG(uiCode, "pic_dep_quant_enabled_flag");
+  }
+  else
+  {
+    uiCode = pps->getPPSDepQuantEnabledIdc() - 1;
+  }
+  picHeader->setDepQuantEnabledFlag( uiCode != 0 );
+
+  // sign data hiding
+  if( !picHeader->getDepQuantEnabledFlag() )
+  {
+    READ_FLAG( uiCode, "pic_sign_data_hiding_enabled_flag" );
+    picHeader->setSignDataHidingEnabledFlag( uiCode != 0 );
+  }
+  else
+  {
+    picHeader->setSignDataHidingEnabledFlag(false);
+  }
+
+  // deblocking filter controls
+  if (pps->getDeblockingFilterControlPresentFlag())
+  {
+    if(pps->getDeblockingFilterOverrideEnabledFlag())
+    {
+      READ_FLAG ( uiCode, "pic_deblocking_filter_override_present_flag" );
+      picHeader->setDeblockingFilterOverridePresentFlag(uiCode != 0);
+    
+      if( picHeader->getDeblockingFilterOverridePresentFlag() ) 
+      {
+        READ_FLAG ( uiCode, "pic_deblocking_filter_override_flag" );
+        picHeader->setDeblockingFilterOverrideFlag(uiCode != 0);
+      }
+      else
+      {
+        picHeader->setDeblockingFilterOverrideFlag(false);
+      }
+    }
+    else
+    {
+      picHeader->setDeblockingFilterOverridePresentFlag(false);
+      picHeader->setDeblockingFilterOverrideFlag(false);
+    }
+
+    if(picHeader->getDeblockingFilterOverrideFlag())
+    {
+      READ_FLAG ( uiCode, "pic_deblocking_filter_disabled_flag" );
+      picHeader->setDeblockingFilterDisable(uiCode != 0);
+      if(!picHeader->getDeblockingFilterDisable())
+      {
+        READ_SVLC( iCode, "pic_beta_offset_div2" );
+        picHeader->setDeblockingFilterBetaOffsetDiv2(iCode);
+        CHECK(  picHeader->getDeblockingFilterBetaOffsetDiv2() < -6 &&
+                picHeader->getDeblockingFilterBetaOffsetDiv2() >  6, "Invalid deblocking filter configuration");
+
+        READ_SVLC( iCode, "pic_tc_offset_div2" );
+        picHeader->setDeblockingFilterTcOffsetDiv2(iCode);
+        CHECK  (picHeader->getDeblockingFilterTcOffsetDiv2() < -6 &&
+                picHeader->getDeblockingFilterTcOffsetDiv2() >  6, "Invalid deblocking filter configuration");
+      }
+    }
+    else
+    {
+      picHeader->setDeblockingFilterDisable       ( pps->getPPSDeblockingFilterDisabledFlag() );
+      picHeader->setDeblockingFilterBetaOffsetDiv2( pps->getDeblockingFilterBetaOffsetDiv2() );
+      picHeader->setDeblockingFilterTcOffsetDiv2  ( pps->getDeblockingFilterTcOffsetDiv2() );
+    }
+  }
+  else
+  {
+    picHeader->setDeblockingFilterDisable       ( false );
+    picHeader->setDeblockingFilterBetaOffsetDiv2( 0 );
+    picHeader->setDeblockingFilterTcOffsetDiv2  ( 0 );
+  }
+
+  // luma mapping / chroma scaling controls
+  if (sps->getUseReshaper())
+  {
+    READ_FLAG(uiCode, "pic_lmcs_enabled_flag");
+    picHeader->setLmcsEnabledFlag(uiCode != 0);
+
+    if (picHeader->getLmcsEnabledFlag())
+    {
+      READ_CODE(2, uiCode, "pic_lmcs_aps_id");
+      picHeader->setLmcsAPSId(uiCode);
+
+      if (sps->getChromaFormatIdc() != CHROMA_400)
+      {
+        READ_FLAG(uiCode, "pic_chroma_residual_scale_flag");
+        picHeader->setLmcsChromaResidualScaleFlag(uiCode != 0);
+      }
+      else
+      {
+        picHeader->setLmcsChromaResidualScaleFlag(false);
+      }
+    }
+  }
+  else
+  {
+    picHeader->setLmcsEnabledFlag(false);
+    picHeader->setLmcsChromaResidualScaleFlag(false);
+  }
+
+  // quantization scaling lists
+  if( sps->getScalingListFlag() )
+  {
+    READ_FLAG( uiCode, "pic_scaling_list_present_flag" );
+    picHeader->setScalingListPresentFlag( uiCode );
+    if( picHeader->getScalingListPresentFlag() )
+    {
+      READ_CODE( 3, uiCode, "pic_scaling_list_aps_id" );
+      picHeader->setScalingListAPSId( uiCode );
+    }
+  }
+  else 
+  {
+    picHeader->setScalingListPresentFlag( false );
+  }
+
+  // picture header extension
+  if(pps->getPictureHeaderExtensionPresentFlag())
+  {
+    READ_UVLC(uiCode,"pic_segment_header_extension_length");
+    for(int i=0; i<uiCode; i++)
+    {
+      uint32_t ignore_;
+      READ_CODE(8,ignore_,"pic_segment_header_extension_data_byte");
+    }
+  }
+
+  xReadRbspTrailingBits();
+}
+#endif
+
+#if JVET_P1006_PICTURE_HEADER
+void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, ParameterSetManager *parameterSetManager, const int prevTid0POC)
+#else
 void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *parameterSetManager, const int prevTid0POC)
+#endif
 {
   uint32_t  uiCode;
   int   iCode;
@@ -1724,9 +2479,15 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
   PPS* pps = NULL;
   SPS* sps = NULL;
 
+#if JVET_P1006_PICTURE_HEADER
+  CHECK(picHeader==0, "Invalid Picture Header");
+  CHECK(picHeader->isValid()==false, "Invalid Picture Header");
+  pps = parameterSetManager->getPPS( picHeader->getPPSId() );
+#else
   READ_UVLC(uiCode, "slice_pic_parameter_set_id");
   pcSlice->setPPSId(uiCode);
   pps = parameterSetManager->getPPS(uiCode);
+#endif
   //!KS: need to add error handling code here, if PPS is not available
   CHECK(pps==0, "Invalid PPS");
   sps = parameterSetManager->getSPS(pps->getSPSId());
@@ -1737,6 +2498,36 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
   const uint32_t numValidComp=getNumberValidComponents(chFmt);
   const bool bChroma=(chFmt!=CHROMA_400);
 
+#if JVET_P1006_PICTURE_HEADER
+  // picture order count
+  READ_CODE(sps->getBitsForPOC(), uiCode, "slice_pic_order_cnt_lsb");
+  if (pcSlice->getIdrPicFlag())
+  {
+    pcSlice->setPOC(uiCode);
+  }
+  else
+  {
+    int iPOClsb = uiCode;
+    int iPrevPOC = prevTid0POC;
+    int iMaxPOClsb = 1 << sps->getBitsForPOC();
+    int iPrevPOClsb = iPrevPOC & (iMaxPOClsb - 1);
+    int iPrevPOCmsb = iPrevPOC - iPrevPOClsb;
+    int iPOCmsb;
+    if ((iPOClsb  <  iPrevPOClsb) && ((iPrevPOClsb - iPOClsb) >= (iMaxPOClsb / 2)))
+    {
+      iPOCmsb = iPrevPOCmsb + iMaxPOClsb;
+    }
+    else if ((iPOClsb  >  iPrevPOClsb) && ((iPOClsb - iPrevPOClsb)  >  (iMaxPOClsb / 2)))
+    {
+      iPOCmsb = iPrevPOCmsb - iMaxPOClsb;
+    }
+    else
+    {
+      iPOCmsb = iPrevPOCmsb;
+    }
+    pcSlice->setPOC(iPOCmsb + iPOClsb);
+  }
+#endif
     int bitsSliceAddress = 1;
     if (!pps->getRectSliceFlag())
     {
@@ -1797,15 +2588,24 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
     }
     pcSlice->setSliceCurStartCtuTsAddr(pcSlice->getSliceCurStartBrickIdx());
 
+#if !JVET_P1006_PICTURE_HEADER
     READ_FLAG(uiCode, "non_reference_picture_flag");  pcSlice->setNonRefPictFlag(uiCode);
 
     for (int i = 0; i < pps->getNumExtraSliceHeaderBits(); i++)
     {
       READ_FLAG(uiCode, "slice_reserved_flag[]"); // ignored
     }
+#endif
 
     READ_UVLC (    uiCode, "slice_type" );            pcSlice->setSliceType((SliceType)uiCode);
 
+#if JVET_P1006_PICTURE_HEADER    
+    // inherit values from picture header
+    //   set default values in case slice overrides are disabled
+    pcSlice->inheritFromPicHeader( picHeader, pps, sps );
+#endif
+
+#if !JVET_P1006_PICTURE_HEADER
     // if (separate_colour_plane_flag == 1)
     //   read colour_plane_id
     //   (separate_colour_plane_flag == 1) is not supported in this version of the standard.
@@ -1858,8 +2658,20 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
     {
       pcSlice->setPicOutputFlag(true);
     }
+#endif
 
+#if JVET_P1006_PICTURE_HEADER
+    if( picHeader->getPicRplPresentFlag() )
+    {
+      pcSlice->setRPL0(picHeader->getRPL0());
+      pcSlice->setRPL1(picHeader->getRPL1());
+      *pcSlice->getLocalRPL0() = *picHeader->getLocalRPL0();
+      *pcSlice->getLocalRPL1() = *picHeader->getLocalRPL1();
+    }
+    else if( pcSlice->getIdrPicFlag() && !(sps->getIDRRefParamListPresent()) )
+#else
     if( pcSlice->getIdrPicFlag() && !(sps->getIDRRefParamListPresent()))
+#endif
     {
       ReferencePictureList* rpl0 = pcSlice->getLocalRPL0();
       (*rpl0) = ReferencePictureList();
@@ -1867,8 +2679,10 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       ReferencePictureList* rpl1 = pcSlice->getLocalRPL1();
       (*rpl1) = ReferencePictureList();
       pcSlice->setRPL1(rpl1);
+#if !JVET_P1006_PICTURE_HEADER
       pcSlice->setNumRefIdx(REF_PIC_LIST_0, 0);
       pcSlice->setNumRefIdx(REF_PIC_LIST_1, 0);
+#endif
     }
     else
     {
@@ -1933,7 +2747,11 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
             pcSlice->getLocalRPL0()->setDeltaPocMSBPresentFlag(i, uiCode ? true : false);
             if (uiCode)
             {
+#if JVET_P1006_PICTURE_HEADER
+              READ_UVLC(uiCode, "slice_delta_poc_msb_cycle_lt[i][j]");
+#else
               READ_FLAG(uiCode, "delta_poc_msb_cycle_lt[i][j]");
+#endif
               pcSlice->getLocalRPL0()->setDeltaPocMSBCycleLT(i, uiCode);
             }
           }
@@ -2014,13 +2832,27 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
             pcSlice->getLocalRPL1()->setDeltaPocMSBPresentFlag(i, uiCode ? true : false);
             if (uiCode)
             {
+#if JVET_P1006_PICTURE_HEADER
+              READ_UVLC(uiCode, "slice_delta_poc_msb_cycle_lt[i][j]");
+#else
               READ_FLAG(uiCode, "delta_poc_msb_cycle_lt[i][j]");
+#endif
               pcSlice->getLocalRPL1()->setDeltaPocMSBCycleLT(i, uiCode);
             }
           }
         }
       }
 
+#if JVET_P1006_PICTURE_HEADER
+    }
+    if( !picHeader->getPicRplPresentFlag() && pcSlice->getIdrPicFlag() && !(sps->getIDRRefParamListPresent()))
+    {
+      pcSlice->setNumRefIdx(REF_PIC_LIST_0, 0);
+      pcSlice->setNumRefIdx(REF_PIC_LIST_1, 0);
+    }
+    else
+    {
+#endif
       if ((!pcSlice->isIntra() && pcSlice->getRPL0()->getNumRefEntries() > 1) ||
           (pcSlice->isInterB() && pcSlice->getRPL1()->getNumRefEntries() > 1) )
       {
@@ -2101,6 +2933,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
         CHECK(pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0, "Number of active entries in RPL1 of B picture shall be greater than 0");
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     if (
       sps->getSplitConsOverrideEnabledFlag()
       )
@@ -2192,6 +3025,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
 
       pcSlice->setMvdL1ZeroFlag( (uiCode ? true : false) );
     }
+#endif
 
     pcSlice->setCabacInitFlag( false ); // default
     if(pps->getCabacInitPresentFlag() && !pcSlice->isIntra())
@@ -2201,7 +3035,11 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       pcSlice->setEncCABACTableIdx( pcSlice->getSliceType() == B_SLICE ? ( uiCode ? P_SLICE : B_SLICE ) : ( uiCode ? B_SLICE : P_SLICE ) );
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    if ( pcSlice->getPicHeader()->getEnableTMVPFlag() )
+#else
     if ( pcSlice->getEnableTMVPFlag() )
+#endif
     {
       if ( pcSlice->getSliceType() == B_SLICE )
       {
@@ -2253,6 +3091,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       }
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     if (!pcSlice->isIntra())
     {
       if (!pps->getPPSSixMinusMaxNumMergeCandPlus1())
@@ -2336,6 +3175,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
     {
       pcSlice->setJointCbCrSignFlag(0);
     }
+#endif
 
     READ_SVLC( iCode, "slice_qp_delta" );
     pcSlice->setSliceQp (26 + pps->getPicInitQPMinus26() + iCode);
@@ -2376,6 +3216,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       }
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     if (pps->getCuChromaQpOffsetEnabledFlag())
     {
       READ_FLAG(uiCode, "cu_chroma_qp_offset_enabled_flag"); pcSlice->setUseChromaQpAdj(uiCode != 0);
@@ -2384,8 +3225,13 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
     {
       pcSlice->setUseChromaQpAdj(false);
     }
+#endif
 
+#if JVET_P1006_PICTURE_HEADER
+    if( sps->getSAOEnabledFlag() && !picHeader->getSaoEnabledPresentFlag() )
+#else
     if(sps->getSAOEnabledFlag())
+#endif
     {
       READ_FLAG(uiCode, "slice_sao_luma_flag");  pcSlice->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, (bool)uiCode);
 
@@ -2395,7 +3241,11 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       }
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    if( sps->getALFEnabledFlag() && !picHeader->getAlfEnabledPresentFlag() )
+#else
     if( sps->getALFEnabledFlag() )
+#endif
     {
       READ_FLAG(uiCode, "slice_alf_enabled_flag");
       pcSlice->setTileGroupAlfEnabledFlag(COMPONENT_Y, uiCode);
@@ -2436,6 +3286,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       pcSlice->setTileGroupAlfEnabledFlag(COMPONENT_Cr, alfChromaIdc >> 1);
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     if (!pps->getPPSDepQuantEnabledIdc())
     {
       READ_FLAG(uiCode, "dep_quant_enabled_flag");
@@ -2455,12 +3306,17 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
     {
       pcSlice->setSignDataHidingEnabledFlag( 0 );
     }
+#endif
 
     if (pps->getDeblockingFilterControlPresentFlag())
     {
+#if JVET_P1006_PICTURE_HEADER
+      if( pps->getDeblockingFilterOverrideEnabledFlag() && !picHeader->getDeblockingFilterOverridePresentFlag() )
+#else
       if(pps->getDeblockingFilterOverrideEnabledFlag())
+#endif
       {
-        READ_FLAG ( uiCode, "deblocking_filter_override_flag" );        pcSlice->setDeblockingFilterOverrideFlag(uiCode ? true : false);
+        READ_FLAG ( uiCode, "slice_deblocking_filter_override_flag" );        pcSlice->setDeblockingFilterOverrideFlag(uiCode ? true : false);
       }
       else
       {
@@ -2481,9 +3337,15 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       }
       else
       {
+#if JVET_P1006_PICTURE_HEADER
+        pcSlice->setDeblockingFilterDisable       ( picHeader->getDeblockingFilterDisable() );
+        pcSlice->setDeblockingFilterBetaOffsetDiv2( picHeader->getDeblockingFilterBetaOffsetDiv2() );
+        pcSlice->setDeblockingFilterTcOffsetDiv2  ( picHeader->getDeblockingFilterTcOffsetDiv2() );
+#else
         pcSlice->setDeblockingFilterDisable       ( pps->getPPSDeblockingFilterDisabledFlag() );
         pcSlice->setDeblockingFilterBetaOffsetDiv2( pps->getDeblockingFilterBetaOffsetDiv2() );
         pcSlice->setDeblockingFilterTcOffsetDiv2  ( pps->getDeblockingFilterTcOffsetDiv2() );
+#endif
       }
     }
     else
@@ -2493,6 +3355,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
       pcSlice->setDeblockingFilterTcOffsetDiv2  ( 0 );
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     bool isSAOEnabled = sps->getSAOEnabledFlag() && (pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_LUMA) || (bChroma && pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA)));
     bool isDBFEnabled = (!pcSlice->getDeblockingFilterDisable());
 
@@ -2538,6 +3401,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
         READ_CODE( 3, uiCode, "slice_scaling_list_aps_id" );
         pcSlice->setscalingListAPSId( uiCode );
       }
+#endif
 
     if( pcSlice->getSliceCurStartBrickIdx() == 0 )
   {
diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h
index 3b0c58719..74bea8b8e 100644
--- a/source/Lib/DecoderLib/VLCReader.h
+++ b/source/Lib/DecoderLib/VLCReader.h
@@ -158,7 +158,12 @@ public:
   void  parseConstraintInfo   (ConstraintInfo *cinfo);
   void  parseProfileTierLevel ( ProfileTierLevel *ptl, int maxNumSubLayersMinus1);
   void  parseHrdParameters  ( HRDParameters *hrd, uint32_t firstSubLayer, uint32_t tempLevelHigh );
+#if JVET_P1006_PICTURE_HEADER
+  void  parsePictureHeader  ( PicHeader* picHeader, ParameterSetManager *parameterSetManager );
+  void  parseSliceHeader    ( Slice* pcSlice, PicHeader* picHeader, ParameterSetManager *parameterSetManager, const int prevTid0POC );
+#else
   void  parseSliceHeader    ( Slice* pcSlice, ParameterSetManager *parameterSetManager, const int prevTid0POC );
+#endif
   void  parseTerminatingBit ( uint32_t& ruiBit );
   void  parseRemainingBytes ( bool noTrailingBytesExpected );
 
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 7c3344497..3e01f3166 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -386,7 +386,11 @@ void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitione
     cuCtx.qgStart    = true;
     cuCtx.isDQPCoded          = false;
   }
+#if JVET_P1006_PICTURE_HEADER
+  if( pps.getCuChromaQpOffsetEnabledFlag() && partitioner.currQgChromaEnable() )
+#else
   if( cs.slice->getUseChromaQpAdj() && partitioner.currQgChromaEnable() )
+#endif
   {
     cuCtx.isChromaQpAdjCoded  = false;
   }
@@ -398,7 +402,11 @@ void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitione
       pCuCtxChroma->qgStart    = true;
       pCuCtxChroma->isDQPCoded = false;
     }
+#if JVET_P1006_PICTURE_HEADER
+    if (pps.getCuChromaQpOffsetEnabledFlag() && pPartitionerChroma->currQgChromaEnable())
+#else
     if (cs.slice->getUseChromaQpAdj() && pPartitionerChroma->currQgChromaEnable())
+#endif
     {
       pCuCtxChroma->isChromaQpAdjCoded = false;
     }
@@ -1481,7 +1489,11 @@ void CABACWriter::cu_palette_info(const CodingUnit& cu, ComponentID compBegin, u
       cuCtx.isDQPCoded = true;
     }
   }
+#if JVET_P1006_PICTURE_HEADER
+  if (cu.useEscape[compBegin] && cu.cs->pps->getCuChromaQpOffsetEnabledFlag() && !cuCtx.isChromaQpAdjCoded)
+#else
   if (cu.useEscape[compBegin] && cu.cs->slice->getUseChromaQpAdj() && !cuCtx.isChromaQpAdjCoded)
+#endif
   {
     if (!CS::isDualITree(*tu.cs) || isChroma(tu.chType))
     {
@@ -1990,7 +2002,11 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu )
     Mv mvd = pu.mvd[REF_PIC_LIST_0];
     mvd.changeIbcPrecInternal2Amvr(pu.cu->imv);
     mvd_coding(mvd, 0); // already changed to signaling precision
+#if JVET_P1006_PICTURE_HEADER
+    if ( pu.cu->slice->getPicHeader()->getMaxNumIBCMergeCand() == 1 )
+#else
     if ( pu.cu->slice->getMaxNumIBCMergeCand() == 1 )
+#endif
     {
       CHECK( pu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" );
     }
@@ -2033,7 +2049,11 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu )
       if ( pu.cu->smvdMode != 1 )
       {
       ref_idx     ( pu, REF_PIC_LIST_1 );
+#if JVET_P1006_PICTURE_HEADER
+      if( !pu.cs->picHeader->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
+#else
       if( !pu.cs->slice->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
+#endif
       {
         if ( pu.cu->affine )
         {
@@ -2083,7 +2103,11 @@ void CABACWriter::smvd_mode( const PredictionUnit& pu )
 void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
 {
 
+ #if JVET_P1006_PICTURE_HEADER
+  if ( !cu.cs->slice->isIntra() && (cu.slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
+#else
   if ( !cu.cs->slice->isIntra() && (cu.slice->getMaxNumAffineMergeCand() > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
+#endif
   {
     unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
     m_BinEncoder.encodeBin( cu.affine, Ctx::SubblockMergeFlag( ctxId ) );
@@ -2129,7 +2153,11 @@ void CABACWriter::merge_data(const PredictionUnit& pu)
     merge_idx(pu);
     return;
   }
+#if JVET_P1006_PICTURE_HEADER
+  const bool triangleAvailable = pu.cu->cs->slice->getSPS()->getUseTriangle() && pu.cu->cs->slice->isInterB() && pu.cu->cs->picHeader->getMaxNumTriangleCand() > 1;
+#else
   const bool triangleAvailable = pu.cu->cs->slice->getSPS()->getUseTriangle() && pu.cu->cs->slice->isInterB() && pu.cu->cs->slice->getMaxNumTriangleCand() > 1;
+#endif
   const bool ciipAvailable = pu.cs->sps->getUseMHIntra() && !pu.cu->skip && pu.cu->lwidth() < MAX_CU_SIZE && pu.cu->lheight() < MAX_CU_SIZE;
   if (pu.cu->lwidth() * pu.cu->lheight() >= 64
     && (triangleAvailable || ciipAvailable))
@@ -2232,7 +2260,11 @@ void CABACWriter::merge_idx( const PredictionUnit& pu )
 
   if ( pu.cu->affine )
   {
+#if JVET_P1006_PICTURE_HEADER
+    int numCandminus1 = int( pu.cs->picHeader->getMaxNumAffineMergeCand() ) - 1;
+#else
     int numCandminus1 = int( pu.cs->slice->getMaxNumAffineMergeCand() ) - 1;
+#endif
     if ( numCandminus1 > 0 )
     {
       if ( pu.mergeIdx == 0 )
@@ -2293,7 +2325,11 @@ void CABACWriter::merge_idx( const PredictionUnit& pu )
         }
       };
       m_BinEncoder.encodeBinEP(splitDir);
+#if JVET_P1006_PICTURE_HEADER
+      const int maxNumTriangleCand = pu.cs->picHeader->getMaxNumTriangleCand();
+#else
       const int maxNumTriangleCand = pu.cs->slice->getMaxNumTriangleCand();
+#endif
       CHECK(maxNumTriangleCand < 2, "Incorrect max number of triangle candidates");
       CHECK(candIdx0 >= maxNumTriangleCand, "Incorrect candIdx0");
       CHECK(candIdx1 >= maxNumTriangleCand, "Incorrect candIdx1");
@@ -2303,9 +2339,17 @@ void CABACWriter::merge_idx( const PredictionUnit& pu )
     }
     int numCandminus1;
     if (pu.cu->predMode == MODE_IBC)
+#if JVET_P1006_PICTURE_HEADER
+      numCandminus1 = int(pu.cs->picHeader->getMaxNumIBCMergeCand()) - 1;
+#else
       numCandminus1 = int(pu.cs->slice->getMaxNumIBCMergeCand()) - 1;
+#endif
     else
+#if JVET_P1006_PICTURE_HEADER
+      numCandminus1 = int(pu.cs->picHeader->getMaxNumMergeCand()) - 1;
+#else
       numCandminus1 = int(pu.cs->slice->getMaxNumMergeCand()) - 1;
+#endif
   if( numCandminus1 > 0 )
   {
     if( pu.mergeIdx == 0 )
@@ -2338,7 +2382,11 @@ void CABACWriter::mmvd_merge_idx(const PredictionUnit& pu)
   var1 = (mvpIdx - (var0 * MMVD_MAX_REFINE_NUM)) / 4;
   var2 = mvpIdx - (var0 * MMVD_MAX_REFINE_NUM) - var1 * 4;
 
+#if JVET_P1006_PICTURE_HEADER
+  if (pu.cs->picHeader->getMaxNumMergeCand() > 1)
+#else
   if (pu.cs->slice->getMaxNumMergeCand() > 1)
+#endif
   {
     static_assert(MMVD_BASE_MV_NUM == 2, "");
     assert(var0 < 2);
@@ -2780,7 +2828,11 @@ void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, Partiti
     SizeType channelWidth = !cu.isSepTree() ? cu.lwidth() : cu.chromaSize().width;
     SizeType channelHeight = !cu.isSepTree() ? cu.lheight() : cu.chromaSize().height;
 
+#if JVET_P1006_PICTURE_HEADER
+    if (cu.cs->pps->getCuChromaQpOffsetEnabledFlag() && (channelWidth > 64 || channelHeight > 64 || cbfChroma) && !cuCtx.isChromaQpAdjCoded)
+#else
     if (cu.cs->slice->getUseChromaQpAdj() && (channelWidth > 64 || channelHeight > 64 || cbfChroma) && !cuCtx.isChromaQpAdjCoded)
+#endif
     {
       cu_chroma_qp_offset(cu);
       cuCtx.isChromaQpAdjCoded = true;
@@ -2924,7 +2976,11 @@ void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID,
   }
 
   // determine sign hiding
+#if JVET_P1006_PICTURE_HEADER
+  bool signHiding  = ( cu.cs->picHeader->getSignDataHidingEnabledFlag() && !cu.transQuantBypass && tu.rdpcm[compID] == RDPCM_OFF );
+#else
   bool signHiding  = ( cu.cs->slice->getSignDataHidingEnabledFlag() && !cu.transQuantBypass && tu.rdpcm[compID] == RDPCM_OFF );
+#endif
 #if JVET_P0058_CHROMA_TS
   if(  signHiding && CU::isIntra(cu) && CU::isRDPCMEnabled(cu) && tu.mtsIdx[compID] == MTS_SKIP)
 #else
@@ -2987,7 +3043,11 @@ void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID,
   last_sig_coeff( cctx, tu, compID );
 
   // code subblocks
+#if JVET_P1006_PICTURE_HEADER
+  const int stateTab  = ( tu.cs->picHeader->getDepQuantEnabledFlag() ? 32040 : 0 );
+#else
   const int stateTab  = ( tu.cs->slice->getDepQuantEnabledFlag() ? 32040 : 0 );
+#endif
   int       state     = 0;
 
   int ctxBinSampleRatio = (compID == COMPONENT_Y) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA;
diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
index f8f584b59..703b56ac7 100644
--- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
+++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp
@@ -722,7 +722,11 @@ void EncAdaptiveLoopFilter::ALFProcess(CodingStructure& cs, const double *lambda
       const int width = ( xPos + pcv.maxCUWidth > pcv.lumaWidth ) ? ( pcv.lumaWidth - xPos ) : pcv.maxCUWidth;
       const int height = ( yPos + pcv.maxCUHeight > pcv.lumaHeight ) ? ( pcv.lumaHeight - yPos ) : pcv.maxCUHeight;
 #if JVET_O0625_ALF_PADDING
+#if JVET_P1006_PICTURE_HEADER
+      if( isCrossedByVirtualBoundaries( cs, xPos, yPos, width, height, alfBryList[0], alfBryList[1], alfBryList[2], alfBryList[3], numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.picHeader ) )
+#else
       if( isCrossedByVirtualBoundaries( cs, xPos, yPos, width, height, alfBryList[0], alfBryList[1], alfBryList[2], alfBryList[3], numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS() ) )
+#endif
 #else
       if( isCrossedByVirtualBoundaries( xPos, yPos, width, height, clipTop, clipBottom, clipLeft, clipRight, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS() ) )
 #endif
@@ -1846,7 +1850,11 @@ void EncAdaptiveLoopFilter::deriveStatsForFiltering( PelUnitBuf& orgYuv, PelUnit
       const int width = ( xPos + m_maxCUWidth > m_picWidth ) ? ( m_picWidth - xPos ) : m_maxCUWidth;
       const int height = ( yPos + m_maxCUHeight > m_picHeight ) ? ( m_picHeight - yPos ) : m_maxCUHeight;
 #if JVET_O0625_ALF_PADDING
+#if JVET_P1006_PICTURE_HEADER
+      if( isCrossedByVirtualBoundaries( cs, xPos, yPos, width, height, alfBryList[0], alfBryList[1], alfBryList[2], alfBryList[3], numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.picHeader ) )
+#else
       if( isCrossedByVirtualBoundaries( cs, xPos, yPos, width, height, alfBryList[0], alfBryList[1], alfBryList[2], alfBryList[3], numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS() ) )
+#endif
 #else
       if( isCrossedByVirtualBoundaries( xPos, yPos, width, height, clipTop, clipBottom, clipLeft, clipRight, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS() ) )
 #endif
@@ -2934,7 +2942,11 @@ void EncAdaptiveLoopFilter::alfReconstructor(CodingStructure& cs, const PelUnitB
         ctuEnableFlag |= m_ctuEnableFlag[compIdx][ctuIdx] > 0;
       }
 #if JVET_O0625_ALF_PADDING
+#if JVET_P1006_PICTURE_HEADER
+      if( isCrossedByVirtualBoundaries( cs, xPos, yPos, width, height, alfBryList[0], alfBryList[1], alfBryList[2], alfBryList[3], numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.picHeader ) )
+#else
       if( isCrossedByVirtualBoundaries( cs, xPos, yPos, width, height, alfBryList[0], alfBryList[1], alfBryList[2], alfBryList[3], numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS() ) )
+#endif
 #else
       if (ctuEnableFlag && isCrossedByVirtualBoundaries(xPos, yPos, width, height, clipTop, clipBottom, clipLeft, clipRight, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS()))
 #endif
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index e03c78000..a3265ebcb 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -589,6 +589,12 @@ protected:
   uint32_t      m_maxNumIBCMergeCand;                 ///< Max number of IBC merge candidates
   ScalingListMode m_useScalingListId;             ///< Using quantization matrix i.e. 0=off, 1=default, 2=file.
   std::string m_scalingListFileName;              ///< quantization matrix file name
+#if JVET_P1006_PICTURE_HEADER
+  bool      m_sliceLevelRpl;                      ///< code reference picture lists in slice headers rather than picture header
+  bool      m_sliceLevelDblk;                     ///< code deblocking filter parameters in slice headers rather than picture header
+  bool      m_sliceLevelSao;                      ///< code SAO parameters in slice headers rather than picture header
+  bool      m_sliceLevelAlf;                      ///< code ALF parameters in slice headers rather than picture header
+#endif
 #if JVET_P0365_SCALING_MATRIX_LFNST
   bool      m_disableScalingMatrixForLfnstBlks;
 #endif
@@ -1520,6 +1526,16 @@ public:
   ScalingListMode getUseScalingListId    ()                          { return m_useScalingListId;      }
   void         setScalingListFileName       ( const std::string &s ) { m_scalingListFileName = s;      }
   const std::string& getScalingListFileName () const                 { return m_scalingListFileName;   }
+#if JVET_P1006_PICTURE_HEADER
+  void         setSliceLevelRpl  ( bool b )                          { m_sliceLevelRpl = b;     }
+  bool         getSliceLevelRpl  ()                                  { return m_sliceLevelRpl;  }
+  void         setSliceLevelDblk ( bool b )                          { m_sliceLevelDblk = b;    }
+  bool         getSliceLevelDblk ()                                  { return m_sliceLevelDblk; }
+  void         setSliceLevelSao  ( bool b )                          { m_sliceLevelSao = b;     }
+  bool         getSliceLevelSao  ()                                  { return m_sliceLevelSao;  }
+  void         setSliceLevelAlf  ( bool b )                          { m_sliceLevelAlf = b;     }
+  bool         getSliceLevelAlf  ()                                  { return m_sliceLevelAlf;  }
+#endif
 #if JVET_P0365_SCALING_MATRIX_LFNST
   void         setDisableScalingMatrixForLfnstBlks(bool u)          { m_disableScalingMatrixForLfnstBlks = u;   }
   bool         getDisableScalingMatrixForLfnstBlks() const          { return m_disableScalingMatrixForLfnstBlks; }
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index ae0beda4d..09508c8c8 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -689,11 +689,19 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 
   m_cuChromaQpOffsetIdxPlus1 = 0;
 
+#if JVET_P1006_PICTURE_HEADER
+  if( pps.getCuChromaQpOffsetEnabledFlag() )
+#else
   if( slice.getUseChromaQpAdj() )
+#endif
   {
     // TODO M0133 : double check encoder decisions with respect to chroma QG detection and actual encode
     int lgMinCuSize = sps.getLog2MinCodingBlockSize() +
+#if JVET_P1006_PICTURE_HEADER
+      std::max<int>( 0, sps.getLog2DiffMaxMinCodingBlockSize() - int( slice.getCuChromaQpOffsetSubdiv()/2 ) );
+#else
       std::max<int>( 0, sps.getLog2DiffMaxMinCodingBlockSize() - int( pps.getCuChromaQpOffsetSubdiv()/2 ) );
+#endif
     m_cuChromaQpOffsetIdxPlus1 = ( ( uiLPelX >> lgMinCuSize ) + ( uiTPelY >> lgMinCuSize ) ) % ( pps.getChromaQpOffsetListLen() + 1 );
   }
 
@@ -1290,7 +1298,11 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
   m_CABACEstimator->getCtx() = SubCtx( Ctx::ModeConsFlag, ctxStartMC );
   if (cost > bestCS->cost + bestCS->costDbOffset
 #if ENABLE_QPA_SUB_CTU
+#if JVET_P1006_PICTURE_HEADER
+    || (m_pcEncCfg->getUsePerceptQPA() && !m_pcEncCfg->getUseRateCtrl() && pps.getUseDQP() && (slice.getCuQpDeltaSubdiv() > 0) && (split == CU_HORZ_SPLIT || split == CU_VERT_SPLIT) &&
+#else
     || (m_pcEncCfg->getUsePerceptQPA() && !m_pcEncCfg->getUseRateCtrl() && pps.getUseDQP() && (pps.getCuQpDeltaSubdiv() > 0) && (split == CU_HORZ_SPLIT || split == CU_VERT_SPLIT) &&
+#endif
         (currDepth == 0)) // force quad-split or no split at CTU level
 #endif
     )
@@ -2218,7 +2230,11 @@ void EncCu::xFillPCMBuffer( CodingUnit &cu )
 
       const CPelBuf source      = tu.cs->getOrgBuf( compArea );
              PelBuf destination = tu.getPcmbuf( compID );
+#if JVET_P1006_PICTURE_HEADER
+      if (tu.cs->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
+#else
       if (tu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
+#endif
       {
         CompArea    tmpArea(COMPONENT_Y, compArea.chromaFormat, Position(0, 0), compArea.size());
         PelBuf tempOrgBuf = m_tmpStorageLCU->getBuf(tmpArea);
@@ -2530,20 +2546,32 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
             m_pcIntraSearch->switchBuffer(pu, COMPONENT_Y, pu.cs->getPredBuf(pu).Y(), m_pcIntraSearch->getPredictorPtr2(COMPONENT_Y, intraCnt));
           }
           pu.cs->getPredBuf(pu).copyFrom(acMergeTmpBuffer[mergeCand]);
+#if JVET_P1006_PICTURE_HEADER
+          if (pu.cs->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
           if (pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
           {
             pu.cs->getPredBuf(pu).Y().rspSignal(m_pcReshape->getFwdLUT());
           }
           m_pcIntraSearch->geneWeightedPred(COMPONENT_Y, pu.cs->getPredBuf(pu).Y(), pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Y, intraCnt));
 
           // calculate cost
+#if JVET_P1006_PICTURE_HEADER
+          if (pu.cs->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
           if (pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
           {
             pu.cs->getPredBuf(pu).Y().rspSignal(m_pcReshape->getInvLUT());
           }
           distParam.cur = pu.cs->getPredBuf(pu).Y();
           Distortion sadValue = distParam.distFunc(distParam);
+#if JVET_P1006_PICTURE_HEADER
+          if (pu.cs->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
           if (pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
           {
             pu.cs->getPredBuf(pu).Y().rspSignal(m_pcReshape->getFwdLUT());
           }
@@ -2761,7 +2789,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
           uint32_t bufIdx = 0;
           PelBuf tmpBuf = tempCS->getPredBuf(pu).Y();
           tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Y());
+#if JVET_P1006_PICTURE_HEADER
+          if (pu.cs->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
           if (pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
           {
             tmpBuf.rspSignal(m_pcReshape->getFwdLUT());
           }
@@ -2867,7 +2899,11 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
   const Slice &slice = *tempCS->slice;
   const SPS &sps = *tempCS->sps;
 
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getMaxNumTriangleCand() < 2)
+#else
   if (slice.getMaxNumTriangleCand() < 2)
+#endif
     return;
 
   CHECK( slice.getSliceType() != B_SLICE, "Triangle mode is only applied to B-slices" );
@@ -2887,7 +2923,11 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
   PelUnitBuf                                      triangleWeightedBuffer[TRIANGLE_MAX_NUM_CANDS];
   static_vector<uint8_t, TRIANGLE_MAX_NUM_CANDS> triangleRdModeList;
   static_vector<double,  TRIANGLE_MAX_NUM_CANDS> tianglecandCostList;
+#if JVET_P1006_PICTURE_HEADER
+  uint8_t                                         numTriangleCandComb = slice.getPicHeader()->getMaxNumTriangleCand() * (slice.getPicHeader()->getMaxNumTriangleCand() - 1) * 2;
+#else
   uint8_t                                         numTriangleCandComb = slice.getMaxNumTriangleCand() * (slice.getMaxNumTriangleCand() - 1) * 2;
+#endif
 
 
   DistParam distParam;
@@ -2915,7 +2955,11 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
     pu.regularMergeFlag = false;
 
     PU::getTriangleMergeCandidates( pu, triangleMrgCtx );
+#if JVET_P1006_PICTURE_HEADER
+    const uint8_t maxNumTriangleCand = pu.cs->picHeader->getMaxNumTriangleCand();
+#else
     const uint8_t maxNumTriangleCand = pu.cs->slice->getMaxNumTriangleCand();
+#endif
     for (uint8_t mergeCand = 0; mergeCand < maxNumTriangleCand; mergeCand++)
     {
       triangleBuffer[mergeCand] = m_acMergeBuffer[mergeCand].getBuf(localUnitArea);
@@ -3236,7 +3280,11 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
 
         Distortion uiSad = distParam.distFunc( distParam );
         uint32_t   uiBitsCand = uiMergeCand + 1;
+#if JVET_P1006_PICTURE_HEADER
+        if ( uiMergeCand == tempCS->picHeader->getMaxNumAffineMergeCand() - 1 )
+#else
         if ( uiMergeCand == tempCS->slice->getMaxNumAffineMergeCand() - 1 )
+#endif
         {
           uiBitsCand--;
         }
@@ -3470,7 +3518,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
       Picture* refPic = pu.cu->slice->getPic();
       const CPelBuf refBuf = refPic->getRecoBuf(pu.blocks[COMPONENT_Y]);
       const Pel*        piRefSrch = refBuf.buf;
+#if JVET_P1006_PICTURE_HEADER
+      if (tempCS->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() )
+#else
       if (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() )
+#endif
       {
         const CompArea &area = cu.blocks[COMPONENT_Y];
         CompArea    tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
@@ -3508,7 +3560,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
 
         Distortion sad = distParam.distFunc(distParam);
         unsigned int bitsCand = mergeCand + 1;
+#if JVET_P1006_PICTURE_HEADER
+        if (mergeCand == tempCS->picHeader->getMaxNumMergeCand() - 1)
+#else
         if (mergeCand == tempCS->slice->getMaxNumMergeCand() - 1)
+#endif
         {
           bitsCand--;
         }
@@ -4093,7 +4149,11 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
       //Copy current CU's reco to Deblock Pic Buffer
       const CompArea&  curCompArea = currCsArea.block( compId );
       picDbBuf.getBuf( curCompArea ).copyFrom( cs.getRecoBuf( curCompArea ) );
+#if JVET_P1006_PICTURE_HEADER
+      if (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma(compId))
+#else
       if (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma(compId))
+#endif
       {
         picDbBuf.getBuf( curCompArea ).rspSignal( m_pcReshape->getInvLUT() );
       }
@@ -4103,7 +4163,11 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
       {
         const CompArea&  compArea = areaLeft.block(compId);
         picDbBuf.getBuf( compArea ).copyFrom( cs.picture->getRecoBuf( compArea ) );
+#if JVET_P1006_PICTURE_HEADER
+        if (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma(compId))
+#else
         if (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma(compId))
+#endif
         {
           picDbBuf.getBuf( compArea ).rspSignal( m_pcReshape->getInvLUT() );
         }
@@ -4113,7 +4177,11 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal
       {
         const CompArea&  compArea = areaTop.block( compId );
         picDbBuf.getBuf( compArea ).copyFrom( cs.picture->getRecoBuf( compArea ) );
+#if JVET_P1006_PICTURE_HEADER
+        if (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma(compId))
+#else
         if (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getSliceReshaperInfo().getUseSliceReshaper() && isLuma(compId))
+#endif
         {
           picDbBuf.getBuf( compArea ).rspSignal( m_pcReshape->getInvLUT() );
         }
@@ -4183,7 +4251,11 @@ Distortion EncCu::getDistortionDb( CodingStructure &cs, CPelBuf org, CPelBuf rec
   m_pcRdCost->setChromaFormat(cs.sps->getChromaFormatIdc());
   CPelBuf orgLuma = cs.picture->getOrigBuf( cs.area.blocks[COMPONENT_Y] );
   if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
+#if JVET_P1006_PICTURE_HEADER
+    m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
+#else
     m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
+#endif
   {
     if ( compID == COMPONENT_Y && !afterDb && !m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled())
     {
@@ -4198,7 +4270,11 @@ Distortion EncCu::getDistortionDb( CodingStructure &cs, CPelBuf org, CPelBuf rec
       dist += m_pcRdCost->getDistPart( org, reco, cs.sps->getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma );
     }
   }
+#if JVET_P1006_PICTURE_HEADER
+  else if (m_pcEncCfg->getReshaper() && cs.picHeader->getLmcsEnabledFlag() && cs.slice->isIntra()) //intra slice
+#else
   else if (m_pcEncCfg->getReshaper() && cs.slice->getLmcsEnabledFlag() && cs.slice->isIntra()) //intra slice
+#endif
   {
     if ( compID == COMPONENT_Y && afterDb )
     {
@@ -4695,7 +4771,11 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best
 
 #if WCG_EXT
       if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
+#if JVET_P1006_PICTURE_HEADER
+        m_pcEncCfg->getReshaper() && (tempCS->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
+#else
         m_pcEncCfg->getReshaper() && (tempCS->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
+#endif
       {
         const CPelBuf orgLuma = tempCS->getOrgBuf(tempCS->area.blocks[COMPONENT_Y]);
         if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 2df410517..c3c4526fc 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -421,6 +421,18 @@ int EncGOP::xWriteParameterSets( AccessUnit &accessUnit, Slice *slice, const boo
   return actualTotalBits;
 }
 
+#if JVET_P1006_PICTURE_HEADER
+int EncGOP::xWritePicHeader( AccessUnit &accessUnit, PicHeader *picHeader )
+{
+  OutputNALUnit nalu(NAL_UNIT_PH);
+  m_HLSWriter->setBitstream( &nalu.m_Bitstream );
+  nalu.m_temporalId = accessUnit.temporalId;
+  m_HLSWriter->codePictureHeader( picHeader );
+  accessUnit.push_back(new NALUnitEBSP(nalu));
+  return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8;
+}
+
+#endif
 void EncGOP::xWriteAccessUnitDelimiter (AccessUnit &accessUnit, Slice *slice)
 {
   AUDWriter audWriter;
@@ -1546,8 +1558,12 @@ void trySkipOrDecodePicture( bool& decPic, bool& encPic, const EncCfg& cfg, Pict
             // patch IDR-slice to CRA-Intra-slice
             pcPic->slices[ i ]->setNalUnitType    ( slice0.getNalUnitType()    );
             pcPic->slices[ i ]->setLastIDR        ( slice0.getLastIDR()        );
+#if JVET_P1006_PICTURE_HEADER
+            if ( pcPic->cs->picHeader->getEnableTMVPFlag() )
+#else
             pcPic->slices[ i ]->setEnableTMVPFlag ( slice0.getEnableTMVPFlag() );
             if ( slice0.getEnableTMVPFlag() )
+#endif
             {
               pcPic->slices[ i ]->setColFromL0Flag( slice0.getColFromL0Flag()  );
               pcPic->slices[ i ]->setColRefIdx    ( slice0.getColRefIdx()      );
@@ -1776,7 +1792,11 @@ void EncGOP::xPicInitRateControl(int &estimatedBits, int gopId, double &lambda,
   m_pcSliceEncoder->resetQP( pic, sliceQP, lambda );
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice)
+#else
 void EncGOP::xPicInitLMCS(Picture *pic, Slice *slice)
+#endif
 {
   if (slice->getSPS()->getUseReshaper())
   {
@@ -1866,9 +1886,15 @@ void EncGOP::xPicInitLMCS(Picture *pic, Slice *slice)
       }
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    //set all necessary information in LMCS APS and picture header
+    picHeader->setLmcsEnabledFlag(m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper());
+    picHeader->setLmcsChromaResidualScaleFlag(m_pcReshaper->getSliceReshaperInfo().getSliceReshapeChromaAdj() == 1);
+#else
     //set all necessary information in LMCS APS and slice
     slice->setLmcsEnabledFlag(m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper());
     slice->setLmcsChromaResidualScaleFlag(m_pcReshaper->getSliceReshaperInfo().getSliceReshapeChromaAdj() == 1);
+#endif
     if (m_pcReshaper->getSliceReshaperInfo().getSliceReshapeModelPresentFlag())
     {
 #if JVET_N0278_FIXES
@@ -1876,8 +1902,13 @@ void EncGOP::xPicInitLMCS(Picture *pic, Slice *slice)
 #else
       int apsId = 0;
 #endif
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setLmcsAPSId(apsId);
+      APS* lmcsAPS = picHeader->getLmcsAPS();
+#else
       slice->setLmcsAPSId(apsId);
       APS* lmcsAPS = slice->getLmcsAPS();
+#endif
       if (lmcsAPS == nullptr)
       {
         ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
@@ -1888,7 +1919,11 @@ void EncGOP::xPicInitLMCS(Picture *pic, Slice *slice)
           lmcsAPS->setAPSId(apsId);
           lmcsAPS->setAPSType(LMCS_APS);
         }
+#if JVET_P1006_PICTURE_HEADER
+        picHeader->setLmcsAPS(lmcsAPS);
+#else
         slice->setLmcsAPS(lmcsAPS);
+#endif
       }
       //m_pcReshaper->copySliceReshaperInfo(lmcsAPS->getReshaperAPSInfo(), m_pcReshaper->getSliceReshaperInfo());
       SliceReshapeInfo& tInfo = lmcsAPS->getReshaperAPSInfo();
@@ -1904,14 +1939,22 @@ void EncGOP::xPicInitLMCS(Picture *pic, Slice *slice)
     }
 
 
+#if JVET_P1006_PICTURE_HEADER
+    if (picHeader->getLmcsEnabledFlag())
+#else
     if (slice->getLmcsEnabledFlag())
+#endif
     {
 #if JVET_N0278_FIXES
       int apsId = std::min<int>( 3, m_pcEncLib->getLayerId() ); //VS: layerId should be converted to laeyrIdx
 #else
       int apsId = 0;
 #endif
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setLmcsAPSId(apsId);
+#else
       slice->setLmcsAPSId(apsId);
+#endif
     }
   }
   else
@@ -1935,6 +1978,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
   // TODO: Split this function up.
 
   Picture*        pcPic = NULL;
+#if JVET_P1006_PICTURE_HEADER
+  PicHeader*      picHeader = NULL;
+#endif
   Slice*      pcSlice;
   OutputBitstream  *pcBitstreamRedirect;
   pcBitstreamRedirect = new OutputBitstream;
@@ -2028,6 +2074,10 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     accessUnit.temporalId = m_pcCfg->getGOPEntry( iGOPid ).m_temporalId;
     xGetBuffer( rcListPic, rcListPicYuvRecOut,
                 iNumPicRcvd, iTimeOffset, pcPic, pocCurr, isField );
+#if JVET_P1006_PICTURE_HEADER
+    picHeader = pcPic->cs->picHeader;
+    picHeader->setSplitConsOverrideFlag(false);
+#endif
 
 #if ER_CHROMA_QP_WCG_PPS
     // th this is a hot fix for the choma qp control
@@ -2083,8 +2133,10 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
     pcSlice->setLastIDR(m_iLastIDR);
     pcSlice->setIndependentSliceIdx(0);
+#if !JVET_P1006_PICTURE_HEADER
     //set default slice level flag to the same as SPS level flag
     pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );
+#endif
 
     if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
     {
@@ -2289,6 +2341,22 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
         if( refLayer >= 0 && m_uiNumBlk[refLayer] != 0 )
         {
+#if JVET_P1006_PICTURE_HEADER
+          picHeader->setSplitConsOverrideFlag(true);
+          double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] );
+          if( dBlkSize < AMAXBT_TH32 || pcPic->cs->sps->getCTUSize()==32 )
+          {
+            picHeader->setMaxBTSize( 1, 32 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 32 );
+          }
+          else if( dBlkSize < AMAXBT_TH64 || pcPic->cs->sps->getCTUSize()==64 )
+          {
+            picHeader->setMaxBTSize( 1, 64 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 64 );
+          }
+          else
+          {
+            picHeader->setMaxBTSize( 1, 128 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 128 );
+          }
+#else
           pcSlice->setSplitConsOverrideFlag(true);
           double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] );
           if( dBlkSize < AMAXBT_TH32 )
@@ -2303,6 +2371,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           {
             pcSlice->setMaxBTSize( 128 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 128 );
           }
+#endif
 
           m_uiBlkSize[refLayer] = 0;
           m_uiNumBlk [refLayer] = 0;
@@ -2381,12 +2450,20 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 #endif
       if (iGOPid == 0) // first picture in SOP (i.e. forward B)
       {
+#if JVET_P1006_PICTURE_HEADER
+        picHeader->setEnableTMVPFlag(0);
+#else
         pcSlice->setEnableTMVPFlag(0);
+#endif
       }
       else
       {
         // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
+#if JVET_P1006_PICTURE_HEADER
+        picHeader->setEnableTMVPFlag(1);
+#else
         pcSlice->setEnableTMVPFlag(1);
+#endif
       }
     }
 #if JVET_P0206_TMVP_flags
@@ -2395,20 +2472,36 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     else if (m_pcEncLib->getTMVPModeId() == 1 && m_pcEncLib->getPPSTemporalMVPEnabledIdc() != 1)
 #endif
     {
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setEnableTMVPFlag(1);
+#else
       pcSlice->setEnableTMVPFlag(1);
+#endif
     }
     else
     {
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setEnableTMVPFlag(0);
+#else
       pcSlice->setEnableTMVPFlag(0);
+#endif
     }
 
     // disable TMVP when current picture is the only ref picture
     if (pcSlice->isIRAP() && pcSlice->getSPS()->getIBCFlag())
     {
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setEnableTMVPFlag(0);
+#else
       pcSlice->setEnableTMVPFlag(0);
+#endif
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    if( pcSlice->getSliceType() != I_SLICE && picHeader->getEnableTMVPFlag() )
+#else
     if( pcSlice->getSliceType() != I_SLICE && pcSlice->getEnableTMVPFlag() )
+#endif
     {
       int colRefIdxL0 = -1, colRefIdxL1 = -1;
 
@@ -2473,11 +2566,19 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       }
       else
       {
+#if JVET_P1006_PICTURE_HEADER
+        picHeader->setEnableTMVPFlag( 0 );
+#else
         pcSlice->setEnableTMVPFlag( 0 );
+#endif
       }
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    pcSlice->scaleRefPicList( scaledRefPic, pcPic->cs->picHeader, m_pcEncLib->getApss(), picHeader->getLmcsAPS(), picHeader->getScalingListAPS(), false );
+#else
     pcSlice->scaleRefPicList( scaledRefPic, m_pcEncLib->getApss(), pcSlice->getLmcsAPS(), pcSlice->getscalingListAPS(), false );
+#endif
 
     // set adaptive search range for non-intra-slices
     if (m_pcCfg->getUseASR() && !pcSlice->isIRAP())
@@ -2504,15 +2605,27 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     }
     if(bGPBcheck)
     {
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setMvdL1ZeroFlag(true);
+#else
       pcSlice->setMvdL1ZeroFlag(true);
+#endif
     }
     else
     {
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setMvdL1ZeroFlag(false);
+#else
       pcSlice->setMvdL1ZeroFlag(false);
+#endif
     }
 
     if ( pcSlice->getSPS()->getUseSMVD() && pcSlice->getCheckLDC() == false
+#if JVET_P1006_PICTURE_HEADER
+      && picHeader->getMvdL1ZeroFlag() == false
+#else
       && pcSlice->getMvdL1ZeroFlag() == false
+#endif
       )
     {
       int currPOC = pcSlice->getPOC();
@@ -2616,7 +2729,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     pcPic->m_uEnerHpCtu.resize (numberOfCtusInFrame);
     pcPic->m_iOffsetCtu.resize (numberOfCtusInFrame);
 #if ENABLE_QPA_SUB_CTU
+#if JVET_P1006_PICTURE_HEADER
+    if (pcSlice->getPPS()->getUseDQP() && pcSlice->getCuQpDeltaSubdiv() > 0)
+#else
     if (pcSlice->getPPS()->getUseDQP() && pcSlice->getPPS()->getCuQpDeltaSubdiv() > 0)
+#endif
     {
       const PreCalcValues &pcv = *pcPic->cs->pcv;
       const unsigned   mtsLog2 = (unsigned)floorLog2(std::min (pcPic->cs->sps->getMaxTbSize(), pcv.maxCUWidth));
@@ -2660,25 +2777,56 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       m_pcSliceEncoder->setUpLambda(pcSlice, pcSlice->getLambdas()[0], pcSlice->getSliceQp());
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    xPicInitLMCS(pcPic, picHeader, pcSlice);
+#else
     xPicInitLMCS(pcPic, pcSlice);
+#endif
 
     if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
     {
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setScalingListPresentFlag( true );
+#else
       pcSlice->setscalingListPresentFlag( true );
+#endif
 
 #if JVET_N0278_FIXES
       int apsId = std::min<int>( 7, m_pcEncLib->getLayerId() ); //VS: layerId should be converted to laeyrIdx
 #else
       int apsId = 0;
 #endif
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setScalingListAPSId( apsId );
+#else
       pcSlice->setscalingListAPSId( apsId );
+#endif
 
       ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
       APS*  scalingListAPS = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
       assert( scalingListAPS != NULL );
+#if JVET_P1006_PICTURE_HEADER
+      picHeader->setScalingListAPS( scalingListAPS );
+#else
       pcSlice->setscalingListAPS( scalingListAPS );
+#endif
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    pcPic->cs->picHeader->setPic(pcPic);
+    pcPic->cs->picHeader->setValid();
+    if(pcPic->cs->sps->getFpelMmvdEnabledFlag()) 
+    {
+      // cannot set pic_fpel_mmvd_enabled_flag at slice level - need new picture-level version of checkDisFracMmvd algorithm?
+      // m_pcSliceEncoder->checkDisFracMmvd( pcPic, 0, numberOfCtusInFrame );
+      bool useIntegerMVD = (pcPic->lwidth()*pcPic->lheight() > 1920 * 1080);
+      pcPic->cs->picHeader->setDisFracMMVD( useIntegerMVD );
+    }
+    if (pcSlice->getSPS()->getJointCbCrEnabledFlag())
+    {
+      m_pcSliceEncoder->setJointCbCrModes(*pcPic->cs, Position(0, 0), pcPic->cs->area.lumaSize());
+    }
+#endif
     if( encPic )
     // now compress (trial encode) the various slice segments (slices, and dependent slices)
     {
@@ -2736,7 +2884,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
       if (pcSlice->getSPS()->getUseReshaper() && m_pcReshaper->getSliceReshaperInfo().getUseSliceReshaper())
       {
+#if JVET_P1006_PICTURE_HEADER
+        picHeader->setLmcsEnabledFlag(true);
+#else
         pcSlice->setLmcsEnabledFlag(true);
+#endif
 
 #if JVET_N0278_FIXES
         int apsId = std::min<int>( 3, m_pcEncLib->getLayerId() ); //VS: layerId should be converted to laeyrIdx
@@ -2744,6 +2896,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         int apsId = 0;
 #endif
 
+#if JVET_P1006_PICTURE_HEADER
+        picHeader->setLmcsAPSId(apsId);
+#else
         pcSlice->setLmcsAPSId(apsId);
         for (int s = 0; s < uiNumSliceSegments; s++)
         {
@@ -2755,6 +2910,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
             pcPic->slices[s]->setLmcsAPSId(pcSlice->getLmcsAPSId());
           }
         }
+#endif
           CHECK((m_pcReshaper->getRecReshaped() == false), "Rec picture is not reshaped!");
           pcPic->getRecoBuf(COMPONENT_Y).rspSignal(m_pcReshaper->getInvLUT());
           m_pcReshaper->setRecReshaped(false);
@@ -2785,10 +2941,17 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 
       if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ )
       {
+#if JVET_P1006_PICTURE_HEADER
+        picHeader->setScalingListPresentFlag(true);
+        int apsId = 0;
+        picHeader->setScalingListAPSId( apsId );
+#else
         pcSlice->setscalingListPresentFlag( true );
         int apsId = 0;
         pcSlice->setscalingListAPSId( apsId );
+#endif
       }
+#if !JVET_P1006_PICTURE_HEADER
       for( int s = 0; s < uiNumSliceSegments; s++ )
       {
         pcPic->slices[ s ]->setscalingListPresentFlag( pcSlice->getscalingListPresentFlag() );
@@ -2797,6 +2960,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           pcPic->slices[ s ]->setscalingListAPSId( pcSlice->getscalingListAPSId() );
         }
       }
+#endif
 
       // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
       if( pcSlice->getSPS()->getSAOEnabledFlag() && m_pcCfg->getSaoCtuBoundary() )
@@ -2966,7 +3130,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       if (pcSlice->getSPS()->getUseReshaper())
       {
         //only 1 LMCS data for 1 picture
+#if JVET_P1006_PICTURE_HEADER
+        int apsId = picHeader->getLmcsAPSId();
+#else
         int apsId = pcSlice->getLmcsAPSId();
+#endif
         ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
         APS* aps = apsMap->getPS((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
         bool writeAPS = aps && apsMap->getChangedFlag((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
@@ -2986,14 +3154,22 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 #endif
 #endif
           apsMap->clearChangedFlag((apsId << NUM_APS_TYPE_LEN) + LMCS_APS);
+#if JVET_P1006_PICTURE_HEADER
+          CHECK(aps != picHeader->getLmcsAPS(), "Wrong LMCS APS pointer in compressGOP");
+#else
           CHECK(aps != pcSlice->getLmcsAPS(), "Wrong LMCS APS pointer in compressGOP");
+#endif
         }
       }
 
       // only 1 SCALING LIST data for 1 picture
       if( pcSlice->getSPS()->getScalingListFlag() && ( m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ ) )
       {
+#if JVET_P1006_PICTURE_HEADER
+        int apsId = picHeader->getScalingListAPSId();
+#else
         int apsId = pcSlice->getscalingListAPSId();
+#endif
         ParameterSetMap<APS> *apsMap = m_pcEncLib->getApsMap();
         APS* aps = apsMap->getPS( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
         bool writeAPS = aps && apsMap->getChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
@@ -3013,7 +3189,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 #endif
 #endif
           apsMap->clearChangedFlag( ( apsId << NUM_APS_TYPE_LEN ) + SCALING_LIST_APS );
+#if JVET_P1006_PICTURE_HEADER
+          CHECK( aps != picHeader->getScalingListAPS(), "Wrong SCALING LIST APS pointer in compressGOP" );
+#else
           CHECK( aps != pcSlice->getscalingListAPS(), "Wrong SCALING LIST APS pointer in compressGOP" );
+#endif
         }
       }
 
@@ -3077,6 +3257,89 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
         pcSlice->setRPL0idx(pcPic->slices[0]->getRPL0idx());
         pcSlice->setRPL1idx(pcPic->slices[0]->getRPL1idx());
 
+#if JVET_P1006_PICTURE_HEADER
+        pcSlice->setNoIncorrectPicOutputFlag(false);
+        if (pcSlice->isIRAP())
+        {
+          if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
+          {
+            pcSlice->setNoIncorrectPicOutputFlag(true);
+          }
+          //the inference for NoOutputPriorPicsFlag
+          // KJS: This cannot happen at the encoder
+          if (!m_bFirst && (pcSlice->isIRAP() || pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_GDR) && pcSlice->getNoIncorrectPicOutputFlag())
+          {
+            if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA || pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_GDR)
+            {
+              picHeader->setNoOutputOfPriorPicsFlag(true);
+            }
+          }
+        }
+
+        // code picture header before first slice
+        if(sliceSegmentIdxCount == 0) 
+        {
+          // code RPL in picture header or slice headers
+          if( !m_pcCfg->getSliceLevelRpl() && (!pcSlice->getIdrPicFlag() || pcSlice->getSPS()->getIDRRefParamListPresent()) )
+          {
+            picHeader->setPicRplPresentFlag(true);
+            picHeader->setRPL0idx(pcSlice->getRPL0idx());
+            picHeader->setRPL1idx(pcSlice->getRPL1idx());
+            picHeader->setRPL0(pcSlice->getRPL0());
+            picHeader->setRPL1(pcSlice->getRPL1());
+            *picHeader->getLocalRPL0() = *pcSlice->getLocalRPL0();
+            *picHeader->getLocalRPL1() = *pcSlice->getLocalRPL1();
+          }
+          else {
+            picHeader->setPicRplPresentFlag(false);
+          }
+          
+          // code DBLK in picture header or slice headers
+          if( !m_pcCfg->getSliceLevelDblk() )
+          {
+            picHeader->setDeblockingFilterOverridePresentFlag( true );
+            picHeader->setDeblockingFilterOverrideFlag   ( pcSlice->getDeblockingFilterOverrideFlag()   );
+            picHeader->setDeblockingFilterDisable        ( pcSlice->getDeblockingFilterDisable()        ); 
+            picHeader->setDeblockingFilterBetaOffsetDiv2 ( pcSlice->getDeblockingFilterBetaOffsetDiv2() ); 
+            picHeader->setDeblockingFilterTcOffsetDiv2   ( pcSlice->getDeblockingFilterTcOffsetDiv2()   );
+          }
+          else {
+            picHeader->setDeblockingFilterOverridePresentFlag( false );
+          }
+          
+          // code SAO parameters in picture header or slice headers
+          if( !m_pcCfg->getSliceLevelSao() )
+          {
+            picHeader->setSaoEnabledPresentFlag( true );
+            picHeader->setSaoEnabledFlag(CHANNEL_TYPE_LUMA,   pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_LUMA  ));
+            picHeader->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA));
+          }
+          else {
+            picHeader->setSaoEnabledPresentFlag( false );
+          }
+          
+          // code ALF parameters in picture header or slice headers
+          if( !m_pcCfg->getSliceLevelAlf() )
+          {
+            picHeader->setAlfEnabledPresentFlag( true );
+            picHeader->setAlfEnabledFlag(COMPONENT_Y,  pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y ) );
+            picHeader->setAlfEnabledFlag(COMPONENT_Cb, pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cb) );
+            picHeader->setAlfEnabledFlag(COMPONENT_Cr, pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Cr) );            
+            picHeader->setNumAlfAps(pcSlice->getTileGroupNumAps());
+            picHeader->setAlfAPSs(pcSlice->getTileGroupApsIdLuma());
+            picHeader->setAlfApsIdChroma(pcSlice->getTileGroupApsIdChroma());
+          }
+          else {
+            picHeader->setAlfEnabledPresentFlag( false );
+          }
+
+          pcPic->cs->picHeader->setPic(pcPic);
+          pcPic->cs->picHeader->setValid();
+          actualTotalBits += xWritePicHeader(accessUnit, pcPic->cs->picHeader);
+        }
+        pcSlice->setPicHeader( pcPic->cs->picHeader );
+
+#endif
         for ( uint32_t ui = 0 ; ui < numSubstreams; ui++ )
         {
           substreamsOut[ui].clear();
@@ -3090,6 +3353,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 #endif
         m_HLSWriter->setBitstream( &nalu.m_Bitstream );
 
+#if !JVET_P1006_PICTURE_HEADER
         pcSlice->setNoIncorrectPicOutputFlag(false);
         if (pcSlice->isIRAP())
         {
@@ -3107,6 +3371,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
             }
           }
         }
+#endif
 
         tmpBitsBeforeWriting = m_HLSWriter->getNumberOfWrittenBits();
         m_HLSWriter->codeSliceHeader( pcSlice );
@@ -4122,7 +4387,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni
       {
         const std::pair<int, int>& scaleRatio = pcSlice->getScalingRatio( RefPicList( iRefList ), iRefIndex );
         
+#if JVET_P1006_PICTURE_HEADER
+        if( pcPic->cs->picHeader->getEnableTMVPFlag() && pcSlice->getColFromL0Flag() == bool(1 - iRefList) && pcSlice->getColRefIdx() == iRefIndex )
+#else
         if( pcSlice->getEnableTMVPFlag() && pcSlice->getColFromL0Flag() == bool(1 - iRefList) && pcSlice->getColRefIdx() == iRefIndex )
+#endif
         {
           if ( scaleRatio.first != 1 << SCALE_RATIO_BITS || scaleRatio.second != 1 << SCALE_RATIO_BITS )
             msg( NOTICE, "%dc(%1.2lfx, %1.2lfx) ", pcSlice->getRefPOC( RefPicList( iRefList ), iRefIndex ), double( scaleRatio.first ) / ( 1 << SCALE_RATIO_BITS ), double( scaleRatio.second ) / ( 1 << SCALE_RATIO_BITS ) );
diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h
index f49e2c773..bec59665a 100644
--- a/source/Lib/EncoderLib/EncGOP.h
+++ b/source/Lib/EncoderLib/EncGOP.h
@@ -266,7 +266,11 @@ protected:
   );
   void  xPicInitHashME( Picture *pic, const PPS *pps, PicList &rcListPic );
   void  xPicInitRateControl(int &estimatedBits, int gopId, double &lambda, Picture *pic, Slice *slice);
+#if JVET_P1006_PICTURE_HEADER
+  void  xPicInitLMCS       (Picture *pic, PicHeader *picHeader, Slice *slice);
+#else
   void  xPicInitLMCS       (Picture *pic, Slice *slice);
+#endif
   void  xGetBuffer        ( PicList& rcListPic, std::list<PelUnitBuf*>& rcListPicYuvRecOut,
                             int iNumPicRcvd, int iTimeOffset, Picture*& rpcPic, int pocCurr, bool isField );
 
@@ -330,6 +334,9 @@ protected:
   int xWriteAPS( AccessUnit &accessUnit, APS *aps, const int layerId );
 #endif
   int xWriteParameterSets (AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst);
+#if JVET_P1006_PICTURE_HEADER
+  int xWritePicHeader( AccessUnit &accessUnit, PicHeader *picHeader );
+#endif
 
   void applyDeblockingFilterMetric( Picture* pcPic, uint32_t uiNumSlices );
 #if W0038_DB_OPT
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index c5bc99a5a..4e5512c2e 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -327,6 +327,9 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
     xInitPPS(pps2, sps0);
     xInitPPSforLT(pps2);
   }
+#if JVET_P1006_PICTURE_HEADER
+  xInitPicHeader(m_picHeader, sps0, pps0);
+#endif
 
   // initialize processing unit classes
   m_cGOPEncoder.  init( this );
@@ -449,7 +452,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
     picBg->create( sps0.getChromaFormatIdc(), Size( pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples() ), sps0.getMaxCUWidth(), sps0.getMaxCUWidth() + 16, false );
 #endif
     picBg->getRecoBuf().fill(0);
+#if JVET_P1006_PICTURE_HEADER
+    picBg->finalInit( sps0, pps0, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     picBg->finalInit( sps0, pps0, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
     pps0.setNumBricksInPic((int)picBg->brickMap->bricks.size());
     picBg->allocateNewSlice();
     picBg->createSpliceIdx(pps0.pcv->sizeInCtus);
@@ -603,7 +610,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
     const SPS *sps = m_spsMap.getPS( pps->getSPSId() );
 
     picCurr->M_BUFS( 0, PIC_ORIGINAL ).copyFrom( m_cGOPEncoder.getPicBg()->getRecoBuf() );
+#if JVET_P1006_PICTURE_HEADER
+    picCurr->finalInit( *sps, *pps, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     picCurr->finalInit( *sps, *pps, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
     picCurr->poc = m_iPOCLast - 1;
     m_iPOCLast -= 2;
     if( getUseAdaptiveQP() )
@@ -692,8 +703,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu
       pcPicCurr->M_BUFS( 0, PIC_ORIGINAL ).swap( *pcPicYuvOrg );
       pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL ).swap( *cPicYuvTrueOrg );
     }
-
+#if JVET_P1006_PICTURE_HEADER    
+    pcPicCurr->finalInit( *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     pcPicCurr->finalInit( *pSPS, *pPPS, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
     PPS *ptrPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
     ptrPPS->setNumBricksInPic( (int)pcPicCurr->brickMap->bricks.size() );
 
@@ -790,7 +804,11 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru
     const SPS *sps = m_spsMap.getPS(pps->getSPSId());
 
     picCurr->M_BUFS(0, PIC_ORIGINAL).copyFrom(m_cGOPEncoder.getPicBg()->getRecoBuf());
+#if JVET_P1006_PICTURE_HEADER
+    picCurr->finalInit( *sps, *pps, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     picCurr->finalInit( *sps, *pps, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
     picCurr->poc = m_iPOCLast - 1;
     m_iPOCLast -= 2;
     if (getUseAdaptiveQP())
@@ -873,7 +891,11 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYuvTru
       pcPicCurr->M_BUFS( 0, PIC_TRUE_ORIGINAL ).swap( *cPicYuvTrueOrg );
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    pcPicCurr->finalInit( *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
     pcPicCurr->finalInit( *pSPS, *pPPS, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
     PPS *ptrPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
     ptrPPS->setNumBricksInPic( (int)pcPicCurr->brickMap->bricks.size() );
 
@@ -975,7 +997,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicY
         int ppsID = -1; // Use default PPS ID
         const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID );
         const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() );
+#if JVET_P1006_PICTURE_HEADER
+        pcField->finalInit( *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
         pcField->finalInit( *pSPS, *pPPS, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
       }
 
       pcField->poc = m_iPOCLast;
@@ -1063,7 +1089,11 @@ void EncLib::encode( bool flush, PelStorage* pcPicYuvOrg, PelStorage* pcPicYuvTr
         const PPS *pPPS=(ppsID<0) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS(ppsID);
         const SPS *pSPS=m_spsMap.getPS(pPPS->getSPSId());
 
+#if JVET_P1006_PICTURE_HEADER
+        pcField->finalInit( *pSPS, *pPPS, &m_picHeader, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#else
         pcField->finalInit( *pSPS, *pPPS, m_apss, m_lmcsAPS, m_scalinglistAPS );
+#endif
       }
 
       pcField->poc = m_iPOCLast;
@@ -1183,7 +1213,11 @@ void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Pict
     }
     if ( getUseAdaptiveQP() )
     {
+#if JVET_P1006_PICTURE_HEADER
+      const uint32_t iMaxDQPLayer = m_picHeader.getCuQpDeltaSubdivIntra()/2+1;
+#else
       const uint32_t iMaxDQPLayer = pps.getCuQpDeltaSubdiv()/2+1;
+#endif
       rpcPic->aqlayer.resize( iMaxDQPLayer );
       for (uint32_t d = 0; d < iMaxDQPLayer; d++)
       {
@@ -1479,6 +1513,28 @@ void EncLib::xInitSPS(SPS &sps)
 
   if (m_uiIntraPeriod < 0)
     sps.setRPL1CopyFromRPL0Flag(true);
+#if JVET_P1006_PICTURE_HEADER
+
+  sps.setNumSubPics(1);  // TODO: modify for subpicture support
+  sps.setSubPicIdSignallingPresentFlag(false);
+  sps.setSubPicIdLen(16);
+  for(int picIdx=0; picIdx<MAX_NUM_SUB_PICS; picIdx++)
+  {
+    sps.setSubPicId(picIdx, picIdx);
+  }
+
+  sps.setLoopFilterAcrossVirtualBoundariesDisabledFlag( m_loopFilterAcrossVirtualBoundariesDisabledFlag );
+  sps.setNumVerVirtualBoundaries            ( m_numVerVirtualBoundaries );
+  sps.setNumHorVirtualBoundaries            ( m_numHorVirtualBoundaries );
+  for( unsigned int i = 0; i < m_numVerVirtualBoundaries; i++ )
+  {
+    sps.setVirtualBoundariesPosX            ( m_virtualBoundariesPosX[i], i );
+  }
+  for( unsigned int i = 0; i < m_numHorVirtualBoundaries; i++ )
+  {
+    sps.setVirtualBoundariesPosY            ( m_virtualBoundariesPosY[i], i );
+  }
+#endif
 }
 
 void EncLib::xInitHrdParameters(SPS &sps)
@@ -1512,6 +1568,15 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
 #endif
   pps.setPPSMaxNumMergeCandMinusMaxNumTriangleCandPlus1(getPPSMaxNumMergeCandMinusMaxNumTriangleCandPlus1());
 
+#if JVET_P1006_PICTURE_HEADER
+  pps.setNumSubPics(sps.getNumSubPics());
+  pps.setSubPicIdSignallingPresentFlag(false);
+  pps.setSubPicIdLen(sps.getSubPicIdLen());
+  for(int picIdx=0; picIdx<pps.getNumSubPics(); picIdx++)
+  {
+    pps.setSubPicId(picIdx, sps.getSubPicId(picIdx));
+  }
+#endif
   pps.setConstrainedIntraPred( m_bUseConstrainedIntraPred );
   bool bUseDQP = (getCuQpDeltaSubdiv() > 0)? true : false;
 
@@ -1543,29 +1608,39 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
   if ( m_RCEnableRateControl )
   {
     pps.setUseDQP(true);
+#if !JVET_P1006_PICTURE_HEADER
     pps.setCuQpDeltaSubdiv( 0 );
+#endif
   }
   else if(bUseDQP)
   {
     pps.setUseDQP(true);
+#if !JVET_P1006_PICTURE_HEADER
     pps.setCuQpDeltaSubdiv( m_cuQpDeltaSubdiv );
+#endif
   }
   else
   {
     pps.setUseDQP(false);
+#if !JVET_P1006_PICTURE_HEADER
     pps.setCuQpDeltaSubdiv( 0 );
+#endif
   }
 
   if ( m_cuChromaQpOffsetSubdiv >= 0 )
   {
+#if !JVET_P1006_PICTURE_HEADER
     pps.setCuChromaQpOffsetSubdiv(m_cuChromaQpOffsetSubdiv);
+#endif
     pps.clearChromaQpOffsetList();
     pps.setChromaQpOffsetListEntry(1, 6, 6, 6);
     /* todo, insert table entries from command line (NB, 0 should not be touched) */
   }
   else
   {
+#if !JVET_P1006_PICTURE_HEADER
     pps.setCuChromaQpOffsetSubdiv(0);
+#endif
     pps.clearChromaQpOffsetList();
   }
   pps.getPpsRangeExtension().setCrossComponentPredictionEnabledFlag(m_crossComponentPredictionEnabledFlag);
@@ -1739,6 +1814,9 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
 
   xInitPPSforTiles(pps);
 
+#if JVET_P1006_PICTURE_HEADER
+  pps.setPictureHeaderExtensionPresentFlag(false);
+#else
   pps.setLoopFilterAcrossVirtualBoundariesDisabledFlag( m_loopFilterAcrossVirtualBoundariesDisabledFlag );
   pps.setNumVerVirtualBoundaries            ( m_numVerVirtualBoundaries );
   pps.setNumHorVirtualBoundaries            ( m_numHorVirtualBoundaries );
@@ -1750,11 +1828,116 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
   {
     pps.setVirtualBoundariesPosY            ( m_virtualBoundariesPosY[i], i );
   }
+#endif
 
   pps.pcv = new PreCalcValues( sps, pps, true );
   pps.setRpl1IdxPresentFlag(sps.getRPL1IdxPresentFlag());
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void EncLib::xInitPicHeader(PicHeader &picHeader, const SPS &sps, const PPS &pps)
+{
+  int i;
+  picHeader.initPicHeader();
+
+  // parameter sets
+  picHeader.setSPSId( sps.getSPSId() );
+  picHeader.setPPSId( pps.getPPSId() );  
+  
+  // merge list sizes
+  picHeader.setMaxNumMergeCand      ( getMaxNumMergeCand()       );
+  picHeader.setMaxNumAffineMergeCand( getMaxNumAffineMergeCand() );
+  picHeader.setMaxNumTriangleCand   ( getMaxNumTriangleCand()    );
+  picHeader.setMaxNumIBCMergeCand   ( getMaxNumIBCMergeCand()    );
+  
+  // copy partitioning constraints from SPS
+  picHeader.setSplitConsOverrideFlag(false);
+  picHeader.setMinQTSizes( sps.getMinQTSizes() );
+  picHeader.setMaxMTTHierarchyDepths( sps.getMaxMTTHierarchyDepths() );
+  picHeader.setMaxBTSizes( sps.getMaxBTSizes() );
+  picHeader.setMaxTTSizes( sps.getMaxTTSizes() );
+
+  // quantization
+  picHeader.setDepQuantEnabledFlag( getDepQuantEnabledFlag() );
+  picHeader.setSignDataHidingEnabledFlag( getSignDataHidingEnabledFlag() );
+  
+  bool bUseDQP = (getCuQpDeltaSubdiv() > 0)? true : false;
+
+  if( (getMaxDeltaQP() != 0 )|| getUseAdaptiveQP() )
+  {
+    bUseDQP = true;
+  }
+
+#if SHARP_LUMA_DELTA_QP
+  if( getLumaLevelToDeltaQPMapping().isEnabled() )
+  {
+    bUseDQP = true;
+  }
+#endif
+#if ENABLE_QPA
+  if( getUsePerceptQPA() && !bUseDQP )
+  {
+    CHECK( m_cuQpDeltaSubdiv != 0, "max. delta-QP subdiv must be zero!" );
+    bUseDQP = (getBaseQP() < 38) && (getSourceWidth() > 512 || getSourceHeight() > 320);
+  }
+#endif
+
+  if( m_costMode==COST_SEQUENCE_LEVEL_LOSSLESS || m_costMode==COST_LOSSLESS_CODING )
+  {
+    bUseDQP=false;
+  }
+
+  if( m_RCEnableRateControl )
+  {
+    picHeader.setCuQpDeltaSubdivIntra( 0 );
+    picHeader.setCuQpDeltaSubdivInter( 0 );
+  }
+  else if( bUseDQP )
+  {
+    picHeader.setCuQpDeltaSubdivIntra( m_cuQpDeltaSubdiv );
+    picHeader.setCuQpDeltaSubdivInter( m_cuQpDeltaSubdiv );
+  }
+  else
+  {
+    picHeader.setCuQpDeltaSubdivIntra( 0 );
+    picHeader.setCuQpDeltaSubdivInter( 0 );
+  }
+
+  if( m_cuChromaQpOffsetSubdiv >= 0 )
+  {
+    picHeader.setCuChromaQpOffsetSubdivIntra(m_cuChromaQpOffsetSubdiv);
+    picHeader.setCuChromaQpOffsetSubdivInter(m_cuChromaQpOffsetSubdiv);
+  }
+  else
+  {
+    picHeader.setCuChromaQpOffsetSubdivIntra(0);
+    picHeader.setCuChromaQpOffsetSubdivInter(0);
+  }
+  
+  // sub-pictures
+  picHeader.setSubPicIdSignallingPresentFlag(sps.getSubPicIdSignallingPresentFlag());
+  picHeader.setSubPicIdLen(sps.getSubPicIdLen());
+  for(i=0; i<sps.getNumSubPics(); i++) {
+    picHeader.setSubPicId(i, sps.getSubPicId(i));
+  }
+
+  // virtual boundaries
+  picHeader.setLoopFilterAcrossVirtualBoundariesDisabledFlag(sps.getLoopFilterAcrossVirtualBoundariesDisabledFlag());
+  picHeader.setNumVerVirtualBoundaries(sps.getNumVerVirtualBoundaries());
+  picHeader.setNumHorVirtualBoundaries(sps.getNumHorVirtualBoundaries());
+  for(i=0; i<3; i++) {
+    picHeader.setVirtualBoundariesPosX(sps.getVirtualBoundariesPosX(i), i);
+    picHeader.setVirtualBoundariesPosY(sps.getVirtualBoundariesPosY(i), i);
+  }
+
+  // gradual decoder refresh flag
+  picHeader.setGdrPicFlag(false);
+  
+  // BDOF / DMVR / PROF
+  picHeader.setDisBdofDmvrFlag(false);
+}
+
+#endif
 void EncLib::xInitAPS(APS &aps)
 {
   //Do nothing now
diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h
index e477bb30d..8045eb45b 100644
--- a/source/Lib/EncoderLib/EncLib.h
+++ b/source/Lib/EncoderLib/EncLib.h
@@ -131,6 +131,9 @@ private:
   ParameterSetMap<SPS>      m_spsMap;                             ///< SPS. This is the base value. This is copied to PicSym
   ParameterSetMap<PPS>      m_ppsMap;                             ///< PPS. This is the base value. This is copied to PicSym
   ParameterSetMap<APS>      m_apsMap;                             ///< APS. This is the base value. This is copied to PicSym
+#endif
+#if JVET_P1006_PICTURE_HEADER
+  PicHeader                 m_picHeader;                          ///< picture header
 #endif
   // RD cost computation
 #if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
@@ -182,6 +185,9 @@ protected:
   void  xInitDPS          (DPS &dps, const SPS &sps, const int dpsId); ///< initialize DPS from encoder options
   void  xInitSPS          (SPS &sps);                 ///< initialize SPS from encoder options
   void  xInitPPS          (PPS &pps, const SPS &sps); ///< initialize PPS from encoder options
+#if JVET_P1006_PICTURE_HEADER
+  void  xInitPicHeader    (PicHeader &picHeader, const SPS &sps, const PPS &pps); ///< initialize Picture Header from encoder options
+#endif
   void  xInitAPS          (APS &aps);                 ///< initialize APS from encoder options
   void  xInitScalingLists ( SPS &sps, APS &aps );     ///< initialize scaling lists
   void  xInitPPSforLT(PPS& pps);
diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp
index 56da31c8c..cfc71f544 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.cpp
+++ b/source/Lib/EncoderLib/EncModeCtrl.cpp
@@ -143,7 +143,11 @@ void EncModeCtrl::xGetMinMaxQP( int& minQP, int& maxQP, const CodingStructure& c
 
   const unsigned subdivIncr = (splitMode == CU_QUAD_SPLIT) ? 2 : (splitMode == CU_BT_SPLIT) ? 1 : 0;
   const bool qgEnable = partitioner.currQgEnable(); // QG possible at current level
+#if JVET_P1006_PICTURE_HEADER
+  const bool qgEnableChildren = qgEnable && ((partitioner.currSubdiv + subdivIncr) <= cs.slice->getCuQpDeltaSubdiv()) && (subdivIncr > 0); // QG possible at next level
+#else
   const bool qgEnableChildren = qgEnable && ((partitioner.currSubdiv + subdivIncr) <= pps.getCuQpDeltaSubdiv()) && (subdivIncr > 0); // QG possible at next level
+#endif
   const bool isLeafQG = (qgEnable && !qgEnableChildren);
 
   if( isLeafQG ) // QG at deepest level
@@ -1192,7 +1196,11 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
       baseQP = Clip3(-cs.sps->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, baseQP + xComputeDQP(cs, partitioner));
     }
 #if ENABLE_QPA_SUB_CTU
+#if JVET_P1006_PICTURE_HEADER
+    else if (m_pcEncCfg->getUsePerceptQPA() && !m_pcEncCfg->getUseRateCtrl() && cs.pps->getUseDQP() && cs.slice->getCuQpDeltaSubdiv() > 0)
+#else
     else if (m_pcEncCfg->getUsePerceptQPA() && !m_pcEncCfg->getUseRateCtrl() && cs.pps->getUseDQP() && cs.pps->getCuQpDeltaSubdiv() > 0)
+#endif
     {
       const PreCalcValues &pcv = *cs.pcv;
 
diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
index 0574e3c50..4755f9c8a 100644
--- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
+++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp
@@ -309,7 +309,11 @@ void EncSampleAdaptiveOffset::getStatistics(std::vector<SAOStatData**>& blkStats
       int verVirBndryPos[] = { -1,-1,-1 };
       int horVirBndryPosComp[] = { -1,-1,-1 };
       int verVirBndryPosComp[] = { -1,-1,-1 };
+#if JVET_P1006_PICTURE_HEADER
+      bool isCtuCrossedByVirtualBoundaries = isCrossedByVirtualBoundaries(xPos, yPos, width, height, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.picHeader );
+#else
       bool isCtuCrossedByVirtualBoundaries = isCrossedByVirtualBoundaries(xPos, yPos, width, height, numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, cs.slice->getPPS());
+#endif
 
       for(int compIdx = 0; compIdx < numberOfComponents; compIdx++)
       {
@@ -1541,6 +1545,9 @@ void EncSampleAdaptiveOffset::getBlkStats(const ComponentID compIdx, const int c
 
 void EncSampleAdaptiveOffset::deriveLoopFilterBoundaryAvailibility(CodingStructure& cs, const Position &pos, bool& isLeftAvail, bool& isAboveAvail, bool& isAboveLeftAvail) const
 {
+#if JVET_P1006_PICTURE_HEADER
+  bool isLoopFiltAcrossSlicePPS = cs.pps->getLoopFilterAcrossSlicesEnabledFlag();
+#endif
   bool isLoopFiltAcrossTilePPS = cs.pps->getLoopFilterAcrossBricksEnabledFlag();
 
   const int width = cs.pcv->maxCUWidth;
@@ -1550,11 +1557,26 @@ void EncSampleAdaptiveOffset::deriveLoopFilterBoundaryAvailibility(CodingStructu
   const CodingUnit* cuAbove = cs.getCU(pos.offset(0, -height), CH_L);
   const CodingUnit* cuAboveLeft = cs.getCU(pos.offset(-width, -height), CH_L);
 
+#if JVET_P1006_PICTURE_HEADER
+  if (!isLoopFiltAcrossSlicePPS)
+  {
+    isLeftAvail      = (cuLeft == NULL)      ? false : CU::isSameTile(*cuCurr, *cuLeft);
+    isAboveAvail     = (cuAbove == NULL)     ? false : CU::isSameTile(*cuCurr, *cuAbove);
+    isAboveLeftAvail = (cuAboveLeft == NULL) ? false : CU::isSameTile(*cuCurr, *cuAboveLeft);
+  }
+  else 
+  {
+    isLeftAvail      = (cuLeft != NULL);
+    isAboveAvail     = (cuAbove != NULL);
+    isAboveLeftAvail = (cuAboveLeft != NULL);
+  }
+#else
   {
     isLeftAvail      = (cuLeft != NULL)      ? ( !CU::isSameSlice(*cuCurr, *cuLeft)      ? cuCurr->slice->getLFCrossSliceBoundaryFlag() : true ) : false;
     isAboveAvail     = (cuAbove != NULL)     ? ( !CU::isSameSlice(*cuCurr, *cuAbove)     ? cuCurr->slice->getLFCrossSliceBoundaryFlag() : true ) : false;
     isAboveLeftAvail = (cuAboveLeft != NULL) ? ( !CU::isSameSlice(*cuCurr, *cuAboveLeft) ? cuCurr->slice->getLFCrossSliceBoundaryFlag() : true ) : false;
   }
+#endif
 
   if (!isLoopFiltAcrossTilePPS)
   {
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index 99aa3691a..a0a043c41 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -329,24 +329,40 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
 {
   double dQP;
   double dLambda;
+#if JVET_P1006_PICTURE_HEADER
+  PicHeader *picHeader = pcPic->cs->picHeader;
+#endif
   pcPic->cs->resetPrevPLT(pcPic->cs->prevPLT);
 
   rpcSlice = pcPic->slices[0];
   rpcSlice->setSliceBits(0);
   rpcSlice->setPic( pcPic );
+#if JVET_P1006_PICTURE_HEADER
+  rpcSlice->setPicHeader( picHeader );
+#endif
   rpcSlice->initSlice();
   int multipleFactor = m_pcCfg->getUseCompositeRef() ? 2 : 1;
   if (m_pcCfg->getUseCompositeRef() && isEncodeLtRef)
   {
+#if JVET_P1006_PICTURE_HEADER
+    picHeader->setPicOutputFlag(false);
+#else
     rpcSlice->setPicOutputFlag(false);
+#endif
   }
   else
   {
+#if JVET_P1006_PICTURE_HEADER
+    picHeader->setPicOutputFlag(true);
+#else
     rpcSlice->setPicOutputFlag(true);
+#endif
   }
   rpcSlice->setPOC( pocCurr );
+#if !JVET_P1006_PICTURE_HEADER
   rpcSlice->setDepQuantEnabledFlag( m_pcCfg->getDepQuantEnabledFlag() );
   rpcSlice->setSignDataHidingEnabledFlag( m_pcCfg->getSignDataHidingEnabledFlag() );
+#endif
 
 #if SHARP_LUMA_DELTA_QP
   pcPic->fieldPic = isField;
@@ -586,7 +602,9 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
   rpcSlice->setSliceChromaQpDelta( COMPONENT_Cr, 0 );
   rpcSlice->setSliceChromaQpDelta( JOINT_CbCr,   0 );
 #endif
+#if !JVET_P1006_PICTURE_HEADER
   rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getCuChromaQpOffsetEnabledFlag() );
+#endif
   rpcSlice->setNumRefIdx(REF_PIC_LIST_0, m_pcCfg->getRPLEntry(0, iGOPid).m_numRefPicsActive);
   rpcSlice->setNumRefIdx(REF_PIC_LIST_1, m_pcCfg->getRPLEntry(1, iGOPid).m_numRefPicsActive);
 
@@ -632,6 +650,7 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
 
   rpcSlice->setSliceMode            ( m_pcCfg->getSliceMode()            );
   rpcSlice->setSliceArgument        ( m_pcCfg->getSliceArgument()        );
+#if !JVET_P1006_PICTURE_HEADER
   rpcSlice->setMaxNumMergeCand      ( m_pcCfg->getMaxNumMergeCand()      );
   rpcSlice->setMaxNumAffineMergeCand( m_pcCfg->getMaxNumAffineMergeCand() );
   rpcSlice->setMaxNumTriangleCand   ( m_pcCfg->getMaxNumTriangleCand() );
@@ -648,6 +667,7 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
     rpcSlice->setMaxBTSizeIChroma( rpcSlice->getSPS()->getMaxBTSizeIChroma() );
     rpcSlice->setMaxTTSizeIChroma( rpcSlice->getSPS()->getMaxTTSizeIChroma() );
   }
+#endif
   rpcSlice->setDisableSATDForRD(false);
 
   if( ( m_pcCfg->getIBCHashSearch() && m_pcCfg->getIBCMode() ) || m_pcCfg->getAllowDisFracMMVD() )
@@ -931,7 +951,11 @@ static bool applyQPAdaptation (Picture* const pcPic,       Slice* const pcSlice,
       pcPic->m_iOffsetCtu[ctuRsAddr] = (Pel)iQPAdapt; // adapted QPs
 
 #if ENABLE_QPA_SUB_CTU
+#if JVET_P1006_PICTURE_HEADER
+      if (pcv.widthInCtus > 1 && pcSlice->getCuQpDeltaSubdiv() == 0)  // reduce local DQP rate peaks
+#else
       if (pcv.widthInCtus > 1 && pcSlice->getPPS()->getCuQpDeltaSubdiv() == 0)  // reduce local DQP rate peaks
+#endif
 #elif ENABLE_QPA_SUB_CTU
       if (pcv.widthInCtus > 1 && pcSlice->getPPS()->getMaxCuDQPDepth() == 0)  // reduce local DQP rate peaks
 #else
@@ -978,7 +1002,11 @@ static int applyQPAdaptationSubCtu (CodingStructure &cs, const UnitArea ctuArea,
   const int       bitDepth = cs.slice->getSPS()->getBitDepth (CHANNEL_TYPE_LUMA); // overall image bit-depth
   const int   adaptedCtuQP = pcPic ? pcPic->m_iOffsetCtu[ctuAddr] : cs.slice->getSliceQpBase();
 
+#if JVET_P1006_PICTURE_HEADER
+  if (!pcPic || cs.slice->getCuQpDeltaSubdiv() == 0) return adaptedCtuQP;
+#else
   if (!pcPic || cs.pps->getCuQpDeltaSubdiv() == 0) return adaptedCtuQP;
+#endif
 
   for (unsigned addr = 0; addr < cs.picture->m_subCtuQP.size(); addr++)
   {
@@ -1384,16 +1412,31 @@ void EncSlice::checkDisFracMmvd( Picture* pcPic, uint32_t startCtuTsAddr, uint32
 
   if ( hashRatio > totalCtu * hashThreshold )
   {
+#if JVET_P1006_PICTURE_HEADER
+    pcPic->cs->picHeader->setDisFracMMVD( true );
+#else
     pcSlice->setDisFracMMVD( true );
+#endif
   }
+#if JVET_P1006_PICTURE_HEADER
+  if (!pcPic->cs->picHeader->getDisFracMMVD()) {
+    bool useIntegerMVD = (pcPic->lwidth()*pcPic->lheight() > 1920 * 1080);
+    pcPic->cs->picHeader->setDisFracMMVD( useIntegerMVD );
+  }
+#else
   if (!pcSlice->getDisFracMMVD()) {
     bool useIntegerMVD = (pcPic->lwidth()*pcPic->lheight() > 1920 * 1080);
     pcSlice->setDisFracMMVD( useIntegerMVD );
   }
+#endif
 }
 
 
+#if JVET_P1006_PICTURE_HEADER
+void EncSlice::setJointCbCrModes( CodingStructure& cs, const Position topLeftLuma, const Size sizeLuma )
+#else
 void setJointCbCrModes( CodingStructure& cs, const Position topLeftLuma, const Size sizeLuma )
+#endif
 {
   bool              sgnFlag = true;
 
@@ -1427,7 +1470,11 @@ void setJointCbCrModes( CodingStructure& cs, const Position topLeftLuma, const S
     sgnFlag = ( sumCbCr < 0 );
   }
 
+#if JVET_P1006_PICTURE_HEADER
+  cs.picHeader->setJointCbCrSignFlag( sgnFlag );
+#else
   cs.slice->setJointCbCrSignFlag( sgnFlag );
+#endif
 }
 
 
@@ -1479,12 +1526,14 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
       cs.slice->setDisableSATDForRD(hashBlkHitPerc > 59);
     }
   }
+#if !JVET_P1006_PICTURE_HEADER
   checkDisFracMmvd( pcPic, startCtuTsAddr, boundingCtuTsAddr );
 
   if (pcSlice->getSPS()->getJointCbCrEnabledFlag())
   {
     setJointCbCrModes(cs, Position(0, 0), cs.area.lumaSize());
   }
+#endif
 
   // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
   uint32_t startSliceRsRow = tileMap.getCtuBsToRsAddrMap(startCtuTsAddr) / widthInCtus;
diff --git a/source/Lib/EncoderLib/EncSlice.h b/source/Lib/EncoderLib/EncSlice.h
index ecc52f4a6..07f157a91 100644
--- a/source/Lib/EncoderLib/EncSlice.h
+++ b/source/Lib/EncoderLib/EncSlice.h
@@ -139,6 +139,9 @@ public:
 #endif
   void    encodeCtus          ( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr, EncLib* pcEncLib );
   void    checkDisFracMmvd    ( Picture* pcPic, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr );
+#if JVET_P1006_PICTURE_HEADER
+  void    setJointCbCrModes( CodingStructure& cs, const Position topLeftLuma, const Size sizeLuma );
+#endif
 
   // misc. functions
   void    setSearchRange      ( Slice* pcSlice  );                                  ///< set ME range adaptively
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index bb6ed55e6..d18b39381 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -1262,7 +1262,11 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf,
   CPelBuf* pcPatternKey = &tmpPattern;
   PelBuf tmpOrgLuma;
 
+#if JVET_P1006_PICTURE_HEADER
+  if ((pu.cs->picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#else
   if ((pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#endif
   {
     const CompArea &area = pu.blocks[COMPONENT_Y];
     CompArea    tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
@@ -1454,7 +1458,11 @@ bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const
     cMv.setZero();
     Distortion cost = 0;
 
+#if JVET_P1006_PICTURE_HEADER
+    if ( pu.cu->slice->getPicHeader()->getMaxNumIBCMergeCand() == 1 )
+#else
     if ( pu.cu->slice->getMaxNumIBCMergeCand() == 1 )
+#endif
     {
       iBvpNum = 1;
       cMvPred[1] = cMvPred[0];
@@ -2373,7 +2381,11 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           aaiMvpIdx[iRefList][iRefIdxTemp] = pu.mvpIdx[eRefPicList];
           aaiMvpNum[iRefList][iRefIdxTemp] = pu.mvpNum[eRefPicList];
 
+#if JVET_P1006_PICTURE_HEADER
+          if(cs.picHeader->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
+#else
           if(cs.slice->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist)
+#endif
           {
             bestBiPDist = biPDistTemp;
             bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
@@ -2468,7 +2480,11 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
 
         uint32_t uiMotBits[2];
 
+#if JVET_P1006_PICTURE_HEADER
+        if(cs.picHeader->getMvdL1ZeroFlag())
+#else
         if(cs.slice->getMvdL1ZeroFlag())
+#endif
         {
           xCopyAMVPInfo(&aacAMVPInfo[1][bestBiPRefIdxL1], &amvp[REF_PIC_LIST_1]);
           aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1;
@@ -2527,7 +2543,11 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         int iNumIter = 4;
 
         // fast encoder setting: only one iteration
+#if JVET_P1006_PICTURE_HEADER
+        if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || cs.picHeader->getMvdL1ZeroFlag() )
+#else
         if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || cs.slice->getMvdL1ZeroFlag() )
+#endif
         {
           iNumIter = 1;
         }
@@ -2556,7 +2576,11 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           {
             iRefList = 0;
           }
+#if JVET_P1006_PICTURE_HEADER
+          if ( iIter == 0 && !cs.picHeader->getMvdL1ZeroFlag())
+#else
           if ( iIter == 0 && !cs.slice->getMvdL1ZeroFlag())
+#endif
           {
             pu.mv    [1 - iRefList] = cMv    [1 - iRefList];
             pu.refIdx[1 - iRefList] = iRefIdx[1 - iRefList];
@@ -2567,7 +2591,11 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
 
           RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
 
+#if JVET_P1006_PICTURE_HEADER
+          if(cs.picHeader->getMvdL1ZeroFlag())
+#else
           if(cs.slice->getMvdL1ZeroFlag())
+#endif
           {
             iRefList = 0;
             eRefPicList = REF_PIC_LIST_0;
@@ -2634,7 +2662,11 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
             {
               xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], &amvp[REF_PIC_LIST_0]);
               xCheckBestMVP( REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], amvp[REF_PIC_LIST_0], uiBits[2], uiCostBi, pu.cu->imv);
+#if JVET_P1006_PICTURE_HEADER
+              if(!cs.picHeader->getMvdL1ZeroFlag())
+#else
               if(!cs.slice->getMvdL1ZeroFlag())
+#endif
               {
                 xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], &amvp[REF_PIC_LIST_1]);
                 xCheckBestMVP( REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], amvp[REF_PIC_LIST_1], uiBits[2], uiCostBi, pu.cu->imv);
@@ -4798,7 +4830,11 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       }
 
       // GPB list 1, save the best MvpIdx, RefIdx and Cost
+#if JVET_P1006_PICTURE_HEADER
+      if ( slice.getPicHeader()->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist )
+#else
       if ( slice.getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist )
+#endif
       {
         bestBiPDist = biPDistTemp;
         bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp];
@@ -4926,7 +4962,11 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
     uint32_t uiMotBits[2];
     bool doBiPred = true;
 
+#if JVET_P1006_PICTURE_HEADER
+    if ( slice.getPicHeader()->getMvdL1ZeroFlag() ) // GPB, list 1 only use Mvp
+#else
     if ( slice.getMvdL1ZeroFlag() ) // GPB, list 1 only use Mvp
+#endif
     {
       xCopyAffineAMVPInfo( aacAffineAMVPInfo[1][bestBiPRefIdxL1], affiAMVPInfoTemp[REF_PIC_LIST_1] );
       pu.mvpIdx[REF_PIC_LIST_1] = bestBiPMvpL1;
@@ -4992,7 +5032,11 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
     // 4-times iteration (default)
     int iNumIter = 4;
     // fast encoder setting or GPB: only one iteration
+#if JVET_P1006_PICTURE_HEADER
+    if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || slice.getPicHeader()->getMvdL1ZeroFlag() )
+#else
     if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || slice.getMvdL1ZeroFlag() )
+#endif
     {
       iNumIter = 1;
     }
@@ -5022,7 +5066,11 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
       }
 
       // First iterate, get prediction block of opposite direction
+#if JVET_P1006_PICTURE_HEADER
+      if( iIter == 0 && !slice.getPicHeader()->getMvdL1ZeroFlag() )
+#else
       if( iIter == 0 && !slice.getMvdL1ZeroFlag() )
+#endif
       {
         PU::setAllAffineMv( pu, aacMv[1-iRefList][0], aacMv[1-iRefList][1], aacMv[1-iRefList][2], RefPicList(1-iRefList));
         pu.refIdx[1-iRefList] = iRefIdx[1-iRefList];
@@ -5033,7 +5081,11 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
 
       RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
 
+#if JVET_P1006_PICTURE_HEADER
+      if ( slice.getPicHeader()->getMvdL1ZeroFlag() ) // GPB, fix List 1, search List 0
+#else
       if ( slice.getMvdL1ZeroFlag() ) // GPB, fix List 1, search List 0
+#endif
       {
         iRefList = 0;
         eRefPicList = REF_PIC_LIST_0;
@@ -5105,7 +5157,11 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
           xCopyAffineAMVPInfo( aacAffineAMVPInfo[0][iRefIdxBi[0]], affiAMVPInfoTemp[REF_PIC_LIST_0] );
           xCheckBestAffineMVP( pu, affiAMVPInfoTemp[REF_PIC_LIST_0], REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi );
 
+#if JVET_P1006_PICTURE_HEADER
+          if ( !slice.getPicHeader()->getMvdL1ZeroFlag() )
+#else
           if ( !slice.getMvdL1ZeroFlag() )
+#endif
           {
             xCopyAffineAMVPInfo( aacAffineAMVPInfo[1][iRefIdxBi[1]], affiAMVPInfoTemp[REF_PIC_LIST_1] );
             xCheckBestAffineMVP( pu, affiAMVPInfoTemp[REF_PIC_LIST_1], REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi );
@@ -6513,7 +6569,11 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
     tu.checkTuNoResidual( partitioner.currPartIdx() );
 
     const Slice           &slice = *cs.slice;
+#if JVET_P1006_PICTURE_HEADER
+    if (slice.getPicHeader()->getLmcsEnabledFlag() && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() && !(CS::isDualITree(cs) && slice.isIntra() && tu.cu->predMode==MODE_IBC ))
+#else
     if (slice.getLmcsEnabledFlag() && slice.getLmcsChromaResidualScaleFlag() && !(CS::isDualITree(cs) && slice.isIntra() && tu.cu->predMode==MODE_IBC ))
+#endif
     {
       const CompArea      &areaY = tu.blocks[COMPONENT_Y];
       int adj = m_pcReshape->calculateChromaAdjVpduNei(tu, areaY);
@@ -6664,7 +6724,11 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
 #if RDOQ_CHROMA_LAMBDA
           m_pcTrQuant->selectLambda(compID);
 #endif
+#if JVET_P1006_PICTURE_HEADER
+          if (slice.getPicHeader()->getLmcsEnabledFlag() && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag())
+#else
           if (slice.getLmcsEnabledFlag() && isChroma(compID) && slice.getLmcsChromaResidualScaleFlag())
+#endif
           {
             double cRescale = (double)(1 << CSCALE_FP_PREC) / (double)(tu.getChromaAdj());
             m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cRescale*cRescale));
@@ -6687,7 +6751,11 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
             PelBuf resiBuf = csFull->getResiBuf( compArea );
             crossComponentPrediction( tu, compID, lumaResi, resiBuf, resiBuf, false );
           }
+#if JVET_P1006_PICTURE_HEADER
+          if (slice.getPicHeader()->getLmcsEnabledFlag() && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() && tu.blocks[compID].width*tu.blocks[compID].height > 4)
+#else
           if (slice.getLmcsEnabledFlag() && isChroma(compID) && slice.getLmcsChromaResidualScaleFlag() && tu.blocks[compID].width*tu.blocks[compID].height > 4)
+#endif
           {
             PelBuf resiBuf = csFull->getResiBuf(compArea);
             resiBuf.scaleSignal(tu.getChromaAdj(), 1, tu.cu->cs->slice->clpRng(compID));
@@ -6799,7 +6867,11 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
             CPelBuf orgResiBuf = csFull->getOrgResiBuf(compArea);
 
             m_pcTrQuant->invTransformNxN(tu, compID, resiBuf, cQP);
+#if JVET_P1006_PICTURE_HEADER
+            if (slice.getPicHeader()->getLmcsEnabledFlag() && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() && tu.blocks[compID].width*tu.blocks[compID].height > 4)
+#else
             if (slice.getLmcsEnabledFlag() && isChroma(compID) && slice.getLmcsChromaResidualScaleFlag() && tu.blocks[compID].width*tu.blocks[compID].height > 4)
+#endif
             {
               resiBuf.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(compID));
             }
@@ -6895,7 +6967,11 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
       const CompArea& crArea = tu.blocks[COMPONENT_Cr];
       bool checkJointCbCr = (sps.getJointCbCrEnabledFlag()) && (!tu.noResidual) && (TU::getCbf(tu, COMPONENT_Cb) || TU::getCbf(tu, COMPONENT_Cr));
       const int channelBitDepth = sps.getBitDepth(toChannelType(COMPONENT_Cb));
+#if JVET_P1006_PICTURE_HEADER
+      bool      reshape         = slice.getPicHeader()->getLmcsEnabledFlag() && slice.getPicHeader()->getLmcsChromaResidualScaleFlag()
+#else
       bool      reshape         = slice.getLmcsEnabledFlag() && slice.getLmcsChromaResidualScaleFlag()
+#endif
                                && tu.blocks[COMPONENT_Cb].width * tu.blocks[COMPONENT_Cb].height > 4;
       double minCostCbCr = minCost[COMPONENT_Cb] + minCost[COMPONENT_Cr];
       bool   isLastBest  = false;
@@ -7230,7 +7306,11 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
     cs.getResiBuf().fill(0);
     {
       cs.getRecoBuf().copyFrom(cs.getPredBuf() );
+#if JVET_P1006_PICTURE_HEADER
+      if (m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()) && !cu.firstPU->mhIntraFlag && !CU::isIBC(cu))
+#else
       if (m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()) && !cu.firstPU->mhIntraFlag && !CU::isIBC(cu))
+#endif
       {
         cs.getRecoBuf().Y().rspSignal(m_pcReshape->getFwdLUT());
       }
@@ -7252,7 +7332,11 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
       CPelBuf org  = cs.getOrgBuf  (compID);
 #if WCG_EXT
       if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
+#if JVET_P1006_PICTURE_HEADER
+        m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())) )
+#else
         m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())) )
+#endif
       {
         const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
         if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
@@ -7295,7 +7379,11 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
   if (luma)
   {
     cs.getResiBuf().bufs[0].copyFrom(cs.getOrgBuf().bufs[0]);
+#if JVET_P1006_PICTURE_HEADER
+    if (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
     if (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
     {
       const CompArea &areaY = cu.Y();
       CompArea      tmpArea(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
@@ -7397,7 +7485,11 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
 
   if (luma)
   {
+#if JVET_P1006_PICTURE_HEADER
+    if (cu.rootCbf && cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
     if (cu.rootCbf && cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
     {
       const CompArea &areaY = cu.Y();
       CompArea      tmpArea(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
@@ -7412,7 +7504,11 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
     else
     {
       cs.getRecoBuf().bufs[0].reconstruct(cs.getPredBuf().bufs[0], cs.getResiBuf().bufs[0], cs.slice->clpRngs().comp[0]);
+#if JVET_P1006_PICTURE_HEADER
+      if (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && !cu.firstPU->mhIntraFlag && !CU::isIBC(cu))
+#else
       if (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && !cu.firstPU->mhIntraFlag && !CU::isIBC(cu))
+#endif
       {
         cs.getRecoBuf().bufs[0].rspSignal(m_pcReshape->getFwdLUT());
       }
@@ -7439,7 +7535,11 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa
 
 #if WCG_EXT
     if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
+#if JVET_P1006_PICTURE_HEADER
+      m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
+#else
       m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
+#endif
     {
       const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
       if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()) )
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index 4de25cec8..edfc7e944 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -504,7 +504,11 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner,
 
         DistParam distParamSad;
         DistParam distParamHad;
+#if JVET_P1006_PICTURE_HEADER
+        if (cu.slice->getPicHeader()->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#else
         if (cu.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+#endif
         {
           CompArea      tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
           PelBuf tmpOrg = m_tmpStorageLCU.getBuf(tmpArea);
@@ -1703,7 +1707,11 @@ void IntraSearch::PLTSearch(CodingStructure &cs, Partitioner& partitioner, Compo
   m_orgCtxRD = PLTCtx(m_CABACEstimator->getCtx());
 #endif
 
+#if JVET_P1006_PICTURE_HEADER
+  if (m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#else
   if (m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#endif
   {
     cs.getPredBuf().copyFrom(cs.getOrgBuf());
     cs.getPredBuf().Y().rspSignal(m_pcReshape->getFwdLUT());
@@ -1794,7 +1802,11 @@ void IntraSearch::PLTSearch(CodingStructure &cs, Partitioner& partitioner, Compo
     CPelBuf org = cs.getOrgBuf(compID);
 #if WCG_EXT
     if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
+#if JVET_P1006_PICTURE_HEADER
+      m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
+#else
       m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())))
+#endif
     {
       const CPelBuf orgLuma = cs.getOrgBuf(cs.area.blocks[COMPONENT_Y]);
 
@@ -1873,7 +1885,11 @@ void IntraSearch::preCalcPLTIndexRD(CodingStructure& cs, Partitioner& partitione
   for (int comp = compBegin; comp < (compBegin + numComp); comp++)
   {
     CompArea  area = cu.blocks[comp];
+#if JVET_P1006_PICTURE_HEADER
+    if (m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#else
     if (m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#endif
     {
       orgBuf[comp] = cs.getPredBuf(area);
     }
@@ -2552,7 +2568,11 @@ void IntraSearch::calcPixelPred(CodingStructure& cs, Partitioner& partitioner, u
   for (int comp = compBegin; comp < (compBegin + numComp); comp++)
   {
     CompArea  area = cu.blocks[comp];
+#if JVET_P1006_PICTURE_HEADER
+    if (m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#else
     if (m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#endif
     {
       orgBuf[comp] = cs.getPredBuf(area);
     }
@@ -2628,7 +2648,11 @@ void IntraSearch::derivePLTLossy(CodingStructure& cs, Partitioner& partitioner,
   for (int comp = compBegin; comp < (compBegin + numComp); comp++)
   {
     CompArea  area = cu.blocks[comp];
+#if JVET_P1006_PICTURE_HEADER
+    if (m_pcEncCfg->getReshaper() && (cs.picHeader->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#else
     if (m_pcEncCfg->getReshaper() && (cs.slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag()))
+#endif
     {
       orgBuf[comp] = cs.getPredBuf(area);
     }
@@ -3306,12 +3330,20 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp
   //DTRACE_PEL_BUF( D_PRED, piPred, tu, tu.cu->predMode, COMPONENT_Y );
 
   const Slice           &slice = *cs.slice;
+#if JVET_P1006_PICTURE_HEADER
+  bool flag = slice.getPicHeader()->getLmcsEnabledFlag() && (slice.isIntra() || (!slice.isIntra() && m_pcReshape->getCTUFlag()));
+#else
   bool flag = slice.getLmcsEnabledFlag() && (slice.isIntra() || (!slice.isIntra() && m_pcReshape->getCTUFlag()));
+#endif
   if (isLuma(compID))
   {
   //===== get residual signal =====
   piResi.copyFrom( piOrg  );
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
+#else
   if (slice.getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
+#endif
   {
     CompArea      tmpArea(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
     PelBuf tmpPred = m_tmpStorageLCU.getBuf(tmpArea);
@@ -3349,7 +3381,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp
 #endif
 
   flag =flag && (tu.blocks[compID].width*tu.blocks[compID].height > 4);
+#if JVET_P1006_PICTURE_HEADER
+  if (flag && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() )
+#else
   if (flag && isChroma(compID) && slice.getLmcsChromaResidualScaleFlag() )
+#endif
   {
     int cResScaleInv = tu.getChromaAdj();
     double cResScale = (double)(1 << CSCALE_FP_PREC) / (double)cResScaleInv;
@@ -3513,7 +3549,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp
   }
 
   //===== reconstruction =====
+#if JVET_P1006_PICTURE_HEADER
+  if ( flag && uiAbsSum > 0 && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() )
+#else
   if ( flag && uiAbsSum > 0 && isChroma(compID) && slice.getLmcsChromaResidualScaleFlag() )
+#endif
   {
     piResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(compID));
     if( jointCbCr )
@@ -3530,7 +3570,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp
     }
   }
 
+#if JVET_P1006_PICTURE_HEADER
+  if (slice.getPicHeader()->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
+#else
   if (slice.getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
+#endif
   {
     CompArea      tmpArea(COMPONENT_Y, area.chromaFormat, Position(0,0), area.size());
     PelBuf tmpPred = m_tmpStorageLCU.getBuf(tmpArea);
@@ -3550,7 +3594,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp
   //===== update distortion =====
 #if WCG_EXT
   if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcEncCfg->getReshaper()
+#if JVET_P1006_PICTURE_HEADER
+    && slice.getPicHeader()->getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD()))))
+#else
     && slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD()))))
+#endif
   {
     const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
     if (compID == COMPONENT_Y  && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
@@ -4349,7 +4397,11 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
     resiCr.subtract( piPredCr );
 
     //----- get reshape parameter ----
+#if JVET_P1006_PICTURE_HEADER
+    bool doReshaping = ( cs.picHeader->getLmcsEnabledFlag() && cs.picHeader->getLmcsChromaResidualScaleFlag()
+#else
     bool doReshaping = ( cs.slice->getLmcsEnabledFlag() && cs.slice->getLmcsChromaResidualScaleFlag()
+#endif
                          && (cs.slice->isIntra() || m_pcReshape->getCTUFlag()) && (cbArea.width * cbArea.height > 4) );
     if( doReshaping )
     {
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 96a733bfc..0df55b342 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -229,6 +229,20 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS )
   }
 
   WRITE_FLAG( pcPPS->getOutputFlagPresentFlag() ? 1 : 0,     "output_flag_present_flag" );
+#if JVET_P1006_PICTURE_HEADER 
+  WRITE_FLAG(pcPPS->getSubPicIdSignallingPresentFlag(), "pps_subpic_id_signalling_present_flag");
+  if( pcPPS->getSubPicIdSignallingPresentFlag() )
+  {
+    WRITE_UVLC( pcPPS->getNumSubPics() - 1, "pps_num_subpics_minus1" );
+
+    WRITE_UVLC( pcPPS->getSubPicIdLen() - 1, "pps_subpic_id_len_minus1" );
+
+    for( int picIdx = 0; picIdx < pcPPS->getNumSubPics( ); picIdx++ )
+    {
+      WRITE_CODE( pcPPS->getSubPicId(picIdx), pcPPS->getSubPicIdLen( ), "pps_subpic_id[i]" );
+    }
+  }
+#endif
   WRITE_CODE( pcPPS->getNumExtraSliceHeaderBits(), 3,        "num_extra_slice_header_bits");
   WRITE_FLAG( pcPPS->getCabacInitPresentFlag() ? 1 : 0,   "cabac_init_present_flag" );
   WRITE_UVLC( pcPPS->getNumRefIdxL0DefaultActive()-1,     "num_ref_idx_l0_default_active_minus1");
@@ -259,10 +273,12 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS )
     WRITE_UVLC(pcPPS->getLog2MaxTransformSkipBlockSize() - 2, "log2_max_transform_skip_block_size_minus2");
   }
   WRITE_FLAG( pcPPS->getUseDQP() ? 1 : 0, "cu_qp_delta_enabled_flag" );
+#if !JVET_P1006_PICTURE_HEADER 
   if ( pcPPS->getUseDQP() )
   {
     WRITE_UVLC( pcPPS->getCuQpDeltaSubdiv(), "cu_qp_delta_subdiv" );
   }
+#endif
 
   WRITE_SVLC( pcPPS->getQpOffset(COMPONENT_Cb), "pps_cb_qp_offset" );
   WRITE_SVLC( pcPPS->getQpOffset(COMPONENT_Cr), "pps_cr_qp_offset" );
@@ -285,7 +301,9 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS )
   WRITE_FLAG(uint32_t(pcPPS->getCuChromaQpOffsetEnabledFlag()),         "cu_chroma_qp_offset_enabled_flag" );
   if (pcPPS->getCuChromaQpOffsetEnabledFlag())
   {
+#if !JVET_P1006_PICTURE_HEADER 
     WRITE_UVLC(pcPPS->getCuChromaQpOffsetSubdiv(),                      "cu_chroma_qp_offset_subdiv");
+#endif
     WRITE_UVLC(pcPPS->getChromaQpOffsetListLen() - 1,                   "chroma_qp_offset_list_len_minus1");
     /* skip zero index */
     for (int cuChromaQpOffsetIdx = 0; cuChromaQpOffsetIdx < pcPPS->getChromaQpOffsetListLen(); cuChromaQpOffsetIdx++)
@@ -437,6 +455,7 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS )
     }
   }
 
+#if !JVET_P1006_PICTURE_HEADER 
   WRITE_FLAG( pcPPS->getLoopFilterAcrossVirtualBoundariesDisabledFlag() ? 1 : 0,     "pps_loop_filter_across_virtual_boundaries_disabled_flag" );
   if( pcPPS->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
   {
@@ -451,8 +470,12 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS )
       WRITE_CODE(pcPPS->getVirtualBoundariesPosY(i) >> 3, 13,                        "pps_virtual_boundaries_pos_y");
     }
   }
+#endif
 
   WRITE_UVLC( pcPPS->getLog2ParallelMergeLevelMinus2(), "log2_parallel_merge_level_minus2");
+#if JVET_P1006_PICTURE_HEADER 
+  WRITE_FLAG( pcPPS->getPictureHeaderExtensionPresentFlag() ? 1 : 0, "picture_header_extension_present_flag");
+#endif
   WRITE_FLAG( pcPPS->getSliceHeaderExtensionPresentFlag() ? 1 : 0, "slice_segment_header_extension_present_flag");
 
   bool pps_extension_present_flag=false;
@@ -746,6 +769,22 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   WRITE_UVLC( pcSPS->getMaxPicWidthInLumaSamples(), "pic_width_max_in_luma_samples" );
   WRITE_UVLC( pcSPS->getMaxPicHeightInLumaSamples(), "pic_height_max_in_luma_samples" );
 
+#if JVET_P1006_PICTURE_HEADER
+  WRITE_FLAG( pcSPS->getSubPicIdPresentFlag(), "sps_subpic_id_present_flag");
+  if( pcSPS->getSubPicIdPresentFlag() )
+  {
+    WRITE_FLAG(pcSPS->getSubPicIdSignallingPresentFlag(), "sps_subpic_id_signalling_present_flag");
+    if( pcSPS->getSubPicIdSignallingPresentFlag() )
+    {
+      WRITE_UVLC( pcSPS->getSubPicIdLen( ) - 1, "sps_subpic_id_len_minus1" );
+      for( int picIdx = 0; picIdx < pcSPS->getNumSubPics( ); picIdx++ )
+      {
+        WRITE_CODE( pcSPS->getSubPicId(picIdx), pcSPS->getSubPicIdLen( ), "sps_subpic_id[i]" );
+      }
+    }
+  }
+
+#endif
 #if JVET_P0243_SINGLE_BIT_DEPTH
   WRITE_UVLC( pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8,                      "bit_depth_minus8" );
 #else
@@ -999,6 +1038,23 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   // KJS: remove scaling lists?
   WRITE_FLAG( pcSPS->getScalingListFlag() ? 1 : 0,                                   "scaling_list_enabled_flag" );
 
+#if JVET_P1006_PICTURE_HEADER
+  WRITE_FLAG( pcSPS->getLoopFilterAcrossVirtualBoundariesDisabledFlag(), "sps_loop_filter_across_virtual_boundaries_disabled_present_flag" );
+  if( pcSPS->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
+  {
+    WRITE_CODE( pcSPS->getNumVerVirtualBoundaries(), 2, "sps_num_ver_virtual_boundaries");
+    for( unsigned i = 0; i < pcSPS->getNumVerVirtualBoundaries(); i++ )
+    {
+      WRITE_CODE((pcSPS->getVirtualBoundariesPosX(i)>>3), 13, "sps_virtual_boundaries_pos_x");
+    }
+    WRITE_CODE(pcSPS->getNumHorVirtualBoundaries(), 2, "sps_num_hor_virtual_boundaries");
+    for( unsigned i = 0; i < pcSPS->getNumHorVirtualBoundaries(); i++ )
+    {
+      WRITE_CODE((pcSPS->getVirtualBoundariesPosY(i)>>3), 13, "sps_virtual_boundaries_pos_y");
+    }
+  }
+
+#endif
   const TimingInfo *timingInfo = pcSPS->getTimingInfo();
   WRITE_FLAG(pcSPS->getHrdParametersPresentFlag(),          "general_hrd_parameters_present_flag");
     if( pcSPS->getHrdParametersPresentFlag() )
@@ -1120,6 +1176,543 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
   xWriteRbspTrailingBits();
 }
 
+#if JVET_P1006_PICTURE_HEADER
+void HLSWriter::codePictureHeader( PicHeader* picHeader )
+{
+  const PPS*  pps = NULL;
+  const SPS*  sps = NULL;
+  
+#if ENABLE_TRACING
+  xTracePictureHeader ();
+#endif
+
+  CodingStructure& cs = *picHeader->getPic()->cs;
+
+  WRITE_FLAG(picHeader->getNonReferencePictureFlag(), "non_reference_picture_flag");
+  WRITE_FLAG(picHeader->getGdrPicFlag(), "gdr_pic_flag");
+  WRITE_FLAG(picHeader->getNoOutputOfPriorPicsFlag(), "no_output_of_prior_pics_flag");
+  if( picHeader->getGdrPicFlag() ) 
+  {
+    WRITE_UVLC(picHeader->getRecoveryPocCnt(), "recovery_poc_cnt");
+  }
+  else 
+  {
+    picHeader->setRecoveryPocCnt( 0 );
+  }
+  
+  // parameter sets
+  WRITE_UVLC(picHeader->getPPSId(), "ph_pic_parameter_set_id");
+  pps = cs.slice->getPPS();
+  CHECK(pps==0, "Invalid PPS");  
+  sps = cs.slice->getSPS();
+  CHECK(sps==0, "Invalid SPS");
+  
+  // sub-picture IDs
+  if( sps->getSubPicIdPresentFlag() ) 
+  {
+    if( sps->getSubPicIdSignallingPresentFlag() ) 
+    {
+      for( int picIdx = 0; picIdx < sps->getNumSubPics( ); picIdx++ )
+      {
+        picHeader->setSubPicId( picIdx, sps->getSubPicId( picIdx ) );
+      }
+    }
+    else 
+    {
+      WRITE_FLAG(picHeader->getSubPicIdSignallingPresentFlag(), "ph_subpic_id_signalling_present_flag");
+      if( picHeader->getSubPicIdSignallingPresentFlag() )
+      {
+        WRITE_UVLC( picHeader->getSubPicIdLen() - 1, "ph_subpic_id_len_minus1" );
+        for( int picIdx = 0; picIdx < sps->getNumSubPics( ); picIdx++ )
+        {
+          WRITE_CODE(picHeader->getSubPicId(picIdx), picHeader->getSubPicIdLen( ), "ph_subpic_id[i]" );
+        }
+      }
+      else 
+      {
+        for( int picIdx = 0; picIdx < pps->getNumSubPics( ); picIdx++ )
+        {
+          picHeader->setSubPicId( picIdx, pps->getSubPicId( picIdx ) );
+        }
+      }
+    }
+  }
+  else 
+  {
+    for( int picIdx = 0; picIdx < sps->getNumSubPics( ); picIdx++ )
+    {
+      picHeader->setSubPicId( picIdx, picIdx );
+    }
+  }
+
+  // virtual boundaries
+  if( !sps->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
+  {
+    WRITE_FLAG( picHeader->getLoopFilterAcrossVirtualBoundariesDisabledFlag(), "ph_loop_filter_across_virtual_boundaries_disabled_present_flag" );
+    if( picHeader->getLoopFilterAcrossVirtualBoundariesDisabledFlag() )
+    {
+      WRITE_CODE(picHeader->getNumVerVirtualBoundaries(), 2, "ph_num_ver_virtual_boundaries");
+      for( unsigned i = 0; i < picHeader->getNumVerVirtualBoundaries(); i++ )
+      {
+        WRITE_CODE(picHeader->getVirtualBoundariesPosX(i) >> 3, 13, "ph_virtual_boundaries_pos_x");
+      }
+      WRITE_CODE(picHeader->getNumHorVirtualBoundaries(), 2, "ph_num_hor_virtual_boundaries");
+      for( unsigned i = 0; i < picHeader->getNumHorVirtualBoundaries(); i++ )
+      {
+        WRITE_CODE(picHeader->getVirtualBoundariesPosY(i)>>3, 13, "ph_virtual_boundaries_pos_y");
+      }
+    }
+    else
+    {
+      picHeader->setLoopFilterAcrossVirtualBoundariesDisabledFlag( 0 );
+      picHeader->setNumVerVirtualBoundaries( 0 );
+      picHeader->setNumHorVirtualBoundaries( 0 );
+    }
+  }
+  else
+  {
+    picHeader->setLoopFilterAcrossVirtualBoundariesDisabledFlag( sps->getLoopFilterAcrossVirtualBoundariesDisabledFlag() );
+    picHeader->setNumVerVirtualBoundaries( sps->getNumVerVirtualBoundaries() );
+    picHeader->setNumHorVirtualBoundaries( sps->getNumHorVirtualBoundaries() );
+    for( unsigned i = 0; i < 3; i++ ) 
+    {
+      picHeader->setVirtualBoundariesPosX( sps->getVirtualBoundariesPosX(i), i );
+      picHeader->setVirtualBoundariesPosY( sps->getVirtualBoundariesPosY(i), i );
+    }
+  }
+  
+  // 4:4:4 colour plane ID
+  if( sps->getSeparateColourPlaneFlag() )	
+  {
+    WRITE_CODE( picHeader->getColourPlaneId(), 2, "colour_plane_id" );
+  }
+  else 
+  {
+    picHeader->setColourPlaneId( 0 );
+  }
+  
+  // picture output flag
+  if( pps->getOutputFlagPresentFlag() )	
+  {
+    WRITE_FLAG( picHeader->getPicOutputFlag(), "pic_output_flag" );
+  }
+  else 
+  {
+    picHeader->setPicOutputFlag(true);
+  }
+
+  // reference picture lists
+  WRITE_FLAG( picHeader->getPicRplPresentFlag(), "pic_rpl_present_flag" ); 
+  if( picHeader->getPicRplPresentFlag() )
+  {	
+    // List0 and List1
+    for(int listIdx = 0; listIdx < 2; listIdx++) 
+    {                 
+      // copy L1 index from L0 index
+      if (listIdx == 1 && !pps->getRpl1IdxPresentFlag())
+      {
+        picHeader->setRPL1idx(picHeader->getRPL0idx());
+      }      
+      // RPL in picture header or SPS
+      else if (sps->getNumRPL(listIdx) > 0)
+      {
+        if (!pps->getPPSRefPicListSPSIdc(listIdx))
+        {
+          WRITE_FLAG(picHeader->getRPLIdx(listIdx) != -1 ? 1 : 0, "pic_rpl_sps_flag[i]");
+        }
+        else if (pps->getPPSRefPicListSPSIdc( listIdx ) == 1)
+        {
+          picHeader->setRPLIdx( listIdx, -1);
+        }
+      }
+      else 
+      {
+          picHeader->setRPLIdx( listIdx, -1 );
+      }
+
+      // use list from SPS
+      if (picHeader->getRPLIdx(listIdx) != -1)
+      {
+        if (listIdx == 1 && !pps->getRpl1IdxPresentFlag())
+        {
+        }
+        else if (sps->getNumRPL( listIdx ) > 1)
+        {
+          int numBits = ceilLog2(sps->getNumRPL( listIdx ));
+          WRITE_CODE(picHeader->getRPLIdx(listIdx), numBits, "pic_rpl_idx[i]");
+        }
+        else
+        {
+          picHeader->setRPLIdx( listIdx, 0 );
+        }
+        picHeader->setRPL( listIdx, sps->getRPLList( listIdx )->getReferencePictureList(picHeader->getRPLIdx(listIdx)));
+      }
+      // explicit RPL in picture header
+      else
+      {
+        xCodeRefPicList( picHeader->getRPL(listIdx), sps->getLongTermRefsPresent(), sps->getBitsForPOC(), !sps->getUseWP() && !sps->getUseWPBiPred() );
+      }
+
+      // POC MSB cycle signalling for LTRP
+      if (picHeader->getRPL(listIdx)->getNumberOfLongtermPictures())
+      {
+        for (int i = 0; i < picHeader->getRPL(listIdx)->getNumberOfLongtermPictures() + picHeader->getRPL(listIdx)->getNumberOfShorttermPictures(); i++)
+        {
+          if (picHeader->getRPL(listIdx)->isRefPicLongterm(i))
+          {
+            if (picHeader->getRPL(listIdx)->getLtrpInSliceHeaderFlag())
+            { 
+              WRITE_CODE(picHeader->getRPL(listIdx)->getRefPicIdentifier(i), sps->getBitsForPOC(),
+                         "pic_poc_lsb_lt[listIdx][rplsIdx][j]");
+            }
+            WRITE_FLAG(picHeader->getLocalRPL(listIdx)->getDeltaPocMSBPresentFlag(i) ? 1 : 0, "pic_delta_poc_msb_present_flag[i][j]");
+            if (picHeader->getLocalRPL(listIdx)->getDeltaPocMSBPresentFlag(i))
+            {
+              WRITE_UVLC(picHeader->getLocalRPL(listIdx)->getDeltaPocMSBCycleLT(i), "pic_delta_poc_msb_cycle_lt[i][j]");
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // partitioning constraint overrides
+  if (sps->getSplitConsOverrideEnabledFlag())
+  {
+    WRITE_FLAG(picHeader->getSplitConsOverrideFlag(), "partition_constraints_override_flag");
+    if (picHeader->getSplitConsOverrideFlag())
+    {
+      WRITE_UVLC(floorLog2(picHeader->getMinQTSize(I_SLICE)) - sps->getLog2MinCodingBlockSize(), "pic_log2_diff_min_qt_min_cb_intra_slice_luma");
+      WRITE_UVLC(floorLog2(picHeader->getMinQTSize(P_SLICE)) - sps->getLog2MinCodingBlockSize(), "pic_log2_diff_min_qt_min_cb_inter_slice");
+      WRITE_UVLC(picHeader->getMaxMTTHierarchyDepth(P_SLICE),  "pic_max_mtt_hierarchy_depth_inter_slice");
+      WRITE_UVLC(picHeader->getMaxMTTHierarchyDepth(I_SLICE), "pic_max_mtt_hierarchy_depth_intra_slice_luma");
+      if (picHeader->getMaxMTTHierarchyDepth(I_SLICE) != 0)
+      {
+        WRITE_UVLC(floorLog2(picHeader->getMaxBTSize(I_SLICE)) - floorLog2(picHeader->getMinQTSize(I_SLICE)), "pic_log2_diff_max_bt_min_qt_intra_slice_luma");
+        WRITE_UVLC(floorLog2(picHeader->getMaxTTSize(I_SLICE)) - floorLog2(picHeader->getMinQTSize(I_SLICE)), "pic_log2_diff_max_tt_min_qt_intra_slice_luma");
+      }
+      if (picHeader->getMaxMTTHierarchyDepth(P_SLICE) != 0)
+      {
+        WRITE_UVLC(floorLog2(picHeader->getMaxBTSize(P_SLICE)) - floorLog2(picHeader->getMinQTSize(P_SLICE)), "pic_log2_diff_max_bt_min_qt_inter_slice");
+        WRITE_UVLC(floorLog2(picHeader->getMaxTTSize(P_SLICE)) - floorLog2(picHeader->getMinQTSize(P_SLICE)), "pic_log2_diff_max_tt_min_qt_inter_slice");
+      }
+      if (sps->getUseDualITree())
+      {
+        WRITE_UVLC(floorLog2(picHeader->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA)) - sps->getLog2MinCodingBlockSize(), "pic_log2_diff_min_qt_min_cb_intra_slice_chroma");
+        WRITE_UVLC(picHeader->getMaxMTTHierarchyDepth(I_SLICE, CHANNEL_TYPE_CHROMA), "pic_max_mtt_hierarchy_depth_intra_slice_chroma");
+        if (picHeader->getMaxMTTHierarchyDepth(I_SLICE, CHANNEL_TYPE_CHROMA) != 0)
+        {
+          WRITE_UVLC(floorLog2(picHeader->getMaxBTSize(I_SLICE, CHANNEL_TYPE_CHROMA)) - floorLog2(picHeader->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA)), "pic_log2_diff_max_bt_min_qt_intra_slice_chroma");
+          WRITE_UVLC(floorLog2(picHeader->getMaxTTSize(I_SLICE, CHANNEL_TYPE_CHROMA)) - floorLog2(picHeader->getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA)), "pic_log2_diff_max_tt_min_qt_intra_slice_chroma");
+        }
+      }
+    }
+  }
+  else 
+  {
+    picHeader->setSplitConsOverrideFlag(0);
+  }
+
+  // inherit constraint values from SPS
+  if (!sps->getSplitConsOverrideEnabledFlag() || !picHeader->getSplitConsOverrideFlag()) 
+  {
+      picHeader->setMinQTSizes(sps->getMinQTSizes());
+      picHeader->setMaxMTTHierarchyDepths(sps->getMaxMTTHierarchyDepths());
+      picHeader->setMaxBTSizes(sps->getMaxBTSizes());
+      picHeader->setMaxTTSizes(sps->getMaxTTSizes());
+  }
+
+  // delta quantization and chrom and chroma offset
+  if (pps->getUseDQP())
+  {
+    WRITE_UVLC( picHeader->getCuQpDeltaSubdivIntra(), "pic_cu_qp_delta_subdiv_intra_slice" );
+    WRITE_UVLC( picHeader->getCuQpDeltaSubdivInter(), "pic_cu_qp_delta_subdiv_inter_slice" );
+  }
+  else 
+  {
+    picHeader->setCuQpDeltaSubdivIntra( 0 );
+    picHeader->setCuQpDeltaSubdivInter( 0 );
+  }
+  if (pps->getCuChromaQpOffsetEnabledFlag())
+  {
+    WRITE_UVLC( picHeader->getCuChromaQpOffsetSubdivIntra(), "pic_cu_chroma_qp_offset_subdiv_intra_slice" );
+    WRITE_UVLC( picHeader->getCuChromaQpOffsetSubdivInter(), "pic_cu_chroma_qp_offset_subdiv_inter_slice" );
+  }
+  else 
+  {
+    picHeader->setCuChromaQpOffsetSubdivIntra( 0 );
+    picHeader->setCuChromaQpOffsetSubdivInter( 0 );
+  }
+  
+  // temporal motion vector prediction
+  if (sps->getSPSTemporalMVPEnabledFlag())
+  {
+    WRITE_FLAG( picHeader->getEnableTMVPFlag(), "pic_temporal_mvp_enabled_flag" );
+  }
+  else
+  {
+    picHeader->setEnableTMVPFlag(false);
+  }
+
+  // mvd L1 zero flag
+  if (!pps->getPPSMvdL1ZeroIdc())
+  {
+    WRITE_FLAG(picHeader->getMvdL1ZeroFlag(), "pic_mvd_l1_zero_flag");
+  }
+  else
+  {
+    picHeader->setMvdL1ZeroFlag( pps->getPPSMvdL1ZeroIdc() - 1 );
+  }
+   
+  // merge candidate list size
+  if (!pps->getPPSSixMinusMaxNumMergeCandPlus1())
+  {
+    CHECK(picHeader->getMaxNumMergeCand() > MRG_MAX_NUM_CANDS, "More merge candidates signalled than supported");
+    WRITE_UVLC(MRG_MAX_NUM_CANDS - picHeader->getMaxNumMergeCand(), "pic_six_minus_max_num_merge_cand");
+  }
+  else
+  {
+    picHeader->setMaxNumMergeCand(MRG_MAX_NUM_CANDS - (pps->getPPSSixMinusMaxNumMergeCandPlus1() - 1));
+  }
+
+  // subblock merge candidate list size
+  if ( sps->getUseAffine() )
+  {
+    CHECK( picHeader->getMaxNumAffineMergeCand() > AFFINE_MRG_MAX_NUM_CANDS, "More affine merge candidates signalled than supported" );
+    WRITE_UVLC(AFFINE_MRG_MAX_NUM_CANDS - picHeader->getMaxNumAffineMergeCand(), "pic_five_minus_max_num_subblock_merge_cand");
+  }
+  else
+  {
+    picHeader->setMaxNumAffineMergeCand( sps->getSBTMVPEnabledFlag() && picHeader->getEnableTMVPFlag() );
+  }
+
+  // full-pel MMVD flag
+  if (sps->getFpelMmvdEnabledFlag())
+  {
+    WRITE_FLAG( picHeader->getDisFracMMVD(), "pic_fpel_mmvd_enabled_flag" );
+  }
+  else
+  {
+    picHeader->setDisFracMMVD(false);
+  }
+  
+  // picture level BDOF/DMVR/PROF disable flags
+  if (sps->getBdofDmvrSlicePresentFlag())
+  {
+    WRITE_FLAG(picHeader->getDisBdofDmvrFlag(), "pic_disable_bdof_dmvr_flag");
+  }
+  else
+  {
+    picHeader->setDisBdofDmvrFlag(0);
+  }
+ 
+  // triangle merge candidate list size
+  if (sps->getUseTriangle() && picHeader->getMaxNumMergeCand() >= 2)
+  {
+    if (!pps->getPPSMaxNumMergeCandMinusMaxNumTriangleCandPlus1())
+    {
+      CHECK(picHeader->getMaxNumMergeCand() < picHeader->getMaxNumTriangleCand(), "Incorrrect max number of triangle candidates!");
+      WRITE_UVLC(picHeader->getMaxNumMergeCand() - picHeader->getMaxNumTriangleCand(), "pic_max_num_merge_cand_minus_max_num_triangle_cand");
+    }
+    else
+    {
+      picHeader->setMaxNumTriangleCand((uint32_t)(picHeader->getMaxNumMergeCand() - (pps->getPPSMaxNumMergeCandMinusMaxNumTriangleCandPlus1() - 1)));
+    }    
+  }
+
+  // ibc merge candidate list size
+  if (sps->getIBCFlag())
+  {
+    CHECK( picHeader->getMaxNumIBCMergeCand() > IBC_MRG_MAX_NUM_CANDS, "More IBC merge candidates signalled than supported" );
+    WRITE_UVLC(IBC_MRG_MAX_NUM_CANDS - picHeader->getMaxNumIBCMergeCand(), "pic_six_minus_max_num_ibc_merge_cand");
+  }
+
+  // joint Cb/Cr sign flag
+  if (sps->getJointCbCrEnabledFlag())
+  {
+    WRITE_FLAG( picHeader->getJointCbCrSignFlag(), "pic_joint_cbcr_sign_flag" );
+  }
+  else
+  {
+    picHeader->setJointCbCrSignFlag(false);
+  }
+
+  // sao enable flags
+  if(sps->getSAOEnabledFlag())
+  {
+    WRITE_FLAG(picHeader->getSaoEnabledPresentFlag(), "pic_sao_enabled_present_flag");
+    if (picHeader->getSaoEnabledPresentFlag())
+    {    
+      WRITE_FLAG(picHeader->getSaoEnabledFlag(CHANNEL_TYPE_LUMA), "slice_sao_luma_flag");  
+      if (sps->getChromaFormatIdc() != CHROMA_400)
+      {
+        WRITE_FLAG(picHeader->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA), "slice_sao_chroma_flag");
+      }
+    }
+    else 
+    {
+      picHeader->setSaoEnabledFlag(CHANNEL_TYPE_LUMA,   true);
+      picHeader->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, true);
+    }
+  }
+  else 
+  {
+    picHeader->setSaoEnabledFlag(CHANNEL_TYPE_LUMA,   false);
+    picHeader->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, false);
+  }
+  
+  // alf enable flags and aps IDs
+  if( sps->getALFEnabledFlag() )
+  {
+    WRITE_FLAG(picHeader->getAlfEnabledPresentFlag(), "pic_alf_enabled_present_flag");
+    if (picHeader->getAlfEnabledPresentFlag()) 
+    {
+      WRITE_FLAG(picHeader->getAlfEnabledFlag(COMPONENT_Y), "pic_alf_enabled_flag");
+      if (picHeader->getAlfEnabledFlag(COMPONENT_Y))
+      {
+        WRITE_CODE(picHeader->getNumAlfAps(), 3, "pic_num_alf_aps_ids_luma");
+        const std::vector<int>&   apsId = picHeader->getAlfAPSs();
+        for (int i = 0; i < picHeader->getNumAlfAps(); i++)
+        {
+          WRITE_CODE(apsId[i], 3, "pic_alf_aps_id_luma");
+        }
+        
+        const int alfChromaIdc = picHeader->getAlfEnabledFlag(COMPONENT_Cb) + picHeader->getAlfEnabledFlag(COMPONENT_Cr) * 2 ;
+        if (sps->getChromaFormatIdc() != CHROMA_400)
+        {
+          WRITE_CODE(alfChromaIdc, 2, "pic_alf_chroma_idc");
+        }
+        if (alfChromaIdc)
+        {
+          WRITE_CODE(picHeader->getAlfApsIdChroma(), 3, "pic_alf_aps_id_chroma");
+        }
+      }
+    }
+    else 
+    {
+      picHeader->setAlfEnabledFlag(COMPONENT_Y,  true);
+      picHeader->setAlfEnabledFlag(COMPONENT_Cb, true);
+      picHeader->setAlfEnabledFlag(COMPONENT_Cr, true);
+    }
+  }
+  else 
+  {
+    picHeader->setAlfEnabledFlag(COMPONENT_Y,  false);
+    picHeader->setAlfEnabledFlag(COMPONENT_Cb, false);
+    picHeader->setAlfEnabledFlag(COMPONENT_Cr, false);
+  }
+
+  // dependent quantization
+  if (!pps->getPPSDepQuantEnabledIdc())
+  {
+    WRITE_FLAG(picHeader->getDepQuantEnabledFlag(), "pic_dep_quant_enabled_flag");
+  }
+  else
+  {
+    picHeader->setDepQuantEnabledFlag( pps->getPPSDepQuantEnabledIdc() - 1 );
+  }
+
+  // sign data hiding
+  if( !picHeader->getDepQuantEnabledFlag() )
+  {
+    WRITE_FLAG( picHeader->getSignDataHidingEnabledFlag(), "pic_sign_data_hiding_enabled_flag" );
+  }
+  else
+  {
+    picHeader->setSignDataHidingEnabledFlag(false);
+  }
+
+  // deblocking filter controls
+  if (pps->getDeblockingFilterControlPresentFlag())
+  {
+    if(pps->getDeblockingFilterOverrideEnabledFlag())
+    {    
+      WRITE_FLAG ( picHeader->getDeblockingFilterOverridePresentFlag(), "pic_deblocking_filter_override_present_flag" );    
+      if( picHeader->getDeblockingFilterOverridePresentFlag() ) 
+      {
+        WRITE_FLAG ( picHeader->getDeblockingFilterOverrideFlag(), "pic_deblocking_filter_override_flag" );
+      }
+      else
+      {    
+        picHeader->setDeblockingFilterOverrideFlag(false);
+      }
+    }
+    else
+    {
+      picHeader->setDeblockingFilterOverridePresentFlag(false);
+      picHeader->setDeblockingFilterOverrideFlag(false);
+    }
+
+    if(picHeader->getDeblockingFilterOverrideFlag())
+    {
+      WRITE_FLAG ( picHeader->getDeblockingFilterDisable(), "pic_deblocking_filter_disabled_flag" );
+      if(!picHeader->getDeblockingFilterDisable())
+      {
+        WRITE_SVLC( picHeader->getDeblockingFilterBetaOffsetDiv2(), "pic_beta_offset_div2" );
+        WRITE_SVLC( picHeader->getDeblockingFilterTcOffsetDiv2(), "pic_tc_offset_div2" );
+      }
+    }
+    else
+    {
+      picHeader->setDeblockingFilterDisable       ( pps->getPPSDeblockingFilterDisabledFlag() );
+      picHeader->setDeblockingFilterBetaOffsetDiv2( pps->getDeblockingFilterBetaOffsetDiv2() );
+      picHeader->setDeblockingFilterTcOffsetDiv2  ( pps->getDeblockingFilterTcOffsetDiv2() );
+    }
+  }
+  else
+  {
+    picHeader->setDeblockingFilterDisable       ( false );
+    picHeader->setDeblockingFilterBetaOffsetDiv2( 0 );
+    picHeader->setDeblockingFilterTcOffsetDiv2  ( 0 );
+  }
+
+  // luma mapping / chroma scaling controls
+  if (sps->getUseReshaper())
+  {
+    WRITE_FLAG(picHeader->getLmcsEnabledFlag(), "pic_lmcs_enabled_flag");
+    if (picHeader->getLmcsEnabledFlag())
+    {
+      WRITE_CODE(picHeader->getLmcsAPSId(), 2, "pic_lmcs_aps_id");
+      if (sps->getChromaFormatIdc() != CHROMA_400)
+      {
+        WRITE_FLAG(picHeader->getLmcsChromaResidualScaleFlag(), "pic_chroma_residual_scale_flag");
+      }
+      else
+      {
+        picHeader->setLmcsChromaResidualScaleFlag(false);
+      }
+    }
+  }
+  else
+  {
+    picHeader->setLmcsEnabledFlag(false);
+    picHeader->setLmcsChromaResidualScaleFlag(false);
+  }
+
+  // quantization scaling lists
+  if( sps->getScalingListFlag() )
+  {
+    WRITE_FLAG( picHeader->getScalingListPresentFlag(), "pic_scaling_list_present_flag" );
+    if( picHeader->getScalingListPresentFlag() )
+    {
+      WRITE_CODE( picHeader->getScalingListAPSId(), 3, "pic_scaling_list_aps_id" );
+    }
+  }
+  else 
+  {
+    picHeader->setScalingListPresentFlag( false );
+  }
+
+  // picture header extension
+  if(pps->getPictureHeaderExtensionPresentFlag())
+  {
+    WRITE_UVLC(0,"pic_segment_header_extension_length");
+  }
+  
+  xWriteRbspTrailingBits();
+}
+
+#endif
 void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
 {
 #if ENABLE_TRACING
@@ -1127,11 +1720,22 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
 #endif
 
   CodingStructure& cs = *pcSlice->getPic()->cs;
+#if JVET_P1006_PICTURE_HEADER
+  const PicHeader *picHeader = cs.picHeader;
+#endif
   const ChromaFormat format                = pcSlice->getSPS()->getChromaFormatIdc();
   const uint32_t         numberValidComponents = getNumberValidComponents(format);
   const bool         chromaEnabled         = isChromaEnabled(format);
 
+#if JVET_P1006_PICTURE_HEADER
+  int pocBits = pcSlice->getSPS()->getBitsForPOC();
+  int pocMask = (1 << pocBits) - 1;
+  WRITE_CODE(pcSlice->getPOC() & pocMask, pocBits, "slice_pic_order_cnt_lsb");
+#endif
+  
+#if !JVET_P1006_PICTURE_HEADER
   WRITE_UVLC( pcSlice->getPPS()->getPPSId(), "slice_pic_parameter_set_id" );
+#endif
   int bitsSliceAddress = 1;
   if (!pcSlice->getPPS()->getRectSliceFlag())
   {
@@ -1170,16 +1774,19 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
     WRITE_UVLC(pcSlice->getSliceNumBricks() - 1, "num_bricks_in_slice_minus1");
   }
 
+#if !JVET_P1006_PICTURE_HEADER
     WRITE_FLAG(pcSlice->getNonRefPictFlag() ? 1 : 0, "non_reference_picture_flag");
 
     for( int i = 0; i < pcSlice->getPPS()->getNumExtraSliceHeaderBits(); i++ )
     {
       WRITE_FLAG( 0, "slice_reserved_flag[]" );
     }
+#endif
 
     WRITE_UVLC( pcSlice->getSliceType(), "slice_type" );
 
 
+#if !JVET_P1006_PICTURE_HEADER
     int pocBits = pcSlice->getSPS()->getBitsForPOC();
     int pocMask = (1 << pocBits) - 1;
     WRITE_CODE(pcSlice->getPOC() & pocMask, pocBits, "slice_pic_order_cnt_lsb");
@@ -1197,7 +1804,13 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
     {
       WRITE_FLAG(pcSlice->getPicOutputFlag() ? 1 : 0, "pic_output_flag");
     }
+#endif
+
+#if JVET_P1006_PICTURE_HEADER
+    if( !picHeader->getPicRplPresentFlag() && (!pcSlice->getIdrPicFlag() || pcSlice->getSPS()->getIDRRefParamListPresent()) )
+#else
     if( !pcSlice->getIdrPicFlag() || pcSlice->getSPS()->getIDRRefParamListPresent())
+#endif
     {
       //Write L0 related syntax elements
       if (pcSlice->getSPS()->getNumRPL0() > 0)
@@ -1299,7 +1912,12 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
           }
         }
       }
+#if JVET_P1006_PICTURE_HEADER
+    }
 
+    if( picHeader->getPicRplPresentFlag() || !pcSlice->getIdrPicFlag() || pcSlice->getSPS()->getIDRRefParamListPresent() )
+    {
+#endif
       //check if numrefidxes match the defaults. If not, override
 
       if ((!pcSlice->isIntra() && pcSlice->getRPL0()->getNumRefEntries() > 1) ||
@@ -1342,6 +1960,7 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
       }
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     if (
       pcSlice->getSPS()->getSplitConsOverrideEnabledFlag()
       )
@@ -1394,6 +2013,7 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
         WRITE_FLAG( pcSlice->getMvdL1ZeroFlag() ? 1 : 0, "mvd_l1_zero_flag" );
       }
     }
+#endif
 
     if( !pcSlice->isIntra() )
     {
@@ -1407,7 +2027,11 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
       }
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    if( pcSlice->getPicHeader()->getEnableTMVPFlag() )
+#else
     if( pcSlice->getEnableTMVPFlag() )
+#endif
     {
       if( pcSlice->getSliceType() == B_SLICE )
       {
@@ -1430,6 +2054,7 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
       xCodePredWeightTable( pcSlice );
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     if (!cs.slice->isIntra())
     {
       CHECK(pcSlice->getMaxNumMergeCand() > MRG_MAX_NUM_CANDS, "More merge candidates signalled than supported");
@@ -1492,6 +2117,7 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
     {
       WRITE_FLAG( pcSlice->getJointCbCrSignFlag() ? 1 : 0, "slice_joint_cbcr_sign_flag");
     }
+#endif
 
     int iCode = pcSlice->getSliceQp() - ( pcSlice->getPPS()->getPicInitQPMinus26() + 26 );
     WRITE_SVLC( iCode, "slice_qp_delta" );
@@ -1512,12 +2138,18 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
       CHECK(numberValidComponents < COMPONENT_Cr+1, "Too many valid components");
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     if (pcSlice->getPPS()->getCuChromaQpOffsetEnabledFlag())
     {
       WRITE_FLAG(pcSlice->getUseChromaQpAdj(), "cu_chroma_qp_offset_enabled_flag");
     }
+#endif
 
+#if JVET_P1006_PICTURE_HEADER
+    if( pcSlice->getSPS()->getSAOEnabledFlag() && !picHeader->getSaoEnabledPresentFlag() )
+#else
     if( pcSlice->getSPS()->getSAOEnabledFlag() )
+#endif
     {
       WRITE_FLAG( pcSlice->getSaoEnabledFlag( CHANNEL_TYPE_LUMA ), "slice_sao_luma_flag" );
       if( chromaEnabled )
@@ -1526,7 +2158,11 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
       }
     }
 
+#if JVET_P1006_PICTURE_HEADER
+    if( pcSlice->getSPS()->getALFEnabledFlag() && !picHeader->getAlfEnabledPresentFlag() )
+#else
     if( pcSlice->getSPS()->getALFEnabledFlag() )
+#endif
     {
       const int alfEnabled = pcSlice->getTileGroupAlfEnabledFlag(COMPONENT_Y);
       WRITE_FLAG(alfEnabled, "slice_alf_enabled_flag");
@@ -1552,6 +2188,7 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
       }
     }
 
+#if !JVET_P1006_PICTURE_HEADER
     if (!pcSlice->getPPS()->getPPSDepQuantEnabledIdc())
     {
       WRITE_FLAG( pcSlice->getDepQuantEnabledFlag() ? 1 : 0, "dep_quant_enabled_flag" );
@@ -1564,12 +2201,23 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
     {
       CHECK( pcSlice->getSignDataHidingEnabledFlag(), "sign data hiding not supported when dependent quantization is enabled" );
     }
+#endif
     if (pcSlice->getPPS()->getDeblockingFilterControlPresentFlag())
     {
+#if JVET_P1006_PICTURE_HEADER
+      if (pcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() && !picHeader->getDeblockingFilterOverridePresentFlag())
+#else
       if (pcSlice->getPPS()->getDeblockingFilterOverrideEnabledFlag() )
+#endif
       {
         WRITE_FLAG(pcSlice->getDeblockingFilterOverrideFlag(), "deblocking_filter_override_flag");
       }
+#if JVET_P1006_PICTURE_HEADER
+      else
+      {
+        pcSlice->setDeblockingFilterOverrideFlag(0);
+      }
+#endif
       if (pcSlice->getDeblockingFilterOverrideFlag())
       {
         WRITE_FLAG(pcSlice->getDeblockingFilterDisable(), "slice_deblocking_filter_disabled_flag");
@@ -1579,8 +2227,25 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
           WRITE_SVLC (pcSlice->getDeblockingFilterTcOffsetDiv2(),   "slice_tc_offset_div2");
         }
       }
+#if JVET_P1006_PICTURE_HEADER
+      else
+      {
+        pcSlice->setDeblockingFilterDisable       ( picHeader->getDeblockingFilterDisable() );
+        pcSlice->setDeblockingFilterBetaOffsetDiv2( picHeader->getDeblockingFilterBetaOffsetDiv2() );
+        pcSlice->setDeblockingFilterTcOffsetDiv2  ( picHeader->getDeblockingFilterTcOffsetDiv2() );
+      }
+#endif
     }
+#if JVET_P1006_PICTURE_HEADER
+    else
+    {
+      pcSlice->setDeblockingFilterDisable       ( false );
+      pcSlice->setDeblockingFilterBetaOffsetDiv2( 0 );
+      pcSlice->setDeblockingFilterTcOffsetDiv2  ( 0 );
+    }
+#endif
 
+#if !JVET_P1006_PICTURE_HEADER
     bool isSAOEnabled = pcSlice->getSPS()->getSAOEnabledFlag() && (pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_LUMA) || (chromaEnabled && pcSlice->getSaoEnabledFlag(CHANNEL_TYPE_CHROMA)));
     bool isDBFEnabled = (!pcSlice->getDeblockingFilterDisable());
 
@@ -1610,6 +2275,7 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
         WRITE_CODE( pcSlice->getscalingListAPSId(), 3, "slice_scaling_list_aps_id" );
       }
     }
+#endif
   if(pcSlice->getPPS()->getSliceHeaderExtensionPresentFlag())
   {
     WRITE_UVLC(0,"slice_segment_header_extension_length");
diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h
index 662c6f99c..5e4784796 100644
--- a/source/Lib/EncoderLib/VLCWriter.h
+++ b/source/Lib/EncoderLib/VLCWriter.h
@@ -131,6 +131,9 @@ public:
   void  codeScalingListAps      ( APS* pcAPS );
   void  codeVPS                 ( const VPS* pcVPS );
   void  codeDPS                 ( const DPS* dps );
+#if JVET_P1006_PICTURE_HEADER
+  void  codePictureHeader       ( PicHeader* picHeader );
+#endif
   void  codeSliceHeader         ( Slice* pcSlice );
   void  codeConstraintInfo      ( const ConstraintInfo* cinfo );
   void  codeProfileTierLevel    ( const ProfileTierLevel* ptl, int maxNumSubLayersMinus1 );
-- 
GitLab