diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 774f0a02caf1536bf95055042943ddf60708b581..e0bef48c13fbd2ea9ee23ee29013521997dbbe91 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -470,6 +470,12 @@ void EncApp::xInitLibCfg()
 #if JVET_O0041_FRAME_FIELD_SEI
   m_cEncLib.setFrameFieldInfoSEIEnabled                          ( m_frameFieldInfoSEIEnabled );
 #endif
+#if JVET_O0189_DU
+  m_cEncLib.setDecodingUnitInfoSEIEnabled                        ( m_decodingUnitInfoSEIEnabled );
+#endif
+#if FIX_HRD_O0189
+  m_cEncLib.setHrdParametersPresentFlag                          ( m_hrdParametersPresentFlag );
+#endif
 #if HEVC_SEI
   m_cEncLib.setToneMappingInfoSEIEnabled                         ( m_toneMappingInfoSEIEnabled );
   m_cEncLib.setTMISEIToneMapId                                   ( m_toneMapId );
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 9c3f7f28279460eb710d748672e2cc44a6675e91..91ba60a3ec5053d418ac291c9621c4b455d084d1 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1239,6 +1239,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 #if HEVC_SEI
   ("SEIActiveParameterSets",                          m_activeParameterSetsSEIEnabled,                      0, "Enable generation of active parameter sets SEI messages");
   opts.addOptions()
+#endif
+#if FIX_HRD_O0189
+  ("HrdParametersPresent,-hrd",                       m_hrdParametersPresentFlag,                       false, "Enable generation of hrd_parameters()")
 #endif
   ("VuiParametersPresent,-vui",                       m_vuiParametersPresentFlag,                       false, "Enable generation of vui_parameters()")
   ("AspectRatioInfoPresent",                          m_aspectRatioInfoPresentFlag,                     false, "Signals whether aspect_ratio_idc is present")
@@ -1264,6 +1267,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 #endif
   ("SEIBufferingPeriod",                              m_bufferingPeriodSEIEnabled,                      false, "Control generation of buffering period SEI messages")
   ("SEIPictureTiming",                                m_pictureTimingSEIEnabled,                        false, "Control generation of picture timing SEI messages")
+#if JVET_O0189_DU
+  ("SEIDecodingUnitInfo",                             m_decodingUnitInfoSEIEnabled,                     false, "Control generation of decoding unit information SEI message.")
+#endif
 #if JVET_O0041_FRAME_FIELD_SEI
   ("SEIFrameFieldInfo",                               m_frameFieldInfoSEIEnabled,                       false, "Control generation of frame field information SEI messages")
 #endif
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 8f077ac89d1bcea11040647305d2683a4774598e..913cfaeb39a6a38d2ec77d08b8b6e3e41bb2fe4e 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -469,6 +469,9 @@ protected:
 #endif
   bool      m_bufferingPeriodSEIEnabled;
   bool      m_pictureTimingSEIEnabled;
+#if JVET_O0189_DU
+  bool      m_decodingUnitInfoSEIEnabled;
+#endif
 #if JVET_O0041_FRAME_FIELD_SEI
   bool      m_frameFieldInfoSEIEnabled;
 #endif
@@ -597,6 +600,9 @@ protected:
 #endif
   bool      m_decodingParameterSetEnabled;                   ///< enable decoding parameter set
 
+#if FIX_HRD_O0189
+  bool      m_hrdParametersPresentFlag;                       ///< enable generation of HRD parameters
+#endif
   bool      m_vuiParametersPresentFlag;                       ///< enable generation of VUI parameters
   bool      m_aspectRatioInfoPresentFlag;                     ///< Signals whether aspect_ratio_idc is present
   int       m_aspectRatioIdc;                                 ///< aspect_ratio_idc
diff --git a/source/Lib/CommonLib/HRD.h b/source/Lib/CommonLib/HRD.h
index 3d3c672037ac6eb0de1714064d85c046e555eea8..5b436d040eae626d0775974b85501ccbc82c32b4 100644
--- a/source/Lib/CommonLib/HRD.h
+++ b/source/Lib/CommonLib/HRD.h
@@ -92,18 +92,30 @@ class HRDParameters
 private:
   bool     m_nalHrdParametersPresentFlag;
   bool     m_vclHrdParametersPresentFlag;
+#if !JVET_O0189_DU
   bool     m_subPicCpbParamsPresentFlag;
+#endif
   uint32_t m_tickDivisorMinus2;
+#if JVET_O0189_DU
+  bool     m_decodingUnitCpbParamsInPicTimingSeiFlag;
+#else
   uint32_t m_duCpbRemovalDelayLengthMinus1;
+#endif
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   bool     m_subPicCpbParamsInPicTimingSEIFlag;
 #else
   bool     m_decodingUnitHrdParamsPresentFlag;
 #endif
+#if !JVET_O0189_DU
   uint32_t m_dpbOutputDelayDuLengthMinus1;
+#endif
   uint32_t m_bitRateScale;
   uint32_t m_cpbSizeScale;
+#if JVET_O0189_DU
+  uint32_t m_cpbSizeDuScale;
+#else
   uint32_t m_ducpbSizeScale;
+#endif
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   uint32_t m_initialCpbRemovalDelayLengthMinus1;
   uint32_t m_cpbRemovalDelayLengthMinus1;
@@ -115,17 +127,28 @@ public:
   HRDParameters()
     :m_nalHrdParametersPresentFlag       (false)
     ,m_vclHrdParametersPresentFlag       (false)
+#if !JVET_O0189_DU
     ,m_subPicCpbParamsPresentFlag        (false)
+#endif
     ,m_tickDivisorMinus2                 (0)
+#if JVET_O0189_DU
+    ,m_decodingUnitCpbParamsInPicTimingSeiFlag (false)
+#else
     ,m_duCpbRemovalDelayLengthMinus1     (0)
+#endif
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
     ,m_subPicCpbParamsInPicTimingSEIFlag (false)
 #else
     ,m_decodingUnitHrdParamsPresentFlag  (false)
 #endif
+#if !JVET_O0189_DU
     ,m_dpbOutputDelayDuLengthMinus1      (0)
+#endif
     ,m_bitRateScale                      (0)
     ,m_cpbSizeScale                      (0)
+#if JVET_O0189_DU
+    ,m_cpbSizeDuScale                    (0)
+#endif
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
     ,m_initialCpbRemovalDelayLengthMinus1(23)
     ,m_cpbRemovalDelayLengthMinus1       (23)
@@ -141,14 +164,18 @@ public:
   void      setVclHrdParametersPresentFlag( bool flag )                                { m_vclHrdParametersPresentFlag = flag;                      }
   bool      getVclHrdParametersPresentFlag( ) const                                    { return m_vclHrdParametersPresentFlag;                      }
 
+#if !JVET_O0189_DU
   void      setSubPicCpbParamsPresentFlag( bool flag )                                 { m_subPicCpbParamsPresentFlag = flag;                       }
   bool      getSubPicCpbParamsPresentFlag( ) const                                     { return m_subPicCpbParamsPresentFlag;                       }
+#endif
 
   void      setTickDivisorMinus2( uint32_t value )                                     { m_tickDivisorMinus2 = value;                               }
   uint32_t  getTickDivisorMinus2( ) const                                              { return m_tickDivisorMinus2;                                }
 
+#if !JVET_O0189_DU
   void      setDuCpbRemovalDelayLengthMinus1( uint32_t value )                         { m_duCpbRemovalDelayLengthMinus1 = value;                   }
   uint32_t  getDuCpbRemovalDelayLengthMinus1( ) const                                  { return m_duCpbRemovalDelayLengthMinus1;                    }
+#endif
 
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   void      setSubPicCpbParamsInPicTimingSEIFlag( bool flag)                           { m_subPicCpbParamsInPicTimingSEIFlag = flag;                }
@@ -158,16 +185,27 @@ public:
   bool      getDecodingUnitHrdParamsPresentFlag( ) const                               { return m_decodingUnitHrdParamsPresentFlag;                 }
 #endif
 
+#if !JVET_O0189_DU
   void      setDpbOutputDelayDuLengthMinus1(uint32_t value )                           { m_dpbOutputDelayDuLengthMinus1 = value;                    }
   uint32_t  getDpbOutputDelayDuLengthMinus1( ) const                                   { return m_dpbOutputDelayDuLengthMinus1;                     }
+#endif
+#if JVET_O0189_DU
+  void      setDecodingUnitCpbParamsInPicTimingSeiFlag( uint32_t value )               { m_decodingUnitCpbParamsInPicTimingSeiFlag = value;                                    }
+  uint32_t  getDecodingUnitCpbParamsInPicTimingSeiFlag( ) const                        { return m_decodingUnitCpbParamsInPicTimingSeiFlag;                                     }
+#endif
 
   void      setBitRateScale( uint32_t value )                                          { m_bitRateScale = value;                                    }
   uint32_t  getBitRateScale( ) const                                                   { return m_bitRateScale;                                     }
 
   void      setCpbSizeScale( uint32_t value )                                          { m_cpbSizeScale = value;                                    }
   uint32_t  getCpbSizeScale( ) const                                                   { return m_cpbSizeScale;                                     }
+#if JVET_O0189_DU
+  void      setCpbSizeDuScale( uint32_t value )                                        { m_cpbSizeDuScale = value;                                  }
+  uint32_t  getCpbSizeDuScale( ) const                                                 { return m_cpbSizeDuScale;                                   }
+#else
   void      setDuCpbSizeScale( uint32_t value )                                        { m_ducpbSizeScale = value;                                  }
   uint32_t  getDuCpbSizeScale( ) const                                                 { return m_ducpbSizeScale;                                   }
+#endif
 
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   void      setInitialCpbRemovalDelayLengthMinus1( uint32_t value )                    { m_initialCpbRemovalDelayLengthMinus1 = value;              }
diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp
index 16e6f7e92f47ff5f6bf6b5eed13569aaa8b13935..36331b693f55954aab908403d8dc0a9aec20639a 100644
--- a/source/Lib/CommonLib/SEI.cpp
+++ b/source/Lib/CommonLib/SEI.cpp
@@ -109,8 +109,14 @@ void SEIBufferingPeriod::copyTo (SEIBufferingPeriod& target) const
   target.m_dpbOutputDelayLength = m_dpbOutputDelayLength;
   target.m_bpCpbCnt = m_bpCpbCnt;
 #endif
+#if !FIX_SEI_O0189
   target.m_cpbDelayOffset = m_cpbDelayOffset;
   target.m_dpbDelayOffset = m_dpbDelayOffset;
+#endif
+#if JVET_O0189_DU
+  target.m_duCpbRemovalDelayIncrementLength = m_duCpbRemovalDelayIncrementLength;
+  target.m_dpbOutputDelayDuLength = m_dpbOutputDelayDuLength;
+#endif
   target.m_concatenationFlag = m_concatenationFlag;
   target.m_auCpbRemovalDelayDelta = m_auCpbRemovalDelayDelta;
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h
index fd1ff2b91326c3eb587d6905f5895f5c5a4b6193..a696353dd535743a6d647c9f5cb692b136ed790e 100644
--- a/source/Lib/CommonLib/SEI.h
+++ b/source/Lib/CommonLib/SEI.h
@@ -200,8 +200,14 @@ public:
   , m_dpbOutputDelayLength (0)
   , m_bpCpbCnt (0)
 #endif
+#if JVET_O0189_DU
+  , m_duCpbRemovalDelayIncrementLength (0)
+  , m_dpbOutputDelayDuLength (0)
+#endif
+#if !FIX_SEI_O0189
   , m_cpbDelayOffset      (0)
   , m_dpbDelayOffset      (0)
+#endif
   {
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
     ::memset(m_initialCpbRemovalDelay, 0, sizeof(m_initialCpbRemovalDelay));
@@ -212,6 +218,12 @@ public:
   }
   virtual ~SEIBufferingPeriod() {}
 
+#if JVET_O0189_DU
+  void      setDuCpbRemovalDelayIncrementLength( uint32_t value )        { m_duCpbRemovalDelayIncrementLength = value;        }
+  uint32_t  getDuCpbRemovalDelayIncrementLength( ) const                 { return m_duCpbRemovalDelayIncrementLength;         }
+  void      setDpbOutputDelayDuLength( uint32_t value )                  { m_dpbOutputDelayDuLength = value;                  }
+  uint32_t  getDpbOutputDelayDuLength( ) const                           { return m_dpbOutputDelayDuLength;                   }
+#endif
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   uint32_t m_bpSeqParameterSetId;
   bool m_rapCpbParamsPresentFlag;
@@ -223,8 +235,14 @@ public:
   uint32_t m_dpbOutputDelayLength;
   int      m_bpCpbCnt;
 #endif
+#if JVET_O0189_DU
+  uint32_t m_duCpbRemovalDelayIncrementLength;
+  uint32_t m_dpbOutputDelayDuLength;
+#endif
+#if !FIX_SEI_O0189
   uint32_t m_cpbDelayOffset;
   uint32_t m_dpbDelayOffset;
+#endif
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   uint32_t m_initialCpbRemovalDelay         [MAX_CPB_CNT][2];
   uint32_t m_initialCpbRemovalDelayOffset   [MAX_CPB_CNT][2];
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 08ae79cbe793a9ead060b4b661a889d49da4a7a0..cb3ec8dab578eaf1d850514dabf3d316104e8470 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -755,6 +755,17 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
   m_scalingListAps                  = pSrc->m_scalingListAps;
   m_scalingListApsId                = pSrc->m_scalingListApsId;
 #endif
+#if JVET_O0189_DU
+#if JVET_O1164_RPR
+  for( int i = 0; i < NUM_REF_PIC_LIST_01; i ++ )
+  {
+    for (int j = 0; j < MAX_NUM_REF_PICS; j ++ )
+    {
+      m_scalingRatio[i][j]          = pSrc->m_scalingRatio[i][j];
+    }
+  }
+#endif
+#endif
 }
 
 
@@ -1636,6 +1647,9 @@ SPS::SPS()
 , m_saoEnabledFlag            (false)
 , m_bTemporalIdNestingFlag    (false)
 , m_scalingListEnabledFlag    (false)
+#if FIX_HRD_O0189
+, m_hrdParametersPresentFlag  (false)
+#endif
 , m_vuiParametersPresentFlag  (false)
 , m_vuiParameters             ()
 , m_wrapAroundEnabledFlag     (false)
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 9b63401a3d13062ac354826f8a7c87d80eb5473a..08a49eb0326c26e80f3baa9bf0f73491a6f8b997 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -272,6 +272,11 @@
 #define JVET_O0376_SPS_JOINTCBCR_FLAG                          1 // JVET-O0376: add the JointCbCr control flag in SPS
 #define JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS         1 // JVET-O0472: LFNST index signalling depends on the position of last significant coefficient
 
+#define JVET_O0189_DU                                     1
+#if JVET_O0189_DU
+#define FIX_SEI_O0189                                     1
+#define FIX_HRD_O0189                                     1
+#endif
 #define JVET_N0353_INDEP_BUFF_TIME_SEI                    1 // JVET-N0353 independent parsing of buffering and timing info SEIs
 
 #define FIX_DB_MAX_TRANSFORM_SIZE                         1
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index eb88707a89582c1d14a71d8565f3f7d9971f0b2b..63a4c14b5d203beae64621cbfddaf4651fe0a232 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -193,7 +193,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       else
       {
         sei = new SEIDecodingUnitInfo;
+#if JVET_O0189_DU
+        xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, sps, hrd, pDecodedMessageOutputStream);
+#else
         xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, sps, pDecodedMessageOutputStream);
+#endif
       }
       break;
     case SEI::BUFFERING_PERIOD:
@@ -209,7 +213,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
       }
 #else
       sei = new SEIBufferingPeriod;
+#if JVET_O0189_DU
+      xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, sps, pDecodedMessageOutputStream);
+#else
       xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, pDecodedMessageOutputStream);
+#endif
       hrd.setBufferingPeriodSEI((SEIBufferingPeriod*) sei);
 #endif
       break;
@@ -234,7 +242,11 @@ void SEIReader::xReadSEImessage(SEIMessages& seis, const NalUnitType nalUnitType
         else
         {
           sei = new SEIPictureTiming;
+#if JVET_O0189_DU
+          xParseSEIPictureTiming((SEIPictureTiming&)*sei, payloadSize, sps, *bp, pDecodedMessageOutputStream);
+#else
           xParseSEIPictureTiming((SEIPictureTiming&)*sei, payloadSize, *bp, pDecodedMessageOutputStream);
+#endif
         }
       }
 #endif
@@ -522,7 +534,11 @@ void SEIReader::xParseSEIActiveParameterSets(SEIActiveParameterSets& sei, uint32
 }
 #endif
 
+#if JVET_O0189_DU
+void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t payloadSize, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream)
+#else
 void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream)
+#endif
 {
   uint32_t val;
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
@@ -535,7 +551,11 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay
   if(sps->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag())
 #endif
   {
+#if JVET_O0189_DU
+    sei_read_code( pDecodedMessageOutputStream, hrd.getBufferingPeriodSEI()->getDuCpbRemovalDelayIncrementLength(), val, "du_spt_cpb_removal_delay_increment");
+#else
     sei_read_code( pDecodedMessageOutputStream, ( sps->getHrdParameters()->getDuCpbRemovalDelayLengthMinus1() + 1 ), val, "du_spt_cpb_removal_delay_increment");
+#endif
     sei.m_duSptCpbRemovalDelay = val;
   }
   else
@@ -545,13 +565,21 @@ void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, uint32_t pay
   sei_read_flag( pDecodedMessageOutputStream, val, "dpb_output_du_delay_present_flag"); sei.m_dpbOutputDuDelayPresentFlag = (val != 0);
   if(sei.m_dpbOutputDuDelayPresentFlag)
   {
+#if JVET_O0189_DU
+    sei_read_code( pDecodedMessageOutputStream, hrd.getBufferingPeriodSEI()->getDpbOutputDelayDuLength(), val, "pic_spt_dpb_output_du_delay");
+#else
     sei_read_code( pDecodedMessageOutputStream, sps->getHrdParameters()->getDpbOutputDelayDuLengthMinus1() + 1, val, "pic_spt_dpb_output_du_delay");
+#endif
     sei.m_picSptDpbOutputDuDelay = val;
   }
 }
 
 #if JVET_N0353_INDEP_BUFF_TIME_SEI
+#if JVET_O0189_DU
+void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream)
+#else
 void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t payloadSize, std::ostream *pDecodedMessageOutputStream)
+#endif
 #else
 void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream)
 #endif
@@ -613,6 +641,13 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
     sei_read_code( pDecodedMessageOutputStream, 5, code, "initial_cpb_removal_delay_length_minus1" );     sei.m_initialCpbRemovalDelayLength = code + 1;
     sei_read_code( pDecodedMessageOutputStream, 5, code, "cpb_removal_delay_length_minus1" );             sei.m_cpbRemovalDelayLength        = code + 1;
     sei_read_code( pDecodedMessageOutputStream, 5, code, "dpb_output_delay_length_minus1" );              sei.m_dpbOutputDelayLength         = code + 1;
+#if JVET_O0189_DU
+    if( sps->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag() )
+    {
+      sei_read_code( pDecodedMessageOutputStream, 5, code, "du_cpb_removal_delay_increment_length_minus1" );  sei.m_duCpbRemovalDelayIncrementLength = code + 1;
+      sei_read_code( pDecodedMessageOutputStream, 5, code, "dpb_output_delay_du_length_minus1" );             sei.m_dpbOutputDelayDuLength = code + 1;
+    }
+#endif
   }
 
   sei_read_flag( pDecodedMessageOutputStream, code, "concatenation_flag");
@@ -644,8 +679,12 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
 void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream)
 #else
+#if JVET_O0189_DU
+void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSize, const SPS *sps, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream)
+#else
 void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSize, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream)
 #endif
+#endif
 {
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   int i;
@@ -656,6 +695,9 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi
 
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   const HRDParameters *hrd = sps->getHrdParameters();
+#endif
+#if JVET_O0189_DU
+  const HRDParameters *hrd = sps->getHrdParameters();
 #endif
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
 #if !JVET_O0041_FRAME_FIELD_SEI
@@ -712,6 +754,38 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi
   sei.m_auCpbRemovalDelay = symbol + 1;
   sei_read_code( pDecodedMessageOutputStream, bp.m_dpbOutputDelayLength,  symbol, "dpb_output_delay" );
   sei.m_picDpbOutputDelay = symbol;
+#if JVET_O0189_DU
+  if( hrd->getDecodingUnitHrdParamsPresentFlag() )
+  {
+    sei_read_code( pDecodedMessageOutputStream, bp.getDpbOutputDelayDuLength(), symbol, "pic_dpb_output_du_delay" );
+    sei.m_picDpbOutputDuDelay = symbol;
+  }
+  if( hrd->getDecodingUnitHrdParamsPresentFlag() && hrd->getDecodingUnitCpbParamsInPicTimingSeiFlag() )
+  {
+    sei_read_uvlc( pDecodedMessageOutputStream, symbol, "num_decoding_units_minus1" );
+    sei.m_numDecodingUnitsMinus1 = symbol;
+    sei.m_numNalusInDuMinus1.resize(sei.m_numDecodingUnitsMinus1 + 1 );
+    sei.m_duCpbRemovalDelayMinus1.resize( sei.m_numDecodingUnitsMinus1 + 1 );
+
+    sei_read_flag( pDecodedMessageOutputStream, symbol, "du_common_cpb_removal_delay_flag" );
+    sei.m_duCommonCpbRemovalDelayFlag = symbol;
+    if( sei.m_duCommonCpbRemovalDelayFlag )
+    {
+      sei_read_code( pDecodedMessageOutputStream, bp.getDuCpbRemovalDelayIncrementLength(), symbol, "du_common_cpb_removal_delay_inrement_minus1" );
+      sei.m_duCommonCpbRemovalDelayMinus1 = symbol;
+    }
+    for( int i = 0; i <= sei.m_numDecodingUnitsMinus1; i ++ )
+    {
+      sei_read_uvlc( pDecodedMessageOutputStream, symbol, "num_nalus_in_du_minus1[i]" );
+      sei.m_numNalusInDuMinus1[i] = symbol;
+      if( !sei.m_duCommonCpbRemovalDelayFlag && i < sei.m_numDecodingUnitsMinus1 )
+      {
+        sei_read_code( pDecodedMessageOutputStream, bp.getDuCpbRemovalDelayIncrementLength(), symbol, "du_cpb_removal_delay_increment_minus1[i]" );
+        sei.m_duCpbRemovalDelayMinus1[i] = symbol;
+      }
+    }
+  }
+#endif
 #endif
 }
 
diff --git a/source/Lib/DecoderLib/SEIread.h b/source/Lib/DecoderLib/SEIread.h
index 2e88714095b444debd46585c3736524cde2598bc..fb65ad4e61c5ef913b696a39d35c3b2ec901553c 100644
--- a/source/Lib/DecoderLib/SEIread.h
+++ b/source/Lib/DecoderLib/SEIread.h
@@ -71,11 +71,20 @@ protected:
   void xParseSEIuserDataUnregistered          (SEIuserDataUnregistered &sei,          uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIActiveParameterSets           (SEIActiveParameterSets  &sei,          uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
 #endif
+#if JVET_O0189_DU
+  void xParseSEIDecodingUnitInfo              (SEIDecodingUnitInfo& sei,              uint32_t payloadSize, const SPS *sps, HRD &hrd, std::ostream *pDecodedMessageOutputStream);
+#else
   void xParseSEIDecodingUnitInfo              (SEIDecodingUnitInfo& sei,              uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream);
+#endif
   void xParseSEIDecodedPictureHash            (SEIDecodedPictureHash& sei,            uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
 #if JVET_N0353_INDEP_BUFF_TIME_SEI
+#if JVET_O0189_DU
+  void xParseSEIBufferingPeriod               (SEIBufferingPeriod& sei,               uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream);
+  void xParseSEIPictureTiming                 (SEIPictureTiming& sei,                 uint32_t payloadSize, const SPS *sps, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream);
+#else
   void xParseSEIBufferingPeriod               (SEIBufferingPeriod& sei,               uint32_t payloadSize,                     std::ostream *pDecodedMessageOutputStream);
   void xParseSEIPictureTiming                 (SEIPictureTiming& sei,                 uint32_t payloadSize, const SEIBufferingPeriod& bp, std::ostream *pDecodedMessageOutputStream);
+#endif
 #else
   void xParseSEIBufferingPeriod               (SEIBufferingPeriod& sei,               uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream);
   void xParseSEIPictureTiming                 (SEIPictureTiming& sei,                 uint32_t payloadSize, const SPS *sps, std::ostream *pDecodedMessageOutputStream);
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index c821a76d455fe3d3f98c5a48af1534fc46df5596..ff485320ca4092a766e8fcea0771508ba4876400 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -1165,14 +1165,32 @@ void HLSyntaxReader::parseHrdParameters(HRDParameters *hrd, uint32_t firstSubLay
   READ_FLAG( symbol, "general_vcl_hrd_parameters_present_flag" );           hrd->setVclHrdParametersPresentFlag( symbol == 1 ? true : false );
   if( hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() )
   {
+#if JVET_O0189_DU
+    READ_FLAG( symbol, "decoding_unit_hrd_params_present_flag" );           hrd->setDecodingUnitHrdParamsPresentFlag( symbol == 1 ? true : false );
+#else
     READ_FLAG( symbol, "decoding_unit_hrd_params_present_flag" );           hrd->setSubPicCpbParamsPresentFlag( symbol == 1 ? true : false );
+#endif
 
+#if JVET_O0189_DU
+    if( hrd->getDecodingUnitHrdParamsPresentFlag() )
+    {
+      READ_CODE( 8, symbol, "tick_divisor_minus2" );                        hrd->setTickDivisorMinus2( symbol );
+      READ_FLAG( symbol, "decoding_unit_cpb_params_in_pic_timing_sei_flag" ); hrd->setDecodingUnitCpbParamsInPicTimingSeiFlag( symbol == 1 ? true : false );
+    }
+#endif
     READ_CODE( 4, symbol, "bit_rate_scale" );                       hrd->setBitRateScale( symbol );
     READ_CODE( 4, symbol, "cpb_size_scale" );                       hrd->setCpbSizeScale( symbol );
+#if JVET_O0189_DU
+    if( hrd->getDecodingUnitHrdParamsPresentFlag() )
+    {
+      READ_CODE( 4, symbol, "cpb_size_du_scale" );                  hrd->setCpbSizeDuScale( symbol );
+    }
+#else
     if( hrd->getSubPicCpbParamsPresentFlag() )
     {
       READ_CODE( 4, symbol, "cpb_size_du_scale" );                  hrd->setDuCpbSizeScale( symbol );
     }
+#endif
   }
 
   for( int i = firstSubLayer; i <= maxNumSubLayersMinus1; i ++ )
@@ -1649,13 +1667,20 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
 #endif
 
   TimingInfo *timingInfo = pcSPS->getTimingInfo();
+#if JVET_O0189_DU
+  READ_FLAG(     uiCode, "general_hrd_parameters_present_flag");        pcSPS->setHrdParametersPresentFlag(uiCode);
+  if( pcSPS->getHrdParametersPresentFlag() )
+#else
   READ_FLAG(       uiCode, "timing_info_present_flag");         timingInfo->setTimingInfoPresentFlag      (uiCode ? true : false);
   if(timingInfo->getTimingInfoPresentFlag())
+#endif
   {
     READ_CODE( 32, uiCode, "num_units_in_tick");                timingInfo->setNumUnitsInTick             (uiCode);
     READ_CODE( 32, uiCode, "time_scale");                       timingInfo->setTimeScale                  (uiCode);
 
+#if !JVET_O0189_DU
     READ_FLAG(     uiCode, "hrd_parameters_present_flag");        pcSPS->setHrdParametersPresentFlag(uiCode);
+#endif
     if( pcSPS->getHrdParametersPresentFlag() )
     {
       parseHrdParameters( pcSPS->getHrdParameters(), 1, pcSPS->getMaxTLayers() - 1 );
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 694c13f38b30ec9bae11813fbbf0392369e0df9c..b541bd96aca6c05436d06c030f3d644d704bcf96 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -653,6 +653,9 @@ protected:
   bool      m_recalculateQPAccordingToLambda;                 ///< recalculate QP value according to the lambda value
 #if HEVC_SEI
   int       m_activeParameterSetsSEIEnabled;                  ///< enable active parameter set SEI message
+#endif
+#if FIX_HRD_O0189
+  bool      m_hrdParametersPresentFlag;                       ///< enable generation of HRD parameters
 #endif
   bool      m_vuiParametersPresentFlag;                       ///< enable generation of VUI parameters
   bool      m_aspectRatioInfoPresentFlag;                     ///< Signals whether aspect_ratio_idc is present
@@ -1645,6 +1648,10 @@ public:
 
   bool         getDecodingParameterSetEnabled()                      { return m_decodingParameterSetEnabled; }
   void         setDecodingParameterSetEnabled(bool i)                { m_decodingParameterSetEnabled = i; }
+#if FIX_HRD_O0189
+  bool         getHrdParametersPresentFlag()                         { return m_hrdParametersPresentFlag; }
+  void         setHrdParametersPresentFlag(bool i)                   { m_hrdParametersPresentFlag = i; }
+#endif
   bool         getVuiParametersPresentFlag()                         { return m_vuiParametersPresentFlag; }
   void         setVuiParametersPresentFlag(bool i)                   { m_vuiParametersPresentFlag = i; }
   bool         getAspectRatioInfoPresentFlag()                       { return m_aspectRatioInfoPresentFlag; }
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 9abf1b45766621b98bcf04e5a14ef335e5ba2d07..c3c1348c62af595cede8e2ce8609ecd59cc89655 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -569,7 +569,11 @@ void EncGOP::xWriteDuSEIMessages (SEIMessages& duInfoSeiMessages, AccessUnit &ac
 {
   const HRDParameters *hrd = sps->getHrdParameters();
 
+#if JVET_O0189_DU
+  if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getDecodingUnitCpbParamsInPicTimingSeiFlag() )
+#else
   if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
+#endif
   {
     int naluIdx = 0;
     AccessUnit::iterator nalu = accessUnit.begin();
@@ -697,15 +701,25 @@ void EncGOP::xCreateIRAPLeadingSEIMessages (SEIMessages& seiMessages, const SPS
 void EncGOP::xCreatePerPictureSEIMessages (int picInGOP, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, Slice *slice)
 {
 #if JVET_OO152_BP_SEI_GDR
+#if JVET_O0189_DU
+  if ((m_pcCfg->getBufferingPeriodSEIEnabled()) && (slice->isIRAP() || slice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) &&
+    ( slice->getSPS()->getHrdParametersPresentFlag() ) )
+#else
   if ((m_pcCfg->getBufferingPeriodSEIEnabled()) && (slice->isIRAP() || slice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR) &&
     (slice->getSPS()->getVuiParametersPresentFlag()) &&
     ((slice->getSPS()->getHrdParameters()->getNalHrdParametersPresentFlag())
       || (slice->getSPS()->getHrdParameters()->getVclHrdParametersPresentFlag())))
+#endif
+#else
+#if JVET_O0189_DU
+  if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( slice->getSliceType() == I_SLICE ) &&
+    ( slice->getSPS()->getHrdParametersPresentFlag() ) )
 #else
   if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( slice->getSliceType() == I_SLICE ) &&
     ( slice->getSPS()->getVuiParametersPresentFlag() ) &&
     ( ( slice->getSPS()->getHrdParameters()->getNalHrdParametersPresentFlag() )
     || ( slice->getSPS()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
+#endif
 #endif
   {
     SEIBufferingPeriod *bufferingPeriodSEI = new SEIBufferingPeriod();
@@ -839,15 +853,23 @@ void EncGOP::xCreatePictureTimingSEI  (int IRAPGOPid, SEIMessages& seiMessages,
   const HRDParameters *hrd = slice->getSPS()->getHrdParameters();
 
   // update decoding unit parameters
+#if JVET_O0189_DU
+  if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) )
+#else
   if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
     ( slice->getSPS()->getVuiParametersPresentFlag() ) &&
     (  hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() ) )
+#endif
   {
     int picSptDpbOutputDuDelay = 0;
     SEIPictureTiming *pictureTimingSEI = new SEIPictureTiming();
 
     // DU parameters
+#if JVET_O0189_DU
+    if( hrd->getDecodingUnitHrdParamsPresentFlag() )
+#else
     if( hrd->getSubPicCpbParamsPresentFlag() )
+#endif
     {
       uint32_t numDU = (uint32_t) duData.size();
       pictureTimingSEI->m_numDecodingUnitsMinus1     = ( numDU - 1 );
@@ -896,7 +918,11 @@ void EncGOP::xCreatePictureTimingSEI  (int IRAPGOPid, SEIMessages& seiMessages,
 #endif
     }
 
+#if JVET_O0189_DU
+    if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getDecodingUnitHrdParamsPresentFlag() )
+#else
     if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
+#endif
     {
       for( int i = 0; i < ( pictureTimingSEI->m_numDecodingUnitsMinus1 + 1 ); i ++ )
       {
@@ -961,7 +987,11 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD
     return;
   }
   const HRDParameters *hrd = sps->getHrdParameters();
+#if JVET_O0189_DU
+  if( hrd->getDecodingUnitHrdParamsPresentFlag() )
+#else
   if( hrd->getSubPicCpbParamsPresentFlag() )
+#endif
   {
     int i;
     uint64_t ui64Tmp;
@@ -3089,11 +3119,18 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
           accessUnit.push_back(new NALUnitEBSP(nalu));
         }
 
+#if JVET_O0189_DU
+        if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
+            ( ( pcSlice->getSPS()->getHrdParameters()->getNalHrdParametersPresentFlag() )
+           || ( pcSlice->getSPS()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
+            ( pcSlice->getSPS()->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag() ) )
+#else
         if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
             ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
             ( ( pcSlice->getSPS()->getHrdParameters()->getNalHrdParametersPresentFlag() )
            || ( pcSlice->getSPS()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
             ( pcSlice->getSPS()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
+#endif
         {
             uint32_t numNalus = 0;
           uint32_t numRBSPBytes = 0;
diff --git a/source/Lib/EncoderLib/EncHRD.cpp b/source/Lib/EncoderLib/EncHRD.cpp
index 2e4c58ceaed385020e2bdabfbd69e88474ad7cb8..51177340b79af9491de90937824d1c332699d409 100644
--- a/source/Lib/EncoderLib/EncHRD.cpp
+++ b/source/Lib/EncoderLib/EncHRD.cpp
@@ -65,9 +65,17 @@ void EncHRD::initHRDParameters (EncCfg* encCfg)
 # if U0132_TARGET_BITS_SATURATION
   int cpbSize          = encCfg->getCpbSize();
   CHECK(!(cpbSize!=0), "Unspecified error");  // CPB size may not be equal to zero. ToDo: have a better default and check for level constraints
+#if FIX_HRD_O0189
+  if( !encCfg->getHrdParametersPresentFlag() && !encCfg->getCpbSaturationEnabled() )
+#else
   if( !encCfg->getVuiParametersPresentFlag() && !encCfg->getCpbSaturationEnabled() )
+#endif
+#else
+#if FIX_HRD_O0189
+  if( !encCfg->getHrdParametersPresentFlag() )
 #else
   if( !encCfg.getVuiParametersPresentFlag() )
+#endif
 #endif
   {
     return;
@@ -112,25 +120,46 @@ void EncHRD::initHRDParameters (EncCfg* encCfg)
   bool rateCnt = ( bitRate > 0 );
   m_hrdParams.setNalHrdParametersPresentFlag( rateCnt );
   m_hrdParams.setVclHrdParametersPresentFlag( rateCnt );
+#if JVET_O0189_DU
+  useSubCpbParams &= ( m_hrdParams.getNalHrdParametersPresentFlag() || m_hrdParams.getVclHrdParametersPresentFlag() );
+  m_hrdParams.setDecodingUnitHrdParamsPresentFlag( useSubCpbParams );
+#else
   m_hrdParams.setSubPicCpbParamsPresentFlag( useSubCpbParams );
+#endif
 
+#if JVET_O0189_DU
+  if( m_hrdParams.getDecodingUnitHrdParamsPresentFlag() )
+#else
   if( m_hrdParams.getSubPicCpbParamsPresentFlag() )
+#endif
   {
     m_hrdParams.setTickDivisorMinus2( 100 - 2 );                          //
+#if !JVET_O0189_DU
     m_hrdParams.setDuCpbRemovalDelayLengthMinus1( 7 );                    // 8-bit precision ( plus 1 for last DU in AU )
+#endif
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
     m_hrdParams.setSubPicCpbParamsInPicTimingSEIFlag( true );
+#else
+#if JVET_O0189_DU
+    m_hrdParams.setDecodingUnitCpbParamsInPicTimingSeiFlag( !encCfg->getDecodingUnitInfoSEIEnabled() );
 #else
     m_hrdParams.setDecodingUnitHrdParamsPresentFlag( true );
 #endif
+#endif
+#if !JVET_O0189_DU
     m_hrdParams.setDpbOutputDelayDuLengthMinus1( 5 + 7 );                 // With sub-clock tick factor of 100, at least 7 bits to have the same value as AU dpb delay
+#endif
   }
   else
   {
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
     m_hrdParams.setSubPicCpbParamsInPicTimingSEIFlag( false );
+#else
+#if JVET_O0189_DU
+    m_hrdParams.setDecodingUnitCpbParamsInPicTimingSeiFlag( false );
 #else
     m_hrdParams.setDecodingUnitHrdParamsPresentFlag( false );
+#endif
 #endif
   }
 
@@ -157,7 +186,11 @@ void EncHRD::initHRDParameters (EncCfg* encCfg)
   m_hrdParams.setCpbSizeScale( 6 );                                       // in units of 2^( 4 + 6 ) = 1,024 bit
 #endif
 
+#if JVET_O0189_DU
+  m_hrdParams.setCpbSizeDuScale( 6 );                                     // in units of 2^( 4 + 6 ) = 1,024 bit
+#else
   m_hrdParams.setDuCpbSizeScale( 6 );                                     // in units of 2^( 4 + 6 ) = 1,024 bit
+#endif
 
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   m_hrdParams.setInitialCpbRemovalDelayLengthMinus1(15);                  // assuming 0.5 sec, log2( 90,000 * 0.5 ) = 16-bit
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index f3c5db87f4c903291e2c0c89450234dda44f4388..07e0ede30aaeec7b163a2a289e2871c91881a91b 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -247,14 +247,19 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI)
     bufferingPeriodSEI->m_cpbRemovalDelayLength = 9;                        // max. 2^10
     bufferingPeriodSEI->m_dpbOutputDelayLength =  9;                        // max. 2^10
   }
-
+#if JVET_O0189_DU
+  bufferingPeriodSEI->m_duCpbRemovalDelayIncrementLength = 7;               // ceil( log2( tick_divisor_minus2 + 2 ) )
+  bufferingPeriodSEI->m_dpbOutputDelayDuLength = bufferingPeriodSEI->m_dpbOutputDelayLength + bufferingPeriodSEI->m_duCpbRemovalDelayIncrementLength;
+#endif
 #endif
   //for the concatenation, it can be set to one during splicing.
   bufferingPeriodSEI->m_concatenationFlag = 0;
   //since the temporal layer HRDParameters is not ready, we assumed it is fixed
   bufferingPeriodSEI->m_auCpbRemovalDelayDelta = 1;
+#if !FIX_SEI_O0189
   bufferingPeriodSEI->m_cpbDelayOffset = 0;
   bufferingPeriodSEI->m_dpbDelayOffset = 0;
+#endif
 }
 
 #if HEVC_SEI
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index 9a4386b62f95f09039f36c521a117a371b8833b7..1878be2e1d9bd7fff77facef5cb58f1233cd51db 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -57,8 +57,13 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream& bs, const SEI& sei, const
     xWriteSEIActiveParameterSets(*static_cast<const SEIActiveParameterSets*>(& sei));
     break;
 #endif
+#if JVET_O0189_DU
+  case SEI::DECODING_UNIT_INFO:
+    xWriteSEIDecodingUnitInfo(*static_cast<const SEIDecodingUnitInfo*>(& sei), sps, hrd);
+#else
     case SEI::DECODING_UNIT_INFO:
     xWriteSEIDecodingUnitInfo(*static_cast<const SEIDecodingUnitInfo*>(& sei), sps);
+#endif
     break;
   case SEI::DECODED_PICTURE_HASH:
     xWriteSEIDecodedPictureHash(*static_cast<const SEIDecodedPictureHash*>(&sei));
@@ -66,9 +71,14 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream& bs, const SEI& sei, const
   case SEI::BUFFERING_PERIOD:
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
     xWriteSEIBufferingPeriod(*static_cast<const SEIBufferingPeriod*>(&sei), sps);
+#else
+#if JVET_O0189_DU
+    xWriteSEIBufferingPeriod(*static_cast<const SEIBufferingPeriod*>(&sei), sps);
+    hrd.setBufferingPeriodSEI(static_cast<const SEIBufferingPeriod*>(&sei));
 #else
     xWriteSEIBufferingPeriod(*static_cast<const SEIBufferingPeriod*>(&sei));
     hrd.setBufferingPeriodSEI(static_cast<const SEIBufferingPeriod*>(&sei));
+#endif
 #endif
     break;
   case SEI::PICTURE_TIMING:
@@ -78,7 +88,11 @@ void SEIWriter::xWriteSEIpayloadData(OutputBitstream& bs, const SEI& sei, const
     {
       const SEIBufferingPeriod *bp = hrd.getBufferingPeriodSEI();
       CHECK (bp == nullptr, "Buffering Period need to be initialized in HRD to allow writing of Picture Timing SEI");
+#if JVET_O0189_DU
+      xWriteSEIPictureTiming(*static_cast<const SEIPictureTiming*>(&sei), sps, *bp);
+#else
       xWriteSEIPictureTiming(*static_cast<const SEIPictureTiming*>(&sei), *bp);
+#endif
     }
 #endif
     break;
@@ -288,7 +302,11 @@ void SEIWriter::xWriteSEIActiveParameterSets(const SEIActiveParameterSets& sei)
 }
 #endif
 
+#if JVET_O0189_DU
+void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SPS *sps, HRD &hrd)
+#else
 void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SPS *sps)
+#endif
 {
   WRITE_UVLC(sei.m_decodingUnitIdx, "decoding_unit_idx");
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
@@ -297,20 +315,32 @@ void SEIWriter::xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const
   if(sps->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag())
 #endif
   {
+#if JVET_O0189_DU
+    WRITE_CODE( sei.m_duSptCpbRemovalDelay, hrd.getBufferingPeriodSEI()->getDuCpbRemovalDelayIncrementLength(), "du_spt_cpb_removal_delay_increment");
+#else
     WRITE_CODE( sei.m_duSptCpbRemovalDelay, (sps->getHrdParameters()->getDuCpbRemovalDelayLengthMinus1() + 1), "du_spt_cpb_removal_delay_increment");
+#endif
   }
   WRITE_FLAG( sei.m_dpbOutputDuDelayPresentFlag, "dpb_output_du_delay_present_flag");
   if(sei.m_dpbOutputDuDelayPresentFlag)
   {
+#if JVET_O0189_DU
+    WRITE_CODE(sei.m_picSptDpbOutputDuDelay, hrd.getBufferingPeriodSEI()->getDpbOutputDelayDuLength(), "pic_spt_dpb_output_du_delay");
+#else
     WRITE_CODE(sei.m_picSptDpbOutputDuDelay, sps->getHrdParameters()->getDpbOutputDelayDuLengthMinus1() + 1, "pic_spt_dpb_output_du_delay");
+#endif
   }
 }
 
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
 void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SPS *sps)
 #else
+#if JVET_O0189_DU
+void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SPS *sps)
+#else
 void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei)
 #endif
+#endif
 {
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   int i, nalOrVcl;
@@ -358,6 +388,15 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei)
     WRITE_CODE( sei.m_cpbRemovalDelayLength - 1,        5, "cpb_removal_delay_length_minus1" );
     CHECK (sei.m_dpbOutputDelayLength < 1, "sei.m_dpbOutputDelayLength must be > 0");
     WRITE_CODE( sei.m_dpbOutputDelayLength - 1,         5, "dpb_output_delay_length_minus1" );
+#if JVET_O0189_DU
+    if( sps->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag() )
+    {
+      CHECK (sei.m_duCpbRemovalDelayIncrementLength < 1, "sei.m_duCpbRemovalDelayIncrementLength must be > 0");
+      WRITE_CODE( sei.m_duCpbRemovalDelayIncrementLength - 1, 5, "du_cpb_removal_delay_increment_length_minus1" );
+      CHECK (sei.m_dpbOutputDelayDuLength < 1, "sei.m_dpbOutputDelayDuLength must be > 0");
+      WRITE_CODE( sei.m_dpbOutputDelayDuLength - 1, 5, "dpb_output_delay_du_length_minus1" );
+    }
+#endif
   }
 
   WRITE_FLAG( sei.m_concatenationFlag, "concatenation_flag");
@@ -388,8 +427,12 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei)
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
 void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *sps)
 #else
+#if JVET_O0189_DU
+void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *sps, const SEIBufferingPeriod &bp)
+#else
 void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBufferingPeriod &bp)
 #endif
+#endif
 {
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   int i;
@@ -434,6 +477,29 @@ void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBuf
   WRITE_CODE( sei.m_auCpbRemovalDelay - 1, bp.m_cpbRemovalDelayLength,                                         "cpb_removal_delay_minus1" );
   WRITE_CODE( sei.m_picDpbOutputDelay,     bp.m_dpbOutputDelayLength,                                          "dpb_output_delay" );
 #endif
+#if JVET_O0189_DU
+  if( sps->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag() )
+  {
+    WRITE_CODE( sei.m_picDpbOutputDuDelay, bp.m_dpbOutputDelayDuLength, "pic_dpb_output_du_delay" );
+  }
+  if( sps->getHrdParameters()->getDecodingUnitHrdParamsPresentFlag() && sps->getHrdParameters()->getDecodingUnitCpbParamsInPicTimingSeiFlag() )
+  {
+    WRITE_UVLC( sei.m_numDecodingUnitsMinus1, "num_decoding_units_minus1" );
+    WRITE_FLAG( sei.m_duCommonCpbRemovalDelayFlag, "du_commmon_cpb_removal_delay_flag" );
+    if( sei.m_duCommonCpbRemovalDelayFlag )
+    {
+      WRITE_CODE( sei.m_duCommonCpbRemovalDelayMinus1, bp.m_duCpbRemovalDelayIncrementLength, "du_common_cpb_removal_delay_increment_minus1" );
+    }
+    for( int i = 0; i <= sei.m_numDecodingUnitsMinus1; i ++ )
+    {
+      WRITE_UVLC( sei.m_numNalusInDuMinus1[i], "num_nalus_in_du_minus1[i]" );
+      if( !sei.m_duCommonCpbRemovalDelayFlag && i < sei.m_numDecodingUnitsMinus1 )
+      {
+        WRITE_CODE( sei.m_duCpbRemovalDelayMinus1[i], bp.m_duCpbRemovalDelayIncrementLength, "du_cpb_removal_delay_increment_minus1[i]" );
+      }
+    }
+  }
+#endif
 }
 
 #if JVET_O0041_FRAME_FIELD_SEI
diff --git a/source/Lib/EncoderLib/SEIwrite.h b/source/Lib/EncoderLib/SEIwrite.h
index da64eeae746f2f68fa0d656b3660eb5b6a818611..5320bdfb72ae405a0aa0250ebbcd94eda365b9fc 100644
--- a/source/Lib/EncoderLib/SEIwrite.h
+++ b/source/Lib/EncoderLib/SEIwrite.h
@@ -60,15 +60,27 @@ protected:
   void xWriteSEIuserDataUnregistered(const SEIuserDataUnregistered &sei);
   void xWriteSEIActiveParameterSets(const SEIActiveParameterSets& sei);
 #endif
+#if JVET_O0189_DU
+  void xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SPS *sps, HRD &hrd);
+#else
   void xWriteSEIDecodingUnitInfo(const SEIDecodingUnitInfo& sei, const SPS *sps);
+#endif
   void xWriteSEIDecodedPictureHash(const SEIDecodedPictureHash& sei);
 #if !JVET_N0353_INDEP_BUFF_TIME_SEI
   void xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SPS *sps);
   void xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *sps);
+#else
+#if JVET_O0189_DU
+  void xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SPS *sps);
 #else
   void xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei);
+#endif
+#if JVET_O0189_DU
+  void xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *sps, const SEIBufferingPeriod& bp);
+#else
   void xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SEIBufferingPeriod& bp);
 #endif
+#endif
 #if JVET_O0041_FRAME_FIELD_SEI
   void xWriteSEIFrameFieldInfo(const SEIFrameFieldInfo& sei);
 #endif
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 445d52f1b50472934fe19a24a4f16d27e5336918..ea6f2082583f1f262c344c6111456c82cd70d658 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -789,10 +789,33 @@ void HLSWriter::codeHrdParameters( const HRDParameters *hrd, const uint32_t firs
   WRITE_FLAG( hrd->getVclHrdParametersPresentFlag() ? 1 : 0 ,  "general_vcl_hrd_parameters_present_flag" );
   if( hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() )
   {
+#if JVET_O0189_DU
+    WRITE_FLAG( hrd->getDecodingUnitHrdParamsPresentFlag() ? 1 : 0,  "decoding_unit_hrd_params_present_flag" );
+#else
     WRITE_FLAG( hrd->getSubPicCpbParamsPresentFlag() ? 1 : 0,  "decoding_unit_hrd_params_present_flag" );
+#endif
+#if JVET_O0189_DU
+    if( hrd->getDecodingUnitHrdParamsPresentFlag() )
+    {
+      WRITE_CODE( hrd->getTickDivisorMinus2(), 8,            "tick_divisor_minus2" );
+      WRITE_FLAG( hrd->getDecodingUnitCpbParamsInPicTimingSeiFlag() ? 1 : 0, "decoding_unit_cpb_params_in_pic_timing_sei_flag" );
+    }
+#endif
+#if FIX_HRD_O0189
+    WRITE_CODE( hrd->getBitRateScale(), 4,                     "bit_rate_scale" );
+    WRITE_CODE( hrd->getCpbSizeScale(), 4,                     "cpb_size_scale" );
+#endif
+#if JVET_O0189_DU
+    if( hrd->getDecodingUnitHrdParamsPresentFlag() )
+    {
+      WRITE_CODE( hrd->getCpbSizeDuScale(), 4,               "cpb_size_du_scale" );
   }
+#endif
+  }
+#if !FIX_HRD_O0189
   WRITE_CODE( hrd->getBitRateScale(), 4,                     "bit_rate_scale" );
   WRITE_CODE( hrd->getCpbSizeScale(), 4,                     "cpb_size_scale" );
+#endif
 
   for( int i = firstSubLayer; i <= maxNumSubLayersMinus1; i ++ )
   {
@@ -1161,12 +1184,19 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
 #endif
 
   const TimingInfo *timingInfo = pcSPS->getTimingInfo();
+#if JVET_O0189_DU
+  WRITE_FLAG(pcSPS->getHrdParametersPresentFlag(),          "general_hrd_parameters_present_flag");
+    if( pcSPS->getHrdParametersPresentFlag() )
+#else
   WRITE_FLAG(timingInfo->getTimingInfoPresentFlag(),          "timing_info_present_flag");
   if(timingInfo->getTimingInfoPresentFlag())
+#endif
   {
     WRITE_CODE(timingInfo->getNumUnitsInTick(), 32,           "num_units_in_tick");
     WRITE_CODE(timingInfo->getTimeScale(),      32,           "time_scale");
+#if !JVET_O0189_DU
     WRITE_FLAG(pcSPS->getHrdParametersPresentFlag(),              "hrd_parameters_present_flag");
+#endif
     if( pcSPS->getHrdParametersPresentFlag() )
     {
       codeHrdParameters(pcSPS->getHrdParameters(), 1, pcSPS->getMaxTLayers() - 1 );