Commit 0ddc9d55 authored by Loren Merritt's avatar Loren Merritt

--crf: 1pass quality-based VBR.



git-svn-id: svn://svn.videolan.org/x264/trunk@334 df754926-b1dd-0310-bc7b-ec298dee348c
parent 06f1dafd
......@@ -89,6 +89,7 @@ void x264_param_default( x264_param_t *param )
param->rc.i_vbv_buffer_size = 0;
param->rc.f_vbv_buffer_init = 0.9;
param->rc.i_qp_constant = 26;
param->rc.i_rf_constant = 0;
param->rc.i_qp_min = 10;
param->rc.i_qp_max = 51;
param->rc.i_qp_step = 4;
......
......@@ -352,6 +352,10 @@ static int x264_validate_parameters( x264_t *h )
}
#endif
if( h->param.rc.i_rf_constant > 0 )
h->param.rc.i_qp_constant = h->param.rc.i_rf_constant;
h->param.rc.i_rf_constant = x264_clip3( h->param.rc.i_rf_constant, 0, 51 );
h->param.rc.i_qp_constant = x264_clip3( h->param.rc.i_qp_constant, 0, 51 );
if( !h->param.rc.b_cbr && h->param.rc.i_qp_constant == 0 )
{
h->mb.b_lossless = 1;
......@@ -412,7 +416,6 @@ static int x264_validate_parameters( x264_t *h )
h->param.rc.f_qblur = 0;
if( h->param.rc.f_complexity_blur < 0 )
h->param.rc.f_complexity_blur = 0;
h->param.rc.i_qp_constant = x264_clip3(h->param.rc.i_qp_constant, 0, 51);
return 0;
}
......@@ -519,7 +522,7 @@ x264_t *x264_encoder_open ( x264_param_t *param )
h->frames.i_max_ref1 = h->sps->vui.i_num_reorder_frames;
h->frames.i_max_dpb = h->sps->vui.i_max_dec_frame_buffering + 1;
h->frames.b_have_lowres = !h->param.rc.b_stat_read
&& ( h->param.rc.b_cbr || h->param.b_bframe_adaptive );
&& ( h->param.rc.b_cbr || h->param.rc.i_rf_constant || h->param.b_bframe_adaptive );
for( i = 0; i < X264_BFRAME_MAX + 3; i++ )
{
......
......@@ -105,6 +105,7 @@ struct x264_ratecontrol_t
double cbr_decay;
double short_term_cplxsum;
double short_term_cplxcount;
double rate_factor_constant;
/* 2pass stuff */
FILE *p_stat_file_out;
......@@ -173,7 +174,7 @@ int x264_ratecontrol_new( x264_t *h )
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_abr = ( h->param.rc.b_cbr || h->param.rc.i_rf_constant ) && !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;
......@@ -189,6 +190,8 @@ int x264_ratecontrol_new( x264_t *h )
rc->last_non_b_pict_type = -1;
rc->cbr_decay = 1.0;
if( rc->b_2pass && h->param.rc.i_rf_constant )
x264_log(h, X264_LOG_ERROR, "constant rate-factor is incompatible with 2pass.\n");
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");
......@@ -217,13 +220,21 @@ int x264_ratecontrol_new( x264_t *h )
{
/* FIXME shouldn't need to arbitrarily specify a QP,
* but this is more robust than BPP measures */
#define ABR_INIT_QP 24
#define ABR_INIT_QP ( h->param.rc.i_rf_constant > 0 ? h->param.rc.i_rf_constant : 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;
}
if( h->param.rc.i_rf_constant )
{
/* arbitrary rescaling to make CRF somewhat similar to QP */
double base_cplx = h->mb.i_mb_count * (h->param.i_bframe ? 120 : 80);
rc->rate_factor_constant = pow( base_cplx, 1 - h->param.rc.f_qcompress )
/ qp2qscale( h->param.rc.i_rf_constant );
}
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 );
......@@ -895,12 +906,21 @@ static float rate_estimate_qscale(x264_t *h, int pict_type)
rce.s_count = 0;
rce.qscale = 1;
rce.pict_type = pict_type;
q = get_qscale(h, &rce, rcc->wanted_bits_window / rcc->cplxr_sum, h->fenc->i_frame);
if( h->param.rc.i_rf_constant )
{
q = get_qscale( h, &rce, rcc->rate_factor_constant, h->fenc->i_frame );
overflow = 1;
}
else
{
q = get_qscale( h, &rce, rcc->wanted_bits_window / rcc->cplxr_sum, h->fenc->i_frame );
wanted_bits = h->fenc->i_frame * rcc->bitrate / rcc->fps;
abr_buffer *= X264_MAX( 1, sqrt(h->fenc->i_frame/25) );
overflow = x264_clip3f( 1.0 + (total_bits - wanted_bits) / abr_buffer, .5, 2 );
q *= overflow;
}
if( pict_type == SLICE_TYPE_I
/* should test _next_ pict type, but that isn't decided yet */
......
......@@ -206,6 +206,7 @@ static void Help( x264_param_t *defaults )
"\n"
" -q, --qp <integer> Set QP (0=lossless) [%d]\n"
" -B, --bitrate <integer> Set bitrate\n"
" --crf <integer> Quality-based VBR (nominal QP)\n"
" --qpmin <integer> Set min QP [%d]\n"
" --qpmax <integer> Set max QP [%d]\n"
" --qpstep <integer> Set max QP step [%d]\n"
......@@ -470,6 +471,7 @@ static int Parse( int argc, char **argv,
#define OPT_COLOURMATRIX 312
#define OPT_CHROMALOC 313
#define OPT_MIXED_REFS 314
#define OPT_CRF 315
static struct option long_options[] =
{
......@@ -489,6 +491,7 @@ static int Parse( int argc, char **argv,
{ "qpmin", required_argument, NULL, OPT_QPMIN },
{ "qpmax", required_argument, NULL, OPT_QPMAX },
{ "qpstep", required_argument, NULL, OPT_QPSTEP },
{ "crf", required_argument, NULL, OPT_CRF },
{ "ref", required_argument, NULL, 'r' },
{ "no-asm", no_argument, NULL, 'C' },
{ "sar", required_argument, NULL, OPT_SAR },
......@@ -571,6 +574,9 @@ static int Parse( int argc, char **argv,
param->rc.i_bitrate = atol( optarg );
param->rc.b_cbr = 1;
break;
case OPT_CRF:
param->rc.i_rf_constant = atol( optarg );
break;
case 'b':
param->i_bframe = atol( optarg );
break;
......
......@@ -35,7 +35,7 @@
#include <stdarg.h>
#define X264_BUILD 36
#define X264_BUILD 37
/* x264_t:
* opaque handler for decoder and encoder */
......@@ -204,13 +204,14 @@ typedef struct
/* Rate control parameters */
struct
{
int i_qp_constant; /* 1-51 */
int i_qp_constant; /* 0-51 */
int i_qp_min; /* min allowed QP value */
int i_qp_max; /* max allowed QP value */
int i_qp_step; /* max QP step between frames */
int b_cbr; /* use bitrate instead of CQP */
int i_bitrate;
int i_rf_constant; /* 1pass VBR, nominal QP */
float f_rate_tolerance;
int i_vbv_max_bitrate;
int i_vbv_buffer_size;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment