Commit aecc6ab0 authored by Loren Merritt's avatar Loren Merritt

New ratecontrol options:

1pass ABR. VBV constraint for ABR and 2pass.
There is no longer a dedicated CBR mode: use ABR+VBV.
VfW now uses ABR instead of CQP for 1st of multipass.


git-svn-id: svn://svn.videolan.org/x264/trunk@223 df754926-b1dd-0310-bc7b-ec298dee348c
parent 540fba7a
......@@ -76,12 +76,13 @@ void x264_param_default( x264_param_t *param )
param->i_cabac_init_idc = -1;
param->rc.b_cbr = 0;
param->rc.i_bitrate = 3000;
param->rc.i_rc_buffer_size = 0;
param->rc.i_rc_init_buffer = 0;
param->rc.i_rc_sens = 10;
param->rc.i_bitrate = 1000;
param->rc.f_rate_tolerance = 1.0;
param->rc.i_vbv_max_bitrate = 0;
param->rc.i_vbv_buffer_size = 0;
param->rc.f_vbv_buffer_init = 0.9;
param->rc.i_qp_constant = 26;
param->rc.i_qp_min = 0;
param->rc.i_qp_min = 10;
param->rc.i_qp_max = 51;
param->rc.i_qp_step = 4;
param->rc.f_ip_factor = 1.4;
......
......@@ -112,6 +112,8 @@ enum slice_type_e
SLICE_TYPE_SI = 4
};
static const char slice_type_to_char[] = { 'P', 'B', 'I', 'S', 'S' };
typedef struct
{
x264_sps_t *sps;
......@@ -303,6 +305,7 @@ struct x264_t
int i_b4_xy;
/* Search parameters */
int i_me_method;
int i_subpel_refine;
int b_chroma_me;
/* Allowed qpel MV range to stay within the picture + emulated edge pixels */
......
......@@ -169,6 +169,7 @@ static void x264_mb_analyse_init( x264_t *h, x264_mb_analysis_t *a, int i_qp )
a->i_qp = i_qp;
a->i_lambda = i_qp0_cost_table[i_qp];
h->mb.i_me_method = h->param.analyse.i_me_method;
h->mb.i_subpel_refine = h->param.analyse.i_subpel_refine;
h->mb.b_chroma_me = h->param.analyse.b_chroma_me && h->sh.i_type == SLICE_TYPE_P
&& h->mb.i_subpel_refine >= 5;
......
......@@ -1128,6 +1128,9 @@ do_encode:
/* ------------------- Init ----------------------------- */
/* build ref list 0/1 */
x264_reference_build_list( h, h->fdec->i_poc, i_slice_type );
/* Init the rate control */
x264_ratecontrol_start( h, i_slice_type, h->fenc->i_qpplus1 );
i_global_qp = x264_ratecontrol_qp( h );
......@@ -1135,9 +1138,6 @@ do_encode:
pic_out->i_qpplus1 =
h->fdec->i_qpplus1 = i_global_qp + 1;
/* build ref list 0/1 */
x264_reference_build_list( h, h->fdec->i_poc, i_slice_type );
if( i_slice_type == SLICE_TYPE_B )
x264_macroblock_bipred_init( h );
......
......@@ -100,7 +100,8 @@ void x264_me_search_ref( x264_t *h, x264_me_t *m, int (*mvc)[2], int i_mvc, int
COST_MV( 0, 0 );
switch( h->param.analyse.i_me_method ) {
switch( h->mb.i_me_method )
{
case X264_ME_DIA:
/* diamond search */
for( i_iter = 0; i_iter < i_me_range; i_iter++ )
......
/***************************************************-*- coding: iso-8859-1 -*-
* ratecontrol.c: h264 encoder library (Rate Control)
*****************************************************************************
* Copyright (C) 2003 Laurent Aimar
* Copyright (C) 2005 x264 project
* $Id: ratecontrol.c,v 1.1 2004/06/03 19:27:08 fenrir Exp $
*
* Authors: Mns Rullgrd <mru@mru.ath.cx>
* 2 pass code: Michael Niedermayer <michaelni@gmx.at>
* Loren Merritt <lorenm@u.washington.edu>
* Authors: Loren Merritt <lorenm@u.washington.edu>
* Michael Niedermayer <michaelni@gmx.at>
* Mns Rullgrd <mru@mru.ath.cx>
*
* 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
......@@ -66,40 +66,47 @@ typedef struct
float blurred_complexity;
} ratecontrol_entry_t;
typedef struct
{
double coeff;
double count;
double decay;
} predictor_t;
struct x264_ratecontrol_t
{
/* constants */
int b_abr;
int b_2pass;
double fps;
int gop_size;
int bitrate;
double bitrate;
double rate_tolerance;
int nmb; /* number of macroblocks in a frame */
int buffer_size;
int rcbufrate;
int init_qp;
int qp_constant[5];
/* 1st pass stuff */
int gop_qp;
int buffer_fullness;
int frames; /* frames in current gop */
int pframes;
int slice_type;
int mb; /* MBs processed in current frame */
int bits_gop; /* allocated bits current gop */
int bits_last_gop; /* bits consumed in gop */
/* current frame */
ratecontrol_entry_t *rce;
int qp; /* qp for current frame */
int qpm; /* qp for next MB */
float qpa; /* average qp for last frame */
int qps;
float qp_avg_p; /* average QP for P frames */
float qp_last_p;
int fbits; /* bits allocated for current frame */
int ufbits; /* bits used for current frame */
int nzcoeffs; /* # of 0-quantized coefficients */
int ncoeffs; /* total # of coefficients */
int overhead;
float qpa; /* average of macroblocks' qp (same as qp if no adaptive quant) */
int slice_type;
int qp_force;
/* VBV stuff */
double buffer_size;
double buffer_fill;
double buffer_rate; /* # of bits added to buffer_fill after each frame */
predictor_t pred[5]; /* predict frame size from satd */
/* ABR stuff */
int last_satd;
double last_rceq;
double cplxr_sum; /* sum of bits*qscale/rceq */
double expected_bits_sum; /* sum of qscale2bits after rceq, ratefactor, and overflow */
double wanted_bits_window; /* target bitrate * window */
double cbr_decay;
double short_term_cplxsum;
double short_term_cplxcount;
/* 2pass stuff */
FILE *p_stat_file_out;
char *psz_stat_file_tmpname;
......@@ -124,6 +131,8 @@ struct x264_ratecontrol_t
static int init_pass2(x264_t *);
static float rate_estimate_qscale( x264_t *h, int pict_type );
static void update_vbv( x264_t *h, int bits );
int x264_rc_analyse_slice( x264_t *h );
/* Terminology:
* qp = h.264's quantizer
......@@ -164,70 +173,63 @@ static inline double bits2qscale(ratecontrol_entry_t *rce, double bits)
int x264_ratecontrol_new( x264_t *h )
{
x264_ratecontrol_t *rc;
float bpp;
int i;
/* Needed(?) for 2 pass */
x264_cpu_restore( h->param.cpu );
h->rc = rc = x264_malloc( sizeof( x264_ratecontrol_t ) );
memset(rc, 0, sizeof(*rc));
rc->b_abr = h->param.rc.b_cbr && !h->param.rc.b_stat_read;
rc->b_2pass = h->param.rc.b_cbr && h->param.rc.b_stat_read;
h->mb.b_variable_qp = 0;
/* FIXME: use integers */
if(h->param.i_fps_num > 0 && h->param.i_fps_den > 0)
rc->fps = (float) h->param.i_fps_num / h->param.i_fps_den;
else
rc->fps = 25.0;
rc->gop_size = h->param.i_keyint_max;
rc->bitrate = h->param.rc.i_bitrate * 1000;
rc->rate_tolerance = h->param.rc.f_rate_tolerance;
rc->nmb = h->mb.i_mb_count;
rc->qp_constant[SLICE_TYPE_P] = h->param.rc.i_qp_constant;
rc->qp_constant[SLICE_TYPE_I] = x264_clip3( (int)( qscale2qp( qp2qscale( h->param.rc.i_qp_constant ) / fabs( h->param.rc.f_ip_factor )) + 0.5 ), 0, 51 );
rc->qp_constant[SLICE_TYPE_B] = x264_clip3( (int)( qscale2qp( qp2qscale( h->param.rc.i_qp_constant ) * fabs( h->param.rc.f_pb_factor )) + 0.5 ), 0, 51 );
/* Currently there is no adaptive quant, and per-MB ratecontrol is used only in CBR. */
h->mb.b_variable_qp = h->param.rc.b_cbr && !h->param.rc.b_stat_read;
/* Init 1pass CBR algo */
if( h->param.rc.b_cbr ){
rc->buffer_size = h->param.rc.i_rc_buffer_size * 1000;
rc->buffer_fullness = h->param.rc.i_rc_init_buffer;
rc->rcbufrate = rc->bitrate / rc->fps;
if(rc->buffer_size < rc->rcbufrate){
x264_log(h, X264_LOG_WARNING, "rc buffer size %i too small\n",
rc->buffer_size);
rc->buffer_size = 0;
}
if(rc->buffer_size <= 0)
rc->buffer_size = rc->bitrate / 2;
if(rc->buffer_fullness > rc->buffer_size || rc->buffer_fullness < 0){
x264_log(h, X264_LOG_WARNING, "invalid initial buffer fullness %i\n",
rc->buffer_fullness);
rc->buffer_fullness = 0;
rc->last_non_b_pict_type = -1;
rc->cbr_decay = 1.0;
if( h->param.rc.i_vbv_max_bitrate < h->param.rc.i_bitrate &&
h->param.rc.i_vbv_max_bitrate > 0)
x264_log(h, X264_LOG_ERROR, "max bitrate less than average bitrate, ignored.\n");
else if( h->param.rc.i_vbv_max_bitrate > 0 &&
h->param.rc.i_vbv_buffer_size > 0 )
{
if( h->param.rc.i_vbv_buffer_size < 10 * h->param.rc.i_vbv_max_bitrate / rc->fps ) {
h->param.rc.i_vbv_buffer_size = 10 * h->param.rc.i_vbv_max_bitrate / rc->fps;
x264_log( h, X264_LOG_ERROR, "VBV buffer size too small, using %d kbit\n",
h->param.rc.i_vbv_buffer_size );
}
rc->buffer_rate = h->param.rc.i_vbv_max_bitrate * 1000 / rc->fps;
rc->buffer_size = h->param.rc.i_vbv_buffer_size * 1000;
rc->buffer_fill = rc->buffer_size * h->param.rc.f_vbv_buffer_init;
rc->cbr_decay = 1.0 - rc->buffer_rate / rc->buffer_size
* 0.5 * X264_MAX(0, 1.5 - rc->buffer_rate * rc->fps / rc->bitrate);
}
else if( h->param.rc.i_vbv_max_bitrate || h->param.rc.i_vbv_buffer_size )
x264_log(h, X264_LOG_ERROR, "VBV maxrate or buffer size specified, but not both.\n");
bpp = rc->bitrate / (rc->fps * h->param.i_width * h->param.i_height);
if(bpp <= 0.6)
rc->init_qp = 31;
else if(bpp <= 1.4)
rc->init_qp = 25;
else if(bpp <= 2.4)
rc->init_qp = 20;
else
rc->init_qp = 10;
rc->gop_qp = rc->init_qp;
rc->bits_last_gop = 0;
x264_log(h, X264_LOG_DEBUG, "%f fps, %i bps, bufsize %i\n",
rc->fps, rc->bitrate, rc->buffer_size);
if( rc->b_abr )
{
/* FIXME shouldn't need to arbitrarily specify a QP,
* but this is more robust than BPP measures */
#define ABR_INIT_QP 24
rc->accum_p_norm = .01;
rc->accum_p_qp = ABR_INIT_QP * rc->accum_p_norm;
rc->cplxr_sum = .01;
rc->wanted_bits_window = .01;
}
rc->qp_constant[SLICE_TYPE_P] = h->param.rc.i_qp_constant;
rc->qp_constant[SLICE_TYPE_I] = x264_clip3( (int)( qscale2qp( qp2qscale( h->param.rc.i_qp_constant ) / fabs( h->param.rc.f_ip_factor )) + 0.5 ), 0, 51 );
rc->qp_constant[SLICE_TYPE_B] = x264_clip3( (int)( qscale2qp( qp2qscale( h->param.rc.i_qp_constant ) * fabs( h->param.rc.f_pb_factor )) + 0.5 ), 0, 51 );
rc->lstep = exp2f(h->param.rc.i_qp_step / 6.0);
rc->last_qscale = qp2qscale(26);
......@@ -236,6 +238,9 @@ int x264_ratecontrol_new( x264_t *h )
rc->last_qscale_for[i] = qp2qscale(26);
rc->lmin[i] = qp2qscale( h->param.rc.i_qp_min );
rc->lmax[i] = qp2qscale( h->param.rc.i_qp_max );
rc->pred[i].coeff= 2.0;
rc->pred[i].count= 1.0;
rc->pred[i].decay= 0.5;
}
#if 0 // FIXME: do we want to assign lmin/lmax based on ip_factor, or leave them all the same?
rc->lmin[SLICE_TYPE_I] /= fabs(h->param.f_ip_factor);
......@@ -269,12 +274,17 @@ int x264_ratecontrol_new( x264_t *h )
/* find number of pics */
p = stats_in;
for(i=-1; p; i++){
for(i=-1; p; i++)
p = strchr(p+1, ';');
if(i==0)
{
x264_log(h, X264_LOG_ERROR, "empty stats file\n");
return -1;
}
i += h->param.i_bframe;
rc->entry = (ratecontrol_entry_t*) x264_malloc(i*sizeof(ratecontrol_entry_t));
memset(rc->entry, 0, i*sizeof(ratecontrol_entry_t));
/* FIXME: num_entries is sometimes treated as number of frames in the video */
rc->num_entries= i;
/* init all to skipped p frames */
......@@ -303,8 +313,11 @@ int x264_ratecontrol_new( x264_t *h )
}
e = sscanf(p, " in:%d ", &frame_number);
assert(frame_number >= 0);
assert(frame_number < rc->num_entries);
if(frame_number < 0 || frame_number >= rc->num_entries)
{
x264_log(h, X264_LOG_ERROR, "bad frame number (%d) at stats line %d\n", frame_number, i);
return -1;
}
rce = &rc->entry[frame_number];
e += sscanf(p, " in:%*d out:%*d type:%c q:%f itex:%d ptex:%d mv:%d misc:%d imb:%d pmb:%d smb:%d",
......@@ -329,11 +342,10 @@ int x264_ratecontrol_new( x264_t *h )
x264_free(stats_in);
/* If using 2pass with constant quant, no need to run the bitrate allocation */
if(h->param.rc.b_cbr)
{
if(init_pass2(h) < 0) return -1;
}
} /* else we're using constant quant, so no need to run the bitrate allocation */
}
/* Open output file */
......@@ -376,211 +388,58 @@ void x264_ratecontrol_delete( x264_t *h )
x264_free( rc );
}
/* Before encoding a frame, choose a QP for it */
void x264_ratecontrol_start( x264_t *h, int i_slice_type, int i_force_qp )
{
x264_ratecontrol_t *rc = h->rc;
int gframes, iframes, pframes, bframes;
int minbits, maxbits;
int gbits, fbits;
int zn = 0;
float kp;
int gbuf;
rc->slice_type = i_slice_type;
x264_cpu_restore( h->param.cpu );
rc->qp_force = i_force_qp;
rc->slice_type = i_slice_type;
if( !h->param.rc.b_cbr )
if( i_force_qp )
{
int q;
if( i_force_qp )
q = i_force_qp - 1;
else if( i_slice_type == SLICE_TYPE_B && h->fdec->b_kept_as_ref )
q = ( rc->qp_constant[ SLICE_TYPE_B ] + rc->qp_constant[ SLICE_TYPE_P ] ) / 2;
else
q = rc->qp_constant[ i_slice_type ];
rc->qpm = rc->qpa = rc->qp = q;
return;
rc->qpa = rc->qp = i_force_qp - 1;
}
else if( rc->b_abr )
{
rc->qpa = rc->qp =
x264_clip3( (int)(qscale2qp( rate_estimate_qscale( h, i_slice_type ) ) + .5), 0, 51 );
}
else if( h->param.rc.b_stat_read )
else if( rc->b_2pass )
{
int frame = h->fenc->i_frame;
ratecontrol_entry_t *rce;
assert( frame >= 0 && frame < rc->num_entries );
rce = &h->rc->entry[frame];
rce = h->rc->rce = &h->rc->entry[frame];
rce->new_qscale = rate_estimate_qscale( h, i_slice_type );
rc->qpm = rc->qpa = rc->qp = rce->new_qp =
(int)(qscale2qp(rce->new_qscale) + 0.5);
return;
}
switch(i_slice_type){
case SLICE_TYPE_I:
gbuf = rc->buffer_fullness + (rc->gop_size-1) * rc->rcbufrate;
rc->bits_gop = gbuf - rc->buffer_size / 2;
if(!rc->mb && rc->pframes){
int qp = rc->qp_avg_p / rc->pframes + 0.5;
#if 0 /* JM does this without explaining why */
int gdq = (float) rc->gop_size / 15 + 0.5;
if(gdq > 2)
gdq = 2;
qp -= gdq;
if(qp > rc->qp_last_p - 2)
qp--;
#endif
qp = x264_clip3(qp, rc->gop_qp - 4, rc->gop_qp + 4);
qp = x264_clip3(qp, h->param.rc.i_qp_min, h->param.rc.i_qp_max);
rc->gop_qp = qp;
} else if(rc->frames > 4){
rc->gop_qp = rc->init_qp;
}
kp = h->param.rc.f_ip_factor * h->param.rc.f_pb_factor;
x264_log(h, X264_LOG_DEBUG,"gbuf=%i bits_gop=%i frames=%i gop_qp=%i\n",
gbuf, rc->bits_gop, rc->frames, rc->gop_qp);
rc->bits_last_gop = 0;
rc->frames = 0;
rc->pframes = 0;
rc->qp_avg_p = 0;
break;
case SLICE_TYPE_P:
kp = h->param.rc.f_pb_factor;
break;
case SLICE_TYPE_B:
kp = 1.0;
break;
default:
x264_log(h, X264_LOG_WARNING, "ratecontrol: unknown slice type %i\n",
i_slice_type);
kp = 1.0;
break;
rc->qpa = rc->qp = rce->new_qp =
x264_clip3( (int)(qscale2qp(rce->new_qscale) + 0.5), 0, 51 );
}
gframes = rc->gop_size - rc->frames;
iframes = gframes / rc->gop_size;
pframes = gframes / (h->param.i_bframe + 1) - iframes;
bframes = gframes - pframes - iframes;
gbits = rc->bits_gop - rc->bits_last_gop;
fbits = kp * gbits /
(h->param.rc.f_ip_factor * h->param.rc.f_pb_factor * iframes +
h->param.rc.f_pb_factor * pframes + bframes);
minbits = rc->buffer_fullness + rc->rcbufrate - rc->buffer_size;
if(minbits < 0)
minbits = 0;
maxbits = rc->buffer_fullness;
rc->fbits = x264_clip3(fbits, minbits, maxbits);
if(i_slice_type == SLICE_TYPE_I){
rc->qp = rc->gop_qp;
} else if(rc->ncoeffs && rc->ufbits){
int dqp, nonzc;
nonzc = (rc->ncoeffs - rc->nzcoeffs);
if(nonzc == 0)
zn = rc->ncoeffs;
else if(rc->fbits < INT_MAX / nonzc)
zn = rc->ncoeffs - rc->fbits * nonzc / rc->ufbits;
else /* CQP */
{
int q;
if( i_slice_type == SLICE_TYPE_B && h->fdec->b_kept_as_ref )
q = ( rc->qp_constant[ SLICE_TYPE_B ] + rc->qp_constant[ SLICE_TYPE_P ] ) / 2;
else
zn = 0;
zn = x264_clip3(zn, 0, rc->ncoeffs);
dqp = h->param.rc.i_rc_sens * exp2f(rc->qpa / 6) *
(zn - rc->nzcoeffs) / rc->nzcoeffs;
dqp = x264_clip3(dqp, -h->param.rc.i_qp_step, h->param.rc.i_qp_step);
rc->qp = (int)(rc->qpa + dqp + .5);
}
if(rc->fbits > 0.9 * maxbits)
rc->qp += 2;
else if(rc->fbits > 0.8 * maxbits)
rc->qp += 1;
else if(rc->fbits < 1.1 * minbits)
rc->qp -= 2;
else if(rc->fbits < 1.2 * minbits)
rc->qp -= 1;
if( i_force_qp > 0 ) {
rc->qpm = rc->qpa = rc->qp = i_force_qp - 1;
} else {
rc->qp = rc->qpm =
x264_clip3(rc->qp, h->param.rc.i_qp_min, h->param.rc.i_qp_max);
q = rc->qp_constant[ i_slice_type ];
rc->qpa = rc->qp = q;
}
x264_log(h, X264_LOG_DEBUG, "fbits=%i, qp=%i, z=%i, min=%i, max=%i\n",
rc->fbits, rc->qpm, zn, minbits, maxbits);
rc->fbits -= rc->overhead;
rc->ufbits = 0;
rc->ncoeffs = 0;
rc->nzcoeffs = 0;
rc->mb = 0;
rc->qps = 0;
}
void x264_ratecontrol_mb( x264_t *h, int bits )
{
x264_ratecontrol_t *rc = h->rc;
int rbits;
int zn, enz, nonz;
int rcoeffs;
int dqp;
int i;
x264_cpu_restore( h->param.cpu );
rc->qps += rc->qpm;
rc->ufbits += bits;
rc->mb++;
for(i = 0; i < 16 + 8; i++)
rc->nzcoeffs += 16 - h->mb.cache.non_zero_count[x264_scan8[i]];
rc->ncoeffs += 16 * (16 + 8);
if(rc->mb < rc->nmb / 16)
return;
else if(rc->mb == rc->nmb)
return;
else if(rc->qp_force > 0)
return;
rcoeffs = (rc->nmb - rc->mb) * 16 * 24;
rbits = rc->fbits - rc->ufbits;
/* if(rbits < 0) */
/* rbits = 0; */
/* zn = (rc->nmb - rc->mb) * 16 * 24; */
nonz = (rc->ncoeffs - rc->nzcoeffs);
if(nonz == 0)
zn = rcoeffs;
else if(rc->ufbits && rbits < INT_MAX / nonz)
zn = rcoeffs - rbits * nonz / rc->ufbits;
else
zn = 0;
zn = x264_clip3(zn, 0, rcoeffs);
enz = rc->nzcoeffs * (rc->nmb - rc->mb) / rc->mb;
dqp = (float) 2*h->param.rc.i_rc_sens * exp2f((float) rc->qps / rc->mb / 6) *
(zn - enz) / enz;
rc->qpm = x264_clip3(rc->qpm + dqp, rc->qp - 3, rc->qp + 3);
if(rbits <= 0)
rc->qpm++;
rc->qpm = x264_clip3(rc->qpm, h->param.rc.i_qp_min, h->param.rc.i_qp_max);
/* currently no adaptive quant */
}
int x264_ratecontrol_qp( x264_t *h )
int x264_ratecontrol_qp( x264_t *h )
{
return h->rc->qpm;
return h->rc->qp;
}
/* In 2pass, force the same frame types as in the 1st pass */
int x264_ratecontrol_slice_type( x264_t *h, int frame_num )
{
if( h->param.rc.b_stat_read )
......@@ -609,6 +468,7 @@ int x264_ratecontrol_slice_type( x264_t *h, int frame_num )
}
}
/* After encoding one frame, save stats and update ratecontrol state */
void x264_ratecontrol_end( x264_t *h, int bits )
{
x264_ratecontrol_t *rc = h->rc;
......@@ -627,7 +487,7 @@ void x264_ratecontrol_end( x264_t *h, int bits )
: rc->slice_type==SLICE_TYPE_P ? 'P'
: h->fenc->b_kept_as_ref ? 'B' : 'b';
fprintf( rc->p_stat_file_out,
"in:%d out:%d type:%c q:%.3f itex:%d ptex:%d mv:%d misc:%d imb:%d pmb:%d smb:%d;\n",
"in:%d out:%d type:%c q:%.2f itex:%d ptex:%d mv:%d misc:%d imb:%d pmb:%d smb:%d;\n",
h->fenc->i_frame, h->i_frame-1,
c_type, rc->qpa,
h->stat.frame.i_itex_bits, h->stat.frame.i_ptex_bits,
......@@ -637,50 +497,51 @@ void x264_ratecontrol_end( x264_t *h, int bits )
h->stat.frame.i_mb_count_skip);
}
if( !h->param.rc.b_cbr || h->param.rc.b_stat_read )
return;
rc->buffer_fullness += rc->rcbufrate - bits;
if(rc->buffer_fullness < 0){
x264_log(h, X264_LOG_WARNING, "buffer underflow %i\n",
rc->buffer_fullness);
rc->buffer_fullness = 0;
if( rc->b_abr )
{
if( rc->slice_type != SLICE_TYPE_B )
rc->cplxr_sum += bits * qp2qscale(rc->qpa) / rc->last_rceq;
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. */
rc->cplxr_sum += bits * qp2qscale(rc->qpa) / (rc->last_rceq * fabs(h->param.rc.f_pb_factor));
}
rc->cplxr_sum *= rc->cbr_decay;
rc->wanted_bits_window += rc->bitrate / rc->fps;
rc->wanted_bits_window *= rc->cbr_decay;
rc->accum_p_qp *= .95;
rc->accum_p_norm *= .95;
rc->accum_p_norm += 1;
if( rc->slice_type == SLICE_TYPE_I )
rc->accum_p_qp += rc->qpa * fabs(h->param.rc.f_ip_factor);
else
rc->accum_p_qp += rc->qpa;
}
rc->qpa = (float)rc->qps / rc->mb;
if(rc->slice_type == SLICE_TYPE_P){
rc->qp_avg_p += rc->qpa;
rc->qp_last_p = rc->qpa;
rc->pframes++;
} else if(rc->slice_type == SLICE_TYPE_I){
float err = (float) rc->ufbits / rc->fbits;
if(err > 1.1)
rc->gop_qp++;
else if(err < 0.9)
rc->gop_qp--;
if( rc->b_2pass )
{
rc->expected_bits_sum += qscale2bits( rc->rce, qp2qscale(rc->rce->new_qp) );
}
rc->overhead = bits - rc->ufbits;
x264_log(h, X264_LOG_DEBUG, "bits=%i, qp=%.1f, z=%i, zr=%6.3f, buf=%i\n",
bits, rc->qpa, rc->nzcoeffs, (float) rc->nzcoeffs / rc->ncoeffs,
rc->buffer_fullness);
update_vbv( h, bits );
rc->bits_last_gop += bits;
rc->frames++;
rc->mb = 0;
if( rc->slice_type != SLICE_TYPE_B )
rc->last_non_b_pict_type = rc->slice_type;
}
/****************************************************************************
* 2 pass functions
***************************************************************************/
double x264_eval( char *s, double *const_value, const char **const_name,
double (**func1)(void *, double), const char **func1_name,
double (**func2)(void *, double, double), char **func2_name,
void *opaque );
/**
* modifies the bitrate curve from pass1 for one frame
* modify the bitrate curve from pass1 for one frame
*/
static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor)
{
......@@ -789,8 +650,6 @@ static double get_diff_limited_q(x264_t *h, ratecontrol_entry_t *rce, double q)
}
/* last qscale / qdiff stuff */
/* TODO take intro account whether the I-frame is a scene cut
* or just a seek point */
if(rcc->last_non_b_pict_type==pict_type
&& (pict_type!=SLICE_TYPE_I || rcc->last_accum_p_norm < 1))
{
......@@ -820,15 +679,72 @@ static double get_diff_limited_q(x264_t *h, ratecontrol_entry_t *rce, double q)
return q;
}
// clip a qscale to between lmin and lmax
static double clip_qscale( x264_t *h, ratecontrol_entry_t *rce, double q )
static double predict_size( predictor_t *p, double q, double var )
{
return p->coeff*var / (q*p->count);
}
static void update_predictor( predictor_t *p, double q, double var, double bits )
{
p->count *= p->decay;
p->coeff *= p->decay;
p->count ++;
p->coeff += bits*q / var;
}
static void update_vbv( x264_t *h, int bits )
{
x264_ratecontrol_t *rcc = h->rc;
if( !rcc->buffer_size )
return;
rcc->buffer_fill += rcc->buffer_rate - bits;
if( rcc->buffer_fill < 0 && !rcc->b_2pass )
x264_log( h, X264_LOG_WARNING, "VBV underflow (%.0f bits)\n", rcc->buffer_fill );
rcc->buffer_fill = x264_clip3( rcc->buffer_fill, 0, rcc->buffer_size );
if(rcc->last_satd > 100)
update_predictor( &rcc->pred[rcc->slice_type], qp2qscale(rcc->qpa), rcc->last_satd, bits );
}
// apply VBV constraints and clip qscale to between lmin and lmax
static double clip_qscale( x264_t *h, int pict_type, double q )
{
double lmin = h->rc->lmin[rce->pict_type];
double lmax = h->rc->lmax[rce->pict_type];
x264_ratecontrol_t *rcc = h->rc;