Newer
Older

Karsten Suehring
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* 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-2018, 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.
*/
/** \file RateCtrl.h
\brief Rate control manager class
*/
#ifndef __ENCRATECTRL__
#define __ENCRATECTRL__
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "../CommonLib/CommonDef.h"
#include <vector>
#include <algorithm>
using namespace std;
//! \ingroup EncoderLib
//! \{
#include "../EncoderLib/EncCfg.h"
#include <list>
const int g_RCInvalidQPValue = -999;
const int g_RCSmoothWindowSize = 40;
const int g_RCMaxPicListSize = 32;
const double g_RCWeightPicTargetBitInGOP = 0.9;
const double g_RCWeightPicRargetBitInBuffer = 1.0 - g_RCWeightPicTargetBitInGOP;
const int g_RCIterationNum = 20;
const double g_RCWeightHistoryLambda = 0.5;
const double g_RCWeightCurrentLambda = 1.0 - g_RCWeightHistoryLambda;
const int g_RCLCUSmoothWindowSize = 4;
const double g_RCAlphaMinValue = 0.05;
const double g_RCAlphaMaxValue = 500.0;
const double g_RCBetaMinValue = -3.0;
const double g_RCBetaMaxValue = -0.1;
#define ALPHA 6.7542;
#define BETA1 1.2517
#define BETA2 1.7860
struct TRCLCU
{
int m_actualBits;
int m_QP; // QP of skip mode is set to g_RCInvalidQPValue
int m_targetBits;
double m_lambda;
double m_bitWeight;
int m_numberOfPixel;
double m_costIntra;
int m_targetBitsLeft;
#if JVET_K0390_RATECTRL
double m_actualSSE;
double m_actualMSE;
#endif

Karsten Suehring
committed
};
struct TRCParameter
{
double m_alpha;
double m_beta;
#if JVET_K0390_RATECTRL
int m_validPix;
#endif

Karsten Suehring
committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
};
class EncRCSeq
{
public:
EncRCSeq();
~EncRCSeq();
public:
void create( int totalFrames, int targetBitrate, int frameRate, int GOPSize, int picWidth, int picHeight, int LCUWidth, int LCUHeight, int numberOfLevel, bool useLCUSeparateModel, int adaptiveBit );
void destroy();
void initBitsRatio( int bitsRatio[] );
void initGOPID2Level( int GOPID2Level[] );
void initPicPara( TRCParameter* picPara = NULL ); // NULL to initial with default value
void initLCUPara( TRCParameter** LCUPara = NULL ); // NULL to initial with default value
void updateAfterPic ( int bits );
void setAllBitRatio( double basicLambda, double* equaCoeffA, double* equaCoeffB );
public:
int getTotalFrames() { return m_totalFrames; }
int getTargetRate() { return m_targetRate; }
int getFrameRate() { return m_frameRate; }
int getGOPSize() { return m_GOPSize; }
int getPicWidth() { return m_picWidth; }
int getPicHeight() { return m_picHeight; }
int getLCUWidth() { return m_LCUWidth; }
int getLCUHeight() { return m_LCUHeight; }
int getNumberOfLevel() { return m_numberOfLevel; }
int getAverageBits() { return m_averageBits; }
int getLeftAverageBits() { CHECK(!( m_framesLeft > 0 ), "No frames left"); return (int)(m_bitsLeft / m_framesLeft); }
bool getUseLCUSeparateModel() { return m_useLCUSeparateModel; }
int getNumPixel() { return m_numberOfPixel; }
int64_t getTargetBits() { return m_targetBits; }
int getNumberOfLCU() { return m_numberOfLCU; }
int* getBitRatio() { return m_bitsRatio; }
int getBitRatio( int idx ) { CHECK(!( idx<m_GOPSize), "Idx exceeds GOP size"); return m_bitsRatio[idx]; }
int* getGOPID2Level() { return m_GOPID2Level; }
int getGOPID2Level( int ID ) { CHECK(!( ID < m_GOPSize ), "Idx exceeds GOP size"); return m_GOPID2Level[ID]; }
TRCParameter* getPicPara() { return m_picPara; }
TRCParameter getPicPara( int level ) { CHECK(!( level < m_numberOfLevel ), "Level too big"); return m_picPara[level]; }
void setPicPara( int level, TRCParameter para ) { CHECK(!( level < m_numberOfLevel ), "Level too big"); m_picPara[level] = para; }
TRCParameter** getLCUPara() { return m_LCUPara; }
TRCParameter* getLCUPara( int level ) { CHECK(!( level < m_numberOfLevel ), "Level too big"); return m_LCUPara[level]; }
TRCParameter getLCUPara( int level, int LCUIdx ) { CHECK(!( LCUIdx < m_numberOfLCU ), "LCU id exceeds number of LCU"); return getLCUPara(level)[LCUIdx]; }
void setLCUPara( int level, int LCUIdx, TRCParameter para ) { CHECK(!( level < m_numberOfLevel ), "Level too big"); CHECK(!( LCUIdx < m_numberOfLCU ), "LCU id exceeds number of LCU"); m_LCUPara[level][LCUIdx] = para; }
int getFramesLeft() { return m_framesLeft; }
int64_t getBitsLeft() { return m_bitsLeft; }
double getSeqBpp() { return m_seqTargetBpp; }
double getAlphaUpdate() { return m_alphaUpdate; }
double getBetaUpdate() { return m_betaUpdate; }
int getAdaptiveBits() { return m_adaptiveBit; }
double getLastLambda() { return m_lastLambda; }
void setLastLambda( double lamdba ) { m_lastLambda = lamdba; }
#if RATECTRL_FIX_FULLNBIT
void setBitDepth(int bitDepth) { m_bitDepth = bitDepth; }
int getbitDepth() { return m_bitDepth; }
#endif

Karsten Suehring
committed
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
private:
int m_totalFrames;
int m_targetRate;
int m_frameRate;
int m_GOPSize;
int m_picWidth;
int m_picHeight;
int m_LCUWidth;
int m_LCUHeight;
int m_numberOfLevel;
int m_averageBits;
int m_numberOfPixel;
int64_t m_targetBits;
int m_numberOfLCU;
int* m_bitsRatio;
int* m_GOPID2Level;
TRCParameter* m_picPara;
TRCParameter** m_LCUPara;
int m_framesLeft;
int64_t m_bitsLeft;
double m_seqTargetBpp;
double m_alphaUpdate;
double m_betaUpdate;
bool m_useLCUSeparateModel;
int m_adaptiveBit;
double m_lastLambda;
#if RATECTRL_FIX_FULLNBIT
int m_bitDepth;
#endif

Karsten Suehring
committed
};
class EncRCGOP
{
public:
EncRCGOP();
~EncRCGOP();
public:
void create( EncRCSeq* encRCSeq, int numPic );
void destroy();
void updateAfterPicture( int bitsCost );
private:
int xEstGOPTargetBits( EncRCSeq* encRCSeq, int GOPSize );
void xCalEquaCoeff( EncRCSeq* encRCSeq, double* lambdaRatio, double* equaCoeffA, double* equaCoeffB, int GOPSize );
#if JVET_K0390_RATECTRL
double xSolveEqua(EncRCSeq* encRCSeq, double targetBpp, double* equaCoeffA, double* equaCoeffB, int GOPSize);
#else

Karsten Suehring
committed
double xSolveEqua( double targetBpp, double* equaCoeffA, double* equaCoeffB, int GOPSize );
#endif

Karsten Suehring
committed
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
public:
EncRCSeq* getEncRCSeq() { return m_encRCSeq; }
int getNumPic() { return m_numPic;}
int getTargetBits() { return m_targetBits; }
int getPicLeft() { return m_picLeft; }
int getBitsLeft() { return m_bitsLeft; }
int getTargetBitInGOP( int i ) { return m_picTargetBitInGOP[i]; }
private:
EncRCSeq* m_encRCSeq;
int* m_picTargetBitInGOP;
int m_numPic;
int m_targetBits;
int m_picLeft;
int m_bitsLeft;
};
class EncRCPic
{
public:
EncRCPic();
~EncRCPic();
public:
void create( EncRCSeq* encRCSeq, EncRCGOP* encRCGOP, int frameLevel, list<EncRCPic*>& listPreviousPictures );
void destroy();
int estimatePicQP ( double lambda, list<EncRCPic*>& listPreviousPictures );
int getRefineBitsForIntra(int orgBits);
double calculateLambdaIntra(double alpha, double beta, double MADPerPixel, double bitsPerPixel);
double estimatePicLambda( list<EncRCPic*>& listPreviousPictures, SliceType eSliceType);
void updateAlphaBetaIntra(double *alpha, double *beta);
double getLCUTargetBpp(SliceType eSliceType);
double getLCUEstLambdaAndQP(double bpp, int clipPicQP, int *estQP);
double getLCUEstLambda( double bpp );
int getLCUEstQP( double lambda, int clipPicQP );
void updateAfterCTU( int LCUIdx, int bits, int QP, double lambda, bool updateLCUParameter = true );
void updateAfterPicture( int actualHeaderBits, int actualTotalBits, double averageQP, double averageLambda, SliceType eSliceType);
void addToPictureLsit( list<EncRCPic*>& listPreviousPictures );
double calAverageQP();
double calAverageLambda();
private:
int xEstPicTargetBits( EncRCSeq* encRCSeq, EncRCGOP* encRCGOP );
int xEstPicHeaderBits( list<EncRCPic*>& listPreviousPictures, int frameLevel );
#if V0078_ADAPTIVE_LOWER_BOUND
int xEstPicLowerBound( EncRCSeq* encRCSeq, EncRCGOP* encRCGOP );
#endif
public:
EncRCSeq* getRCSequence() { return m_encRCSeq; }
EncRCGOP* getRCGOP() { return m_encRCGOP; }
int getFrameLevel() { return m_frameLevel; }
int getNumberOfPixel() { return m_numberOfPixel; }
int getNumberOfLCU() { return m_numberOfLCU; }
int getTargetBits() { return m_targetBits; }
int getEstHeaderBits() { return m_estHeaderBits; }
int getLCULeft() { return m_LCULeft; }
int getBitsLeft() { return m_bitsLeft; }
int getPixelsLeft() { return m_pixelsLeft; }
int getBitsCoded() { return m_targetBits - m_estHeaderBits - m_bitsLeft; }
int getLCUCoded() { return m_numberOfLCU - m_LCULeft; }
#if V0078_ADAPTIVE_LOWER_BOUND
int getLowerBound() { return m_lowerBound; }
#endif
TRCLCU* getLCU() { return m_LCUs; }
TRCLCU& getLCU( int LCUIdx ) { return m_LCUs[LCUIdx]; }
int getPicActualHeaderBits() { return m_picActualHeaderBits; }
#if U0132_TARGET_BITS_SATURATION
void setBitLeft(int bits) { m_bitsLeft = bits; }
#endif
void setTargetBits( int bits ) { m_targetBits = bits; m_bitsLeft = bits;}
void setTotalIntraCost(double cost) { m_totalCostIntra = cost; }
void getLCUInitTargetBits();
int getPicActualBits() { return m_picActualBits; }
int getPicActualQP() { return m_picQP; }
double getPicActualLambda() { return m_picLambda; }
int getPicEstQP() { return m_estPicQP; }
void setPicEstQP( int QP ) { m_estPicQP = QP; }
double getPicEstLambda() { return m_estPicLambda; }
void setPicEstLambda( double lambda ) { m_picLambda = lambda; }
#if JVET_K0390_RATECTRL
double getPicMSE() { return m_picMSE; }
void setPicMSE(double avgMSE) { m_picMSE = avgMSE; }
#endif

Karsten Suehring
committed
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
private:
EncRCSeq* m_encRCSeq;
EncRCGOP* m_encRCGOP;
int m_frameLevel;
int m_numberOfPixel;
int m_numberOfLCU;
int m_targetBits;
int m_estHeaderBits;
int m_estPicQP;
#if V0078_ADAPTIVE_LOWER_BOUND
int m_lowerBound;
#endif
double m_estPicLambda;
int m_LCULeft;
int m_bitsLeft;
int m_pixelsLeft;
TRCLCU* m_LCUs;
int m_picActualHeaderBits; // only SH and potential APS
double m_totalCostIntra;
double m_remainingCostIntra;
int m_picActualBits; // the whole picture, including header
int m_picQP; // in integer form
double m_picLambda;
#if JVET_K0390_RATECTRL
double m_picMSE;
int m_validPixelsInPic;
#endif

Karsten Suehring
committed
};
class RateCtrl
{
public:
RateCtrl();
~RateCtrl();
public:
#if RATECTRL_FIX_FULLNBIT
void init(int totalFrames, int targetBitrate, int frameRate, int GOPSize, int picWidth, int picHeight, int LCUWidth, int LCUHeight, int bitDepth, int keepHierBits, bool useLCUSeparateModel, GOPEntry GOPList[MAX_GOP]);
#else

Karsten Suehring
committed
void init( int totalFrames, int targetBitrate, int frameRate, int GOPSize, int picWidth, int picHeight, int LCUWidth, int LCUHeight, int keepHierBits, bool useLCUSeparateModel, GOPEntry GOPList[MAX_GOP] );
#endif

Karsten Suehring
committed
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
void destroy();
void initRCPic( int frameLevel );
void initRCGOP( int numberOfPictures );
void destroyRCGOP();
public:
void setRCQP ( int QP ) { m_RCQP = QP; }
int getRCQP () const { return m_RCQP; }
EncRCSeq* getRCSeq() { CHECK( m_encRCSeq == NULL, "Object does not exist" ); return m_encRCSeq; }
EncRCGOP* getRCGOP() { CHECK( m_encRCGOP == NULL, "Object does not exist" ); return m_encRCGOP; }
EncRCPic* getRCPic() { CHECK( m_encRCPic == NULL, "Object does not exist" ); return m_encRCPic; }
list<EncRCPic*>& getPicList() { return m_listRCPictures; }
#if U0132_TARGET_BITS_SATURATION
bool getCpbSaturationEnabled() { return m_CpbSaturationEnabled; }
uint32_t getCpbState() { return m_cpbState; }
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);
#endif
private:
EncRCSeq* m_encRCSeq;
EncRCGOP* m_encRCGOP;
EncRCPic* m_encRCPic;
list<EncRCPic*> m_listRCPictures;
int m_RCQP;
#if U0132_TARGET_BITS_SATURATION
bool m_CpbSaturationEnabled; // Enable target bits saturation to avoid CPB overflow and underflow
int m_cpbState; // CPB State
uint32_t m_cpbSize; // CPB size
uint32_t m_bufferingRate; // Buffering rate
#endif
};
#endif