diff --git a/cfg/sei_vui/timing.cfg b/cfg/sei_vui/timing.cfg
index 63f37a73919737867258e173f4c611176003d05d..12125434e73b93d404abd232b736306c0c1b7fee 100644
--- a/cfg/sei_vui/timing.cfg
+++ b/cfg/sei_vui/timing.cfg
@@ -1,4 +1,4 @@
 SEIBufferingPeriod:  1
 SEIPictureTiming:  1
-VuiParametersPresent: 1
+HrdParametersPresent: 1
 RCCpbSize: 2000
diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp
index 27550e7ba09c353e725639603ad768c0cb94647f..ce9faa4a14c43d67e028634537cea8ec80ce5d32 100644
--- a/source/Lib/CommonLib/SEI.cpp
+++ b/source/Lib/CommonLib/SEI.cpp
@@ -119,6 +119,10 @@ void SEIBufferingPeriod::copyTo (SEIBufferingPeriod& target) const
   target.m_sublayerInitialCpbRemovalDelayPresentFlag = m_sublayerInitialCpbRemovalDelayPresentFlag;
   target.m_concatenationFlag = m_concatenationFlag;
   target.m_maxInitialRemovalDelayForConcatenation = m_maxInitialRemovalDelayForConcatenation;
+#if JVET_R0094_DPB_TID_OFFSET
+  target.m_sublayerDpbOutputOffsetsPresentFlag = m_sublayerDpbOutputOffsetsPresentFlag;
+  ::memcpy(target.m_dpbOutputTidOffset, m_dpbOutputTidOffset, sizeof(m_dpbOutputTidOffset));
+#endif
   target.m_altCpbParamsPresentFlag = m_altCpbParamsPresentFlag;
 }
 
diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h
index c45634c6121541828dd13bc3acf0577136d4ee8e..d51f7ccde4870090151343a99b7ce07485fbbd1d 100644
--- a/source/Lib/CommonLib/SEI.h
+++ b/source/Lib/CommonLib/SEI.h
@@ -281,12 +281,18 @@ public:
     , m_sublayerInitialCpbRemovalDelayPresentFlag(false)
     , m_additionalConcatenationInfoPresentFlag (false)
     , m_maxInitialRemovalDelayForConcatenation (0)
+#if JVET_R0094_DPB_TID_OFFSET
+    , m_sublayerDpbOutputOffsetsPresentFlag (false)
+#endif
     , m_altCpbParamsPresentFlag (false)
     , m_useAltCpbParamsFlag (false)
   {
     ::memset(m_initialCpbRemovalDelay, 0, sizeof(m_initialCpbRemovalDelay));
     ::memset(m_initialCpbRemovalOffset, 0, sizeof(m_initialCpbRemovalOffset));
     ::memset(m_cpbRemovalDelayDelta, 0, sizeof(m_cpbRemovalDelayDelta));
+#if JVET_R0094_DPB_TID_OFFSET
+    ::memset(m_dpbOutputTidOffset, 0, sizeof(m_dpbOutputTidOffset));
+#endif
   }
   virtual ~SEIBufferingPeriod() {}
 
@@ -316,6 +322,10 @@ public:
   bool m_sublayerInitialCpbRemovalDelayPresentFlag;
   bool     m_additionalConcatenationInfoPresentFlag;
   uint32_t m_maxInitialRemovalDelayForConcatenation;
+#if JVET_R0094_DPB_TID_OFFSET
+  bool     m_sublayerDpbOutputOffsetsPresentFlag;
+  uint32_t m_dpbOutputTidOffset      [MAX_TLAYER];
+#endif
   bool     m_altCpbParamsPresentFlag;
   bool     m_useAltCpbParamsFlag;
 };
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 7bc995a8baace5598950c171ed835a6a7e72de6e..4aceeb7a079025b2c6d2f4fe4da6c8adf11d4e4e 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -68,6 +68,8 @@
 
 #define JVET_R0266_DESC                                   1 // JVET-R0266: change the signalling of the PPS ID from ue(v) to u(6); Code virtual boundary positions using ue(v)
 
+#define JVET_R0094_DPB_TID_OFFSET                         1 // JVET-R0094: DPB output temporal ID offsets
+
 #define JVET_R0330_CRS_CLIP_REM                           1 // JVET-R0330: Remove redundant clipping in chroma residual scaling factor derivation
 
 #define JVET_R0059_RPL_CLEANUP                            1 // JVET-R0059 aspect 2: Condition the signalling of ltrp_in_header_flag[ listIdx ][ rplsIdx ].
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index 961e63a51d1811f19e197d7ec9512475808237cb..204d88c06e0022493de64d04dd56ec750eb5ebb6 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -675,6 +675,19 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
       }
     }
   }
+#if JVET_R0094_DPB_TID_OFFSET
+  sei_read_flag( pDecodedMessageOutputStream, code, "sublayer_dpb_output_offsets_present_flag" );
+  sei.m_sublayerDpbOutputOffsetsPresentFlag = code;
+  if(sei.m_sublayerDpbOutputOffsetsPresentFlag)
+  {
+    for(int i = 0; i < sei.m_bpMaxSubLayers - 1; i++)
+    {
+      sei_read_uvlc( pDecodedMessageOutputStream, code, "dpb_output_tid_offset[i]" );
+      sei.m_dpbOutputTidOffset[i] = code;
+    }
+    sei.m_dpbOutputTidOffset[sei.m_bpMaxSubLayers-1] = 0;
+  }
+#endif
   if (sei.m_altCpbParamsPresentFlag)
   {
     sei_read_flag(pDecodedMessageOutputStream, code, "use_alt_cpb_params_flag"); sei.m_useAltCpbParamsFlag = code;
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index 7a03748627dbddc6db14a96a78e11eef2160cdcc..cd9d018061664191efbcfa771286445ede4892b9 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -179,6 +179,21 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI,
         break;
     }
   }
+#if JVET_R0094_DPB_TID_OFFSET
+  bufferingPeriodSEI->m_sublayerDpbOutputOffsetsPresentFlag = true;
+  for(int i = 0; i < bufferingPeriodSEI->m_bpMaxSubLayers; i++)
+  {
+    bufferingPeriodSEI->m_dpbOutputTidOffset[i] = m_pcCfg->getNumReorderPics(i) * static_cast<int>(pow(2, static_cast<double>(bufferingPeriodSEI->m_bpMaxSubLayers-1-i)));
+    if(bufferingPeriodSEI->m_dpbOutputTidOffset[i] >= m_pcCfg->getNumReorderPics(bufferingPeriodSEI->m_bpMaxSubLayers-1))
+    {
+      bufferingPeriodSEI->m_dpbOutputTidOffset[i] -= m_pcCfg->getNumReorderPics(bufferingPeriodSEI->m_bpMaxSubLayers-1);
+    }
+    else
+    {
+      bufferingPeriodSEI->m_dpbOutputTidOffset[i] = 0;
+    }
+  }
+#endif
   // A commercial encoder should track the buffer state for all layers and sub-layers
   // to ensure CPB conformance. Such tracking is required for calculating alternative
   // CPB parameters.
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index b3913cdb178fc48075099840f4b74cea8036309e..5e05748a22f384cd15a03eab89fad8a0a36df8d5 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -328,6 +328,16 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei)
       }
     }
   }
+#if JVET_R0094_DPB_TID_OFFSET
+  WRITE_FLAG(sei.m_sublayerDpbOutputOffsetsPresentFlag, "sublayer_dpb_output_offsets_present_flag");
+  if(sei.m_sublayerDpbOutputOffsetsPresentFlag)
+  {
+    for(int i = 0; i < sei.m_bpMaxSubLayers - 1; i++)
+    {
+      WRITE_UVLC( sei.m_dpbOutputTidOffset[i], "dpb_output_tid_offset[i]" );
+    }
+  }
+#endif
   if (sei.m_altCpbParamsPresentFlag)
   {
     WRITE_FLAG(sei.m_useAltCpbParamsFlag, "use_alt_cpb_params_flag");