diff x265/source/encoder/ratecontrol.h @ 0:772086c29cc7

Initial import.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 16 Nov 2016 11:16:33 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/x265/source/encoder/ratecontrol.h	Wed Nov 16 11:16:33 2016 +0200
@@ -0,0 +1,267 @@
+/*****************************************************************************
+ * Copyright (C) 2013 x265 project
+ *
+ * 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"
+
+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 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 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  frameSizePlanned;  /* frame Size decided by RateCotrol before encoding the frame */
+    double  bufferRate;
+    double  movingAvgSum;
+    double  rowCplxrSum;
+    double  qpNoVbv;
+    double  bufferFill;
+    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;
+    /* 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;
+
+    SEIPictureTiming *picTimingSEI;
+    HRDTiming        *hrdTiming;
+};
+
+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 */
+
+    bool   m_isAbr;
+    bool   m_isVbv;
+    bool   m_isCbr;
+    bool   m_singleFrameVbv;
+
+    bool   m_isAbrReset;
+    int    m_lastAbrResetPoc;
+
+    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_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). */
+
+    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_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) */
+    double  m_fps;
+    int64_t m_satdCostWindow[50];
+    int64_t m_encodedBitsWindow[50];
+    int     m_sliderPos;
+
+    /* 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;
+
+    /* 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;
+    int     m_numEntries;
+    FILE*   m_statFileOut;
+    FILE*   m_cutreeStatFileOut;
+    FILE*   m_cutreeStatFileIn;
+    double  m_lastAccumPNorm;
+    double  m_expectedBitsSum;   /* sum of qscale2bits after rceq, ratefactor, and overflow, only includes finished frames */
+    int64_t m_predictedBits;
+    RateControlEntry* m_rce2Pass;
+
+    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);
+    bool init(const SPS& sps);
+    void initHRD(SPS& sps);
+
+    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  rowDiagonalVbvRateControl(Frame* curFrame, uint32_t row, RateControlEntry* rce, double& qpVbv);
+    int  rateControlSliceType(int frameNum);
+    bool cuTreeReadFor2Pass(Frame* curFrame);
+    void hrdFullness(SEIBufferingPeriod* sei);
+    int writeRateControlFrameStats(Frame* curFrame, RateControlEntry* rce);
+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);
+    void   accumPQpUpdate();
+
+    int    getPredictorType(int lowresSliceType, int sliceType);
+    void   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   initPass2();
+    double getDiffLimitedQScale(RateControlEntry *rce, double q);
+    double countExpectedBits();
+    bool   vbv2Pass(uint64_t allAvailableBits);
+    bool   findUnderflow(double *fills, int *t0, int *t1, int over);
+    bool   fixUnderflow(int t0, int t1, double adjustment, double qscaleMin, double qscaleMax);
+};
+}
+#endif // ifndef X265_RATECONTROL_H