📄 ratecontrol.c
字号:
s->lambda_table[mb_xy]= intq;
}
}
void ff_get_2pass_fcode(MpegEncContext *s){
RateControlContext *rcc= &s->rc_context;
int picture_number= s->picture_number;
RateControlEntry *rce;
rce= &rcc->entry[picture_number];
s->f_code= rce->f_code;
s->b_code= rce->b_code;
}
//FIXME rd or at least approx for dquant
float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
{
float q;
int qmin, qmax;
float br_compensation;
double diff;
double short_term_q;
double fps;
int picture_number= s->picture_number;
int64_t wanted_bits;
RateControlContext *rcc= &s->rc_context;
AVCodecContext *a= s->avctx;
RateControlEntry local_rce, *rce;
double bits;
double rate_factor;
int var;
const int pict_type= s->pict_type;
Picture * const pic= &s->current_picture;
emms_c();
#ifdef CONFIG_LIBXVID
if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)
return ff_xvid_rate_estimate_qscale(s, dry_run);
#endif
get_qminmax(&qmin, &qmax, s, pict_type);
fps= 1/av_q2d(s->avctx->time_base);
//printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate);
/* update predictors */
if(picture_number>2 && !dry_run){
const int last_var= s->last_pict_type == I_TYPE ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum;
update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits);
}
if(s->flags&CODEC_FLAG_PASS2){
assert(picture_number>=0);
assert(picture_number<rcc->num_entries);
rce= &rcc->entry[picture_number];
wanted_bits= rce->expected_bits;
}else{
Picture *dts_pic;
rce= &local_rce;
//FIXME add a dts field to AVFrame and ensure its set and use it here instead of reordering
//but the reordering is simpler for now until h.264 b pyramid must be handeld
if(s->pict_type == B_TYPE || s->low_delay)
dts_pic= s->current_picture_ptr;
else
dts_pic= s->last_picture_ptr;
//if(dts_pic)
// av_log(NULL, AV_LOG_ERROR, "%Ld %Ld %Ld %d\n", s->current_picture_ptr->pts, s->user_specified_pts, dts_pic->pts, picture_number);
if(!dts_pic || dts_pic->pts == AV_NOPTS_VALUE)
wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps);
else
wanted_bits= (uint64_t)(s->bit_rate*(double)dts_pic->pts/fps);
}
diff= s->total_bits - wanted_bits;
br_compensation= (a->bit_rate_tolerance - diff)/a->bit_rate_tolerance;
if(br_compensation<=0.0) br_compensation=0.001;
var= pict_type == I_TYPE ? pic->mb_var_sum : pic->mc_mb_var_sum;
short_term_q = 0; /* avoid warning */
if(s->flags&CODEC_FLAG_PASS2){
if(pict_type!=I_TYPE)
assert(pict_type == rce->new_pict_type);
q= rce->new_qscale / br_compensation;
//printf("%f %f %f last:%d var:%d type:%d//\n", q, rce->new_qscale, br_compensation, s->frame_bits, var, pict_type);
}else{
rce->pict_type=
rce->new_pict_type= pict_type;
rce->mc_mb_var_sum= pic->mc_mb_var_sum;
rce->mb_var_sum = pic-> mb_var_sum;
rce->qscale = FF_QP2LAMBDA * 2;
rce->f_code = s->f_code;
rce->b_code = s->b_code;
rce->misc_bits= 1;
bits= predict_size(&rcc->pred[pict_type], rce->qscale, sqrt(var));
if(pict_type== I_TYPE){
rce->i_count = s->mb_num;
rce->i_tex_bits= bits;
rce->p_tex_bits= 0;
rce->mv_bits= 0;
}else{
rce->i_count = 0; //FIXME we do know this approx
rce->i_tex_bits= 0;
rce->p_tex_bits= bits*0.9;
rce->mv_bits= bits*0.1;
}
rcc->i_cplx_sum [pict_type] += rce->i_tex_bits*rce->qscale;
rcc->p_cplx_sum [pict_type] += rce->p_tex_bits*rce->qscale;
rcc->mv_bits_sum[pict_type] += rce->mv_bits;
rcc->frame_count[pict_type] ++;
bits= rce->i_tex_bits + rce->p_tex_bits;
rate_factor= rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum * br_compensation;
q= get_qscale(s, rce, rate_factor, picture_number);
if (q < 0)
return -1;
assert(q>0.0);
//printf("%f ", q);
q= get_diff_limited_q(s, rce, q);
//printf("%f ", q);
assert(q>0.0);
if(pict_type==P_TYPE || s->intra_only){ //FIXME type dependent blur like in 2-pass
rcc->short_term_qsum*=a->qblur;
rcc->short_term_qcount*=a->qblur;
rcc->short_term_qsum+= q;
rcc->short_term_qcount++;
//printf("%f ", q);
q= short_term_q= rcc->short_term_qsum/rcc->short_term_qcount;
//printf("%f ", q);
}
assert(q>0.0);
q= modify_qscale(s, rce, q, picture_number);
rcc->pass1_wanted_bits+= s->bit_rate/fps;
assert(q>0.0);
}
if(s->avctx->debug&FF_DEBUG_RC){
av_log(s->avctx, AV_LOG_DEBUG, "%c qp:%d<%2.1f<%d %d want:%d total:%d comp:%f st_q:%2.2f size:%d var:%d/%d br:%d fps:%d\n",
av_get_pict_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits/1000, (int)s->total_bits/1000,
br_compensation, short_term_q, s->frame_bits, pic->mb_var_sum, pic->mc_mb_var_sum, s->bit_rate/1000, (int)fps
);
}
if (q<qmin) q=qmin;
else if(q>qmax) q=qmax;
if(s->adaptive_quant)
adaptive_quantization(s, q);
else
q= (int)(q + 0.5);
if(!dry_run){
rcc->last_qscale= q;
rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum;
rcc->last_mb_var_sum= pic->mb_var_sum;
}
#if 0
{
static int mvsum=0, texsum=0;
mvsum += s->mv_bits;
texsum += s->i_tex_bits + s->p_tex_bits;
printf("%d %d//\n\n", mvsum, texsum);
}
#endif
return q;
}
//----------------------------------------------
// 2-Pass code
static int init_pass2(MpegEncContext *s)
{
RateControlContext *rcc= &s->rc_context;
AVCodecContext *a= s->avctx;
int i, toobig;
double fps= 1/av_q2d(s->avctx->time_base);
double complexity[5]={0,0,0,0,0}; // aproximate bits at quant=1
uint64_t const_bits[5]={0,0,0,0,0}; // quantizer independent bits
uint64_t all_const_bits;
uint64_t all_available_bits= (uint64_t)(s->bit_rate*(double)rcc->num_entries/fps);
double rate_factor=0;
double step;
//int last_i_frame=-10000000;
const int filter_size= (int)(a->qblur*4) | 1;
double expected_bits;
double *qscale, *blured_qscale, qscale_sum;
/* find complexity & const_bits & decide the pict_types */
for(i=0; i<rcc->num_entries; i++){
RateControlEntry *rce= &rcc->entry[i];
rce->new_pict_type= rce->pict_type;
rcc->i_cplx_sum [rce->pict_type] += rce->i_tex_bits*rce->qscale;
rcc->p_cplx_sum [rce->pict_type] += rce->p_tex_bits*rce->qscale;
rcc->mv_bits_sum[rce->pict_type] += rce->mv_bits;
rcc->frame_count[rce->pict_type] ++;
complexity[rce->new_pict_type]+= (rce->i_tex_bits+ rce->p_tex_bits)*(double)rce->qscale;
const_bits[rce->new_pict_type]+= rce->mv_bits + rce->misc_bits;
}
all_const_bits= const_bits[I_TYPE] + const_bits[P_TYPE] + const_bits[B_TYPE];
if(all_available_bits < all_const_bits){
av_log(s->avctx, AV_LOG_ERROR, "requested bitrate is too low\n");
return -1;
}
qscale= av_malloc(sizeof(double)*rcc->num_entries);
blured_qscale= av_malloc(sizeof(double)*rcc->num_entries);
toobig = 0;
for(step=256*256; step>0.0000001; step*=0.5){
expected_bits=0;
rate_factor+= step;
rcc->buffer_index= s->avctx->rc_buffer_size/2;
/* find qscale */
for(i=0; i<rcc->num_entries; i++){
qscale[i]= get_qscale(s, &rcc->entry[i], rate_factor, i);
}
assert(filter_size%2==1);
/* fixed I/B QP relative to P mode */
for(i=rcc->num_entries-1; i>=0; i--){
RateControlEntry *rce= &rcc->entry[i];
qscale[i]= get_diff_limited_q(s, rce, qscale[i]);
}
/* smooth curve */
for(i=0; i<rcc->num_entries; i++){
RateControlEntry *rce= &rcc->entry[i];
const int pict_type= rce->new_pict_type;
int j;
double q=0.0, sum=0.0;
for(j=0; j<filter_size; j++){
int index= i+j-filter_size/2;
double d= index-i;
double coeff= a->qblur==0 ? 1.0 : exp(-d*d/(a->qblur * a->qblur));
if(index < 0 || index >= rcc->num_entries) continue;
if(pict_type != rcc->entry[index].new_pict_type) continue;
q+= qscale[index] * coeff;
sum+= coeff;
}
blured_qscale[i]= q/sum;
}
/* find expected bits */
for(i=0; i<rcc->num_entries; i++){
RateControlEntry *rce= &rcc->entry[i];
double bits;
rce->new_qscale= modify_qscale(s, rce, blured_qscale[i], i);
bits= qp2bits(rce, rce->new_qscale) + rce->mv_bits + rce->misc_bits;
//printf("%d %f\n", rce->new_bits, blured_qscale[i]);
bits += 8*ff_vbv_update(s, bits);
rce->expected_bits= expected_bits;
expected_bits += bits;
}
/*
av_log(s->avctx, AV_LOG_INFO,
"expected_bits: %f all_available_bits: %d rate_factor: %f\n",
expected_bits, (int)all_available_bits, rate_factor);
*/
if(expected_bits > all_available_bits) {
rate_factor-= step;
++toobig;
}
}
av_free(qscale);
av_free(blured_qscale);
/* check bitrate calculations and print info */
qscale_sum = 0.0;
for(i=0; i<rcc->num_entries; i++){
/* av_log(s->avctx, AV_LOG_DEBUG, "[lavc rc] entry[%d].new_qscale = %.3f qp = %.3f\n",
i, rcc->entry[i].new_qscale, rcc->entry[i].new_qscale / FF_QP2LAMBDA); */
qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA, s->avctx->qmin, s->avctx->qmax);
}
assert(toobig <= 40);
av_log(s->avctx, AV_LOG_DEBUG,
"[lavc rc] requested bitrate: %d bps expected bitrate: %d bps\n",
s->bit_rate,
(int)(expected_bits / ((double)all_available_bits/s->bit_rate)));
av_log(s->avctx, AV_LOG_DEBUG,
"[lavc rc] estimated target average qp: %.3f\n",
(float)qscale_sum / rcc->num_entries);
if (toobig == 0) {
av_log(s->avctx, AV_LOG_INFO,
"[lavc rc] Using all of requested bitrate is not "
"necessary for this video with these parameters.\n");
} else if (toobig == 40) {
av_log(s->avctx, AV_LOG_ERROR,
"[lavc rc] Error: bitrate too low for this video "
"with these parameters.\n");
return -1;
} else if (fabs(expected_bits/all_available_bits - 1.0) > 0.01) {
av_log(s->avctx, AV_LOG_ERROR,
"[lavc rc] Error: 2pass curve failed to converge\n");
return -1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -