[x265] [PATCH] add rate control parameters to x265_param_t
sumalatha at multicorewareinc.com
sumalatha at multicorewareinc.com
Wed Aug 14 10:16:18 CEST 2013
# HG changeset patch
# User sumalatha
# Date 1376468168 -19800
# Node ID 21a97bdeea8a0f250ba58f8b33c0a676b2316fa6
# Parent a2026f0e1556e129d7c86d951b9d3e694a43fac6
add rate control parameters to x265_param_t
make corresponding changes to ratecontrol.cpp and .h
moved the macro definition of QP_BD_OFFSET from slicetype.cpp to common.h
diff -r a2026f0e1556 -r 21a97bdeea8a source/common/common.cpp
--- a/source/common/common.cpp Tue Aug 13 22:10:41 2013 -0500
+++ b/source/common/common.cpp Wed Aug 14 13:46:08 2013 +0530
@@ -139,6 +139,14 @@
param->bEnableTSkipFast = 1;
param->bFrameAdaptive = X265_B_ADAPT_FAST;
param->lookaheadDepth = 10;
+ param->rc.bitrate = 1000;//TODO:take from CLI
+ param->rc.rateTolerance = 1;
+ param->rc.qCompress = 0.6;
+ param->rc.ipFactor = 1.4;
+ param->rc.pbFactor = 1.3;
+ param->rc.qpStep = 4;
+ param->rc.rateControlMode = X265_RC_ABR;
+
}
extern "C"
diff -r a2026f0e1556 -r 21a97bdeea8a source/common/common.h
--- a/source/common/common.h Tue Aug 13 22:10:41 2013 -0500
+++ b/source/common/common.h Wed Aug 14 13:46:08 2013 +0530
@@ -94,6 +94,7 @@
#define X265_MAX3(a, b, c) X265_MAX((a), X265_MAX((b), (c)))
#define X265_MIN4(a, b, c, d) X265_MIN((a), X265_MIN3((b), (c), (d)))
#define X265_MAX4(a, b, c, d) X265_MAX((a), X265_MAX3((b), (c), (d)))
+#define QP_BD_OFFSET (6*(X265_DEPTH-8))
#define ENABLE_CYCLE_COUNTERS 0
#if ENABLE_CYCLE_COUNTERS
diff -r a2026f0e1556 -r 21a97bdeea8a source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Tue Aug 13 22:10:41 2013 -0500
+++ b/source/encoder/ratecontrol.cpp Wed Aug 14 13:46:08 2013 +0530
@@ -1,8 +1,8 @@
/*****************************************************************************
* Copyright (C) 2013 x265 project
*
- * Authors: Sumalatha <sumalatha at multicorewareinc.com>
- * Aarthi <aarthi at multicorewareinc.com>
+ * Authors: Sumalatha Polureddy <sumalatha at multicorewareinc.com>
+ * Aarthi Priya Thirumalai <aarthi at multicorewareinc.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
@@ -28,23 +28,24 @@
RateControl::RateControl(x265_param_t * param)
{
- keyFrameInterval = param->keyframeInterval;
+ keyFrameInterval = param->keyframeMax;
fps = param->frameRate;
bframes = param->bframes;
- //TODO : set default value here,later can get from param as done in x264?
- rateTolerance = 1;
- //TODO : introduce bitrate var in param and cli options
- bitrate = param->bitrate * 1000;
- fps = param->frameRate;
- isAbrEnabled = true; // set from param later.
+ rateTolerance = param->rc.rateTolerance;
+ bitrate = param->rc.bitrate * 1000;
+ frameDuration = 1/param->frameRate;
+ rateControlMode = param->rc.rateControlMode;
ncu = (param->sourceHeight * param->sourceWidth) / pow(2, param->maxCUSize);
lastNonBPictType = -1;
- //TODO : need to confirm default val if mbtree is disabled
- qCompress = 1;
- if (isAbrEnabled)
+ qCompress = param->rc.qCompress;
+ ipFactor = param->rc.ipFactor;
+ pbFactor = param->rc.pbFactor;
+ totalBits = 0;
+ if (rateControlMode == X265_RC_ABR)
{
- //TODO : confirm this value. obtained it from x264 when crf is disabled , abr enabled.
-#define ABR_INIT_QP (24 + 6 * (param->internalBitDepth - 8));
+ //TODO : confirm this value. obtained it from x264 when crf is disabled , abr enabled.
+ //h->param.rc.i_rc_method == X264_RC_CRF ? h->param.rc.f_rf_constant : 24
+#define ABR_INIT_QP (24 + QP_BD_OFFSET)
accumPNorm = .01;
accumPQp = (ABR_INIT_QP)*accumPNorm;
/* estimated ratio that produces a reasonable QP for the first I-frame */
@@ -52,6 +53,16 @@
wantedBitsWindow = 1.0 * bitrate / fps;
lastNonBPictType = I_SLICE;
}
+ ipOffset = 6.0 * log( param->rc.ipFactor );
+ pbOffset = 6.0 * log( param->rc.pbFactor );
+ for( int i = 0; i < 3; i++ )
+ {
+ lastQScaleFor[i] = qp2qScale( ABR_INIT_QP );
+ lmin[i] = qp2qScale( MIN_QP);
+ lmax[i] = qp2qScale( MAX_QP );
+ }
+ lstep = pow( 2, param->rc.qpStep / 6.0 );
+ cbrDecay = 1.0;
}
void RateControl::rateControlInit(TComSlice* frame)
@@ -66,15 +77,13 @@
float q;
//Always enabling ABR
- if (isAbrEnabled)
+ if (rateControlMode == X265_RC_ABR)
{
q = qScale2qp(rateEstimateQscale(lFrame));
}
q = Clip3((int)q, MIN_QP, MAX_QP);
-
qp = Clip3((int)(q + 0.5f), 0, MAX_QP);
-
- qpm = q;
+ qpaRc = qpm = q; // qpaRc is set in the rate_control_mb call in x264. we are updating here itself.
if (rce)
rce->newQp = qp;
@@ -86,7 +95,6 @@
void RateControl::accumPQpUpdate()
{
- //x264_ratecontrol_t *rc = h->rc;
accumPQp *= .95;
accumPNorm *= .95;
accumPNorm += 1;
@@ -101,7 +109,6 @@
float q;
// ratecontrol_entry_t rce = UNINIT(rce);
int pictType = frameType;
- int64_t totalBits = 0; //CHECK:for ABR
if (pictType == B_SLICE)
{
@@ -114,8 +121,8 @@
int dt1 = abs(curFrame->getPOC() - curFrame->getRefPic(REF_PIC_LIST_1, 0)->getPOC());
//TODO:need to figure out this
- float q0 = h->fref_nearest[0]->f_qp_avg_rc;
- float q1 = h->fref_nearest[1]->f_qp_avg_rc;
+ float q0 = curFrame->getRefPic(REF_PIC_LIST_0, 0)->getSlice()->getSliceQp();
+ float q1 = curFrame->getRefPic(REF_PIC_LIST_1, 0)->getSlice()->getSliceQp();
if (i0 && i1)
q = (q0 + q1) / 2 + ipOffset;
@@ -125,13 +132,12 @@
q = q0;
else
q = (q0 * dt1 + q1 * dt0) / (dt0 + dt1);
-
- if (h->fenc->b_kept_as_ref)
+
+ if (curFrame->isReferenced())
q += pbOffset / 2;
else
q += pbOffset;
- qpNoVbv = q;
return qp2qScale(q);
}
else
@@ -151,34 +157,27 @@
* tolerances, the bit distribution approaches that of 2pass. */
double wantedBits, overflow = 1;
+ lastSatd = 0; //TODO:need to get this from lookahead //x264_rc_analyse_slice( h );
+ rce->pCount = ncu;
- lastSatd = 0; //need to get this from lookahead //x264_rc_analyse_slice( h );
shortTermCplxSum *= 0.5;
shortTermCplxCount *= 0.5;
- //TODO:need to get the duration for each frame
- //short_term_cplxsum += last_satd / (CLIP_DURATION(h->fenc->f_duration) / BASE_FRAME_DURATION);
- shortTermCplxCount++;
-
- rce->pCount = ncu;
-
+ shortTermCplxSum += lastSatd / (CLIP_DURATION(frameDuration) / BASE_FRAME_DURATION);
+ shortTermCplxCount ++;
+ rce->texBits = lastSatd;
+ rce->blurredComplexity = shortTermCplxSum / shortTermCplxCount;
+ rce->mvBits = 0;
rce->pictType = pictType;
-
- //TODO:wanted_bits_window, fps , h->fenc->i_reordered_pts, h->i_reordered_pts_delay, h->fref_nearest[0]->f_qp_avg_rc, h->param.rc.f_ip_factor, h->sh.i_type
//need to checked where it is initialized
- q = getQScale(rce, wantedBitsWindow / cplxrSum, fps);
+ q = getQScale(rce, wantedBitsWindow / cplxrSum);
/* ABR code can potentially be counterproductive in CBR, so just don't bother.
* Don't run it if the frame complexity is zero either. */
- if ( /*!rcc->b_vbv_min_rate && */ lastSatd)
+ if ( lastSatd)
{
- // TODO: need to check the thread_frames
- int iFrameDone = fps + 1 - h->i_thread_frames;
+ // TODO: need to check the thread_frames - add after min chen plugs in frame parallelism.
+ int iFrameDone = fps + 1 - 0; //h->i_thread_frames;
double timeDone = iFrameDone / fps;
- if (iFrameDone > 0)
- {
- //time_done = ((double)(h->fenc->i_reordered_pts - h->i_reordered_pts_delay)) * h->param.i_timebase_num / h->param.i_timebase_den;
- timeDone = ((double)(h->fenc->i_reordered_pts - h->i_reordered_pts_delay)) * (1 / fps);
- }
wantedBits = timeDone * bitrate;
if (wantedBits > 0)
{
@@ -193,11 +192,11 @@
&& lastNonBPictType != I_SLICE)
{
q = qp2qScale(accumPQp / accumPNorm);
- q /= fabs(h->param.rc.f_ip_factor);
+ q /= fabs(ipFactor);
}
else if (fps > 0)
{
- if (1) //assume that for ABR this is always enabled h->param.rc.i_rc_method != X264_RC_CRF )
+ if (rateControlMode != X265_RC_CRF)
{
/* Asymmetric clipping, because symmetric would prevent
* overflow control in areas of rapidly oscillating complexity */
@@ -212,22 +211,15 @@
}
}
- qpNoVbv = qScale2qp(q);
-
//FIXME use get_diff_limited_q() ?
- //q = clip_qscale( h, pict_type, q );
float lmin1 = lmin[pictType];
float lmax1 = lmax[pictType];
- Clip3(q, lmin1, lmax1);
-
+ q= Clip3(q, lmin1, lmax1);
lastQScaleFor[pictType] =
lastQScale = q;
if (!fps == 0)
- lastQScaleFor[P_SLICE] = q * fabs(h->param.rc.f_ip_factor);
-
- //this is for VBV stuff
- //frame_size_planned = predict_size( &pred[h->sh.i_type], q, last_satd );
+ lastQScaleFor[P_SLICE] = q * fabs(ipFactor);
return q;
}
@@ -239,9 +231,6 @@
double RateControl::getQScale(RateControlEntry *rce, double rateFactor)
{
double q;
-
- //x264_zone_t *zone = get_zone( h, frame_num );
-
q = pow(rce->blurredComplexity, 1 - qCompress);
// avoid NaN's in the rc_eq
@@ -253,15 +242,28 @@
q /= rateFactor;
lastQScale = q;
}
-
- /*TODO: need to check zone is required */
- //if( zone )
- //{
- // if( zone->b_force_qp )
- // q = qp2qscale( zone->i_qp );
- // else
- // q /= zone->f_bitrate_factor;
- //}
-
return q;
}
+
+/* After encoding one frame, save stats and update ratecontrol state */
+int RateControl::rateControlEnd(int64_t bits)
+{
+ if( rateControlMode == X265_RC_ABR)
+ {
+ if( frameType != B_SLICE)
+ cplxrSum += bits * qp2qScale( qpaRc ) / lastRceq;
+ else
+ {
+ /* Depends on the fact that B-frame's QP is an offset from the following P-frame's.
+ * Not perfectly accurate with B-refs, but good enough. */
+ cplxrSum += bits * qp2qScale( qpaRc ) / (lastRceq * fabs( pbFactor ));
+ }
+ cplxrSum *= cbrDecay;
+ wantedBitsWindow += frameDuration * bitrate;
+ wantedBitsWindow *= cbrDecay;
+ }
+ totalBits += bits;
+ return 0;
+}
+
+
diff -r a2026f0e1556 -r 21a97bdeea8a source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Tue Aug 13 22:10:41 2013 -0500
+++ b/source/encoder/ratecontrol.h Wed Aug 14 13:46:08 2013 +0530
@@ -28,9 +28,18 @@
#include <stdint.h>
#include "TLibEncoder/TEncTop.h"
#include "TLibCommon/TComRom.h"
-#include "math.h"
+
+
+
+#define BASE_FRAME_DURATION 0.04f
+/* Arbitrary limitations as a sanity check. */
+#define MAX_FRAME_DURATION 1.00f
+#define MIN_FRAME_DURATION 0.01f
+
+#define CLIP_DURATION(f) Clip3(f,MIN_FRAME_DURATION,MAX_FRAME_DURATION)
namespace x265 {
+
struct RateControlEntry
{
int pictType;
@@ -41,67 +50,49 @@
float blurredComplexity;
};
-struct Predictor
-{
- float coeff;
- float count;
- float decay;
- float offset;
-
- float predictSize(float q, float var)
- {
- return (coeff * var + offset) / (q * count);
- }
-};
-
struct RateControl
{
int ncu; /* number of CUs in a frame */
TComSlice *curFrame; /* all info abt the current frame */
SliceType frameType; /* Current frame type */
float frameDuration; /* current frame duration in seconds */
- int fps; /* current frame number TODO: need to initaialize in init */
+ int fps; /* current frame rate TODO: need to initaialize in init */
int keyFrameInterval; /* TODO: need to initialize in init */
- bool isAbrEnabled;
-
- /* current frame */
RateControlEntry *rce;
int qp; /* updated qp for current frame */
float qpm; /* qp for current macroblock: precise float for AQ */
-
+ float qpaRc; /* average of macroblocks' qp before aq */
double bitrate;
double rateTolerance;
double qCompress;
int bframes;
- /* ABR stuff */
int lastSatd;
- double lastRceq;
double cplxrSum; /* sum of bits*qscale/rceq */
- double expectedBitsSum; /* sum of qscale2bits after rceq, ratefactor, and overflow, only includes finished frames */
- int64_t fillerBitsSum; /* sum in bits of finished frames' filler data */
double wantedBitsWindow; /* target bitrate * window */
- double cbrDecay;
- double shortTermCplxSum;
- double shortTermCplxCount;
- double rateFactorConstant;
double ipOffset;
double pbOffset;
-
+ float ipFactor;
+ float pbFactor;
int lastNonBPictType;
double accumPQp; /* for determining I-frame quant */
double accumPNorm;
double lastQScale;
double lastQScaleFor[3]; /* last qscale for a specific pict type, used for max_diff & ipb factor stuff */
-
double lstep;
float qpNoVbv; /* QP for the current frame if 1-pass VBV was disabled. */
+ double lastRceq;
+ double cbrDecay;
double lmin[3]; /* min qscale by frame type */
double lmax[3];
- double frameSizePlanned;
+ double shortTermCplxSum;
+ double shortTermCplxCount;
+ RcMethod rateControlMode;
+ int64_t totalBits; /* totalbits used for already encoded frames */
RateControl(x265_param_t * param); // constructor for initializing values for ratecontrol vars
void rateControlInit(TComSlice* frame); // to be called for each frame to set the reqired parameters for rateControl.
void rateControlStart(LookaheadFrame* lframe); // to be called for each frame to process RateCOntrol and set QP
+ int rateControlEnd(int64_t bits );
float rateEstimateQscale(LookaheadFrame* lframe); // main logic for calculating QP based on ABR
void accumPQpUpdate();
double getQScale(RateControlEntry *rce, double rateFactor);
diff -r a2026f0e1556 -r 21a97bdeea8a source/encoder/slicetype.h
--- a/source/encoder/slicetype.h Tue Aug 13 22:10:41 2013 -0500
+++ b/source/encoder/slicetype.h Wed Aug 14 13:46:08 2013 +0530
@@ -29,7 +29,6 @@
class TComPic;
-#define QP_BD_OFFSET (6 * (X265_DEPTH - 8))
// arbitrary, but low because SATD scores are 1/4 normal
#define X265_LOOKAHEAD_QP (12 + QP_BD_OFFSET)
diff -r a2026f0e1556 -r 21a97bdeea8a source/x265.h
--- a/source/x265.h Tue Aug 13 22:10:41 2013 -0500
+++ b/source/x265.h Wed Aug 14 13:46:08 2013 +0530
@@ -158,7 +158,17 @@
#define X265_B_ADAPT_NONE 0
#define X265_B_ADAPT_FAST 1
-#define X265_B_ADAPT_TRELLIS 2
+#define X265_B_ADAPT_TRELLIS 2
+
+/* rate tolerance method */
+typedef enum RcMethod
+{
+ X265_RC_ABR,
+ X265_RC_CQP,
+ X265_RC_CRF
+}
+X265_RC_METHODS;
+
typedef struct x265_param_t
{
@@ -228,6 +238,16 @@
// debugging
int bEnableDecodedPictureHashSEI; ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
+ struct
+ {
+ int bitrate;
+ double rateTolerance;
+ double qCompress;
+ float ipFactor;
+ float pbFactor;
+ int qpStep;
+ RcMethod rateControlMode;
+ } rc;
}
x265_param_t;
More information about the x265-devel
mailing list