Index: branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 893)
+++ branches/SHM-dev/source/Lib/TLibDecoder/SEIread.cpp	(revision 894)
@@ -251,5 +251,9 @@
       {
         sei = new SEIDecodingUnitInfo; 
+#if VPS_VUI_BSP_HRD_PARAMS
+        xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, sps, nestingSei, bspNestingSei, vps);
+#else
         xParseSEIDecodingUnitInfo((SEIDecodingUnitInfo&) *sei, payloadSize, sps);
+#endif
       }
       break; 
@@ -262,5 +266,9 @@
       {
         sei = new SEIBufferingPeriod;
+#if VPS_VUI_BSP_HRD_PARAMS
+        xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, sps, nestingSei, bspNestingSei, vps);
+#else
         xParseSEIBufferingPeriod((SEIBufferingPeriod&) *sei, payloadSize, sps);
+#endif
       }
       break;
@@ -273,5 +281,9 @@
       {
         sei = new SEIPictureTiming;
+#if VPS_VUI_BSP_HRD_PARAMS
+        xParseSEIPictureTiming((SEIPictureTiming&)*sei, payloadSize, sps, nestingSei, bspNestingSei, vps);
+#else
         xParseSEIPictureTiming((SEIPictureTiming&)*sei, payloadSize, sps);
+#endif
       }
       break;
@@ -600,5 +612,9 @@
 }
 
+#if VPS_VUI_BSP_HRD_PARAMS
+Void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, UInt /*payloadSize*/, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps)
+#else
 Void SEIReader::xParseSEIDecodingUnitInfo(SEIDecodingUnitInfo& sei, UInt /*payloadSize*/, TComSPS *sps)
+#endif
 {
   UInt val;
@@ -606,8 +622,48 @@
   sei.m_decodingUnitIdx = val;
 
+#if VPS_VUI_BSP_HRD_PARAMS
+  TComHRD *hrd;
+  if( bspNestingSei )   // If DU info SEI contained inside a BSP nesting SEI message
+  {
+    assert( nestingSei );
+    Int psIdx = bspNestingSei->m_seiPartitioningSchemeIdx;
+    Int seiOlsIdx = bspNestingSei->m_seiOlsIdx;
+    Int maxTemporalId = nestingSei->m_nestingMaxTemporalIdPlus1[0] - 1;
+    Int maxValues = vps->getNumBspSchedulesMinus1(seiOlsIdx, psIdx, maxTemporalId) + 1;
+    std::vector<Int> hrdIdx(maxValues, 0);
+    std::vector<TComHRD *> hrdVec;
+    std::vector<Int> syntaxElemLen(maxValues, 0);
+    for(Int i = 0; i < maxValues; i++)
+    {
+      hrdIdx[i] = vps->getBspHrdIdx( seiOlsIdx, psIdx, maxTemporalId, i, bspNestingSei->m_bspIdx);
+      hrdVec.push_back(vps->getBspHrd(hrdIdx[i]));
+    
+      syntaxElemLen[i] = hrdVec[i]->getInitialCpbRemovalDelayLengthMinus1() + 1;
+      if ( !(hrdVec[i]->getNalHrdParametersPresentFlag() || hrdVec[i]->getVclHrdParametersPresentFlag()) )
+      {
+        assert( syntaxElemLen[i] == 24 ); // Default of value init_cpb_removal_delay_length_minus1 is 23
+      }
+      if( i > 0 )
+      {
+        assert( hrdVec[i]->getSubPicCpbParamsPresentFlag()    == hrdVec[i-1]->getSubPicCpbParamsPresentFlag() );
+        assert( hrdVec[i]->getSubPicCpbParamsInPicTimingSEIFlag()   == hrdVec[i-1]->getSubPicCpbParamsInPicTimingSEIFlag() );
+        assert( hrdVec[i]->getDpbOutputDelayDuLengthMinus1()  == hrdVec[i-1]->getDpbOutputDelayDuLengthMinus1() );
+        // To be done: Check CpbDpbDelaysPresentFlag
+      }
+    }
+    hrd = hrdVec[0];
+  }
+  else
+  {
+    TComVUI *vui = sps->getVuiParameters();
+    hrd = vui->getHrdParameters();
+  }
+#else
   TComVUI *vui = sps->getVuiParameters();
-  if(vui->getHrdParameters()->getSubPicCpbParamsInPicTimingSEIFlag())
-  {
-    READ_CODE( ( vui->getHrdParameters()->getDuCpbRemovalDelayLengthMinus1() + 1 ), val, "du_spt_cpb_removal_delay");
+  TComHrd *hrd = vui->getHrdParameters();
+#endif
+  if(hrd->getSubPicCpbParamsInPicTimingSEIFlag())
+  {
+    READ_CODE( ( hrd->getDuCpbRemovalDelayLengthMinus1() + 1 ), val, "du_spt_cpb_removal_delay");
     sei.m_duSptCpbRemovalDelay = val;
   }
@@ -619,5 +675,5 @@
   if(sei.m_dpbOutputDuDelayPresentFlag)
   {
-    READ_CODE(vui->getHrdParameters()->getDpbOutputDelayDuLengthMinus1() + 1, val, "pic_spt_dpb_output_du_delay"); 
+    READ_CODE(hrd->getDpbOutputDelayDuLengthMinus1() + 1, val, "pic_spt_dpb_output_du_delay"); 
     sei.m_picSptDpbOutputDuDelay = val;
   }
@@ -625,11 +681,54 @@
 }
 
+#if VPS_VUI_BSP_HRD_PARAMS
+Void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, UInt /*payloadSize*/, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps)
+#else
 Void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, UInt /*payloadSize*/, TComSPS *sps)
+#endif
 {
   Int i, nalOrVcl;
   UInt code;
 
+#if VPS_VUI_BSP_HRD_PARAMS
+  TComHRD *pHRD;
+  if( bspNestingSei )   // If BP SEI contained inside a BSP nesting SEI message
+  {
+    assert( nestingSei );
+    Int psIdx = bspNestingSei->m_seiPartitioningSchemeIdx;
+    Int seiOlsIdx = bspNestingSei->m_seiOlsIdx;
+    Int maxTemporalId = nestingSei->m_nestingMaxTemporalIdPlus1[0] - 1;
+    Int maxValues = vps->getNumBspSchedulesMinus1(seiOlsIdx, psIdx, maxTemporalId) + 1;
+    std::vector<Int> hrdIdx(maxValues, 0);
+    std::vector<TComHRD *> hrdVec;
+    std::vector<Int> syntaxElemLen(maxValues, 0);
+    for(i = 0; i < maxValues; i++)
+    {
+      hrdIdx[i] = vps->getBspHrdIdx( seiOlsIdx, psIdx, maxTemporalId, i, bspNestingSei->m_bspIdx);
+      hrdVec.push_back(vps->getBspHrd(hrdIdx[i]));
+    
+      syntaxElemLen[i] = hrdVec[i]->getInitialCpbRemovalDelayLengthMinus1() + 1;
+      if ( !(hrdVec[i]->getNalHrdParametersPresentFlag() || hrdVec[i]->getVclHrdParametersPresentFlag()) )
+      {
+        assert( syntaxElemLen[i] == 24 ); // Default of value init_cpb_removal_delay_length_minus1 is 23
+      }
+      if( i > 0 )
+      {
+        assert( hrdVec[i]->getCpbRemovalDelayLengthMinus1()   == hrdVec[i-1]->getCpbRemovalDelayLengthMinus1() );
+        assert( hrdVec[i]->getDpbOutputDelayDuLengthMinus1()  == hrdVec[i-1]->getDpbOutputDelayDuLengthMinus1() );
+        assert( hrdVec[i]->getSubPicCpbParamsPresentFlag()    == hrdVec[i-1]->getSubPicCpbParamsPresentFlag() );
+      }
+    }
+    pHRD = hrdVec[i];
+  }
+  else
+  {
+    TComVUI *vui = sps->getVuiParameters();
+    pHRD = vui->getHrdParameters();
+  }
+  // To be done: When contained in an BSP HRD SEI message, the hrd structure is to be chosen differently.
+#else
   TComVUI *pVUI = sps->getVuiParameters();
   TComHRD *pHRD = pVUI->getHrdParameters();
+#endif
 
   READ_UVLC( code, "bp_seq_parameter_set_id" );                         sei.m_bpSeqParameterSetId     = code;
@@ -683,11 +782,58 @@
   xParseByteAlign();
 }
+#if VPS_VUI_BSP_HRD_PARAMS
+Void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, UInt /*payloadSize*/, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps)
+#else
 Void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, UInt /*payloadSize*/, TComSPS *sps)
+#endif
 {
   Int i;
   UInt code;
 
+#if VPS_VUI_BSP_HRD_PARAMS
+  TComHRD *hrd;    
+  TComVUI *vui = sps->getVuiParameters(); 
+  if( bspNestingSei )   // If BP SEI contained inside a BSP nesting SEI message
+  {
+    assert( nestingSei );
+    Int psIdx = bspNestingSei->m_seiPartitioningSchemeIdx;
+    Int seiOlsIdx = bspNestingSei->m_seiOlsIdx;
+    Int maxTemporalId = nestingSei->m_nestingMaxTemporalIdPlus1[0] - 1;
+    Int maxValues = vps->getNumBspSchedulesMinus1(seiOlsIdx, psIdx, maxTemporalId) + 1;
+    std::vector<Int> hrdIdx(maxValues, 0);
+    std::vector<TComHRD *> hrdVec;
+    std::vector<Int> syntaxElemLen(maxValues, 0);
+    for(i = 0; i < maxValues; i++)
+    {
+      hrdIdx[i] = vps->getBspHrdIdx( seiOlsIdx, psIdx, maxTemporalId, i, bspNestingSei->m_bspIdx);
+      hrdVec.push_back(vps->getBspHrd(hrdIdx[i]));
+    
+      syntaxElemLen[i] = hrdVec[i]->getInitialCpbRemovalDelayLengthMinus1() + 1;
+      if ( !(hrdVec[i]->getNalHrdParametersPresentFlag() || hrdVec[i]->getVclHrdParametersPresentFlag()) )
+      {
+        assert( syntaxElemLen[i] == 24 ); // Default of value init_cpb_removal_delay_length_minus1 is 23
+      }
+      if( i > 0 )
+      {
+        assert( hrdVec[i]->getSubPicCpbParamsPresentFlag()    == hrdVec[i-1]->getSubPicCpbParamsPresentFlag() );
+        assert( hrdVec[i]->getSubPicCpbParamsInPicTimingSEIFlag()   == hrdVec[i-1]->getSubPicCpbParamsInPicTimingSEIFlag() );
+        assert( hrdVec[i]->getCpbRemovalDelayLengthMinus1()  == hrdVec[i-1]->getCpbRemovalDelayLengthMinus1() );
+        assert( hrdVec[i]->getDpbOutputDelayLengthMinus1()  == hrdVec[i-1]->getDpbOutputDelayLengthMinus1() );
+        assert( hrdVec[i]->getDpbOutputDelayDuLengthMinus1()  == hrdVec[i-1]->getDpbOutputDelayDuLengthMinus1() );
+        assert( hrdVec[i]->getDuCpbRemovalDelayLengthMinus1()  == hrdVec[i-1]->getDuCpbRemovalDelayLengthMinus1() );
+        // To be done: Check CpbDpbDelaysPresentFlag
+      }
+    }
+    hrd = hrdVec[0];
+  }
+  else
+  {
+    hrd = vui->getHrdParameters();
+  }
+  // To be done: When contained in an BSP HRD SEI message, the hrd structure is to be chosen differently.
+#else
   TComVUI *vui = sps->getVuiParameters();
   TComHRD *hrd = vui->getHrdParameters();
+#endif
 
   if( vui->getFrameFieldInfoPresentFlag() )
@@ -1264,4 +1410,44 @@
   assert(vps->getVpsVuiPresentFlag());
 
+#if VPS_VUI_BSP_HRD_PARAMS
+  UInt uiCode;
+  Int psIdx         = bspNestingSei.m_seiPartitioningSchemeIdx;
+  Int seiOlsIdx     = bspNestingSei.m_seiOlsIdx;
+  Int maxTemporalId = nestingSei.m_nestingMaxTemporalIdPlus1[0];
+  Int maxValues     = vps->getNumBspSchedulesMinus1(seiOlsIdx, psIdx, maxTemporalId) + 1;
+  std::vector<Int> hrdIdx(0, maxValues);
+  std::vector<TComHRD *> hrdVec;
+  std::vector<Int> syntaxElemLen;
+  for(Int i = 0; i < maxValues; i++)
+  {
+    hrdIdx[i] = vps->getBspHrdIdx( seiOlsIdx, psIdx, maxTemporalId, i, bspNestingSei.m_bspIdx);
+    hrdVec[i] = vps->getBspHrd(hrdIdx[i]);
+    
+    syntaxElemLen[i] = hrdVec[i]->getInitialCpbRemovalDelayLengthMinus1() + 1;
+    if ( !(hrdVec[i]->getNalHrdParametersPresentFlag() || hrdVec[i]->getVclHrdParametersPresentFlag()) )
+    {
+      assert( syntaxElemLen[i] == 24 ); // Default value of init_cpb_removal_delay_length_minus1 is 23
+    }
+    if( i > 0 )
+    {
+      assert( hrdVec[i]->getNalHrdParametersPresentFlag() == hrdVec[i-1]->getNalHrdParametersPresentFlag() );
+      assert( hrdVec[i]->getVclHrdParametersPresentFlag() == hrdVec[i-1]->getVclHrdParametersPresentFlag() );
+    }
+  }
+  if (hrdVec[0]->getNalHrdParametersPresentFlag())
+  {
+    for(UInt i = 0; i < maxValues; i++)
+    {
+      READ_CODE( syntaxElemLen[i], uiCode, "nal_initial_arrival_delay[i]" ); sei.m_nalInitialArrivalDelay[i] = uiCode;
+    }
+  }
+  if( hrdVec[0]->getVclHrdParametersPresentFlag() )
+  {
+    for(UInt i = 0; i < maxValues; i++)
+    {
+      READ_CODE( syntaxElemLen[i], uiCode, "vcl_initial_arrival_delay[i]" ); sei.m_vclInitialArrivalDelay[i] = uiCode;
+    }
+  }
+#else
   UInt schedCombCnt = vps->getNumBspSchedCombinations(nestingSei.m_nestingOpIdx[0]);
   UInt len;
@@ -1307,4 +1493,5 @@
     }
   }
+#endif
 }
 
Index: branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h	(revision 893)
+++ branches/SHM-dev/source/Lib/TLibDecoder/SEIread.h	(revision 894)
@@ -80,8 +80,14 @@
   Void xParseSEIuserDataUnregistered  (SEIuserDataUnregistered &sei, UInt payloadSize);
   Void xParseSEIActiveParameterSets   (SEIActiveParameterSets  &sei, UInt payloadSize);
+  Void xParseSEIDecodedPictureHash    (SEIDecodedPictureHash& sei, UInt payloadSize);
+#if VPS_VUI_BSP_HRD_PARAMS
+  Void xParseSEIDecodingUnitInfo      (SEIDecodingUnitInfo& sei, UInt payloadSize, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps);
+  Void xParseSEIBufferingPeriod       (SEIBufferingPeriod& sei, UInt payloadSize, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps);
+  Void xParseSEIPictureTiming         (SEIPictureTiming& sei, UInt payloadSize, TComSPS *sps, const SEIScalableNesting* nestingSei, const SEIBspNesting* bspNestingSei, TComVPS *vps);
+#else
   Void xParseSEIDecodingUnitInfo      (SEIDecodingUnitInfo& sei, UInt payloadSize, TComSPS *sps);
-  Void xParseSEIDecodedPictureHash    (SEIDecodedPictureHash& sei, UInt payloadSize);
   Void xParseSEIBufferingPeriod       (SEIBufferingPeriod& sei, UInt payloadSize, TComSPS *sps);
   Void xParseSEIPictureTiming         (SEIPictureTiming& sei, UInt payloadSize, TComSPS *sps);
+#endif
   Void xParseSEIRecoveryPoint         (SEIRecoveryPoint& sei, UInt payloadSize);
   Void xParseSEIFramePacking          (SEIFramePacking& sei, UInt payloadSize);
Index: branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 893)
+++ branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 894)
@@ -578,4 +578,11 @@
       READ_CODE( 5, uiCode, "dpb_output_delay_length_minus1" );       hrd->setDpbOutputDelayLengthMinus1( uiCode );
     }
+#if VPS_VUI_BSP_HRD_PARAMS
+    else
+    {
+      hrd->setInitialCpbRemovalDelayLengthMinus1( 23 );
+      // Add inferred values for other syntax elements here.
+    }
+#endif
   }
   Int i, j, nalOrVcl;
@@ -2625,4 +2632,7 @@
   if (vps->getVpsVuiBspHrdPresentFlag())
   {
+#if VPS_VUI_BSP_HRD_PARAMS
+    parseVpsVuiBspHrdParams(vps);
+#else
 #if R0227_VUI_BSP_HRD_FLAG
     assert (vps->getTimingInfo()->getTimingInfoPresentFlag() == 1);
@@ -2703,7 +2713,7 @@
       }
     }
-  }
-#endif
-
+#endif
+  }
+#endif
 #if P0182_VPS_VUI_PS_FLAG
   for(i = 1; i < vps->getMaxLayers(); i++)
@@ -2721,4 +2731,5 @@
 #endif
 }
+
 #endif //SVC_EXTENSION
 
@@ -4487,4 +4498,80 @@
 }
 #endif
+#if VPS_VUI_BSP_HRD_PARAMS
+Void TDecCavlc::parseVpsVuiBspHrdParams( TComVPS *vps )
+{
+  UInt uiCode;
+  assert (vps->getTimingInfo()->getTimingInfoPresentFlag() == 1);
+  READ_UVLC( uiCode, "vps_num_add_hrd_params" ); vps->setVpsNumAddHrdParams(uiCode);
+  vps->createBspHrdParamBuffer(vps->getVpsNumAddHrdParams()); // Also allocates m_cprmsAddPresentFlag and m_numSubLayerHrdMinus
+
+  for( Int i = vps->getNumHrdParameters(), j = 0; i < vps->getNumHrdParameters() + vps->getVpsNumAddHrdParams(); i++, j++ ) // j = i - vps->getNumHrdParameters()
+  {
+    if( i > 0 )
+    {
+      READ_FLAG( uiCode, "cprms_add_present_flag[i]" );   vps->setCprmsAddPresentFlag(j, uiCode ? true : false);
+    }
+    else
+    {
+      // i == 0
+      if( vps->getNumHrdParameters() == 0 )
+      {
+        vps->setCprmsAddPresentFlag(0, true);
+      }
+    }
+    READ_UVLC( uiCode, "num_sub_layer_hrd_minus1[i]" ); vps->setNumSubLayerHrdMinus1(j, uiCode );
+    assert( uiCode <= vps->getMaxTLayers() - 1 );
+    
+    parseHrdParameters( vps->getBspHrd(j), vps->getCprmsAddPresentFlag(j), vps->getNumSubLayerHrdMinus1(j) );
+    if( i > 0 && !vps->getCprmsAddPresentFlag(i) )
+    {
+      // Copy common information parameters
+      if( i == vps->getNumHrdParameters() )
+      {
+        vps->getBspHrd(j)->copyCommonInformation( vps->getHrdParameters( vps->getNumHrdParameters() - 1 ) );
+      }
+      else
+      {
+        vps->getBspHrd(j)->copyCommonInformation( vps->getBspHrd( j - 1 ) );
+      }
+    }
+  }
+  for (Int h = 1; h < vps->getNumOutputLayerSets(); h++)
+  {
+    Int lsIdx = vps->getOutputLayerSetIdx( h );
+    READ_UVLC( uiCode, "num_signalled_partitioning_schemes[h]"); vps->setNumSignalledPartitioningSchemes(h, uiCode);
+    for( Int j = 0; j < vps->getNumSignalledPartitioningSchemes(h); j++ )
+    {
+      READ_UVLC( uiCode, "num_partitions_in_scheme_minus1[h][j]" ); vps->setNumPartitionsInSchemeMinus1(h, j, uiCode);
+      for( Int k = 0; k <= vps->getNumPartitionsInSchemeMinus1(h, j); k++ )
+      {
+        for( Int r = 0; r < vps->getNumLayersInIdList( lsIdx ); r++ )
+        {
+          READ_FLAG( uiCode, "layer_included_in_partition_flag[h][j][k][r]" ); vps->setLayerIncludedInPartitionFlag(h, j, k, r, uiCode ? true : false);
+        }
+      }
+    }
+    for( Int i = 0; i < vps->getNumSignalledPartitioningSchemes(h) + 1; i++ )
+    {
+      for( Int t = 0; t <= vps->getMaxSLayersInLayerSetMinus1(lsIdx); t++ )
+      {
+        READ_UVLC( uiCode, "num_bsp_schedules_minus1[h][i][t]");              vps->setNumBspSchedulesMinus1(h, i, t, uiCode);
+        for( Int j = 0; j <= vps->getNumBspSchedulesMinus1(h, i, t); j++ )
+        {
+          for( Int k = 0; k < vps->getNumPartitionsInSchemeMinus1(h, i); k++ )
+          {
+            READ_UVLC( uiCode, "bsp_comb_hrd_idx[h][i][t][j][k]");      vps->setBspHrdIdx(h, i, t, j, k, uiCode);
+            READ_UVLC( uiCode, "bsp_comb_sched_idx[h][i][t][j][k]");    vps->setBspSchedIdx(h, i, t, j, k, uiCode);
+          }
+        }
+      }
+    }
+
+    // To be done: Check each layer included in not more than one BSP in every partitioning scheme,
+    // and other related checks associated with layers in bitstream partitions.
+
+  }
+}
+#endif
 #endif
 //! \}
Index: branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 893)
+++ branches/SHM-dev/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 894)
@@ -86,4 +86,7 @@
   Void  parseVpsDpbSizeTable( TComVPS *vps );
 #endif
+#if VPS_VUI_BSP_HRD_PARAMS
+  Void  parseVpsVuiBspHrdParams( TComVPS *vps );
+#endif
 #if SPS_DPB_PARAMS
   Void  parseSPS            ( TComSPS* pcSPS ); // it should be removed after macro clean up
