// MEANX double bitrate_constraint(MpegEncContext *s, RateControlEntry *rce, double q, int frame_num) { const double buffer_size= s->avctx->rc_buffer_size; const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; const double min_rate= s->avctx->rc_min_rate / fps; const double max_rate= s->avctx->rc_max_rate / fps; double q_limit; RateControlContext *rcc= &s->rc_context; double expected_size= rcc->buffer_index; 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; } } return q; }
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, frame_num); /* 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) * s->avctx->rc_min_vbv_overflow_use, 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 * s->avctx->rc_max_available_vbv_use, 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; }
/** * modifies the bitrate curve from pass1 for one frame */ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num){ RateControlContext *rcc= &s->rc_context; AVCodecContext *a= s->avctx; double q, bits; const int pict_type= rce->new_pict_type; const double mb_num= s->mb_num; int i; double const_values[]={ M_PI, M_E, rce->i_tex_bits*rce->qscale, rce->p_tex_bits*rce->qscale, (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale, rce->mv_bits/mb_num, rce->pict_type == FF_B_TYPE ? (rce->f_code + rce->b_code)*0.5 : rce->f_code, rce->i_count/mb_num, rce->mc_mb_var_sum/mb_num, rce->mb_var_sum/mb_num, rce->pict_type == FF_I_TYPE, rce->pict_type == FF_P_TYPE, rce->pict_type == FF_B_TYPE, rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type], a->qcompress, /* 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 }; bits= ff_parse_eval(rcc->rc_eq_eval, const_values, rce); #ifdef __GNUC__ if (isnan(bits)) { av_log(s->avctx, AV_LOG_ERROR, "Error evaluating rc_eq \"%s\"\n", s->avctx->rc_eq); return -1; } #endif 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; }
/** * modifies the bitrate curve from pass1 for one frame */ static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num){ RateControlContext *rcc= &s->rc_context; AVCodecContext *a= s->avctx; double q, bits; const int pict_type= rce->new_pict_type; const double mb_num= s->mb_num; int i; double const_values[]={ M_PI, M_E, rce->i_tex_bits*rce->qscale, rce->p_tex_bits*rce->qscale, (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale, rce->mv_bits/mb_num, rce->pict_type == B_TYPE ? (rce->f_code + rce->b_code)*0.5 : rce->f_code, rce->i_count/mb_num, rce->mc_mb_var_sum/mb_num, rce->mb_var_sum/mb_num, rce->pict_type == I_TYPE, rce->pict_type == P_TYPE, rce->pict_type == B_TYPE, rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type], a->qcompress, /* rcc->last_qscale_for[I_TYPE], rcc->last_qscale_for[P_TYPE], rcc->last_qscale_for[B_TYPE], rcc->next_non_b_qscale,*/ rcc->i_cplx_sum[I_TYPE] / (double)rcc->frame_count[I_TYPE], rcc->i_cplx_sum[P_TYPE] / (double)rcc->frame_count[P_TYPE], rcc->p_cplx_sum[P_TYPE] / (double)rcc->frame_count[P_TYPE], rcc->p_cplx_sum[B_TYPE] / (double)rcc->frame_count[B_TYPE], (rcc->i_cplx_sum[pict_type] + rcc->p_cplx_sum[pict_type]) / (double)rcc->frame_count[pict_type], 0 }; static const char *const_names[]={ "PI", "E", "iTex", "pTex", "tex", "mv", "fCode", "iCount", "mcVar", "var", "isI", "isP", "isB", "avgQP", "qComp", /* "lastIQP", "lastPQP", "lastBQP", "nextNonBQP",*/ "avgIITex", "avgPITex", "avgPPTex", "avgBPTex", "avgTex", NULL }; static double (*func1[])(void *, double)={ (void *)bits2qp, (void *)qp2bits, NULL }; static const char *func1_names[]={ "bits2qp", "qp2bits", NULL }; bits= ff_eval(s->avctx->rc_eq, const_values, const_names, func1, func1_names, NULL, NULL, rce); 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==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==B_TYPE && s->avctx->b_quant_factor<0.0) q= -q*s->avctx->b_quant_factor + s->avctx->b_quant_offset; return q; }