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;
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",
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 )
int i;
int i_max;
- int predict_mode[9];
+ int predict_mode[4];
uint8_t *p_dstc[2], *p_srcc[2];
}
#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;
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
/* 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 );
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++ )
{
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)
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)
{
/* 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);
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" );
}
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 */
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",
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 )
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;
{
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 )
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;
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:
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 )
{
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 );
}
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 );
#include <stdarg.h>
-#define X264_BUILD 47
+#define X264_BUILD 48
/* x264_t:
* opaque handler for decoder and encoder */
#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 };
/* 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;