Skip to content

Commit

Permalink
Improve quantizer handling
Browse files Browse the repository at this point in the history
The default value for i_qpplus1 in x264_picture_t is now X264_QP_AUTO.  This is currently 0, but may change in the future.
qpfiles no longer use -1 to indicate "auto"; QP is just omitted.  The old method should still work though.

CRF values now make sense in high bit depth mode.
--qp should be used for lossless mode, not --crf.
--crf 0 will still work as expected in 8-bit mode, but won't be lossless with higher bit depths.
Add bit depth to statsfiles.

These changes are required to make the QP interface sensible in combination with high bit depth.
  • Loading branch information
Fiona Glaser committed Nov 10, 2010
1 parent d50a5bf commit 2f2ab0f
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 29 deletions.
5 changes: 3 additions & 2 deletions common/common.c
Expand Up @@ -97,7 +97,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 = 23 + QP_BD_OFFSET;
param->rc.f_rf_constant = 23 + QP_BD_OFFSET;
param->rc.f_rf_constant = 23;
param->rc.i_qp_min = 10;
param->rc.i_qp_max = QP_MAX;
param->rc.i_qp_step = 4;
Expand Down Expand Up @@ -1038,7 +1038,7 @@ void x264_picture_init( x264_picture_t *pic )
{
memset( pic, 0, sizeof( x264_picture_t ) );
pic->i_type = X264_TYPE_AUTO;
pic->i_qpplus1 = 0;
pic->i_qpplus1 = X264_QP_AUTO;
pic->i_pic_struct = PIC_STRUCT_AUTO;
}

Expand Down Expand Up @@ -1197,6 +1197,7 @@ char *x264_param2string( x264_param_t *p, int b_res )
s += sprintf( s, "%dx%d ", p->i_width, p->i_height );
s += sprintf( s, "fps=%u/%u ", p->i_fps_num, p->i_fps_den );
s += sprintf( s, "timebase=%u/%u ", p->i_timebase_num, p->i_timebase_den );
s += sprintf( s, "bitdepth=%d", BIT_DEPTH );
}

s += sprintf( s, "cabac=%d", p->b_cabac );
Expand Down
2 changes: 1 addition & 1 deletion common/frame.c
Expand Up @@ -78,7 +78,7 @@ x264_frame_t *x264_frame_new( x264_t *h, int b_fdec )

frame->i_poc = -1;
frame->i_type = X264_TYPE_AUTO;
frame->i_qpplus1 = 0;
frame->i_qpplus1 = X264_QP_AUTO;
frame->i_pts = -1;
frame->i_frame = -1;
frame->i_frame_num = -1;
Expand Down
4 changes: 2 additions & 2 deletions encoder/encoder.c
Expand Up @@ -488,11 +488,11 @@ static int x264_validate_parameters( x264_t *h )
x264_log( h, X264_LOG_ERROR, "no ratecontrol method specified\n" );
return -1;
}
h->param.rc.f_rf_constant = x264_clip3f( h->param.rc.f_rf_constant, 0, QP_MAX );
h->param.rc.f_rf_constant = x264_clip3f( h->param.rc.f_rf_constant, -QP_BD_OFFSET, 51 );
h->param.rc.i_qp_constant = x264_clip3( h->param.rc.i_qp_constant, 0, QP_MAX );
if( h->param.rc.i_rc_method == X264_RC_CRF )
{
h->param.rc.i_qp_constant = h->param.rc.f_rf_constant;
h->param.rc.i_qp_constant = h->param.rc.f_rf_constant + QP_BD_OFFSET;
h->param.rc.i_bitrate = 0;
}
if( (h->param.rc.i_rc_method == X264_RC_CQP || h->param.rc.i_rc_method == X264_RC_CRF)
Expand Down
10 changes: 4 additions & 6 deletions encoder/ratecontrol.c
Expand Up @@ -90,7 +90,6 @@ struct x264_ratecontrol_t
float qpa_rc; /* average of macroblocks' qp before aq */
float qpa_aq; /* average of macroblocks' qp after aq */
float qp_novbv; /* QP for the current frame if 1-pass VBV was disabled. */
int qp_force;

/* VBV stuff */
double buffer_size;
Expand Down Expand Up @@ -456,7 +455,7 @@ void x264_ratecontrol_init_reconfigurable( x264_t *h, int b_init )
double base_cplx = h->mb.i_mb_count * (h->param.i_bframe ? 120 : 80);
double mbtree_offset = h->param.rc.b_mb_tree ? (1.0-h->param.rc.f_qcompress)*13.5 : 0;
rc->rate_factor_constant = pow( base_cplx, 1 - rc->qcompress )
/ qp2qscale( h->param.rc.f_rf_constant + mbtree_offset );
/ qp2qscale( h->param.rc.f_rf_constant + mbtree_offset + QP_BD_OFFSET );
}

if( h->param.rc.i_vbv_max_bitrate > 0 && h->param.rc.i_vbv_buffer_size > 0 )
Expand Down Expand Up @@ -621,7 +620,7 @@ int x264_ratecontrol_new( x264_t *h )
if( rc->b_abr )
{
/* FIXME ABR_INIT_QP is actually used only in CRF */
#define ABR_INIT_QP ( h->param.rc.i_rc_method == X264_RC_CRF ? h->param.rc.f_rf_constant : 24 )
#define ABR_INIT_QP (( h->param.rc.i_rc_method == X264_RC_CRF ? h->param.rc.f_rf_constant : 24 ) + QP_BD_OFFSET)
rc->accum_p_norm = .01;
rc->accum_p_qp = ABR_INIT_QP * rc->accum_p_norm;
/* estimated ratio that produces a reasonable QP for the first I-frame */
Expand Down Expand Up @@ -732,6 +731,7 @@ int x264_ratecontrol_new( x264_t *h )
return -1;
}

CMP_OPT_FIRST_PASS( "bitdepth", BIT_DEPTH );
CMP_OPT_FIRST_PASS( "weightp", X264_MAX( 0, h->param.analyse.i_weighted_pred ) );
CMP_OPT_FIRST_PASS( "bframes", h->param.i_bframe );
CMP_OPT_FIRST_PASS( "b_pyramid", h->param.i_bframe_pyramid );
Expand Down Expand Up @@ -1173,8 +1173,6 @@ void x264_ratecontrol_start( x264_t *h, int i_force_qp, int overhead )
x264_encoder_reconfig( h, zone->param );
rc->prev_zone = zone;

rc->qp_force = i_force_qp;

if( h->param.rc.b_stat_read )
{
int frame = h->fenc->i_frame;
Expand Down Expand Up @@ -1230,7 +1228,7 @@ void x264_ratecontrol_start( x264_t *h, int i_force_qp, int overhead )
if( h->sh.i_type != SLICE_TYPE_B )
rc->bframes = h->fenc->i_bframes;

if( i_force_qp )
if( i_force_qp != X264_QP_AUTO )
{
q = i_force_qp - 1;
}
Expand Down
25 changes: 9 additions & 16 deletions x264.c
Expand Up @@ -381,7 +381,7 @@ static void help( x264_param_t *defaults, int longhelp )
H0( " x264 --pass 2 --bitrate 1000 -o <output> <input>\n" );
H0( "\n" );
H0( " Lossless:\n" );
H0( " x264 --crf 0 -o <output> <input>\n" );
H0( " x264 --qp 0 -o <output> <input>\n" );
H0( "\n" );
H0( " Maximum PSNR at the cost of speed and visual quality:\n" );
H0( " x264 --preset placebo --tune psnr -o <output> <input>\n" );
Expand Down Expand Up @@ -538,7 +538,7 @@ static void help( x264_param_t *defaults, int longhelp )
H0( "\n" );
H1( " -q, --qp <integer> Force constant QP (0-%d, 0=lossless)\n", QP_MAX );
H0( " -B, --bitrate <integer> Set bitrate (kbit/s)\n" );
H0( " --crf <float> Quality-based VBR (0-%d, 0=lossless) [%.1f]\n", QP_MAX, defaults->rc.f_rf_constant );
H0( " --crf <float> Quality-based VBR (%d-51) [%.1f]\n", 51 - QP_MAX, defaults->rc.f_rf_constant );
H1( " --rc-lookahead <integer> Number of frames for frametype lookahead [%d]\n", defaults->rc.i_lookahead );
H0( " --vbv-maxrate <integer> Max local bitrate (kbit/s) [%d]\n", defaults->rc.i_vbv_max_bitrate );
H0( " --vbv-bufsize <integer> Set size of the VBV buffer (kbit) [%d]\n", defaults->rc.i_vbv_buffer_size );
Expand Down Expand Up @@ -576,7 +576,7 @@ static void help( x264_param_t *defaults, int longhelp )
" or b=<float> (bitrate multiplier)\n" );
H2( " --qpfile <string> Force frametypes and QPs for some or all frames\n"
" Format of each line: framenumber frametype QP\n"
" QP of -1 lets x264 choose. Frametypes: I,i,K,P,B,b.\n"
" QP is optional (none lets x264 choose). Frametypes: I,i,K,P,B,b.\n"
" K=<I or i> depending on open-gop setting\n"
" QPs are restricted by qpmin/qpmax.\n" );
H1( "\n" );
Expand Down Expand Up @@ -1485,30 +1485,29 @@ static void parse_qpfile( cli_opt_t *opt, x264_picture_t *pic, int i_frame )
{
file_pos = ftell( opt->qpfile );
ret = fscanf( opt->qpfile, "%d %c %d\n", &num, &type, &qp );
pic->i_type = X264_TYPE_AUTO;
pic->i_qpplus1 = X264_QP_AUTO;
if( num > i_frame || ret == EOF )
{
pic->i_type = X264_TYPE_AUTO;
pic->i_qpplus1 = 0;
fseek( opt->qpfile, file_pos, SEEK_SET );
break;
}
if( num < i_frame && ret == 3 )
continue;
pic->i_qpplus1 = qp+1;
if( ret == 3 && qp >= 0 )
pic->i_qpplus1 = qp+1;
if ( type == 'I' ) pic->i_type = X264_TYPE_IDR;
else if( type == 'i' ) pic->i_type = X264_TYPE_I;
else if( type == 'K' ) pic->i_type = X264_TYPE_KEYFRAME;
else if( type == 'P' ) pic->i_type = X264_TYPE_P;
else if( type == 'B' ) pic->i_type = X264_TYPE_BREF;
else if( type == 'b' ) pic->i_type = X264_TYPE_B;
else ret = 0;
if( ret != 3 || qp < -1 || qp > QP_MAX )
if( ret < 2 || qp < -1 || qp > QP_MAX )
{
x264_cli_log( "x264", X264_LOG_ERROR, "can't parse qpfile for frame %d\n", i_frame );
fclose( opt->qpfile );
opt->qpfile = NULL;
pic->i_type = X264_TYPE_AUTO;
pic->i_qpplus1 = 0;
break;
}
}
Expand Down Expand Up @@ -1594,7 +1593,6 @@ static int encode( x264_param_t *param, cli_opt_t *opt )

opt->b_progress &= param->i_log_level < X264_LOG_DEBUG;
i_update_interval = param->i_frame_total ? x264_clip3( param->i_frame_total / 1000, 1, 10 ) : 10;
x264_picture_init( &pic );

/* set up pulldown */
if( opt->i_pulldown && !param->b_vfr_input )
Expand Down Expand Up @@ -1649,6 +1647,7 @@ static int encode( x264_param_t *param, cli_opt_t *opt )
{
if( filter.get_frame( opt->hin, &cli_pic, i_frame + opt->i_seek ) )
break;
x264_picture_init( &pic );
convert_cli_to_lib_pic( &pic, &cli_pic );

if( !param->b_vfr_input )
Expand Down Expand Up @@ -1681,12 +1680,6 @@ static int encode( x264_param_t *param, cli_opt_t *opt )

if( opt->qpfile )
parse_qpfile( opt, &pic, i_frame + opt->i_seek );
else
{
/* Do not force any parameters */
pic.i_type = X264_TYPE_AUTO;
pic.i_qpplus1 = 0;
}

prev_dts = last_dts;
i_frame_size = encode_frame( h, opt->hout, &pic, &last_dts );
Expand Down
5 changes: 3 additions & 2 deletions x264.h
Expand Up @@ -143,6 +143,7 @@ typedef struct
#define X264_RC_CQP 0
#define X264_RC_CRF 1
#define X264_RC_ABR 2
#define X264_QP_AUTO 0
#define X264_AQ_NONE 0
#define X264_AQ_VARIANCE 1
#define X264_AQ_AUTOVARIANCE 2
Expand Down Expand Up @@ -343,7 +344,7 @@ typedef struct x264_param_t
{
int i_rc_method; /* X264_RC_* */

int i_qp_constant; /* 0 to (51 + 6*(x264_bit_depth-8)) */
int i_qp_constant; /* 0 to (51 + 6*(x264_bit_depth-8)). 0=lossless */
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 */
Expand Down Expand Up @@ -658,7 +659,7 @@ typedef struct
* mixing of auto and forced frametypes is done.
* Out: type of the picture encoded */
int i_type;
/* In: force quantizer for > 0 */
/* In: force quantizer for != X264_QP_AUTO */
int i_qpplus1;
/* In: pic_struct, for pulldown/doubling/etc...used only if b_pic_timing_sei=1.
* use pic_struct_e for pic_struct inputs */
Expand Down

0 comments on commit 2f2ab0f

Please sign in to comment.