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 87 88 89 90 91 92 93 94 95 96 97 98 99 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 157 158 159 160 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 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 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 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
|
/*****************************************************************************
* Copyright (C) 2013-2020 MulticoreWare, Inc
*
* Authors: Sumalatha Polureddy <sumalatha@multicorewareinc.com>
* Aarthi Priya Thirumalai <aarthi@multicorewareinc.com>
* Xun Xu, PPLive Corporation <xunxu@pptv.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
*
* This program is also available under a commercial proprietary license.
* For more information, contact us at license @ x265.com.
*****************************************************************************/
#ifndef X265_RATECONTROL_H
#define X265_RATECONTROL_H
#include "common.h"
#include "sei.h"
#include "ringmem.h"
namespace X265_NS {
// encoder namespace
class Encoder;
class Frame;
class SEIBufferingPeriod;
struct SPS;
#define BASE_FRAME_DURATION 0.04
/* Arbitrary limitations as a sanity check. */
#define MAX_FRAME_DURATION 1.00
#define MIN_FRAME_DURATION 0.01
#define MIN_AMORTIZE_FRAME 10
#define MIN_AMORTIZE_FRACTION 0.2
#define CLIP_DURATION(f) x265_clip3(MIN_FRAME_DURATION, MAX_FRAME_DURATION, f)
struct Predictor
{
double coeffMin;
double coeff;
double count;
double decay;
double offset;
};
struct HRDTiming
{
double cpbInitialAT;
double cpbFinalAT;
double dpbOutputTime;
double cpbRemovalTime;
};
struct RateControlEntry
{
Predictor rowPreds[3][2];
Predictor* rowPred[2];
int64_t currentSatd;
int64_t lastSatd; /* Contains the picture cost of the previous frame, required for resetAbr and VBV */
int64_t leadingNoBSatd;
int64_t rowTotalBits; /* update cplxrsum and totalbits at the end of 2 rows */
double blurredComplexity;
double qpaRc;
double qpAq;
double qRceq;
double qpPrev;
double frameSizePlanned; /* frame Size decided by RateCotrol before encoding the frame */
double bufferRate;
double movingAvgSum;
double rowCplxrSum;
double qpNoVbv;
double bufferFill;
double bufferFillFinal;
double bufferFillActual;
double targetFill;
bool vbvEndAdj;
double frameDuration;
double clippedDuration;
double frameSizeEstimated; /* hold frameSize, updated from cu level vbv rc */
double frameSizeMaximum; /* max frame Size according to minCR restrictions and level of the video */
int sliceType;
int bframes;
int poc;
int encodeOrder;
bool bLastMiniGopBFrame;
bool isActive;
double amortizeFrames;
double amortizeFraction;
int remainingVbvEndFrames;
/* Required in 2-pass rate control */
uint64_t expectedBits; /* total expected bits up to the current frame (current one excluded) */
double iCuCount;
double pCuCount;
double skipCuCount;
double expectedVbv;
double qScale;
double newQScale;
double newQp;
int mvBits;
int miscBits;
int coeffBits;
bool keptAsRef;
bool scenecut;
bool isIdr;
SEIPictureTiming *picTimingSEI;
HRDTiming *hrdTiming;
int rpsIdx;
RPS rpsData;
bool isFadeEnd;
};
class RateControl
{
public:
x265_param* m_param;
Slice* m_curSlice; /* all info about the current frame */
SliceType m_sliceType; /* Current frame type */
int m_ncu; /* number of CUs in a frame */
int m_qp; /* updated qp for current frame */
/*Zone reconfiguration*/
double* m_relativeComplexity;
int m_zoneBufferIdx;
int m_totalFrames;
bool m_isAbr;
bool m_isVbv;
bool m_isCbr;
bool m_singleFrameVbv;
bool m_isGrainEnabled;
bool m_isAbrReset;
bool m_isNextGop;
bool m_initVbv;
int m_lastAbrResetPoc;
int m_lastScenecut;
int m_lastScenecutAwareIFrame;
double m_rateTolerance;
double m_frameDuration; /* current frame duration in seconds */
double m_bitrate;
double m_rateFactorConstant;
double m_bufferSize;
double m_bufferFillFinal; /* real buffer as of the last finished frame */
double m_unclippedBufferFillFinal; /* real unclipped buffer as of the last finished frame used to log in CSV*/
double m_bufferFill; /* planned buffer, if all in-progress frames hit their bit budget */
double m_bufferRate; /* # of bits added to buffer_fill after each frame */
double m_vbvMaxRate; /* in kbps */
double m_rateFactorMaxIncrement; /* Don't allow RF above (CRF + this value). */
double m_rateFactorMaxDecrement; /* don't allow RF below (this value). */
double m_avgPFrameQp;
double m_bufferFillActual;
double m_bufferExcess;
double m_minBufferFill;
double m_maxBufferFill;
bool m_isFirstMiniGop;
Predictor m_pred[4]; /* Slice predictors to preidct bits for each Slice type - I,P,Bref and B */
int64_t m_leadingNoBSatd;
int m_predType; /* Type of slice predictors to be used - depends on the slice type */
double m_ipOffset;
double m_pbOffset;
int64_t m_bframeBits;
int64_t m_currentSatd;
int m_qpConstant[3];
int m_lastNonBPictType;
int m_framesDone; /* # of frames passed through RateCotrol already */
double m_cplxrSum; /* sum of bits*qscale/rceq */
double m_wantedBitsWindow; /* target bitrate * window */
double m_accumPQp; /* for determining I-frame quant */
double m_accumPNorm;
double m_lastQScaleFor[3]; /* last qscale for a specific pict type, used for max_diff & ipb factor stuff */
double m_lstep;
double m_lmin[3];
double m_lmax[3];
double m_shortTermCplxSum;
double m_shortTermCplxCount;
double m_lastRceq;
double m_qCompress;
int64_t m_totalBits; /* total bits used for already encoded frames (after ammortization) */
int64_t m_encodedBits; /* bits used for encoded frames (without ammortization) */
int64_t m_encodedSegmentBits; /* bits used for encoded frames in a segment*/
double m_segDur;
double m_fps;
int64_t m_satdCostWindow[50];
int64_t m_encodedBitsWindow[50];
int m_sliderPos;
int64_t m_lastRemovedSatdCost;
double m_movingAvgSum;
/* To detect a pattern of low detailed static frames in single pass ABR using satdcosts */
int64_t m_lastBsliceSatdCost;
int m_numBframesInPattern;
bool m_isPatternPresent;
bool m_isSceneTransition;
int m_lastPredictorReset;
double m_qpToEncodedBits[QP_MAX_MAX + 1];
/* a common variable on which rateControlStart, rateControlEnd and rateControUpdateStats waits to
* sync the calls to these functions. For example
* -F2:
* rceStart 10
* rceUpdate 10
* rceEnd 9
* rceStart 11
* rceUpdate 11
* rceEnd 10
* rceStart 12
* rceUpdate 12
* rceEnd 11 */
ThreadSafeInteger m_startEndOrder;
int m_finalFrameCount; /* set when encoder begins flushing */
bool m_bTerminated; /* set true when encoder is closing */
/* hrd stuff */
SEIBufferingPeriod m_bufPeriodSEI;
double m_nominalRemovalTime;
double m_prevCpbFinalAT;
/* 2 pass */
bool m_2pass;
bool m_isGopReEncoded;
bool m_isQpModified;
int m_numEntries;
int m_start;
int m_reencode;
FILE* m_statFileOut;
FILE* m_cutreeStatFileOut;
FILE* m_cutreeStatFileIn;
///< store the cutree data in memory instead of file
RingMem *m_cutreeShrMem;
double m_lastAccumPNorm;
double m_expectedBitsSum; /* sum of qscale2bits after rceq, ratefactor, and overflow, only includes finished frames */
int64_t m_predictedBits;
int *m_encOrder;
RateControlEntry* m_rce2Pass;
Encoder* m_top;
bool m_bRcReConfig; /* RC-reconfigurtion */
struct
{
uint16_t *qpBuffer[2]; /* Global buffers for converting MB-tree quantizer data. */
int qpBufPos; /* In order to handle pyramid reordering, QP buffer acts as a stack.
* This value is the current position (0 or 1). */
} m_cuTreeStats;
RateControl(x265_param& p, Encoder *enc);
bool init(const SPS& sps);
void initHRD(SPS& sps);
void initVBV(const SPS& sps);
void reconfigureRC();
void setFinalFrameCount(int count);
void terminate(); /* un-block all waiting functions so encoder may close */
void destroy();
// to be called for each curFrame to process RateControl and set QP
int rateControlStart(Frame* curFrame, RateControlEntry* rce, Encoder* enc);
void rateControlUpdateStats(RateControlEntry* rce);
int rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry* rce, int *filler);
int rowVbvRateControl(Frame* curFrame, uint32_t row, RateControlEntry* rce, double& qpVbv, uint32_t* m_sliceBaseRow, uint32_t sliceId);
int rateControlSliceType(int frameNum);
bool cuTreeReadFor2Pass(Frame* curFrame);
void hrdFullness(SEIBufferingPeriod* sei);
int writeRateControlFrameStats(Frame* curFrame, RateControlEntry* rce);
bool initPass2();
bool initCUTreeSharedMem();
void skipCUTreeSharedMemRead(int32_t cnt);
double forwardMasking(Frame* curFrame, double q);
double backwardMasking(Frame* curFrame, double q);
protected:
static const int s_slidingWindowFrames;
static const char* s_defaultStatFileName;
double m_amortizeFraction;
int m_amortizeFrames;
int m_residualFrames;
int m_partialResidualFrames;
int m_residualCost;
int m_partialResidualCost;
x265_zone* getZone();
double getQScale(RateControlEntry *rce, double rateFactor);
double rateEstimateQscale(Frame* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR
double tuneAbrQScaleFromFeedback(double qScale);
double tuneQScaleForZone(RateControlEntry *rce, double qScale); // Tune qScale to adhere to zone budget
double tuneQscaleForSBRC(Frame* curFrame, double q); // Tune qScale to adhere to segment budget
double tuneQscaleToUpdatedBitrate(Frame* curFrame, double q); // Tune qScale according to updated bitrate
void accumPQpUpdate();
int getPredictorType(int lowresSliceType, int sliceType);
int updateVbv(int64_t bits, RateControlEntry* rce);
void updatePredictor(Predictor *p, double q, double var, double bits);
double clipQscale(Frame* pic, RateControlEntry* rce, double q);
void updateVbvPlan(Encoder* enc);
double predictSize(Predictor *p, double q, double var);
void checkAndResetABR(RateControlEntry* rce, bool isFrameDone);
double predictRowsSizeSum(Frame* pic, RateControlEntry* rce, double qpm, int32_t& encodedBits);
bool analyseABR2Pass(uint64_t allAvailableBits);
void initFramePredictors();
double getDiffLimitedQScale(RateControlEntry *rce, double q);
double countExpectedBits(int startPos, int framesCount);
bool vbv2Pass(uint64_t allAvailableBits, int frameCount, int startPos);
bool findUnderflow(double *fills, int *t0, int *t1, int over, int framesCount);
bool fixUnderflow(int t0, int t1, double adjustment, double qscaleMin, double qscaleMax);
double tuneQScaleForGrain(double rcOverflow);
void splitdeltaPOC(char deltapoc[], RateControlEntry *rce);
void splitbUsed(char deltapoc[], RateControlEntry *rce);
void checkAndResetCRF(RateControlEntry* rce);
};
}
#endif // ifndef X265_RATECONTROL_H
|