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