📄 ratecontrol.c
字号:
q= FFMAX(q, bits2qp(rce, FFMAX(rcc->buffer_index/2, 1))); } }//printf("q:%f max:%f min:%f size:%f index:%d bits:%f agr:%f\n", q,max_rate, min_rate, buffer_size, rcc->buffer_index, bits, s->avctx->rc_buffer_aggressivity); if(s->avctx->rc_qsquish==0.0 || qmin==qmax){ if (q<qmin) q=qmin; else if(q>qmax) q=qmax; }else{ double min2= log(qmin); double max2= log(qmax); q= log(q); q= (q - min2)/(max2-min2) - 0.5; q*= -4.0; q= 1.0/(1.0 + exp(q)); q= q*(max2-min2) + min2; q= exp(q); } return q;}//----------------------------------// 1 Pass Codestatic double predict_size(Predictor *p, double q, double var){ return p->coeff*var / (q*p->count);}/*static double predict_qp(Predictor *p, double size, double var){//printf("coeff:%f, count:%f, var:%f, size:%f//\n", p->coeff, p->count, var, size); return p->coeff*var / (size*p->count);}*/static void update_predictor(Predictor *p, double q, double var, double size){ double new_coeff= size*q / (var + 1); if(var<10) return; p->count*= p->decay; p->coeff*= p->decay; p->count++; p->coeff+= new_coeff;}static void adaptive_quantization(MpegEncContext *s, double q){ int i; const float lumi_masking= s->avctx->lumi_masking / (128.0*128.0); const float dark_masking= s->avctx->dark_masking / (128.0*128.0); const float temp_cplx_masking= s->avctx->temporal_cplx_masking; const float spatial_cplx_masking = s->avctx->spatial_cplx_masking; const float p_masking = s->avctx->p_masking; float bits_sum= 0.0; float cplx_sum= 0.0; float cplx_tab[s->mb_num]; float bits_tab[s->mb_num]; const int qmin= s->avctx->lmin; const int qmax= s->avctx->lmax; Picture * const pic= &s->current_picture; for(i=0; i<s->mb_num; i++){ const int mb_xy= s->mb_index2xy[i]; float temp_cplx= sqrt(pic->mc_mb_var[mb_xy]); //FIXME merge in pow() float spat_cplx= sqrt(pic->mb_var[mb_xy]); const int lumi= pic->mb_mean[mb_xy]; float bits, cplx, factor;#if 0 if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune if(temp_cplx < q/3) temp_cplx= q/3; //FIXME finetune#endif if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune if((s->mb_type[mb_xy]&MB_TYPE_INTRA)){//FIXME hq mode cplx= spat_cplx; factor= 1.0 + p_masking; }else{ cplx= temp_cplx; factor= pow(temp_cplx, - temp_cplx_masking); } factor*=pow(spat_cplx, - spatial_cplx_masking); if(lumi>127) factor*= (1.0 - (lumi-128)*(lumi-128)*lumi_masking); else factor*= (1.0 - (lumi-128)*(lumi-128)*dark_masking); if(factor<0.00001) factor= 0.00001; bits= cplx*factor; cplx_sum+= cplx; bits_sum+= bits; cplx_tab[i]= cplx; bits_tab[i]= bits; } /* handle qmin/qmax cliping */ if(s->flags&CODEC_FLAG_NORMALIZE_AQP){ for(i=0; i<s->mb_num; i++){ float newq= q*cplx_tab[i]/bits_tab[i]; newq*= bits_sum/cplx_sum; if (newq > qmax){ bits_sum -= bits_tab[i]; cplx_sum -= cplx_tab[i]*q/qmax; } else if(newq < qmin){ bits_sum -= bits_tab[i]; cplx_sum -= cplx_tab[i]*q/qmin; } } } for(i=0; i<s->mb_num; i++){ const int mb_xy= s->mb_index2xy[i]; float newq= q*cplx_tab[i]/bits_tab[i]; int intq; if(s->flags&CODEC_FLAG_NORMALIZE_AQP){ newq*= bits_sum/cplx_sum; } intq= (int)(newq + 0.5); if (intq > qmax) intq= qmax; else if(intq < qmin) intq= qmin;//if(i%s->mb_width==0) printf("\n");//printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i])); s->lambda_table[mb_xy]= intq; }}//FIXME rd or at least approx for dquantfloat ff_rate_estimate_qscale(MpegEncContext *s){ 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; 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(); get_qminmax(&qmin, &qmax, s, pict_type); fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_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){ 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{ rce= &local_rce; wanted_bits= (uint64_t)(s->bit_rate*(double)picture_number/fps); } diff= s->total_bits - wanted_bits; br_compensation= (s->bit_rate_tolerance - diff)/s->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; if(picture_number>0) update_rc_buffer(s, s->frame_bits); 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); 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 dependant blur like in 2-pass rcc->short_term_qsum*=s->qblur; rcc->short_term_qcount*=s->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); 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 codestatic int init_pass2(MpegEncContext *s){ RateControlContext *rcc= &s->rc_context; int i; double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; double complexity[5]={0,0,0,0,0}; // aproximate bits at quant=1 double avg_quantizer[5]; uint64_t const_bits[5]={0,0,0,0,0}; // quantizer idependant bits uint64_t available_bits[5]; 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)(s->qblur*4) | 1; double expected_bits; double *qscale, *blured_qscale; /* 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 to low\n"); return -1; } /* find average quantizers */ avg_quantizer[P_TYPE]=0; for(step=256*256; step>0.0000001; step*=0.5){ double expected_bits=0; avg_quantizer[P_TYPE]+= step; avg_quantizer[I_TYPE]= avg_quantizer[P_TYPE]*ABS(s->avctx->i_quant_factor) + s->avctx->i_quant_offset; avg_quantizer[B_TYPE]= avg_quantizer[P_TYPE]*ABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset; expected_bits= + all_const_bits + complexity[I_TYPE]/avg_quantizer[I_TYPE] + complexity[P_TYPE]/avg_quantizer[P_TYPE] + complexity[B_TYPE]/avg_quantizer[B_TYPE]; if(expected_bits < all_available_bits) avg_quantizer[P_TYPE]-= step;//printf("%f %lld %f\n", expected_bits, all_available_bits, avg_quantizer[P_TYPE]); }//printf("qp_i:%f, qp_p:%f, qp_b:%f\n", avg_quantizer[I_TYPE],avg_quantizer[P_TYPE],avg_quantizer[B_TYPE]); for(i=0; i<5; i++){ available_bits[i]= const_bits[i] + complexity[i]/avg_quantizer[i]; }//printf("%lld %lld %lld %lld\n", available_bits[I_TYPE], available_bits[P_TYPE], available_bits[B_TYPE], all_available_bits); qscale= av_malloc(sizeof(double)*rcc->num_entries); blured_qscale= av_malloc(sizeof(double)*rcc->num_entries); 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= s->qblur==0 ? 1.0 : exp(-d*d/(s->qblur * s->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]); update_rc_buffer(s, bits); rce->expected_bits= expected_bits; expected_bits += bits; }// printf("%f %d %f\n", expected_bits, (int)all_available_bits, rate_factor); if(expected_bits > all_available_bits) rate_factor-= step; } av_free(qscale); av_free(blured_qscale); if(abs(expected_bits/all_available_bits - 1.0) > 0.01 ){ av_log(s->avctx, AV_LOG_ERROR, "Error: 2pass curve failed to converge\n"); return -1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -