Commit b8692db2 authored by Loren Merritt's avatar Loren Merritt

api change: select ratecontrol method with an enum (param.rc.i_rc_method)...

api change: select ratecontrol method with an enum (param.rc.i_rc_method) instead of a bunch of booleans.


git-svn-id: svn://svn.videolan.org/x264/trunk@537 df754926-b1dd-0310-bc7b-ec298dee348c
parent 4e7bd4a1
......@@ -80,7 +80,7 @@ void x264_param_default( x264_param_t *param )
param->b_cabac = 1;
param->i_cabac_init_idc = 0;
param->rc.b_cbr = 0;
param->rc.i_rc_method = X264_RC_CQP;
param->rc.i_bitrate = 0;
param->rc.f_rate_tolerance = 1.0;
param->rc.i_vbv_max_bitrate = 0;
......@@ -494,12 +494,12 @@ char *x264_param2string( x264_param_t *p, int b_res )
s += sprintf( s, " keyint=%d keyint_min=%d scenecut=%d",
p->i_keyint_max, p->i_keyint_min, p->i_scenecut_threshold );
s += sprintf( s, " rc=%s", p->rc.b_stat_read && p->rc.b_cbr ? "2pass" :
p->rc.b_cbr ? p->rc.i_vbv_buffer_size ? "cbr" : "abr" :
p->rc.i_rf_constant ? "crf" : "cqp" );
if( p->rc.b_cbr || p->rc.i_rf_constant )
s += sprintf( s, " rc=%s", p->rc.i_rc_method == X264_RC_ABR ?
( p->rc.b_stat_read ? "2pass" : p->rc.i_vbv_buffer_size ? "cbr" : "abr" )
: p->rc.i_rc_method == X264_RC_CRF ? "crf" : "cqp" );
if( p->rc.i_rc_method == X264_RC_ABR || p->rc.i_rc_method == X264_RC_CRF )
{
if( p->rc.i_rf_constant )
if( p->rc.i_rc_method == X264_RC_CRF )
s += sprintf( s, " crf=%d", p->rc.i_rf_constant );
else
s += sprintf( s, " bitrate=%d ratetol=%.1f",
......@@ -514,9 +514,9 @@ char *x264_param2string( x264_param_t *p, int b_res )
s += sprintf( s, " vbv_maxrate=%d vbv_bufsize=%d",
p->rc.i_vbv_max_bitrate, p->rc.i_vbv_buffer_size );
}
else
else if( p->rc.i_rc_method == X264_RC_CQP )
s += sprintf( s, " qp=%d", p->rc.i_qp_constant );
if( p->rc.b_cbr || p->rc.i_qp_constant != 0 )
if( !(p->rc.i_rc_method == X264_RC_CQP && p->rc.i_qp_constant == 0) )
{
s += sprintf( s, " ip_ratio=%.2f", p->rc.f_ip_factor );
if( p->i_bframe )
......
......@@ -422,7 +422,7 @@ static void x264_mb_analyse_intra_chroma( x264_t *h, x264_mb_analysis_t *a )
int i;
int i_max;
int predict_mode[9];
int predict_mode[4];
uint8_t *p_dstc[2], *p_srcc[2];
......
......@@ -341,20 +341,25 @@ static int x264_validate_parameters( x264_t *h )
}
#endif
if( h->param.rc.b_cbr )
h->param.rc.i_rf_constant = 0;
if( h->param.rc.i_rf_constant > 0 )
h->param.rc.i_qp_constant = h->param.rc.i_rf_constant;
if( h->param.rc.i_rc_method < 0 || h->param.rc.i_rc_method > 2 )
{
x264_log( h, X264_LOG_ERROR, "invalid RC method\n" );
return -1;
}
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 )
if( h->param.rc.i_rc_method == X264_RC_CRF )
h->param.rc.i_qp_constant = h->param.rc.i_rf_constant;
if( (h->param.rc.i_rc_method == X264_RC_CQP || h->param.rc.i_rc_method == X264_RC_CRF)
&& h->param.rc.i_qp_constant == 0 )
{
h->mb.b_lossless = 1;
h->param.analyse.b_transform_8x8 = 0;
h->param.i_cqm_preset = X264_CQM_FLAT;
h->param.psz_cqm_file = NULL;
h->param.rc.i_rc_method = X264_RC_CQP;
h->param.rc.f_ip_factor = 1;
h->param.rc.f_pb_factor = 1;
h->param.analyse.b_transform_8x8 = 0;
h->param.analyse.b_psnr = 0;
h->param.analyse.i_chroma_qp_offset = 0;
h->param.analyse.i_trellis = 0;
......@@ -448,7 +453,6 @@ static int x264_validate_parameters( x264_t *h )
BOOLIFY( analyse.b_bidir_me );
BOOLIFY( analyse.b_chroma_me );
BOOLIFY( analyse.b_fast_pskip );
BOOLIFY( rc.b_cbr );
BOOLIFY( rc.b_stat_write );
BOOLIFY( rc.b_stat_read );
#undef BOOLIFY
......@@ -522,7 +526,7 @@ x264_t *x264_encoder_open ( x264_param_t *param )
/* Init x264_t */
h->out.i_nal = 0;
h->out.i_bitstream = X264_MAX( 1000000, h->param.i_width * h->param.i_height * 1.7
* ( h->param.rc.b_cbr ? pow( 0.5, h->param.rc.i_qp_min )
* ( h->param.rc.i_rc_method == X264_RC_ABR ? pow( 0.5, h->param.rc.i_qp_min )
: pow( 0.5, h->param.rc.i_qp_constant ) * X264_MAX( 1, h->param.rc.f_ip_factor )));
h->out.p_bitstream = x264_malloc( h->out.i_bitstream );
......@@ -548,7 +552,9 @@ 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.rc.i_rf_constant || h->param.b_bframe_adaptive );
&& ( h->param.rc.i_rc_method == X264_RC_ABR
|| h->param.rc.i_rc_method == X264_RC_CRF
|| h->param.b_bframe_adaptive );
for( i = 0; i < X264_BFRAME_MAX + 3; i++ )
{
......
......@@ -200,8 +200,8 @@ int x264_ratecontrol_new( x264_t *h )
h->rc = rc = x264_malloc( h->param.i_threads * sizeof(x264_ratecontrol_t) );
memset( rc, 0, h->param.i_threads * sizeof(x264_ratecontrol_t) );
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;
rc->b_abr = h->param.rc.i_rc_method != X264_RC_CQP && !h->param.rc.b_stat_read;
rc->b_2pass = h->param.rc.i_rc_method == X264_RC_ABR && h->param.rc.b_stat_read;
/* FIXME: use integers */
if(h->param.i_fps_num > 0 && h->param.i_fps_den > 0)
......@@ -215,18 +215,20 @@ int x264_ratecontrol_new( x264_t *h )
rc->last_non_b_pict_type = -1;
rc->cbr_decay = 1.0;
if( h->param.rc.i_rf_constant && h->param.rc.b_stat_read )
if( h->param.rc.i_rc_method == X264_RC_CRF && h->param.rc.b_stat_read )
{
x264_log(h, X264_LOG_ERROR, "constant rate-factor is incompatible with 2pass.\n");
return -1;
}
if( h->param.rc.i_vbv_buffer_size && !h->param.rc.b_cbr && !h->param.rc.i_rf_constant )
x264_log(h, X264_LOG_WARNING, "VBV is incompatible with constant QP.\n");
if( h->param.rc.i_vbv_buffer_size && h->param.rc.b_cbr
&& h->param.rc.i_vbv_max_bitrate == 0 )
if( h->param.rc.i_vbv_buffer_size )
{
x264_log( h, X264_LOG_DEBUG, "VBV maxrate unspecified, assuming CBR\n" );
h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
if( h->param.rc.i_rc_method == X264_RC_CQP )
x264_log(h, X264_LOG_WARNING, "VBV is incompatible with constant QP, ignored.\n");
else if( h->param.rc.i_vbv_max_bitrate == 0 )
{
x264_log( h, X264_LOG_DEBUG, "VBV maxrate unspecified, assuming CBR\n" );
h->param.rc.i_vbv_max_bitrate = h->param.rc.i_bitrate;
}
}
if( h->param.rc.i_vbv_max_bitrate < h->param.rc.i_bitrate &&
h->param.rc.i_vbv_max_bitrate > 0)
......@@ -259,14 +261,14 @@ 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 ( h->param.rc.i_rf_constant > 0 ? h->param.rc.i_rf_constant : 24 )
#define ABR_INIT_QP ( h->param.rc.i_rc_method == X264_RC_CRF ? 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 )
if( h->param.rc.i_rc_method == X264_RC_CRF )
{
/* arbitrary rescaling to make CRF somewhat similar to QP */
double base_cplx = h->mb.i_mb_count * (h->param.i_bframe ? 120 : 80);
......@@ -342,7 +344,7 @@ int x264_ratecontrol_new( x264_t *h )
x264_log( h, X264_LOG_WARNING, "different keyint than 1st pass (%d vs %d)\n",
h->param.i_keyint_max, i );
if( strstr( opts, "qp=0" ) && h->param.rc.b_cbr )
if( strstr( opts, "qp=0" ) && h->param.rc.i_rc_method == X264_RC_ABR )
x264_log( h, X264_LOG_WARNING, "1st pass was lossless, bitrate prediction will be inaccurate\n" );
}
......@@ -432,7 +434,7 @@ int x264_ratecontrol_new( x264_t *h )
x264_free(stats_buf);
if(h->param.rc.b_cbr)
if(h->param.rc.i_rc_method == X264_RC_ABR)
{
if(init_pass2(h) < 0) return -1;
} /* else we're using constant quant, so no need to run the bitrate allocation */
......@@ -524,7 +526,7 @@ static int parse_zones( x264_t *h )
void x264_ratecontrol_summary( x264_t *h )
{
x264_ratecontrol_t *rc = h->rc;
if( rc->b_abr && !h->param.rc.i_rf_constant && !h->param.rc.i_vbv_max_bitrate )
if( rc->b_abr && h->param.rc.i_rc_method == X264_RC_ABR && !h->param.rc.i_vbv_max_bitrate )
{
double base_cplx = h->mb.i_mb_count * (h->param.i_bframe ? 120 : 80);
x264_log( h, X264_LOG_INFO, "final ratefactor: %.2f\n",
......@@ -739,7 +741,7 @@ int x264_ratecontrol_slice_type( x264_t *h, int frame_num )
rc->b_abr = 0;
rc->b_2pass = 0;
h->param.rc.b_cbr = 0;
h->param.rc.i_rc_method = X264_RC_CQP;
h->param.rc.b_stat_read = 0;
h->param.b_bframe_adaptive = 0;
if( h->param.i_bframe > 1 )
......@@ -1235,7 +1237,7 @@ static float rate_estimate_qscale(x264_t *h, int pict_type)
rce.qscale = 1;
rce.pict_type = pict_type;
if( h->param.rc.i_rf_constant )
if( h->param.rc.i_rc_method == X264_RC_CRF )
{
q = get_qscale( h, &rce, rcc->rate_factor_constant, h->fenc->i_frame );
overflow = 1;
......
......@@ -77,7 +77,7 @@ void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
{
sps->i_id = i_id;
sps->b_qpprime_y_zero_transform_bypass = !param->rc.b_cbr && param->rc.i_qp_constant == 0;
sps->b_qpprime_y_zero_transform_bypass = param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0;
if( sps->b_qpprime_y_zero_transform_bypass )
sps->i_profile_idc = PROFILE_HIGH444;
else if( param->analyse.b_transform_8x8 || param->i_cqm_preset != X264_CQM_FLAT )
......@@ -376,7 +376,7 @@ void x264_pps_init( x264_pps_t *pps, int i_id, x264_param_t *param, x264_sps_t *
pps->b_weighted_pred = 0;
pps->b_weighted_bipred = param->analyse.b_weighted_bipred ? 2 : 0;
pps->i_pic_init_qp = param->rc.b_cbr ? 26 : param->rc.i_qp_constant;
pps->i_pic_init_qp = param->rc.i_rc_method == X264_RC_ABR ? 26 : param->rc.i_qp_constant;
pps->i_pic_init_qs = 26;
pps->i_chroma_qp_index_offset = param->analyse.i_chroma_qp_offset;
......
......@@ -282,10 +282,11 @@ LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiO
switch( config->i_encoding_type )
{
case 0: /* 1 PASS ABR */
param.rc.b_cbr = 1;
param.rc.i_rc_method = X264_RC_ABR;
param.rc.i_bitrate = config->bitrate;
break;
case 1: /* 1 PASS CQ */
param.rc.i_rc_method = X264_RC_CQP;
param.rc.i_qp_constant = config->i_qp;
break;
default:
......@@ -312,8 +313,8 @@ LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiO
return ICERR_ERROR;
}
param.rc.i_rc_method = X264_RC_ABR;
param.rc.i_bitrate = config->i_2passbitrate;
param.rc.b_cbr = 1;
if( config->i_pass == 1 )
{
......
......@@ -560,10 +560,11 @@ static int Parse( int argc, char **argv,
break;
case 'B':
param->rc.i_bitrate = atol( optarg );
param->rc.b_cbr = 1;
param->rc.i_rc_method = X264_RC_ABR;
break;
case OPT_CRF:
param->rc.i_rf_constant = atol( optarg );
param->rc.i_rc_method = X264_RC_CRF;
break;
case 'b':
param->i_bframe = atol( optarg );
......@@ -603,6 +604,7 @@ static int Parse( int argc, char **argv,
}
case 'q':
param->rc.i_qp_constant = atoi( optarg );
param->rc.i_rc_method = X264_RC_CQP;
break;
case OPT_QPMIN:
param->rc.i_qp_min = atoi( optarg );
......
......@@ -35,7 +35,7 @@
#include <stdarg.h>
#define X264_BUILD 47
#define X264_BUILD 48
/* x264_t:
* opaque handler for decoder and encoder */
......@@ -73,6 +73,10 @@ typedef struct x264_t x264_t;
#define X264_CQM_JVT 1
#define X264_CQM_CUSTOM 2
#define X264_RC_CQP 0
#define X264_RC_CRF 1
#define X264_RC_ABR 2
static const char * const x264_direct_pred_names[] = { "none", "spatial", "temporal", "auto", 0 };
static const char * const x264_motion_est_names[] = { "dia", "hex", "umh", "esa", 0 };
......@@ -212,12 +216,13 @@ typedef struct
/* Rate control parameters */
struct
{
int i_rc_method; /* X264_RC_* */
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;
......
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