Commit 71f820d7 authored by Loren Merritt's avatar Loren Merritt

improved 2pass ratecontrol:

ensures that I-frames have comparable quantizer to the following P-frames,
and produces more consistent quality in areas of fluctuating complexity.


git-svn-id: svn://svn.videolan.org/x264/trunk@61 df754926-b1dd-0310-bc7b-ec298dee348c
parent 7972ae1f
...@@ -78,16 +78,17 @@ void x264_param_default( x264_param_t *param ) ...@@ -78,16 +78,17 @@ void x264_param_default( x264_param_t *param )
param->rc.i_qp_min = 0; param->rc.i_qp_min = 0;
param->rc.i_qp_max = 51; param->rc.i_qp_max = 51;
param->rc.i_qp_step = 4; param->rc.i_qp_step = 4;
param->rc.f_ip_factor = 2.0; param->rc.f_ip_factor = 1.4;
param->rc.f_pb_factor = 2.0; param->rc.f_pb_factor = 1.4;
param->rc.b_stat_write = 0; param->rc.b_stat_write = 0;
param->rc.psz_stat_out = "x264_2pass.log"; param->rc.psz_stat_out = "x264_2pass.log";
param->rc.b_stat_read = 0; param->rc.b_stat_read = 0;
param->rc.psz_stat_in = "x264_2pass.log"; param->rc.psz_stat_in = "x264_2pass.log";
param->rc.psz_rc_eq = "(tex^qComp)*(avgTex^(1-qComp))"; param->rc.psz_rc_eq = "tex*blurTex^(qComp-1)";
param->rc.f_qcompress = 0.6; param->rc.f_qcompress = 0.6;
param->rc.f_qblur = 0.5; param->rc.f_qblur = 0.5;
param->rc.f_complexity_blur = 20;
/* Log */ /* Log */
param->pf_log = x264_log_default; param->pf_log = x264_log_default;
......
...@@ -68,20 +68,13 @@ void x264_log( x264_t *h, int i_level, const char *psz_fmt, ... ); ...@@ -68,20 +68,13 @@ void x264_log( x264_t *h, int i_level, const char *psz_fmt, ... );
static inline int x264_clip3( int v, int i_min, int i_max ) static inline int x264_clip3( int v, int i_min, int i_max )
{ {
if( v < i_min ) return ( (v < i_min) ? i_min : (v > i_max) ? i_max : v );
{
return i_min;
}
else if( v > i_max )
{
return i_max;
}
else
{
return v;
}
} }
static inline float x264_clip3f( float v, float f_min, float f_max )
{
return ( (v < f_min) ? f_min : (v > f_max) ? f_max : v );
}
/**************************************************************************** /****************************************************************************
* *
......
...@@ -333,14 +333,10 @@ x264_t *x264_encoder_open ( x264_param_t *param ) ...@@ -333,14 +333,10 @@ x264_t *x264_encoder_open ( x264_param_t *param )
/* Fix parameters values */ /* Fix parameters values */
h->param.i_frame_reference = x264_clip3( h->param.i_frame_reference, 1, 15 ); h->param.i_frame_reference = x264_clip3( h->param.i_frame_reference, 1, 15 );
if( h->param.i_idrframe <= 0 ) if( h->param.i_idrframe <= 0 )
{
h->param.i_idrframe = 1; h->param.i_idrframe = 1;
}
if( h->param.i_iframe <= 0 ) if( h->param.i_iframe <= 0 )
{
h->param.i_iframe = 1; h->param.i_iframe = 1;
} h->param.i_bframe = x264_clip3( h->param.i_bframe, 0, X264_BFRAME_MAX );
h->param.i_bframe = x264_clip3( h->param.i_bframe , 0, X264_BFRAME_MAX );
h->param.i_deblocking_filter_alphac0 = x264_clip3( h->param.i_deblocking_filter_alphac0, -6, 6 ); h->param.i_deblocking_filter_alphac0 = x264_clip3( h->param.i_deblocking_filter_alphac0, -6, 6 );
h->param.i_deblocking_filter_beta = x264_clip3( h->param.i_deblocking_filter_beta, -6, 6 ); h->param.i_deblocking_filter_beta = x264_clip3( h->param.i_deblocking_filter_beta, -6, 6 );
...@@ -349,6 +345,11 @@ x264_t *x264_encoder_open ( x264_param_t *param ) ...@@ -349,6 +345,11 @@ x264_t *x264_encoder_open ( x264_param_t *param )
param->analyse.i_subpel_refine = x264_clip3( param->analyse.i_subpel_refine, 0, 5 ); param->analyse.i_subpel_refine = x264_clip3( param->analyse.i_subpel_refine, 0, 5 );
if( h->param.rc.f_qblur < 0 )
h->param.rc.f_qblur = 0;
if( h->param.rc.f_complexity_blur < 0 )
h->param.rc.f_complexity_blur = 0;
/* VUI */ /* VUI */
if( h->param.vui.i_sar_width > 0 && h->param.vui.i_sar_height > 0 ) if( h->param.vui.i_sar_width > 0 && h->param.vui.i_sar_height > 0 )
{ {
......
...@@ -60,8 +60,7 @@ typedef struct ...@@ -60,8 +60,7 @@ typedef struct
int i_count; int i_count;
int p_count; int p_count;
int s_count; int s_count;
int f_code; float blurred_complexity;
int b_code;
} ratecontrol_entry_t; } ratecontrol_entry_t;
struct x264_ratecontrol_t struct x264_ratecontrol_t
...@@ -100,12 +99,13 @@ struct x264_ratecontrol_t ...@@ -100,12 +99,13 @@ struct x264_ratecontrol_t
FILE *p_stat_file_out; FILE *p_stat_file_out;
int num_entries; /* number of ratecontrol_entry_ts */ int num_entries; /* number of ratecontrol_entry_ts */
ratecontrol_entry_t *entry; ratecontrol_entry_t *entry; /* FIXME: copy needed data and free this once init is done */
double last_qscale; double last_qscale;
double last_qscale_for[5]; /* last qscale for a specific pict type, used for max_diff & ipb factor stuff */ double last_qscale_for[5]; /* last qscale for a specific pict type, used for max_diff & ipb factor stuff */
int last_non_b_pict_type; int last_non_b_pict_type;
double lmin[5]; /* min qscale by frame type */ double lmin[5]; /* min qscale by frame type */
double lmax[5]; double lmax[5];
double lstep; /* max change (multiply) in qscale per frame */
double i_cplx_sum[5]; /* estimated total texture bits in intra MBs at qscale=1 */ double i_cplx_sum[5]; /* estimated total texture bits in intra MBs at qscale=1 */
double p_cplx_sum[5]; double p_cplx_sum[5];
double mv_bits_sum[5]; double mv_bits_sum[5];
...@@ -131,12 +131,12 @@ static inline double qscale2qp(double qscale) ...@@ -131,12 +131,12 @@ static inline double qscale2qp(double qscale)
static inline double qscale2bits(ratecontrol_entry_t *rce, double qscale) static inline double qscale2bits(ratecontrol_entry_t *rce, double qscale)
{ {
if(qscale<=0.0) if(qscale<0.1)
{ {
fprintf(stderr, "qscale<=0.0\n"); fprintf(stderr, "qscale<0.1\n");
qscale = 0.1; qscale = 0.1;
} }
return (double)(rce->i_tex_bits + rce->p_tex_bits + 1) * rce->qscale / qscale; return (double)(rce->i_tex_bits + rce->p_tex_bits + .1) * rce->qscale / qscale;
} }
static inline double bits2qscale(ratecontrol_entry_t *rce, double bits) static inline double bits2qscale(ratecontrol_entry_t *rce, double bits)
...@@ -146,7 +146,7 @@ static inline double bits2qscale(ratecontrol_entry_t *rce, double bits) ...@@ -146,7 +146,7 @@ static inline double bits2qscale(ratecontrol_entry_t *rce, double bits)
fprintf(stderr, "bits<0.9\n"); fprintf(stderr, "bits<0.9\n");
bits = 1.0; bits = 1.0;
} }
return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + 1) / bits; return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits + .1) / bits;
} }
...@@ -215,6 +215,7 @@ int x264_ratecontrol_new( x264_t *h ) ...@@ -215,6 +215,7 @@ int x264_ratecontrol_new( x264_t *h )
} }
rc->lstep = exp2f(h->param.rc.i_qp_step / 6.0);
for( i = 0; i < 5; i++ ) for( i = 0; i < 5; i++ )
{ {
rc->last_qscale_for[i] = qp2qscale(26); rc->last_qscale_for[i] = qp2qscale(26);
...@@ -378,8 +379,7 @@ void x264_ratecontrol_start( x264_t *h, int i_slice_type ) ...@@ -378,8 +379,7 @@ void x264_ratecontrol_start( x264_t *h, int i_slice_type )
qp--; qp--;
#endif #endif
qp = x264_clip3(qp, rc->gop_qp - 4, rc->gop_qp + 4); qp = x264_clip3(qp, rc->gop_qp - 4, rc->gop_qp + 4);
qp = qp = x264_clip3(qp, h->param.rc.i_qp_min, h->param.rc.i_qp_max);
x264_clip3(qp, h->param.rc.i_qp_min, h->param.rc.i_qp_max);
rc->gop_qp = qp; rc->gop_qp = qp;
} else if(rc->frames > 4){ } else if(rc->frames > 4){
rc->gop_qp = rc->init_qp; rc->gop_qp = rc->init_qp;
...@@ -616,7 +616,6 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor ...@@ -616,7 +616,6 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor
{ {
x264_ratecontrol_t *rcc= h->rc; x264_ratecontrol_t *rcc= h->rc;
double bits; double bits;
//double q, avg_cplx;
const int pict_type = rce->new_pict_type; const int pict_type = rce->new_pict_type;
double const_values[]={ double const_values[]={
...@@ -636,6 +635,7 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor ...@@ -636,6 +635,7 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor
rcc->p_cplx_sum[SLICE_TYPE_P] / rcc->frame_count[SLICE_TYPE_P], rcc->p_cplx_sum[SLICE_TYPE_P] / rcc->frame_count[SLICE_TYPE_P],
rcc->p_cplx_sum[SLICE_TYPE_B] / rcc->frame_count[SLICE_TYPE_B], rcc->p_cplx_sum[SLICE_TYPE_B] / rcc->frame_count[SLICE_TYPE_B],
(rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / rcc->frame_count[pict_type], (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / rcc->frame_count[pict_type],
rce->blurred_complexity,
0 0
}; };
static const char *const_names[]={ static const char *const_names[]={
...@@ -655,6 +655,7 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor ...@@ -655,6 +655,7 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor
"avgPPTex", "avgPPTex",
"avgBPTex", "avgBPTex",
"avgTex", "avgTex",
"blurTex",
NULL NULL
}; };
static double (*func1[])(void *, double)={ static double (*func1[])(void *, double)={
...@@ -670,6 +671,10 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor ...@@ -670,6 +671,10 @@ static double get_qscale(x264_t *h, ratecontrol_entry_t *rce, double rate_factor
bits = x264_eval((char*)h->param.rc.psz_rc_eq, const_values, const_names, func1, func1_names, NULL, NULL, rce); bits = x264_eval((char*)h->param.rc.psz_rc_eq, const_values, const_names, func1, func1_names, NULL, NULL, rce);
// avoid NaN's in the rc_eq
if(bits != bits || rce->i_tex_bits + rce->p_tex_bits == 0)
bits = 0;
bits *= rate_factor; bits *= rate_factor;
if(bits<0.0) bits=0.0; if(bits<0.0) bits=0.0;
bits += 1.0; //avoid 1/0 issues bits += 1.0; //avoid 1/0 issues
...@@ -700,42 +705,35 @@ static double get_diff_limited_q(x264_t *h, ratecontrol_entry_t *rce, double q) ...@@ -700,42 +705,35 @@ static double get_diff_limited_q(x264_t *h, ratecontrol_entry_t *rce, double q)
if(rcc->last_non_b_pict_type==pict_type || pict_type!=SLICE_TYPE_I) if(rcc->last_non_b_pict_type==pict_type || pict_type!=SLICE_TYPE_I)
{ {
double last_q = rcc->last_qscale_for[pict_type]; double last_q = rcc->last_qscale_for[pict_type];
const double max_qscale = qp2qscale(qscale2qp(last_q) + h->param.rc.i_qp_step); double max_qscale = last_q * rcc->lstep;
const double min_qscale = qp2qscale(qscale2qp(last_q) - h->param.rc.i_qp_step); double min_qscale = last_q / rcc->lstep;
if (q > max_qscale) q = max_qscale; if (q > max_qscale) q = max_qscale;
else if(q < min_qscale) q = min_qscale; else if(q < min_qscale) q = min_qscale;
} }
rcc->last_qscale_for[pict_type] = q; //Note we can't do that after blurring rcc->last_qscale_for[pict_type] = q;
if(pict_type!=SLICE_TYPE_B) if(pict_type!=SLICE_TYPE_B)
rcc->last_non_b_pict_type = pict_type; rcc->last_non_b_pict_type = pict_type;
return q; return q;
} }
static double modify_qscale( x264_t *h, ratecontrol_entry_t *rce, double q ) // clip a qscale to between lmin and lmax
static double clip_qscale( x264_t *h, ratecontrol_entry_t *rce, double q )
{ {
x264_ratecontrol_t *rcc = h->rc; double lmin = h->rc->lmin[rce->new_pict_type];
const int pict_type = rce->new_pict_type; double lmax = h->rc->lmax[rce->new_pict_type];
double lmin = rcc->lmin[pict_type];
double lmax = rcc->lmax[pict_type];
if(lmin==lmax /* || !h->param.b_qsquish */){ if(lmin==lmax){
if (q<lmin) q = lmin; return lmin;
else if(q>lmax) q = lmax;
}else{ }else{
double min2 = log(lmin); double min2 = log(lmin);
double max2 = log(lmax); double max2 = log(lmax);
q = (log(q) - min2)/(max2-min2) - 0.5;
q = log(q); q = 1.0/(1.0 + exp(-4*q));
q = (q - min2)/(max2-min2) - 0.5;
q *= -4.0;
q = 1.0/(1.0 + exp(q));
q = q*(max2-min2) + min2; q = q*(max2-min2) + min2;
return exp(q);
q = exp(q);
} }
return q;
} }
// update qscale for 1 frame based on actual bits used so far // update qscale for 1 frame based on actual bits used so far
...@@ -749,7 +747,6 @@ static float rate_estimate_qscale(x264_t *h, int pict_type) ...@@ -749,7 +747,6 @@ static float rate_estimate_qscale(x264_t *h, int pict_type)
ratecontrol_entry_t *rce; ratecontrol_entry_t *rce;
double lmin = rcc->lmin[pict_type]; double lmin = rcc->lmin[pict_type];
double lmax = rcc->lmax[pict_type]; double lmax = rcc->lmax[pict_type];
int64_t wanted_bits;
int64_t total_bits = 8*(h->stat.i_slice_size[SLICE_TYPE_I] int64_t total_bits = 8*(h->stat.i_slice_size[SLICE_TYPE_I]
+ h->stat.i_slice_size[SLICE_TYPE_P] + h->stat.i_slice_size[SLICE_TYPE_P]
+ h->stat.i_slice_size[SLICE_TYPE_B]); + h->stat.i_slice_size[SLICE_TYPE_B]);
...@@ -761,17 +758,12 @@ static float rate_estimate_qscale(x264_t *h, int pict_type) ...@@ -761,17 +758,12 @@ static float rate_estimate_qscale(x264_t *h, int pict_type)
if(pict_type!=SLICE_TYPE_I) if(pict_type!=SLICE_TYPE_I)
assert(pict_type == rce->new_pict_type); assert(pict_type == rce->new_pict_type);
wanted_bits = rce->expected_bits; diff = (int64_t)total_bits - (int64_t)rce->expected_bits;
diff = total_bits - wanted_bits;
br_compensation = (rcc->buffer_size - diff) / rcc->buffer_size; br_compensation = (rcc->buffer_size - diff) / rcc->buffer_size;
if(br_compensation<=0.0) br_compensation=0.001; if(br_compensation<=0.0) br_compensation=0.001;
q = rce->new_qscale / br_compensation; q = rce->new_qscale / br_compensation;
q = x264_clip3f(q, lmin, lmax);
if (q<lmin) q=lmin;
else if(q>lmax) q=lmax;
rcc->last_qscale = q; rcc->last_qscale = q;
return q; return q;
} }
...@@ -783,7 +775,9 @@ static int init_pass2( x264_t *h ) ...@@ -783,7 +775,9 @@ static int init_pass2( x264_t *h )
uint64_t all_available_bits = (uint64_t)(h->param.rc.i_bitrate * 1000 * (double)rcc->num_entries / rcc->fps); uint64_t all_available_bits = (uint64_t)(h->param.rc.i_bitrate * 1000 * (double)rcc->num_entries / rcc->fps);
double rate_factor, step, step_mult; double rate_factor, step, step_mult;
double qblur = h->param.rc.f_qblur; double qblur = h->param.rc.f_qblur;
double cplxblur = h->param.rc.f_complexity_blur;
const int filter_size = (int)(qblur*4) | 1; const int filter_size = (int)(qblur*4) | 1;
const int cplx_filter_size = (int)(cplxblur*2);
double expected_bits; double expected_bits;
double *qscale, *blurred_qscale; double *qscale, *blurred_qscale;
int i; int i;
...@@ -806,19 +800,51 @@ static int init_pass2( x264_t *h ) ...@@ -806,19 +800,51 @@ static int init_pass2( x264_t *h )
return -1; return -1;
} }
if(cplxblur<.01)
cplxblur = .01;
for(i=0; i<rcc->num_entries; i++){
ratecontrol_entry_t *rce = &rcc->entry[i];
double weight, weight_sum = 0;
double cplx_sum = 0;
double mask = 1.0;
int j;
/* weighted average of cplx of future frames */
for(j=1; j<cplx_filter_size && j<rcc->num_entries-i; j++){
ratecontrol_entry_t *rcj = &rcc->entry[i+j];
mask *= (double)(rcc->nmb + rcj->i_count) / rcc->nmb;
weight = mask * exp(-j*j/(cplxblur*cplxblur));
if(weight < .0001)
break;
weight_sum += weight;
cplx_sum += weight * (rcj->i_tex_bits + rcj->p_tex_bits) * rce->qscale;
}
/* weighted average of cplx of past frames */
mask = 1.0;
for(j=0; j<cplx_filter_size && j<=i; j++){
ratecontrol_entry_t *rcj = &rcc->entry[i-j];
weight = mask * exp(-j*j/(cplxblur*cplxblur));
weight_sum += weight;
cplx_sum += weight * (rcj->i_tex_bits + rcj->p_tex_bits) * rce->qscale;
mask *= (double)(rcc->nmb + rcj->i_count) / rcc->nmb;
if(weight < .0001)
break;
}
rce->blurred_complexity = cplx_sum / weight_sum;
}
qscale = x264_malloc(sizeof(double)*rcc->num_entries); qscale = x264_malloc(sizeof(double)*rcc->num_entries);
if(filter_size > 1) if(filter_size > 1)
blurred_qscale = x264_malloc(sizeof(double)*rcc->num_entries); blurred_qscale = x264_malloc(sizeof(double)*rcc->num_entries);
else else
blurred_qscale = qscale; blurred_qscale = qscale;
expected_bits = 0; expected_bits = 1;
for(i=0; i<rcc->num_entries; i++) for(i=0; i<rcc->num_entries; i++)
expected_bits += qscale2bits(&rcc->entry[i], get_qscale(h, &rcc->entry[i], 1.0)); expected_bits += qscale2bits(&rcc->entry[i], get_qscale(h, &rcc->entry[i], 1.0));
step_mult = all_available_bits / expected_bits; step_mult = all_available_bits / expected_bits;
rate_factor = 0; rate_factor = 0;
for(step = 1E4 * step_mult; step > 1E-7 * step_mult; step*=0.5){ for(step = 1E4 * step_mult; step > 1E-7 * step_mult; step *= 0.5){
expected_bits = 0; expected_bits = 0;
rate_factor += step; rate_factor += step;
...@@ -859,7 +885,7 @@ static int init_pass2( x264_t *h ) ...@@ -859,7 +885,7 @@ static int init_pass2( x264_t *h )
for(i=0; i<rcc->num_entries; i++){ for(i=0; i<rcc->num_entries; i++){
ratecontrol_entry_t *rce = &rcc->entry[i]; ratecontrol_entry_t *rce = &rcc->entry[i];
double bits; double bits;
rce->new_qscale = modify_qscale(h, rce, blurred_qscale[i]); rce->new_qscale = clip_qscale(h, rce, blurred_qscale[i]);
assert(rce->new_qscale >= 0); assert(rce->new_qscale >= 0);
bits = qscale2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits; bits = qscale2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
...@@ -879,9 +905,8 @@ static int init_pass2( x264_t *h ) ...@@ -879,9 +905,8 @@ static int init_pass2( x264_t *h )
{ {
double avgq = 0; double avgq = 0;
for(i=0; i<rcc->num_entries; i++) for(i=0; i<rcc->num_entries; i++)
if(rcc->entry[i].new_pict_type == SLICE_TYPE_P) avgq += rcc->entry[i].new_qscale;
avgq += rcc->entry[i].new_qscale; avgq = qscale2qp(avgq / rcc->num_entries);
avgq = qscale2qp(avgq / rcc->frame_count[SLICE_TYPE_P]);
x264_log(h, X264_LOG_ERROR, "Error: 2pass curve failed to converge\n"); x264_log(h, X264_LOG_ERROR, "Error: 2pass curve failed to converge\n");
x264_log(h, X264_LOG_ERROR, "expected bits: %llu, available: %llu, avg QP: %.4lf\n", (uint64_t)expected_bits, all_available_bits, avgq); x264_log(h, X264_LOG_ERROR, "expected bits: %llu, available: %llu, avg QP: %.4lf\n", (uint64_t)expected_bits, all_available_bits, avgq);
......
...@@ -127,6 +127,8 @@ static void Help( void ) ...@@ -127,6 +127,8 @@ static void Help( void )
" --stats <string> Filename for 2 pass stats\n" " --stats <string> Filename for 2 pass stats\n"
" --rceq <string> Ratecontrol equation\n" " --rceq <string> Ratecontrol equation\n"
" --qcomp <float> 0.0 => CBR, 1.0 => CQP, 0.6 => default\n" " --qcomp <float> 0.0 => CBR, 1.0 => CQP, 0.6 => default\n"
" --cplxblur <float> reduce fluctuations in QP (before curve compression)\n"
" --qblur <float> reduce fluctuations in QP (after curve compression)\n"
"\n" "\n"
" -A, --analyse <string> Analyse options:\n" " -A, --analyse <string> Analyse options:\n"
...@@ -180,6 +182,8 @@ static int Parse( int argc, char **argv, ...@@ -180,6 +182,8 @@ static int Parse( int argc, char **argv,
#define OPT_QUIET 268 #define OPT_QUIET 268
#define OPT_SUBME 269 #define OPT_SUBME 269
#define OPT_SCENECUT 270 #define OPT_SCENECUT 270
#define OPT_QBLUR 271
#define OPT_CPLXBLUR 272
static struct option long_options[] = static struct option long_options[] =
{ {
...@@ -211,6 +215,8 @@ static int Parse( int argc, char **argv, ...@@ -211,6 +215,8 @@ static int Parse( int argc, char **argv,
{ "stats", required_argument, NULL, OPT_RCSTATS }, { "stats", required_argument, NULL, OPT_RCSTATS },
{ "rceq", required_argument, NULL, OPT_RCEQ }, { "rceq", required_argument, NULL, OPT_RCEQ },
{ "qcomp", required_argument, NULL, OPT_QCOMP }, { "qcomp", required_argument, NULL, OPT_QCOMP },
{ "qblur", required_argument, NULL, OPT_QBLUR },
{ "cplxblur",required_argument, NULL, OPT_CPLXBLUR },
{ "no-psnr", no_argument, NULL, OPT_NOPSNR }, { "no-psnr", no_argument, NULL, OPT_NOPSNR },
{ "quiet", no_argument, NULL, OPT_QUIET }, { "quiet", no_argument, NULL, OPT_QUIET },
{0, 0, 0, 0} {0, 0, 0, 0}
...@@ -353,7 +359,12 @@ static int Parse( int argc, char **argv, ...@@ -353,7 +359,12 @@ static int Parse( int argc, char **argv,
case OPT_QCOMP: case OPT_QCOMP:
param->rc.f_qcompress = atof(optarg); param->rc.f_qcompress = atof(optarg);
break; break;
case OPT_QBLUR:
param->rc.f_qblur = atof(optarg);
break;
case OPT_CPLXBLUR:
param->rc.f_complexity_blur = atof(optarg);
break;
case OPT_NOPSNR: case OPT_NOPSNR:
param->analyse.b_psnr = 0; param->analyse.b_psnr = 0;
break; break;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <stdarg.h> #include <stdarg.h>
#define X264_BUILD 0x000b #define X264_BUILD 0x000c
/* x264_t: /* x264_t:
* opaque handler for decoder and encoder */ * opaque handler for decoder and encoder */
...@@ -158,6 +158,7 @@ typedef struct ...@@ -158,6 +158,7 @@ typedef struct
char *psz_rc_eq; /* 2 pass rate control equation */ char *psz_rc_eq; /* 2 pass rate control equation */
float f_qcompress; /* 0.0 => cbr, 1.0 => constant qp */ float f_qcompress; /* 0.0 => cbr, 1.0 => constant qp */
float f_qblur; /* temporally blur quants */ float f_qblur; /* temporally blur quants */
float f_complexity_blur; /* temporally blur complexity */
} rc; } rc;
} x264_param_t; } x264_param_t;
......
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