double last_qscale;
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;
+ double accum_p_qp; /* for determining I-frame quant */
+ double accum_p_norm;
double lmin[5]; /* min qscale by frame type */
double lmax[5];
double lstep; /* max change (multiply) in qscale per frame */
{
if(qscale<0.1)
{
- fprintf(stderr, "qscale<0.1\n");
+// fprintf(stderr, "qscale<0.1\n");
qscale = 0.1;
}
return (double)(rce->i_tex_bits + rce->p_tex_bits + .1) * rce->qscale / qscale;
{
if( h->param.rc.b_stat_read )
{
- assert(frame_num < h->rc->num_entries);
+ if( frame_num >= h->rc->num_entries )
+ {
+ x264_log(h, X264_LOG_ERROR, "More input frames than in the 1st pass\n");
+ return X264_TYPE_P;
+ }
switch( h->rc->entry[frame_num].new_pict_type )
{
case SLICE_TYPE_I:
if(bits<0.0) bits=0.0;
bits += 1.0; //avoid 1/0 issues
- /* I/B difference */
- if( pict_type==SLICE_TYPE_I && h->param.rc.f_ip_factor > 0 )
- bits *= h->param.rc.f_ip_factor;
- else if( pict_type==SLICE_TYPE_B && h->param.rc.f_pb_factor > 0 )
- bits /= h->param.rc.f_pb_factor;
-
return bits2qscale(rce, bits);
}
// force I/B quants as a function of P quants
const double last_p_q = rcc->last_qscale_for[SLICE_TYPE_P];
const double last_non_b_q= rcc->last_qscale_for[rcc->last_non_b_pict_type];
- if( pict_type == SLICE_TYPE_I && h->param.rc.f_ip_factor < 0 )
- q = last_p_q / fabs( h->param.rc.f_ip_factor );
- else if( pict_type == SLICE_TYPE_B
- && ( h->param.rc.f_pb_factor < 0 || rce->i_tex_bits + rce->p_tex_bits == 0 ) )
- q = last_non_b_q * fabs( h->param.rc.f_pb_factor );
- else if( pict_type == SLICE_TYPE_P && rce->i_tex_bits + rce->p_tex_bits == 0 )
+ if( pict_type == SLICE_TYPE_I )
+ {
+ if( rcc->accum_p_norm > 0 && h->param.rc.f_ip_factor > 0 )
+ q = qp2qscale(rcc->accum_p_qp / rcc->accum_p_norm);
+ q /= fabs( h->param.rc.f_ip_factor );
+ }
+ else if( pict_type == SLICE_TYPE_B )
+ {
+ if( h->param.rc.f_pb_factor > 0 )
+ q = last_non_b_q;
+ q *= fabs( h->param.rc.f_pb_factor );
+ }
+ else if( pict_type == SLICE_TYPE_P
+ && rcc->last_non_b_pict_type == SLICE_TYPE_P
+ && rce->i_tex_bits + rce->p_tex_bits == 0 )
+ {
q = last_p_q;
+ }
/* last qscale / qdiff stuff */
if(rcc->last_non_b_pict_type==pict_type || pict_type!=SLICE_TYPE_I)
rcc->last_qscale_for[pict_type] = q;
if(pict_type!=SLICE_TYPE_B)
rcc->last_non_b_pict_type = pict_type;
+ if(pict_type==SLICE_TYPE_I)
+ {
+ rcc->accum_p_norm = 0;
+ rcc->accum_p_qp = 0;
+ }
+ if(pict_type==SLICE_TYPE_P)
+ {
+ float mask = 1 - pow( (float)rce->i_count / rcc->nmb, 2 );
+ rcc->accum_p_qp = mask * (qscale2qp(q) + rcc->accum_p_qp);
+ rcc->accum_p_norm = mask * (1 + rcc->accum_p_norm);
+ }
return q;
}
rce = &rcc->entry[picture_number];
- if(pict_type!=SLICE_TYPE_I)
- assert(pict_type == rce->new_pict_type);
+ assert(pict_type == rce->new_pict_type);
- diff = (int64_t)total_bits - (int64_t)rce->expected_bits;
- br_compensation = (rcc->buffer_size - diff) / rcc->buffer_size;
- if(br_compensation<=0.0) br_compensation=0.001;
-
- q = rce->new_qscale / br_compensation;
- q = x264_clip3f(q, lmin, lmax);
- rcc->last_qscale = q;
- return q;
+ if(rce->pict_type == SLICE_TYPE_B)
+ {
+ return rcc->last_qscale * h->param.rc.f_pb_factor;
+ }
+ else
+ {
+ diff = (int64_t)total_bits - (int64_t)rce->expected_bits;
+ br_compensation = (rcc->buffer_size - diff) / rcc->buffer_size;
+ br_compensation = x264_clip3f(br_compensation, .5, 2);
+
+ q = rce->new_qscale / br_compensation;
+ q = x264_clip3f(q, lmin, lmax);
+ rcc->last_qscale = q;
+ return q;
+ }
}
static int init_pass2( x264_t *h )
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 cplx_filter_size = (int)(cplxblur*2);
double expected_bits;
double *qscale, *blurred_qscale;
int i;
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 weight_sum = 0;
double cplx_sum = 0;
- double mask = 1.0;
+ double weight = 1.0;
int j;
/* weighted average of cplx of future frames */
- for(j=1; j<cplx_filter_size && j<rcc->num_entries-i; j++){
+ for(j=1; j<cplxblur*2 && 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));
+ weight *= 1 - pow( (float)rcj->i_count / rcc->nmb, 2 );
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++){
+ weight = 1.0;
+ for(j=0; j<cplxblur*2 && 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;
+ weight *= 1 - pow( (float)rcj->i_count / rcc->nmb, 2 );
if(weight < .0001)
break;
}