📄 ratecontrol.c
字号:
/* rcc->last_qscale_for[FF_I_TYPE], rcc->last_qscale_for[FF_P_TYPE], rcc->last_qscale_for[FF_B_TYPE], rcc->next_non_b_qscale,*/ rcc->i_cplx_sum[FF_I_TYPE] / (double)rcc->frame_count[FF_I_TYPE], rcc->i_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE], rcc->p_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE], rcc->p_cplx_sum[FF_B_TYPE] / (double)rcc->frame_count[FF_B_TYPE], (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / (double)rcc->frame_count[pict_type], 0 };#else double const_values[21]; const_values[ 0] = M_PI; const_values[ 1] = M_E; const_values[ 2] = rce->i_tex_bits*rce->qscale; const_values[ 3] = rce->p_tex_bits*rce->qscale; const_values[ 4] = (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale; const_values[ 5] = rce->mv_bits/mb_num; const_values[ 6] = rce->pict_type == FF_B_TYPE ? (rce->f_code + rce->b_code)*0.5 : rce->f_code; const_values[ 7] = rce->i_count/mb_num; const_values[ 8] = rce->mc_mb_var_sum/mb_num; const_values[ 9] = rce->mb_var_sum/mb_num; const_values[10] = rce->pict_type == FF_I_TYPE; const_values[11] = rce->pict_type == FF_P_TYPE; const_values[12] = rce->pict_type == FF_B_TYPE; const_values[13] = rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type]; const_values[14] = a->qcompress; const_values[15] = rcc->i_cplx_sum[FF_I_TYPE] / (double)rcc->frame_count[FF_I_TYPE]; const_values[16] = rcc->i_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE]; const_values[17] = rcc->p_cplx_sum[FF_P_TYPE] / (double)rcc->frame_count[FF_P_TYPE]; const_values[18] = rcc->p_cplx_sum[FF_B_TYPE] / (double)rcc->frame_count[FF_B_TYPE]; const_values[19] = (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / (double)rcc->frame_count[pict_type]; const_values[20] = 0;#endif bits= ff_parse_eval(rcc->rc_eq_eval, const_values, rce); if (isnan(bits)) { av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->avctx->rc_eq); return -1; } rcc->pass1_rc_eq_output_sum+= bits; bits*=rate_factor; if(bits<0.0) bits=0.0; bits+= 1.0; //avoid 1/0 issues /* user override */ for(i=0; i<s->avctx->rc_override_count; i++){ RcOverride *rco= s->avctx->rc_override; if(rco[i].start_frame > frame_num) continue; if(rco[i].end_frame < frame_num) continue; if(rco[i].qscale) bits= qp2bits(rce, rco[i].qscale); //FIXME move at end to really force it? else bits*= rco[i].quality_factor; } q= bits2qp(rce, bits); /* I/B difference */ if (pict_type==FF_I_TYPE && s->avctx->i_quant_factor<0.0) q= -q*s->avctx->i_quant_factor + s->avctx->i_quant_offset; else if(pict_type==FF_B_TYPE && s->avctx->b_quant_factor<0.0) q= -q*s->avctx->b_quant_factor + s->avctx->b_quant_offset; if(q<1) q=1; return q;}static double get_diff_limited_q(MpegEncContext *s, RateControlEntry *rce, double q){ RateControlContext *rcc= &s->rc_context; AVCodecContext *a= s->avctx; const int pict_type= rce->new_pict_type; const double last_p_q = rcc->last_qscale_for[FF_P_TYPE]; const double last_non_b_q= rcc->last_qscale_for[rcc->last_non_b_pict_type]; if (pict_type==FF_I_TYPE && (a->i_quant_factor>0.0 || rcc->last_non_b_pict_type==FF_P_TYPE)) q= last_p_q *FFABS(a->i_quant_factor) + a->i_quant_offset; else if(pict_type==FF_B_TYPE && a->b_quant_factor>0.0) q= last_non_b_q* a->b_quant_factor + a->b_quant_offset; if(q<1) q=1; /* last qscale / qdiff stuff */ if(rcc->last_non_b_pict_type==pict_type || pict_type!=FF_I_TYPE){ double last_q= rcc->last_qscale_for[pict_type]; const int maxdiff= FF_QP2LAMBDA * a->max_qdiff; if (q > last_q + maxdiff) q= last_q + maxdiff; else if(q < last_q - maxdiff) q= last_q - maxdiff; } rcc->last_qscale_for[pict_type]= q; //Note we cannot do that after blurring if(pict_type!=FF_B_TYPE) rcc->last_non_b_pict_type= pict_type; return q;}/** * gets the qmin & qmax for pict_type */static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pict_type){ int qmin= s->avctx->lmin; int qmax= s->avctx->lmax; assert(qmin <= qmax); if(pict_type==FF_B_TYPE){ qmin= (int)(qmin*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5); qmax= (int)(qmax*FFABS(s->avctx->b_quant_factor)+s->avctx->b_quant_offset + 0.5); }else if(pict_type==FF_I_TYPE){ qmin= (int)(qmin*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5); qmax= (int)(qmax*FFABS(s->avctx->i_quant_factor)+s->avctx->i_quant_offset + 0.5); } qmin= av_clip(qmin, 1, FF_LAMBDA_MAX); qmax= av_clip(qmax, 1, FF_LAMBDA_MAX); if(qmax<qmin) qmax= qmin; *qmin_ret= qmin; *qmax_ret= qmax;}static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, double q, int frame_num){ RateControlContext *rcc= &s->rc_context; int qmin, qmax; double bits; const int pict_type= rce->new_pict_type; const double buffer_size= s->avctx->rc_buffer_size; const double fps= 1/av_q2d(s->avctx->time_base); const double min_rate= s->avctx->rc_min_rate / fps; const double max_rate= s->avctx->rc_max_rate / fps; get_qminmax(&qmin, &qmax, s, pict_type); /* modulation */ if(s->avctx->rc_qmod_freq && frame_num%s->avctx->rc_qmod_freq==0 && pict_type==FF_P_TYPE) q*= s->avctx->rc_qmod_amp; bits= qp2bits(rce, q);//printf("q:%f\n", q); /* buffer overflow/underflow protection */ if(buffer_size){ double expected_size= rcc->buffer_index; double q_limit; if(min_rate){ double d= 2*(buffer_size - expected_size)/buffer_size; if(d>1.0) d=1.0; else if(d<0.0001) d=0.0001; q*= pow(d, 1.0/s->avctx->rc_buffer_aggressivity); q_limit= bits2qp(rce, FFMAX((min_rate - buffer_size + rcc->buffer_index)*3, 1)); if(q > q_limit){ if(s->avctx->debug&FF_DEBUG_RC){ av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit); } q= q_limit; } } if(max_rate){ double d= 2*expected_size/buffer_size; if(d>1.0) d=1.0; else if(d<0.0001) d=0.0001; q/= pow(d, 1.0/s->avctx->rc_buffer_aggressivity); q_limit= bits2qp(rce, FFMAX(rcc->buffer_index/3, 1)); if(q < q_limit){ if(s->avctx->debug&FF_DEBUG_RC){ av_log(s->avctx, AV_LOG_DEBUG, "limiting QP %f -> %f\n", q, q_limit); } q= q_limit; } } }//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; const float border_masking = s->avctx->border_masking; float bits_sum= 0.0; float cplx_sum= 0.0;#ifdef __CW32__ float *cplx_tab; float *bits_tab;#else float cplx_tab[s->mb_num]; float bits_tab[s->mb_num];#endif const int qmin= s->avctx->mb_lmin; const int qmax= s->avctx->mb_lmax; Picture * const pic= &s->current_picture; const int mb_width = s->mb_width; const int mb_height = s->mb_height;#ifdef __CW32__ cplx_tab = av_malloc(sizeof(float)*s->mb_num); bits_tab = av_malloc(sizeof(float)*s->mb_num);#endif 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; int mb_x = mb_xy % s->mb_stride; int mb_y = mb_xy / s->mb_stride; int mb_distance; float mb_factor = 0.0;#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]&CANDIDATE_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(mb_x < mb_width/5){ mb_distance = mb_width/5 - mb_x; mb_factor = (float)mb_distance / (float)(mb_width/5); }else if(mb_x > 4*mb_width/5){ mb_distance = mb_x - 4*mb_width/5; mb_factor = (float)mb_distance / (float)(mb_width/5); } if(mb_y < mb_height/5){ mb_distance = mb_height/5 - mb_y; mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5)); }else if(mb_y > 4*mb_height/5){ mb_distance = mb_y - 4*mb_height/5; mb_factor = FFMAX(mb_factor, (float)mb_distance / (float)(mb_height/5)); } factor*= 1.0 - border_masking*mb_factor; 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 clipping */ if(s->flags&CODEC_FLAG_NORMALIZE_AQP){ float factor= bits_sum/cplx_sum; for(i=0; i<s->mb_num; i++){ float newq= q*cplx_tab[i]/bits_tab[i]; newq*= factor; 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; } } if(bits_sum < 0.001) bits_sum= 0.001; if(cplx_sum < 0.001) cplx_sum= 0.001; } 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -