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(); #if 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 = get_fps(s->avctx); /* update predictors */ if (picture_number > 2 && !dry_run) { const int last_var = s->last_pict_type == AV_PICTURE_TYPE_I ? rcc->last_mb_var_sum : rcc->last_mc_mb_var_sum; av_assert1(s->frame_bits >= s->stuffing_bits); update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits - s->stuffing_bits); } if (s->flags & CODEC_FLAG_PASS2) { assert(picture_number >= 0); if (picture_number >= rcc->num_entries) { av_log(s, AV_LOG_ERROR, "Input is longer than 2-pass log file\n"); return -1; } 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 it is set and use it * here instead of reordering but the reordering is simpler for now * until H.264 B-pyramid must be handled. */ if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) dts_pic = s->current_picture_ptr; else dts_pic = s->last_picture_ptr; if (!dts_pic || dts_pic->f.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->f.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 == AV_PICTURE_TYPE_I ? pic->mb_var_sum : pic->mc_mb_var_sum; short_term_q = 0; /* avoid warning */ if (s->flags & CODEC_FLAG_PASS2) { if (pict_type != AV_PICTURE_TYPE_I) assert(pict_type == rce->new_pict_type); q = rce->new_qscale / br_compensation; av_dlog(s, "%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 == AV_PICTURE_TYPE_I) { 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); q = get_diff_limited_q(s, rce, q); assert(q > 0.0); // FIXME type dependent blur like in 2-pass if (pict_type == AV_PICTURE_TYPE_P || s->intra_only) { rcc->short_term_qsum *= a->qblur; rcc->short_term_qcount *= a->qblur; rcc->short_term_qsum += q; rcc->short_term_qcount++; q = short_term_q = rcc->short_term_qsum / rcc->short_term_qcount; } 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:%"PRId64"/%"PRId64" br:%d fps:%d\n", av_get_picture_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; } return q; }