From bdcf49c92ddd2fb7ce8e2515c0bfda8b9a017c7c Mon Sep 17 00:00:00 2001
From: Karsten Suehring <karsten.suehring@hhi.fraunhofer.de>
Date: Mon, 13 May 2019 19:42:29 +0200
Subject: [PATCH] refactor HRD parameters in preparation of JVET-N0353

- create own files for HRD classes
- rename HRD to HRDParameters
- create HRD class that can hold all HRD related parameters as base for encoder/decoder specific implementations
---
 source/Lib/CommonLib/HRD.cpp         |  34 +++++
 source/Lib/CommonLib/HRD.h           | 213 +++++++++++++++++++++++++++
 source/Lib/CommonLib/Slice.h         | 165 +--------------------
 source/Lib/DecoderLib/SEIread.cpp    |   4 +-
 source/Lib/DecoderLib/VLCReader.cpp  |   2 +-
 source/Lib/DecoderLib/VLCReader.h    |   2 +-
 source/Lib/EncoderLib/EncGOP.cpp     |   6 +-
 source/Lib/EncoderLib/EncHRD.cpp     | 209 ++++++++++++++++++++++++++
 source/Lib/EncoderLib/EncHRD.h       |  55 +++++++
 source/Lib/EncoderLib/EncLib.cpp     | 175 +---------------------
 source/Lib/EncoderLib/EncLib.h       |   6 +-
 source/Lib/EncoderLib/RateCtrl.cpp   |   2 +-
 source/Lib/EncoderLib/RateCtrl.h     |   2 +-
 source/Lib/EncoderLib/SEIEncoder.cpp |   2 +-
 source/Lib/EncoderLib/SEIwrite.cpp   |   4 +-
 source/Lib/EncoderLib/VLCWriter.cpp  |   2 +-
 source/Lib/EncoderLib/VLCWriter.h    |   2 +-
 17 files changed, 543 insertions(+), 342 deletions(-)
 create mode 100644 source/Lib/CommonLib/HRD.cpp
 create mode 100644 source/Lib/CommonLib/HRD.h
 create mode 100644 source/Lib/EncoderLib/EncHRD.cpp
 create mode 100644 source/Lib/EncoderLib/EncHRD.h

diff --git a/source/Lib/CommonLib/HRD.cpp b/source/Lib/CommonLib/HRD.cpp
new file mode 100644
index 000000000..bfb0baa70
--- /dev/null
+++ b/source/Lib/CommonLib/HRD.cpp
@@ -0,0 +1,34 @@
+/* The copyright in this software is being made available under the BSD
+* License, included below. This software may be subject to other third party
+* and contributor rights, including patent rights, and no such rights are
+* granted under this license.
+*
+* Copyright (c) 2010-2019, ITU/ISO/IEC
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+*  * Redistributions of source code must retain the above copyright notice,
+*    this list of conditions and the following disclaimer.
+*  * Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+*    be used to endorse or promote products derived from this software without
+*    specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
diff --git a/source/Lib/CommonLib/HRD.h b/source/Lib/CommonLib/HRD.h
new file mode 100644
index 000000000..3c70bdad9
--- /dev/null
+++ b/source/Lib/CommonLib/HRD.h
@@ -0,0 +1,213 @@
+/* The copyright in this software is being made available under the BSD
+* License, included below. This software may be subject to other third party
+* and contributor rights, including patent rights, and no such rights are
+* granted under this license.
+*
+* Copyright (c) 2010-2019, ITU/ISO/IEC
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+*  * Redistributions of source code must retain the above copyright notice,
+*    this list of conditions and the following disclaimer.
+*  * Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+*    be used to endorse or promote products derived from this software without
+*    specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __HRD__
+#define __HRD__
+
+#include "Common.h"
+
+class TimingInfo
+{
+protected:
+  bool     m_timingInfoPresentFlag;
+  uint32_t m_numUnitsInTick;
+  uint32_t m_timeScale;
+  bool     m_pocProportionalToTimingFlag;
+  int      m_numTicksPocDiffOneMinus1;
+
+public:
+  TimingInfo()
+    : m_timingInfoPresentFlag      (false)
+    , m_numUnitsInTick             (1001)
+    , m_timeScale                  (60000)
+    , m_pocProportionalToTimingFlag(false)
+    , m_numTicksPocDiffOneMinus1   (0)
+  {}
+
+  void     setTimingInfoPresentFlag( bool flag )   { m_timingInfoPresentFlag = flag;       }
+  bool     getTimingInfoPresentFlag( ) const       { return m_timingInfoPresentFlag;       }
+
+  void     setNumUnitsInTick( uint32_t value )     { m_numUnitsInTick = value;             }
+  uint32_t getNumUnitsInTick( ) const              { return m_numUnitsInTick;              }
+  void     setTimeScale( uint32_t value )          { m_timeScale = value;                  }
+  uint32_t getTimeScale( ) const                   { return m_timeScale;                   }
+
+  void     setPocProportionalToTimingFlag(bool x)  { m_pocProportionalToTimingFlag = x;    }
+  bool     getPocProportionalToTimingFlag( ) const { return m_pocProportionalToTimingFlag; }
+
+  void     setNumTicksPocDiffOneMinus1(int x)      { m_numTicksPocDiffOneMinus1 = x;       }
+  int      getNumTicksPocDiffOneMinus1( ) const    { return m_numTicksPocDiffOneMinus1;    }
+};
+
+struct HrdSubLayerInfo
+{
+  bool     fixedPicRateFlag;
+  bool     fixedPicRateWithinCvsFlag;
+  uint32_t picDurationInTcMinus1;
+  bool     lowDelayHrdFlag;
+  uint32_t cpbCntMinus1;
+  uint32_t bitRateValueMinus1[MAX_CPB_CNT][2];
+  uint32_t cpbSizeValue      [MAX_CPB_CNT][2];
+  uint32_t ducpbSizeValue    [MAX_CPB_CNT][2];
+  bool     cbrFlag           [MAX_CPB_CNT][2];
+  uint32_t duBitRateValue    [MAX_CPB_CNT][2];
+};
+
+class HRDParameters
+{
+private:
+  bool     m_nalHrdParametersPresentFlag;
+  bool     m_vclHrdParametersPresentFlag;
+  bool     m_subPicCpbParamsPresentFlag;
+  uint32_t m_tickDivisorMinus2;
+  uint32_t m_duCpbRemovalDelayLengthMinus1;
+  bool     m_subPicCpbParamsInPicTimingSEIFlag;
+  uint32_t m_dpbOutputDelayDuLengthMinus1;
+  uint32_t m_bitRateScale;
+  uint32_t m_cpbSizeScale;
+  uint32_t m_ducpbSizeScale;
+  uint32_t m_initialCpbRemovalDelayLengthMinus1;
+  uint32_t m_cpbRemovalDelayLengthMinus1;
+  uint32_t m_dpbOutputDelayLengthMinus1;
+  HrdSubLayerInfo m_HRD[MAX_TLAYER];
+
+public:
+  HRDParameters()
+    :m_nalHrdParametersPresentFlag       (false)
+    ,m_vclHrdParametersPresentFlag       (false)
+    ,m_subPicCpbParamsPresentFlag        (false)
+    ,m_tickDivisorMinus2                 (0)
+    ,m_duCpbRemovalDelayLengthMinus1     (0)
+    ,m_subPicCpbParamsInPicTimingSEIFlag (false)
+    ,m_dpbOutputDelayDuLengthMinus1      (0)
+    ,m_bitRateScale                      (0)
+    ,m_cpbSizeScale                      (0)
+    ,m_initialCpbRemovalDelayLengthMinus1(23)
+    ,m_cpbRemovalDelayLengthMinus1       (23)
+    ,m_dpbOutputDelayLengthMinus1        (23)
+  {}
+
+  virtual ~HRDParameters() {}
+
+  void      setNalHrdParametersPresentFlag( bool flag )                                { m_nalHrdParametersPresentFlag = flag;                      }
+  bool      getNalHrdParametersPresentFlag( ) const                                    { return m_nalHrdParametersPresentFlag;                      }
+
+  void      setVclHrdParametersPresentFlag( bool flag )                                { m_vclHrdParametersPresentFlag = flag;                      }
+  bool      getVclHrdParametersPresentFlag( ) const                                    { return m_vclHrdParametersPresentFlag;                      }
+
+  void      setSubPicCpbParamsPresentFlag( bool flag )                                 { m_subPicCpbParamsPresentFlag = flag;                       }
+  bool      getSubPicCpbParamsPresentFlag( ) const                                     { return m_subPicCpbParamsPresentFlag;                       }
+
+  void      setTickDivisorMinus2( uint32_t value )                                     { m_tickDivisorMinus2 = value;                               }
+  uint32_t  getTickDivisorMinus2( ) const                                              { return m_tickDivisorMinus2;                                }
+
+  void      setDuCpbRemovalDelayLengthMinus1( uint32_t value )                         { m_duCpbRemovalDelayLengthMinus1 = value;                   }
+  uint32_t  getDuCpbRemovalDelayLengthMinus1( ) const                                  { return m_duCpbRemovalDelayLengthMinus1;                    }
+
+  void      setSubPicCpbParamsInPicTimingSEIFlag( bool flag)                           { m_subPicCpbParamsInPicTimingSEIFlag = flag;                }
+  bool      getSubPicCpbParamsInPicTimingSEIFlag( ) const                              { return m_subPicCpbParamsInPicTimingSEIFlag;                }
+
+  void      setDpbOutputDelayDuLengthMinus1(uint32_t value )                           { m_dpbOutputDelayDuLengthMinus1 = value;                    }
+  uint32_t  getDpbOutputDelayDuLengthMinus1( ) const                                   { return m_dpbOutputDelayDuLengthMinus1;                     }
+
+  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;                                     }
+  void      setDuCpbSizeScale( uint32_t value )                                        { m_ducpbSizeScale = value;                                  }
+  uint32_t  getDuCpbSizeScale( ) const                                                 { return m_ducpbSizeScale;                                   }
+
+  void      setInitialCpbRemovalDelayLengthMinus1( uint32_t value )                    { m_initialCpbRemovalDelayLengthMinus1 = value;              }
+  uint32_t  getInitialCpbRemovalDelayLengthMinus1( ) const                             { return m_initialCpbRemovalDelayLengthMinus1;               }
+
+  void      setCpbRemovalDelayLengthMinus1( uint32_t value )                           { m_cpbRemovalDelayLengthMinus1 = value;                     }
+  uint32_t  getCpbRemovalDelayLengthMinus1( ) const                                    { return m_cpbRemovalDelayLengthMinus1;                      }
+
+  void      setDpbOutputDelayLengthMinus1( uint32_t value )                            { m_dpbOutputDelayLengthMinus1 = value;                      }
+  uint32_t  getDpbOutputDelayLengthMinus1( ) const                                     { return m_dpbOutputDelayLengthMinus1;                       }
+
+  void      setFixedPicRateFlag( int layer, bool flag )                                { m_HRD[layer].fixedPicRateFlag = flag;                      }
+  bool      getFixedPicRateFlag( int layer ) const                                     { return m_HRD[layer].fixedPicRateFlag;                      }
+
+  void      setFixedPicRateWithinCvsFlag( int layer, bool flag )                       { m_HRD[layer].fixedPicRateWithinCvsFlag = flag;             }
+  bool      getFixedPicRateWithinCvsFlag( int layer ) const                            { return m_HRD[layer].fixedPicRateWithinCvsFlag;             }
+
+  void      setPicDurationInTcMinus1( int layer, uint32_t value )                      { m_HRD[layer].picDurationInTcMinus1 = value;                }
+  uint32_t  getPicDurationInTcMinus1( int layer ) const                                { return m_HRD[layer].picDurationInTcMinus1;                 }
+
+  void      setLowDelayHrdFlag( int layer, bool flag )                                 { m_HRD[layer].lowDelayHrdFlag = flag;                       }
+  bool      getLowDelayHrdFlag( int layer ) const                                      { return m_HRD[layer].lowDelayHrdFlag;                       }
+
+  void      setCpbCntMinus1( int layer, uint32_t value )                               { m_HRD[layer].cpbCntMinus1 = value;                         }
+  uint32_t  getCpbCntMinus1( int layer ) const                                         { return m_HRD[layer].cpbCntMinus1;                          }
+
+  void      setBitRateValueMinus1( int layer, int cpbcnt, int nalOrVcl, uint32_t value )   { m_HRD[layer].bitRateValueMinus1[cpbcnt][nalOrVcl] = value; }
+  uint32_t  getBitRateValueMinus1( int layer, int cpbcnt, int nalOrVcl ) const             { return m_HRD[layer].bitRateValueMinus1[cpbcnt][nalOrVcl];  }
+
+  void      setCpbSizeValueMinus1( int layer, int cpbcnt, int nalOrVcl, uint32_t value )   { m_HRD[layer].cpbSizeValue[cpbcnt][nalOrVcl] = value;       }
+  uint32_t  getCpbSizeValueMinus1( int layer, int cpbcnt, int nalOrVcl ) const             { return m_HRD[layer].cpbSizeValue[cpbcnt][nalOrVcl];        }
+  void      setDuCpbSizeValueMinus1( int layer, int cpbcnt, int nalOrVcl, uint32_t value ) { m_HRD[layer].ducpbSizeValue[cpbcnt][nalOrVcl] = value;     }
+  uint32_t  getDuCpbSizeValueMinus1( int layer, int cpbcnt, int nalOrVcl ) const           { return m_HRD[layer].ducpbSizeValue[cpbcnt][nalOrVcl];      }
+  void      setDuBitRateValueMinus1( int layer, int cpbcnt, int nalOrVcl, uint32_t value ) { m_HRD[layer].duBitRateValue[cpbcnt][nalOrVcl] = value;     }
+  uint32_t  getDuBitRateValueMinus1(int layer, int cpbcnt, int nalOrVcl ) const            { return m_HRD[layer].duBitRateValue[cpbcnt][nalOrVcl];      }
+  void      setCbrFlag( int layer, int cpbcnt, int nalOrVcl, bool value )                  { m_HRD[layer].cbrFlag[cpbcnt][nalOrVcl] = value;            }
+  bool      getCbrFlag( int layer, int cpbcnt, int nalOrVcl ) const                        { return m_HRD[layer].cbrFlag[cpbcnt][nalOrVcl];             }
+
+  bool      getCpbDpbDelaysPresentFlag( ) const                                            { return getNalHrdParametersPresentFlag() || getVclHrdParametersPresentFlag(); }
+};
+
+class HRD
+{
+public:
+  HRD()
+  {};
+
+  virtual ~HRD()
+  {};
+
+  void                 setHRDParameters(HRDParameters &hrdParam)    { m_hrdParams=hrdParam; }
+  HRDParameters        getHRDParameters() const                     { return m_hrdParams; }
+  const HRDParameters& getHRDParameters()                           { return m_hrdParams; }
+
+  void                 setTimingInfo(TimingInfo &timingInfo)        { m_timingInfo=timingInfo; }
+  TimingInfo           getTimingInfo() const                        { return m_timingInfo; }
+  const TimingInfo&    getTimingInfo()                              { return m_timingInfo; }
+
+protected:
+  HRDParameters m_hrdParams;
+  TimingInfo    m_timingInfo;
+};
+
+#endif //__HRD__
\ No newline at end of file
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index b61310f3d..550b0bc6b 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -46,6 +46,7 @@
 #include "Rom.h"
 #include "ChromaFormat.h"
 #include "Common.h"
+#include "HRD.h"
 
 //! \ingroup CommonLib
 //! \{
@@ -441,20 +442,6 @@ public:
 };
 #endif
 
-struct HrdSubLayerInfo
-{
-  bool fixedPicRateFlag;
-  bool fixedPicRateWithinCvsFlag;
-  uint32_t picDurationInTcMinus1;
-  bool lowDelayHrdFlag;
-  uint32_t cpbCntMinus1;
-  uint32_t bitRateValueMinus1[MAX_CPB_CNT][2];
-  uint32_t cpbSizeValue      [MAX_CPB_CNT][2];
-  uint32_t ducpbSizeValue    [MAX_CPB_CNT][2];
-  bool cbrFlag           [MAX_CPB_CNT][2];
-  uint32_t duBitRateValue    [MAX_CPB_CNT][2];
-};
-
 class SliceReshapeInfo
 {
 public:
@@ -485,142 +472,6 @@ struct ReshapeCW
   int rspFpsToIp;
 };
 
-class HRD
-{
-private:
-  bool m_nalHrdParametersPresentFlag;
-  bool m_vclHrdParametersPresentFlag;
-  bool m_subPicCpbParamsPresentFlag;
-  uint32_t m_tickDivisorMinus2;
-  uint32_t m_duCpbRemovalDelayLengthMinus1;
-  bool m_subPicCpbParamsInPicTimingSEIFlag;
-  uint32_t m_dpbOutputDelayDuLengthMinus1;
-  uint32_t m_bitRateScale;
-  uint32_t m_cpbSizeScale;
-  uint32_t m_ducpbSizeScale;
-  uint32_t m_initialCpbRemovalDelayLengthMinus1;
-  uint32_t m_cpbRemovalDelayLengthMinus1;
-  uint32_t m_dpbOutputDelayLengthMinus1;
-  HrdSubLayerInfo m_HRD[MAX_TLAYER];
-
-public:
-  HRD()
-  :m_nalHrdParametersPresentFlag       (0)
-  ,m_vclHrdParametersPresentFlag       (0)
-  ,m_subPicCpbParamsPresentFlag        (false)
-  ,m_tickDivisorMinus2                 (0)
-  ,m_duCpbRemovalDelayLengthMinus1     (0)
-  ,m_subPicCpbParamsInPicTimingSEIFlag (false)
-  ,m_dpbOutputDelayDuLengthMinus1      (0)
-  ,m_bitRateScale                      (0)
-  ,m_cpbSizeScale                      (0)
-  ,m_initialCpbRemovalDelayLengthMinus1(23)
-  ,m_cpbRemovalDelayLengthMinus1       (23)
-  ,m_dpbOutputDelayLengthMinus1        (23)
-  {}
-
-  virtual ~HRD() {}
-
-  void    setNalHrdParametersPresentFlag( bool flag )                                { m_nalHrdParametersPresentFlag = flag;                      }
-  bool    getNalHrdParametersPresentFlag( ) const                                    { return m_nalHrdParametersPresentFlag;                      }
-
-  void    setVclHrdParametersPresentFlag( bool flag )                                { m_vclHrdParametersPresentFlag = flag;                      }
-  bool    getVclHrdParametersPresentFlag( ) const                                    { return m_vclHrdParametersPresentFlag;                      }
-
-  void    setSubPicCpbParamsPresentFlag( bool flag )                                 { m_subPicCpbParamsPresentFlag = flag;                       }
-  bool    getSubPicCpbParamsPresentFlag( ) const                                     { return m_subPicCpbParamsPresentFlag;                       }
-
-  void    setTickDivisorMinus2( uint32_t value )                                         { m_tickDivisorMinus2 = value;                               }
-  uint32_t    getTickDivisorMinus2( ) const                                              { return m_tickDivisorMinus2;                                }
-
-  void    setDuCpbRemovalDelayLengthMinus1( uint32_t value )                             { m_duCpbRemovalDelayLengthMinus1 = value;                   }
-  uint32_t    getDuCpbRemovalDelayLengthMinus1( ) const                                  { return m_duCpbRemovalDelayLengthMinus1;                    }
-
-  void    setSubPicCpbParamsInPicTimingSEIFlag( bool flag)                           { m_subPicCpbParamsInPicTimingSEIFlag = flag;                }
-  bool    getSubPicCpbParamsInPicTimingSEIFlag( ) const                              { return m_subPicCpbParamsInPicTimingSEIFlag;                }
-
-  void    setDpbOutputDelayDuLengthMinus1(uint32_t value )                               { m_dpbOutputDelayDuLengthMinus1 = value;                    }
-  uint32_t    getDpbOutputDelayDuLengthMinus1( ) const                                   { return m_dpbOutputDelayDuLengthMinus1;                     }
-
-  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;                                     }
-  void    setDuCpbSizeScale( uint32_t value )                                            { m_ducpbSizeScale = value;                                  }
-  uint32_t    getDuCpbSizeScale( ) const                                                 { return m_ducpbSizeScale;                                   }
-
-  void    setInitialCpbRemovalDelayLengthMinus1( uint32_t value )                        { m_initialCpbRemovalDelayLengthMinus1 = value;              }
-  uint32_t    getInitialCpbRemovalDelayLengthMinus1( ) const                             { return m_initialCpbRemovalDelayLengthMinus1;               }
-
-  void    setCpbRemovalDelayLengthMinus1( uint32_t value )                               { m_cpbRemovalDelayLengthMinus1 = value;                     }
-  uint32_t    getCpbRemovalDelayLengthMinus1( ) const                                    { return m_cpbRemovalDelayLengthMinus1;                      }
-
-  void    setDpbOutputDelayLengthMinus1( uint32_t value )                                { m_dpbOutputDelayLengthMinus1 = value;                      }
-  uint32_t    getDpbOutputDelayLengthMinus1( ) const                                     { return m_dpbOutputDelayLengthMinus1;                       }
-
-  void    setFixedPicRateFlag( int layer, bool flag )                                { m_HRD[layer].fixedPicRateFlag = flag;                      }
-  bool    getFixedPicRateFlag( int layer ) const                                     { return m_HRD[layer].fixedPicRateFlag;                      }
-
-  void    setFixedPicRateWithinCvsFlag( int layer, bool flag )                       { m_HRD[layer].fixedPicRateWithinCvsFlag = flag;             }
-  bool    getFixedPicRateWithinCvsFlag( int layer ) const                            { return m_HRD[layer].fixedPicRateWithinCvsFlag;             }
-
-  void    setPicDurationInTcMinus1( int layer, uint32_t value )                          { m_HRD[layer].picDurationInTcMinus1 = value;                }
-  uint32_t    getPicDurationInTcMinus1( int layer ) const                                { return m_HRD[layer].picDurationInTcMinus1;                 }
-
-  void    setLowDelayHrdFlag( int layer, bool flag )                                 { m_HRD[layer].lowDelayHrdFlag = flag;                       }
-  bool    getLowDelayHrdFlag( int layer ) const                                      { return m_HRD[layer].lowDelayHrdFlag;                       }
-
-  void    setCpbCntMinus1( int layer, uint32_t value )                                   { m_HRD[layer].cpbCntMinus1 = value;                         }
-  uint32_t    getCpbCntMinus1( int layer ) const                                         { return m_HRD[layer].cpbCntMinus1;                          }
-
-  void    setBitRateValueMinus1( int layer, int cpbcnt, int nalOrVcl, uint32_t value )   { m_HRD[layer].bitRateValueMinus1[cpbcnt][nalOrVcl] = value; }
-  uint32_t    getBitRateValueMinus1( int layer, int cpbcnt, int nalOrVcl ) const         { return m_HRD[layer].bitRateValueMinus1[cpbcnt][nalOrVcl];  }
-
-  void    setCpbSizeValueMinus1( int layer, int cpbcnt, int nalOrVcl, uint32_t value )   { m_HRD[layer].cpbSizeValue[cpbcnt][nalOrVcl] = value;       }
-  uint32_t    getCpbSizeValueMinus1( int layer, int cpbcnt, int nalOrVcl ) const         { return m_HRD[layer].cpbSizeValue[cpbcnt][nalOrVcl];        }
-  void    setDuCpbSizeValueMinus1( int layer, int cpbcnt, int nalOrVcl, uint32_t value ) { m_HRD[layer].ducpbSizeValue[cpbcnt][nalOrVcl] = value;     }
-  uint32_t    getDuCpbSizeValueMinus1( int layer, int cpbcnt, int nalOrVcl ) const       { return m_HRD[layer].ducpbSizeValue[cpbcnt][nalOrVcl];      }
-  void    setDuBitRateValueMinus1( int layer, int cpbcnt, int nalOrVcl, uint32_t value ) { m_HRD[layer].duBitRateValue[cpbcnt][nalOrVcl] = value;     }
-  uint32_t    getDuBitRateValueMinus1(int layer, int cpbcnt, int nalOrVcl ) const        { return m_HRD[layer].duBitRateValue[cpbcnt][nalOrVcl];      }
-  void    setCbrFlag( int layer, int cpbcnt, int nalOrVcl, bool value )              { m_HRD[layer].cbrFlag[cpbcnt][nalOrVcl] = value;            }
-  bool    getCbrFlag( int layer, int cpbcnt, int nalOrVcl ) const                    { return m_HRD[layer].cbrFlag[cpbcnt][nalOrVcl];             }
-
-  bool    getCpbDpbDelaysPresentFlag( ) const                      { return getNalHrdParametersPresentFlag() || getVclHrdParametersPresentFlag(); }
-};
-
-class TimingInfo
-{
-  bool m_timingInfoPresentFlag;
-  uint32_t m_numUnitsInTick;
-  uint32_t m_timeScale;
-  bool m_pocProportionalToTimingFlag;
-  int  m_numTicksPocDiffOneMinus1;
-public:
-  TimingInfo()
-  : m_timingInfoPresentFlag      (false)
-  , m_numUnitsInTick             (1001)
-  , m_timeScale                  (60000)
-  , m_pocProportionalToTimingFlag(false)
-  , m_numTicksPocDiffOneMinus1   (0)
-  {}
-
-  void setTimingInfoPresentFlag( bool flag )   { m_timingInfoPresentFlag = flag;       }
-  bool getTimingInfoPresentFlag( ) const       { return m_timingInfoPresentFlag;       }
-
-  void setNumUnitsInTick( uint32_t value )         { m_numUnitsInTick = value;             }
-  uint32_t getNumUnitsInTick( ) const              { return m_numUnitsInTick;              }
-
-  void setTimeScale( uint32_t value )              { m_timeScale = value;                  }
-  uint32_t getTimeScale( ) const                   { return m_timeScale;                   }
-
-  void setPocProportionalToTimingFlag(bool x)  { m_pocProportionalToTimingFlag = x;    }
-  bool getPocProportionalToTimingFlag( ) const { return m_pocProportionalToTimingFlag; }
-
-  void setNumTicksPocDiffOneMinus1(int x)      { m_numTicksPocDiffOneMinus1 = x;       }
-  int  getNumTicksPocDiffOneMinus1( ) const    { return m_numTicksPocDiffOneMinus1;    }
-};
-
 struct ChromaQpAdj
 {
   union
@@ -648,7 +499,7 @@ private:
 
   uint32_t                  m_numHrdParameters;
   uint32_t                  m_maxNuhReservedZeroLayerId;
-  std::vector<HRD>      m_hrdParameters;
+  std::vector<HRDParameters> m_hrdParameters;
   std::vector<uint32_t>     m_hrdOpSetIdx;
   std::vector<bool>     m_cprmsPresentFlag;
   uint32_t                  m_numOpSets;
@@ -669,8 +520,8 @@ public:
     m_cprmsPresentFlag.resize(getNumHrdParameters());
   }
 
-  HRD*              getHrdParameters( uint32_t i )                           { return &m_hrdParameters[ i ];                                    }
-  const HRD*        getHrdParameters( uint32_t i ) const                     { return &m_hrdParameters[ i ];                                    }
+  HRDParameters*        getHrdParameters( uint32_t i )                           { return &m_hrdParameters[ i ];                                    }
+  const HRDParameters*  getHrdParameters( uint32_t i ) const                     { return &m_hrdParameters[ i ];                                    }
   uint32_t              getHrdOpSetIdx( uint32_t i ) const                       { return m_hrdOpSetIdx[ i ];                                       }
   void              setHrdOpSetIdx( uint32_t val, uint32_t i )                   { m_hrdOpSetIdx[ i ] = val;                                        }
   bool              getCprmsPresentFlag( uint32_t i ) const                  { return m_cprmsPresentFlag[ i ];                                  }
@@ -786,8 +637,8 @@ private:
   int        m_maxBitsPerMinCuDenom;
   int        m_log2MaxMvLengthHorizontal;
   int        m_log2MaxMvLengthVertical;
-  HRD    m_hrdParameters;
-  TimingInfo m_timingInfo;
+  HRDParameters m_hrdParameters;
+  TimingInfo    m_timingInfo;
 
 public:
   VUI()
@@ -915,8 +766,8 @@ public:
   int               getLog2MaxMvLengthVertical() const                     { return m_log2MaxMvLengthVertical;              }
   void              setLog2MaxMvLengthVertical(int i)                      { m_log2MaxMvLengthVertical = i;                 }
 
-  HRD*              getHrdParameters()                                     { return &m_hrdParameters;                       }
-  const HRD*        getHrdParameters()  const                              { return &m_hrdParameters;                       }
+  HRDParameters*       getHrdParameters()                                  { return &m_hrdParameters;                       }
+  const HRDParameters* getHrdParameters()  const                           { return &m_hrdParameters;                       }
 
   TimingInfo*       getTimingInfo()                                        { return &m_timingInfo;                          }
   const TimingInfo* getTimingInfo() const                                  { return &m_timingInfo;                          }
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index 377045344..5011f9d48 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -498,7 +498,7 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
   uint32_t code;
 
   const VUI *pVUI = sps->getVuiParameters();
-  const HRD *pHRD = pVUI->getHrdParameters();
+  const HRDParameters *pHRD = pVUI->getHrdParameters();
 
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
 
@@ -548,7 +548,7 @@ void SEIReader::xParseSEIPictureTiming(SEIPictureTiming& sei, uint32_t payloadSi
   uint32_t code;
 
   const VUI *vui = sps->getVuiParameters();
-  const HRD *hrd = vui->getHrdParameters();
+  const HRDParameters *hrd = vui->getHrdParameters();
   output_sei_message_header(sei, pDecodedMessageOutputStream, payloadSize);
 
   if( vui->getFrameFieldInfoPresentFlag() )
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 195f1eb90..b3f5b9488 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -805,7 +805,7 @@ void  HLSyntaxReader::parseVUI(VUI* pcVUI, SPS *pcSPS)
   }
 }
 
-void HLSyntaxReader::parseHrdParameters(HRD *hrd, bool commonInfPresentFlag, uint32_t maxNumSubLayersMinus1)
+void HLSyntaxReader::parseHrdParameters(HRDParameters *hrd, bool commonInfPresentFlag, uint32_t maxNumSubLayersMinus1)
 {
   uint32_t  uiCode;
   if( commonInfPresentFlag )
diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h
index cb4908840..6f0261a78 100644
--- a/source/Lib/DecoderLib/VLCReader.h
+++ b/source/Lib/DecoderLib/VLCReader.h
@@ -161,7 +161,7 @@ public:
   void  parseConstraintInfo   (ConstraintInfo *cinfo);
   void  parseProfileTierLevel ( ProfileTierLevel *ptl, int maxNumSubLayersMinus1);
 #endif
-  void  parseHrdParameters  ( HRD *hrd, bool cprms_present_flag, uint32_t tempLevelHigh );
+  void  parseHrdParameters  ( HRDParameters *hrd, bool cprms_present_flag, uint32_t tempLevelHigh );
   void  parseSliceHeader    ( Slice* pcSlice, ParameterSetManager *parameterSetManager, const int prevTid0POC );
   void  parseTerminatingBit ( uint32_t& ruiBit );
   void  parseRemainingBytes ( bool noTrailingBytesExpected );
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 75c65ee8c..2d8d6fe63 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -416,7 +416,7 @@ void EncGOP::xWriteTrailingSEIMessages (SEIMessages& seiMessages, AccessUnit &ac
 
 void EncGOP::xWriteDuSEIMessages (SEIMessages& duInfoSeiMessages, AccessUnit &accessUnit, int temporalId, const SPS *sps, std::deque<DUData> &duData)
 {
-  const HRD *hrd = sps->getVuiParameters()->getHrdParameters();
+  const HRDParameters *hrd = sps->getVuiParameters()->getHrdParameters();
 
   if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
   {
@@ -635,7 +635,7 @@ void EncGOP::xCreateScalableNestingSEI (SEIMessages& seiMessages, SEIMessages& n
 void EncGOP::xCreatePictureTimingSEI  (int IRAPGOPid, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, SEIMessages& duInfoSeiMessages, Slice *slice, bool isField, std::deque<DUData> &duData)
 {
   const VUI *vui = slice->getSPS()->getVuiParameters();
-  const HRD *hrd = vui->getHrdParameters();
+  const HRDParameters *hrd = vui->getHrdParameters();
 
   // update decoding unit parameters
   if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
@@ -814,7 +814,7 @@ void EncGOP::xUpdateTimingSEI(SEIPictureTiming *pictureTimingSEI, std::deque<DUD
     return;
   }
   const VUI *vui = sps->getVuiParameters();
-  const HRD *hrd = vui->getHrdParameters();
+  const HRDParameters *hrd = vui->getHrdParameters();
   if( hrd->getSubPicCpbParamsPresentFlag() )
   {
     int i;
diff --git a/source/Lib/EncoderLib/EncHRD.cpp b/source/Lib/EncoderLib/EncHRD.cpp
new file mode 100644
index 000000000..60c135a88
--- /dev/null
+++ b/source/Lib/EncoderLib/EncHRD.cpp
@@ -0,0 +1,209 @@
+/* The copyright in this software is being made available under the BSD
+* License, included below. This software may be subject to other third party
+* and contributor rights, including patent rights, and no such rights are
+* granted under this license.
+*
+* Copyright (c) 2010-2019, ITU/ISO/IEC
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+*  * Redistributions of source code must retain the above copyright notice,
+*    this list of conditions and the following disclaimer.
+*  * Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+*    be used to endorse or promote products derived from this software without
+*    specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "EncHRD.h"
+
+#if U0132_TARGET_BITS_SATURATION
+
+// calculate scale value of bitrate and initial delay
+int EncHRD::xCalcScale(int x)
+{
+  if (x==0)
+  {
+    return 0;
+  }
+  uint32_t mask = 0xffffffff;
+  int scaleValue = 32;
+
+  while ((x&mask) != 0)
+  {
+    scaleValue--;
+    mask = (mask >> 1);
+  }
+
+  return scaleValue;
+}
+#endif
+
+void EncHRD::initHRDParameters (EncCfg* encCfg)
+{
+  bool useSubCpbParams = (encCfg->getSliceMode() > 0) || (encCfg->getSliceSegmentMode() > 0);
+  int  bitRate         = encCfg->getTargetBitrate();
+  bool isRandomAccess  = encCfg->getIntraPeriod() > 0;
+# 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( !encCfg->getVuiParametersPresentFlag() && !encCfg->getCpbSaturationEnabled() )
+#else
+  if( !encCfg.getVuiParametersPresentFlag() )
+#endif
+  {
+    return;
+  }
+
+  m_timingInfo.setTimingInfoPresentFlag( true );
+  switch( encCfg->getFrameRate() )
+  {
+  case 24:
+    m_timingInfo.setNumUnitsInTick( 1125000 );    m_timingInfo.setTimeScale    ( 27000000 );
+    break;
+  case 25:
+    m_timingInfo.setNumUnitsInTick( 1080000 );    m_timingInfo.setTimeScale    ( 27000000 );
+    break;
+  case 30:
+    m_timingInfo.setNumUnitsInTick( 900900 );     m_timingInfo.setTimeScale    ( 27000000 );
+    break;
+  case 50:
+    m_timingInfo.setNumUnitsInTick( 540000 );     m_timingInfo.setTimeScale    ( 27000000 );
+    break;
+  case 60:
+    m_timingInfo.setNumUnitsInTick( 450450 );     m_timingInfo.setTimeScale    ( 27000000 );
+    break;
+  default:
+    m_timingInfo.setNumUnitsInTick( 1001 );       m_timingInfo.setTimeScale    ( 60000 );
+    break;
+  }
+
+  if (encCfg->getTemporalSubsampleRatio()>1)
+  {
+    uint32_t temporalSubsampleRatio = encCfg->getTemporalSubsampleRatio();
+    if ( double(m_timingInfo.getNumUnitsInTick()) * temporalSubsampleRatio > std::numeric_limits<uint32_t>::max() )
+    {
+      m_timingInfo.setTimeScale( m_timingInfo.getTimeScale() / temporalSubsampleRatio );
+    }
+    else
+    {
+      m_timingInfo.setNumUnitsInTick( m_timingInfo.getNumUnitsInTick() * temporalSubsampleRatio );
+    }
+  }
+
+  bool rateCnt = ( bitRate > 0 );
+  m_hrdParams.setNalHrdParametersPresentFlag( rateCnt );
+  m_hrdParams.setVclHrdParametersPresentFlag( rateCnt );
+  m_hrdParams.setSubPicCpbParamsPresentFlag( useSubCpbParams );
+
+  if( m_hrdParams.getSubPicCpbParamsPresentFlag() )
+  {
+    m_hrdParams.setTickDivisorMinus2( 100 - 2 );                          //
+    m_hrdParams.setDuCpbRemovalDelayLengthMinus1( 7 );                    // 8-bit precision ( plus 1 for last DU in AU )
+    m_hrdParams.setSubPicCpbParamsInPicTimingSEIFlag( true );
+    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
+  }
+  else
+  {
+    m_hrdParams.setSubPicCpbParamsInPicTimingSEIFlag( false );
+  }
+
+#if U0132_TARGET_BITS_SATURATION
+  if (xCalcScale(bitRate) <= 6)
+  {
+    m_hrdParams.setBitRateScale(0);
+  }
+  else
+  {
+    m_hrdParams.setBitRateScale(xCalcScale(bitRate) - 6);
+  }
+
+  if (xCalcScale(cpbSize) <= 4)
+  {
+    m_hrdParams.setCpbSizeScale(0);
+  }
+  else
+  {
+    m_hrdParams.setCpbSizeScale(xCalcScale(cpbSize) - 4);
+  }
+#else
+  m_hrdParams.setBitRateScale( 4 );                                       // in units of 2^( 6 + 4 ) = 1,024 bps
+  m_hrdParams.setCpbSizeScale( 6 );                                       // in units of 2^( 4 + 6 ) = 1,024 bit
+#endif
+
+  m_hrdParams.setDuCpbSizeScale( 6 );                                     // in units of 2^( 4 + 6 ) = 1,024 bit
+
+  m_hrdParams.setInitialCpbRemovalDelayLengthMinus1(15);                  // assuming 0.5 sec, log2( 90,000 * 0.5 ) = 16-bit
+  if( isRandomAccess )
+  {
+    m_hrdParams.setCpbRemovalDelayLengthMinus1(5);                        // 32 = 2^5 (plus 1)
+    m_hrdParams.setDpbOutputDelayLengthMinus1 (5);                        // 32 + 3 = 2^6
+  }
+  else
+  {
+    m_hrdParams.setCpbRemovalDelayLengthMinus1(9);                        // max. 2^10
+    m_hrdParams.setDpbOutputDelayLengthMinus1 (9);                        // max. 2^10
+  }
+
+  // Note: parameters for all temporal layers are initialized with the same values
+  int i, j;
+  uint32_t bitrateValue, cpbSizeValue;
+  uint32_t duCpbSizeValue;
+  uint32_t duBitRateValue = 0;
+
+  for( i = 0; i < MAX_TLAYER; i ++ )
+  {
+    m_hrdParams.setFixedPicRateFlag( i, 1 );
+    m_hrdParams.setPicDurationInTcMinus1( i, 0 );
+    m_hrdParams.setLowDelayHrdFlag( i, 0 );
+    m_hrdParams.setCpbCntMinus1( i, 0 );
+
+    //! \todo check for possible PTL violations
+    // BitRate[ i ] = ( bit_rate_value_minus1[ i ] + 1 ) * 2^( 6 + bit_rate_scale )
+    bitrateValue = bitRate / (1 << (6 + m_hrdParams.getBitRateScale()) );      // bitRate is in bits, so it needs to be scaled down
+                                                                        // CpbSize[ i ] = ( cpb_size_value_minus1[ i ] + 1 ) * 2^( 4 + cpb_size_scale )
+#if U0132_TARGET_BITS_SATURATION
+    cpbSizeValue = cpbSize / (1 << (4 + m_hrdParams.getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
+#else
+    cpbSizeValue = bitRate / (1 << (4 + m_hrdParams.getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
+#endif
+
+
+                                                                        // DU CPB size could be smaller (i.e. bitrateValue / number of DUs), but we don't know
+                                                                        // in how many DUs the slice segment settings will result
+    duCpbSizeValue = bitrateValue;
+    duBitRateValue = cpbSizeValue;
+
+    for( j = 0; j < ( m_hrdParams.getCpbCntMinus1( i ) + 1 ); j ++ )
+    {
+      m_hrdParams.setBitRateValueMinus1( i, j, 0, ( bitrateValue - 1 ) );
+      m_hrdParams.setCpbSizeValueMinus1( i, j, 0, ( cpbSizeValue - 1 ) );
+      m_hrdParams.setDuCpbSizeValueMinus1( i, j, 0, ( duCpbSizeValue - 1 ) );
+      m_hrdParams.setDuBitRateValueMinus1( i, j, 0, ( duBitRateValue - 1 ) );
+      m_hrdParams.setCbrFlag( i, j, 0, false );
+
+      m_hrdParams.setBitRateValueMinus1( i, j, 1, ( bitrateValue - 1) );
+      m_hrdParams.setCpbSizeValueMinus1( i, j, 1, ( cpbSizeValue - 1 ) );
+      m_hrdParams.setDuCpbSizeValueMinus1( i, j, 1, ( duCpbSizeValue - 1 ) );
+      m_hrdParams.setDuBitRateValueMinus1( i, j, 1, ( duBitRateValue - 1 ) );
+      m_hrdParams.setCbrFlag( i, j, 1, false );
+    }
+  }
+}
+
diff --git a/source/Lib/EncoderLib/EncHRD.h b/source/Lib/EncoderLib/EncHRD.h
new file mode 100644
index 000000000..b22ac2287
--- /dev/null
+++ b/source/Lib/EncoderLib/EncHRD.h
@@ -0,0 +1,55 @@
+/* The copyright in this software is being made available under the BSD
+* License, included below. This software may be subject to other third party
+* and contributor rights, including patent rights, and no such rights are
+* granted under this license.
+*
+* Copyright (c) 2010-2019, ITU/ISO/IEC
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+*  * Redistributions of source code must retain the above copyright notice,
+*    this list of conditions and the following disclaimer.
+*  * Redistributions in binary form must reproduce the above copyright notice,
+*    this list of conditions and the following disclaimer in the documentation
+*    and/or other materials provided with the distribution.
+*  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
+*    be used to endorse or promote products derived from this software without
+*    specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __ENCHRD__
+#define __ENCHRD__
+
+#include "Common.h"
+#include "HRD.h"
+#include "Slice.h"
+#include "EncCfg.h"
+
+class EncHRD:public HRD
+{
+public:
+  void initHRDParameters (EncCfg* encCfg);
+
+protected:
+  // calculate scale value of bitrate and initial delay
+  int xCalcScale(int x);
+
+};
+
+
+#endif // __ENCHRD__
\ No newline at end of file
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 4512f3669..7d0dd1cd6 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -1143,180 +1143,17 @@ void EncLib::xInitSPS(SPS &sps)
   sps.getSpsRangeExtension().setCabacBypassAlignmentEnabledFlag(m_cabacBypassAlignmentEnabledFlag);
 }
 
-#if U0132_TARGET_BITS_SATURATION
-// calculate scale value of bitrate and initial delay
-int calcScale(int x)
-{
-  if (x==0)
-  {
-    return 0;
-  }
-  uint32_t iMask = 0xffffffff;
-  int ScaleValue = 32;
-
-  while ((x&iMask) != 0)
-  {
-    ScaleValue--;
-    iMask = (iMask >> 1);
-  }
-
-  return ScaleValue;
-}
-#endif
 void EncLib::xInitHrdParameters(SPS &sps)
 {
-  bool useSubCpbParams = (getSliceMode() > 0) || (getSliceSegmentMode() > 0);
-  int  bitRate         = getTargetBitrate();
-  bool isRandomAccess  = getIntraPeriod() > 0;
-# if U0132_TARGET_BITS_SATURATION
-  int cpbSize          = 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( !getVuiParametersPresentFlag() && !getCpbSaturationEnabled() )
-#else
-  if( !getVuiParametersPresentFlag() )
-#endif
-  {
-    return;
-  }
-
+  m_encHRD.initHRDParameters((EncCfg*) this);
+  
   VUI *vui = sps.getVuiParameters();
-  HRD *hrd = vui->getHrdParameters();
+  
+  HRDParameters *hrdParams = vui->getHrdParameters();
+  *hrdParams = m_encHRD.getHRDParameters();
 
   TimingInfo *timingInfo = vui->getTimingInfo();
-  timingInfo->setTimingInfoPresentFlag( true );
-  switch( getFrameRate() )
-  {
-  case 24:
-    timingInfo->setNumUnitsInTick( 1125000 );    timingInfo->setTimeScale    ( 27000000 );
-    break;
-  case 25:
-    timingInfo->setNumUnitsInTick( 1080000 );    timingInfo->setTimeScale    ( 27000000 );
-    break;
-  case 30:
-    timingInfo->setNumUnitsInTick( 900900 );     timingInfo->setTimeScale    ( 27000000 );
-    break;
-  case 50:
-    timingInfo->setNumUnitsInTick( 540000 );     timingInfo->setTimeScale    ( 27000000 );
-    break;
-  case 60:
-    timingInfo->setNumUnitsInTick( 450450 );     timingInfo->setTimeScale    ( 27000000 );
-    break;
-  default:
-    timingInfo->setNumUnitsInTick( 1001 );       timingInfo->setTimeScale    ( 60000 );
-    break;
-  }
-
-  if (getTemporalSubsampleRatio()>1)
-  {
-    uint32_t temporalSubsampleRatio = getTemporalSubsampleRatio();
-    if ( double(timingInfo->getNumUnitsInTick()) * temporalSubsampleRatio > std::numeric_limits<uint32_t>::max() )
-    {
-      timingInfo->setTimeScale( timingInfo->getTimeScale() / temporalSubsampleRatio );
-    }
-    else
-    {
-      timingInfo->setNumUnitsInTick( timingInfo->getNumUnitsInTick() * temporalSubsampleRatio );
-    }
-  }
-
-  bool rateCnt = ( bitRate > 0 );
-  hrd->setNalHrdParametersPresentFlag( rateCnt );
-  hrd->setVclHrdParametersPresentFlag( rateCnt );
-  hrd->setSubPicCpbParamsPresentFlag( useSubCpbParams );
-
-  if( hrd->getSubPicCpbParamsPresentFlag() )
-  {
-    hrd->setTickDivisorMinus2( 100 - 2 );                          //
-    hrd->setDuCpbRemovalDelayLengthMinus1( 7 );                    // 8-bit precision ( plus 1 for last DU in AU )
-    hrd->setSubPicCpbParamsInPicTimingSEIFlag( true );
-    hrd->setDpbOutputDelayDuLengthMinus1( 5 + 7 );                 // With sub-clock tick factor of 100, at least 7 bits to have the same value as AU dpb delay
-  }
-  else
-  {
-    hrd->setSubPicCpbParamsInPicTimingSEIFlag( false );
-  }
-
-#if U0132_TARGET_BITS_SATURATION
-  if (calcScale(bitRate) <= 6)
-  {
-    hrd->setBitRateScale(0);
-  }
-  else
-  {
-    hrd->setBitRateScale(calcScale(bitRate) - 6);
-  }
-
-  if (calcScale(cpbSize) <= 4)
-  {
-    hrd->setCpbSizeScale(0);
-  }
-  else
-  {
-    hrd->setCpbSizeScale(calcScale(cpbSize) - 4);
-  }
-#else
-  hrd->setBitRateScale( 4 );                                       // in units of 2^( 6 + 4 ) = 1,024 bps
-  hrd->setCpbSizeScale( 6 );                                       // in units of 2^( 4 + 6 ) = 1,024 bit
-#endif
-
-  hrd->setDuCpbSizeScale( 6 );                                     // in units of 2^( 4 + 6 ) = 1,024 bit
-
-  hrd->setInitialCpbRemovalDelayLengthMinus1(15);                  // assuming 0.5 sec, log2( 90,000 * 0.5 ) = 16-bit
-  if( isRandomAccess )
-  {
-    hrd->setCpbRemovalDelayLengthMinus1(5);                        // 32 = 2^5 (plus 1)
-    hrd->setDpbOutputDelayLengthMinus1 (5);                        // 32 + 3 = 2^6
-  }
-  else
-  {
-    hrd->setCpbRemovalDelayLengthMinus1(9);                        // max. 2^10
-    hrd->setDpbOutputDelayLengthMinus1 (9);                        // max. 2^10
-  }
-
-  // Note: parameters for all temporal layers are initialized with the same values
-  int i, j;
-  uint32_t bitrateValue, cpbSizeValue;
-  uint32_t duCpbSizeValue;
-  uint32_t duBitRateValue = 0;
-
-  for( i = 0; i < MAX_TLAYER; i ++ )
-  {
-    hrd->setFixedPicRateFlag( i, 1 );
-    hrd->setPicDurationInTcMinus1( i, 0 );
-    hrd->setLowDelayHrdFlag( i, 0 );
-    hrd->setCpbCntMinus1( i, 0 );
-
-    //! \todo check for possible PTL violations
-    // BitRate[ i ] = ( bit_rate_value_minus1[ i ] + 1 ) * 2^( 6 + bit_rate_scale )
-    bitrateValue = bitRate / (1 << (6 + hrd->getBitRateScale()) );      // bitRate is in bits, so it needs to be scaled down
-    // CpbSize[ i ] = ( cpb_size_value_minus1[ i ] + 1 ) * 2^( 4 + cpb_size_scale )
-#if U0132_TARGET_BITS_SATURATION
-    cpbSizeValue = cpbSize / (1 << (4 + hrd->getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
-#else
-    cpbSizeValue = bitRate / (1 << (4 + hrd->getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
-#endif
-
-
-    // DU CPB size could be smaller (i.e. bitrateValue / number of DUs), but we don't know
-    // in how many DUs the slice segment settings will result
-    duCpbSizeValue = bitrateValue;
-    duBitRateValue = cpbSizeValue;
-
-    for( j = 0; j < ( hrd->getCpbCntMinus1( i ) + 1 ); j ++ )
-    {
-      hrd->setBitRateValueMinus1( i, j, 0, ( bitrateValue - 1 ) );
-      hrd->setCpbSizeValueMinus1( i, j, 0, ( cpbSizeValue - 1 ) );
-      hrd->setDuCpbSizeValueMinus1( i, j, 0, ( duCpbSizeValue - 1 ) );
-      hrd->setDuBitRateValueMinus1( i, j, 0, ( duBitRateValue - 1 ) );
-      hrd->setCbrFlag( i, j, 0, false );
-
-      hrd->setBitRateValueMinus1( i, j, 1, ( bitrateValue - 1) );
-      hrd->setCpbSizeValueMinus1( i, j, 1, ( cpbSizeValue - 1 ) );
-      hrd->setDuCpbSizeValueMinus1( i, j, 1, ( duCpbSizeValue - 1 ) );
-      hrd->setDuBitRateValueMinus1( i, j, 1, ( duBitRateValue - 1 ) );
-      hrd->setCbrFlag( i, j, 1, false );
-    }
-  }
+  *timingInfo = m_encHRD.getTimingInfo();
 }
 
 void EncLib::xInitPPS(PPS &pps, const SPS &sps)
diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h
index cfca5a744..a31de975f 100644
--- a/source/Lib/EncoderLib/EncLib.h
+++ b/source/Lib/EncoderLib/EncLib.h
@@ -48,6 +48,7 @@
 #include "EncCfg.h"
 #include "EncGOP.h"
 #include "EncSlice.h"
+#include "EncHRD.h"
 #include "VLCWriter.h"
 #include "CABACWriter.h"
 #include "InterSearch.h"
@@ -57,7 +58,6 @@
 #include "EncAdaptiveLoopFilter.h"
 #include "RateCtrl.h"
 
-
 //! \ingroup EncoderLib
 //! \{
 
@@ -142,6 +142,8 @@ private:
   APS*                      m_apss[MAX_NUM_APS];
 #endif
 
+  EncHRD                    m_encHRD;
+
 public:
   Ctx                       m_entropyCodingSyncContextState;      ///< leave in addition to vector for compatibility
 #if ENABLE_WPP_PARALLELISM
@@ -160,7 +162,7 @@ protected:
   void  xInitScalingLists (SPS &sps, PPS &pps);   ///< initialize scaling lists
 #endif
   void  xInitPPSforLT(PPS& pps);
-  void  xInitHrdParameters(SPS &sps);                 ///< initialize HRD parameters
+  void  xInitHrdParameters(SPS &sps);                 ///< initialize HRDParameters parameters
 
   void  xInitPPSforTiles  (PPS &pps);
   void  xInitRPS          (SPS &sps, bool isFieldCoding);           ///< initialize PPS from encoder options
diff --git a/source/Lib/EncoderLib/RateCtrl.cpp b/source/Lib/EncoderLib/RateCtrl.cpp
index da6c26d84..9d8a07456 100644
--- a/source/Lib/EncoderLib/RateCtrl.cpp
+++ b/source/Lib/EncoderLib/RateCtrl.cpp
@@ -1822,7 +1822,7 @@ int  RateCtrl::updateCpbState(int actualBits)
   return cpbState;
 }
 
-void RateCtrl::initHrdParam(const HRD* pcHrd, int iFrameRate, double fInitialCpbFullness)
+void RateCtrl::initHrdParam(const HRDParameters* pcHrd, int iFrameRate, double fInitialCpbFullness)
 {
   m_CpbSaturationEnabled = true;
   m_cpbSize = (pcHrd->getCpbSizeValueMinus1(0, 0, 0) + 1) << (4 + pcHrd->getCpbSizeScale());
diff --git a/source/Lib/EncoderLib/RateCtrl.h b/source/Lib/EncoderLib/RateCtrl.h
index 09e84409f..6500c7cc3 100644
--- a/source/Lib/EncoderLib/RateCtrl.h
+++ b/source/Lib/EncoderLib/RateCtrl.h
@@ -347,7 +347,7 @@ public:
   uint32_t       getCpbSize()               { return m_cpbSize;        }
   uint32_t       getBufferingRate()         { return m_bufferingRate;  }
   int        updateCpbState(int actualBits);
-  void       initHrdParam(const HRD* pcHrd, int iFrameRate, double fInitialCpbFullness);
+  void       initHrdParam(const HRDParameters* pcHrd, int iFrameRate, double fInitialCpbFullness);
 #endif
 
 private:
diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp
index cc4e16ce4..b0ac87ffa 100644
--- a/source/Lib/EncoderLib/SEIEncoder.cpp
+++ b/source/Lib/EncoderLib/SEIEncoder.cpp
@@ -259,7 +259,7 @@ void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI,
   bufferingPeriodSEI->m_rapCpbParamsPresentFlag = 0;
   //for the concatenation, it can be set to one during splicing.
   bufferingPeriodSEI->m_concatenationFlag = 0;
-  //since the temporal layer HRD is not ready, we assumed it is fixed
+  //since the temporal layer HRDParameters is not ready, we assumed it is fixed
   bufferingPeriodSEI->m_auCpbRemovalDelayDelta = 1;
   bufferingPeriodSEI->m_cpbDelayOffset = 0;
   bufferingPeriodSEI->m_dpbDelayOffset = 0;
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index 7c449ce7f..4999e5754 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -263,7 +263,7 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP
 {
   int i, nalOrVcl;
   const VUI *vui = sps->getVuiParameters();
-  const HRD *hrd = vui->getHrdParameters();
+  const HRDParameters *hrd = vui->getHrdParameters();
 
   WRITE_UVLC( sei.m_bpSeqParameterSetId, "bp_seq_parameter_set_id" );
   if( !hrd->getSubPicCpbParamsPresentFlag() )
@@ -299,7 +299,7 @@ void SEIWriter::xWriteSEIPictureTiming(const SEIPictureTiming& sei, const SPS *s
 {
   int i;
   const VUI *vui = sps->getVuiParameters();
-  const HRD *hrd = vui->getHrdParameters();
+  const HRDParameters *hrd = vui->getHrdParameters();
 
   if( vui->getFrameFieldInfoPresentFlag() )
   {
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 82dd1c93f..21d9d367c 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -529,7 +529,7 @@ void HLSWriter::codeVUI( const VUI *pcVUI, const SPS* pcSPS )
   }
 }
 
-void HLSWriter::codeHrdParameters( const HRD *hrd, bool commonInfPresentFlag, uint32_t maxNumSubLayersMinus1 )
+void HLSWriter::codeHrdParameters( const HRDParameters *hrd, bool commonInfPresentFlag, uint32_t maxNumSubLayersMinus1 )
 {
   if( commonInfPresentFlag )
   {
diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h
index 468212280..5ecc4d08a 100644
--- a/source/Lib/EncoderLib/VLCWriter.h
+++ b/source/Lib/EncoderLib/VLCWriter.h
@@ -137,7 +137,7 @@ public:
   void  codeConstraintInfo      ( const ConstraintInfo* cinfo );
   void  codeProfileTierLevel    ( const ProfileTierLevel* ptl, int maxNumSubLayersMinus1 );
 #endif
-  void  codeHrdParameters       ( const HRD *hrd, bool commonInfPresentFlag, uint32_t maxNumSubLayersMinus1 );
+  void  codeHrdParameters       ( const HRDParameters *hrd, bool commonInfPresentFlag, uint32_t maxNumSubLayersMinus1 );
   void  codeTilesWPPEntryPoint  ( Slice* pSlice );
 #if HEVC_USE_SCALING_LISTS
   void  codeScalingList         ( const ScalingList &scalingList );
-- 
GitLab