/src/vvenc/source/Lib/EncoderLib/RateCtrl.h
Line | Count | Source |
1 | | /* ----------------------------------------------------------------------------- |
2 | | The copyright in this software is being made available under the Clear BSD |
3 | | License, included below. No patent rights, trademark rights and/or |
4 | | other Intellectual Property Rights other than the copyrights concerning |
5 | | the Software are granted under this license. |
6 | | |
7 | | The Clear BSD License |
8 | | |
9 | | Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors. |
10 | | All rights reserved. |
11 | | |
12 | | Redistribution and use in source and binary forms, with or without modification, |
13 | | are permitted (subject to the limitations in the disclaimer below) provided that |
14 | | the following conditions are met: |
15 | | |
16 | | * Redistributions of source code must retain the above copyright notice, |
17 | | this list of conditions and the following disclaimer. |
18 | | |
19 | | * Redistributions in binary form must reproduce the above copyright |
20 | | notice, this list of conditions and the following disclaimer in the |
21 | | documentation and/or other materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the copyright holder nor the names of its |
24 | | contributors may be used to endorse or promote products derived from this |
25 | | software without specific prior written permission. |
26 | | |
27 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY |
28 | | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
29 | | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
31 | | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
32 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
33 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
34 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
35 | | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
36 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
37 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | | POSSIBILITY OF SUCH DAMAGE. |
39 | | |
40 | | |
41 | | ------------------------------------------------------------------------------------------- */ |
42 | | /** \file RateCtrl.h |
43 | | \brief Rate control manager class |
44 | | */ |
45 | | |
46 | | #ifndef __ENCRATECTRL__ |
47 | | #define __ENCRATECTRL__ |
48 | | |
49 | | #pragma once |
50 | | |
51 | | #include "CommonLib/CommonDef.h" |
52 | | #include "Utilities/MsgLog.h" |
53 | | |
54 | | #include "vvenc/vvencCfg.h" |
55 | | |
56 | | #include <vector> |
57 | | #include <algorithm> |
58 | | #include <list> |
59 | | #include <fstream> |
60 | | |
61 | | namespace vvenc { |
62 | | struct Picture; |
63 | | |
64 | | struct TRCPassStats |
65 | | { |
66 | | TRCPassStats( const int _poc, const int _qp, const double _lambda, const uint16_t _visActY, |
67 | | const uint32_t _numBits, const double _psnrY, const bool _isIntra, const int _tempLayer, |
68 | | const bool _isStartOfIntra, const bool _isStartOfGop, const int _gopNum, const SceneType _scType, |
69 | | int _spVisAct, const uint16_t _motionEstError, const uint8_t _minNoiseLevels[ QPA_MAX_NOISE_LEVELS ] ) : |
70 | 0 | poc( _poc ), qp( _qp ), lambda( _lambda ), visActY( _visActY ), |
71 | 0 | numBits( _numBits ), psnrY( _psnrY ), isIntra( _isIntra ), tempLayer( _tempLayer ), |
72 | 0 | isStartOfIntra( _isStartOfIntra ), isStartOfGop( _isStartOfGop ), gopNum( _gopNum ), scType( _scType ), |
73 | 0 | spVisAct(_spVisAct), motionEstError( _motionEstError ), |
74 | 0 | isNewScene( false ), refreshParameters( false ), frameInGopRatio( -1.0 ), targetBits( 0 ), addedToList( false ) |
75 | 0 | { |
76 | 0 | std::memcpy( minNoiseLevels, _minNoiseLevels, sizeof( minNoiseLevels ) ); |
77 | 0 | } |
78 | 0 | TRCPassStats() {}; |
79 | | int poc { 0 }; |
80 | | int qp { 0 }; |
81 | | double lambda { 0.0 }; |
82 | | uint16_t visActY { 0 }; |
83 | | uint32_t numBits { 0 }; |
84 | | double psnrY { 0.0 }; |
85 | | bool isIntra { false }; |
86 | | int tempLayer { 0 }; |
87 | | bool isStartOfIntra { false }; |
88 | | bool isStartOfGop { false }; |
89 | | int gopNum { 0 }; |
90 | | SceneType scType { SCT_NONE }; |
91 | | int spVisAct { 0 }; |
92 | | uint16_t motionEstError { 0 }; |
93 | | uint8_t minNoiseLevels[ QPA_MAX_NOISE_LEVELS ] {}; |
94 | | bool isNewScene { false }; |
95 | | bool refreshParameters { false }; |
96 | | double frameInGopRatio { 0.0 }; |
97 | | int targetBits { 0 }; |
98 | | bool addedToList { false }; |
99 | | }; |
100 | | |
101 | | class EncRCSeq |
102 | | { |
103 | | public: |
104 | | EncRCSeq(); |
105 | | ~EncRCSeq(); |
106 | | |
107 | | void create( bool twoPassRC, bool lookAhead, int targetBitrate, int maxBitrate, double frRate, int intraPer, int GOPSize, int bitDpth, std::list<TRCPassStats> &firstPassStats ); |
108 | | void destroy(); |
109 | | void updateAfterPic (const int actBits, const int tgtBits); |
110 | | |
111 | | bool twoPass; |
112 | | bool isLookAhead; |
113 | | bool isIntraGOP; |
114 | | bool isRateSavingMode; |
115 | | double frameRate; |
116 | | int targetRate; |
117 | | int maxGopRate; |
118 | | int gopSize; |
119 | | unsigned intraPeriod; |
120 | | bool scRelax; |
121 | | int bitDepth; |
122 | | int64_t bitsUsed; |
123 | | int64_t bitsUsedQPLimDiff; |
124 | | int64_t estimatedBitUsage; |
125 | | double rateBoostFac; |
126 | | double qpCorrection[8]; |
127 | | uint64_t actualBitCnt[8]; |
128 | | uint64_t targetBitCnt[8]; |
129 | | int lastAverageQP; |
130 | | int lastIntraQP; |
131 | | double lastIntraSM; // temporal stationarity measure; 1: highly stationary (static), 0: highly nonstationary (irregular) |
132 | | std::list<TRCPassStats> firstPassData; |
133 | | double minEstLambda; |
134 | | double maxEstLambda; |
135 | | }; |
136 | | |
137 | | class EncRCPic |
138 | | { |
139 | | public: |
140 | | EncRCPic(); |
141 | | ~EncRCPic(); |
142 | | |
143 | | void create( EncRCSeq* encRCSeq, int frameLevel, int framePoc ); |
144 | | void destroy(); |
145 | | void clipTargetQP (std::list<EncRCPic*>& listPreviousPictures, const int baseQP, const int refrIncrFac, const int maxTL, const double resRatio, int &qp, int* qpAvg); |
146 | | void updateAfterPicture (const int picActualBits, const int averageQP); |
147 | | void addToPictureList( std::list<EncRCPic*>& listPreviousPictures ); |
148 | | |
149 | | int targetBits; |
150 | | int tmpTargetBits; |
151 | | int poc; |
152 | | bool refreshParams; |
153 | | uint16_t visActSteady; |
154 | | |
155 | | protected: |
156 | | EncRCSeq* encRCSeq; |
157 | | int frameLevel; // non-I: TLayer + 1 |
158 | | int16_t picQP; // in integer form |
159 | | uint16_t picBits; // after 2nd pass |
160 | | }; |
161 | | |
162 | | class RateCtrl |
163 | | { |
164 | | public: |
165 | | RateCtrl(MsgLog& logger); |
166 | | ~RateCtrl(); |
167 | | |
168 | | void init( const VVEncCfg& encCfg ); |
169 | | void destroy(); |
170 | | int getBaseQP(); |
171 | | void setRCPass (const VVEncCfg& encCfg, const int pass, const char* statsFName); |
172 | | void addRCPassStats( const int poc, const int qp, const double lambda, const uint16_t visActY, |
173 | | const uint32_t numBits, const double psnrY, const bool isIntra, const uint32_t tempLayer, |
174 | | const bool isStartOfIntra, const bool isStartOfGop, const int gopNum, const SceneType scType, |
175 | | int spVisAct, const uint16_t motEstError, const uint8_t minNoiseLevels[QPA_MAX_NOISE_LEVELS] ); |
176 | | void setRCRateSavingState( const int maxRate ); |
177 | | void processFirstPassData( const bool flush, const int poc = -1 ); |
178 | | void updateAfterPicEncRC( const Picture* pic ); |
179 | | void initRateControlPic( Picture& pic, Slice* slice, int& qp, double& finalLambda ); |
180 | | |
181 | 0 | std::list<EncRCPic*>& getPicList() { return m_listRCPictures; } |
182 | 0 | std::list<TRCPassStats>& getFirstPassStats() { return m_listRCFirstPassStats; } |
183 | 0 | std::vector<uint8_t>* getIntraPQPAStats() { return &m_listRCIntraPQPAStats; } |
184 | 0 | const uint8_t* getMinNoiseLevels() { return m_minNoiseLevels; } |
185 | 0 | int lastPOCInCache() { CHECK(m_firstPassCache.empty(), "Accessing empty cache"); return m_firstPassCache.back().poc; } |
186 | | |
187 | | std::list<EncRCPic*> m_listRCPictures; |
188 | | EncRCSeq* encRCSeq; |
189 | | EncRCPic* encRCPic; |
190 | | int flushPOC; |
191 | | int rcPass; |
192 | | bool rcIsFinalPass; |
193 | | const VVEncCfg* m_pcEncCfg; |
194 | | |
195 | | protected: |
196 | | MsgLog& msg; |
197 | | |
198 | | void xProcessFirstPassData( const bool flush, const int poc ); |
199 | | void storeStatsData( TRCPassStats statsData ); |
200 | | double getAverageBitsFromFirstPass(); |
201 | | void detectSceneCuts(); |
202 | | void processGops(); |
203 | | void updateMotionErrStatsGop( const bool flush, const int poc ); |
204 | | double getLookAheadBoostFac ( const int thresholdDivisor ); |
205 | | double updateQPstartModelVal(); |
206 | | #ifdef VVENC_ENABLE_THIRDPARTY_JSON |
207 | | void openStatsFile( const std::string& name ); |
208 | | void writeStatsHeader(); |
209 | | void readStatsHeader(); |
210 | | void readStatsFile(); |
211 | | #endif |
212 | | void adjustStatsDownsample(); |
213 | | |
214 | | private: |
215 | | std::list<TRCPassStats> m_listRCFirstPassStats; |
216 | | std::list<TRCPassStats> m_firstPassCache; |
217 | | std::vector<uint8_t> m_listRCIntraPQPAStats; |
218 | | #ifdef VVENC_ENABLE_THIRDPARTY_JSON |
219 | | std::fstream m_rcStatsFHandle; |
220 | | int m_pqpaStatsWritten; |
221 | | #endif |
222 | | int m_numPicStatsTotal; |
223 | | int m_numPicAddedToList; |
224 | | int m_updateNoisePoc; |
225 | | bool m_resetNoise; |
226 | | uint8_t m_gopMEErrorCBufIdx; |
227 | | uint16_t m_maxPicMotionError; |
228 | | uint16_t m_gopMEErrorCBuf[ QPA_MAX_NOISE_LEVELS ]; |
229 | | uint8_t m_minNoiseLevels[ QPA_MAX_NOISE_LEVELS ]; |
230 | | TRCPassStats m_tempDownSamplStats[ VVENC_MAX_TLAYER + 1 ]; |
231 | | }; |
232 | | |
233 | | } |
234 | | #endif |