diff options
Diffstat (limited to 'libavcodec/ratecontrol.c')
-rw-r--r-- | libavcodec/ratecontrol.c | 122 |
1 files changed, 82 insertions, 40 deletions
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 097da2ee2c..49d169ba25 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -3,20 +3,20 @@ * * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -35,12 +35,31 @@ #include "mpegvideo.h" #include "libavutil/eval.h" -#undef NDEBUG // Always check asserts, the speed effect is far too small to disable them. -#include <assert.h> +void ff_write_pass1_stats(MpegEncContext *s) +{ + snprintf(s->avctx->stats_out, 256, + "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d " + "fcode:%d bcode:%d mc-var:%"PRId64" var:%"PRId64" icount:%d skipcount:%d hbits:%d;\n", + s->current_picture_ptr->f->display_picture_number, + s->current_picture_ptr->f->coded_picture_number, + s->pict_type, + s->current_picture.f->quality, + s->i_tex_bits, + s->p_tex_bits, + s->mv_bits, + s->misc_bits, + s->f_code, + s->b_code, + s->current_picture.mc_mb_var_sum, + s->current_picture.mb_var_sum, + s->i_count, s->skip_count, + s->header_bits); +} -#ifndef M_E -#define M_E 2.718281828 -#endif +static double get_fps(AVCodecContext *avctx) +{ + return 1.0 / av_q2d(avctx->time_base) / FFMAX(avctx->ticks_per_frame, 1); +} static inline double qp2bits(RateControlEntry *rce, double qp) { @@ -102,7 +121,7 @@ static void get_qminmax(int *qmin_ret, int *qmax_ret, MpegEncContext *s, int pic int qmin = s->lmin; int qmax = s->lmax; - assert(qmin <= qmax); + av_assert0(qmin <= qmax); switch (pict_type) { case AV_PICTURE_TYPE_B: @@ -130,7 +149,7 @@ static double modify_qscale(MpegEncContext *s, RateControlEntry *rce, { RateControlContext *rcc = &s->rc_context; const double buffer_size = s->avctx->rc_buffer_size; - const double fps = 1 / av_q2d(s->avctx->time_base); + const double fps = get_fps(s->avctx); const double min_rate = s->avctx->rc_min_rate / fps; const double max_rate = s->avctx->rc_max_rate / fps; const int pict_type = rce->new_pict_type; @@ -294,7 +313,7 @@ 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 fps = get_fps(s->avctx); double complexity[5] = { 0 }; // approximate bits at quant=1 uint64_t const_bits[5] = { 0 }; // quantizer independent bits uint64_t all_const_bits; @@ -303,7 +322,7 @@ static int init_pass2(MpegEncContext *s) double rate_factor = 0; double step; const int filter_size = (int)(a->qblur * 4) | 1; - double expected_bits; + double expected_bits = 0; // init to silence gcc warning double *qscale, *blurred_qscale, qscale_sum; /* find complexity & const_bits & decide the pict_types */ @@ -330,8 +349,8 @@ static int init_pass2(MpegEncContext *s) return -1; } - qscale = av_malloc(sizeof(double) * rcc->num_entries); - blurred_qscale = av_malloc(sizeof(double) * rcc->num_entries); + qscale = av_malloc_array(rcc->num_entries, sizeof(double)); + blurred_qscale = av_malloc_array(rcc->num_entries, sizeof(double)); if (!qscale || !blurred_qscale) { av_free(qscale); av_free(blurred_qscale); @@ -352,9 +371,15 @@ static int init_pass2(MpegEncContext *s) qscale[i] = get_qscale(s, &rcc->entry[i], rate_factor, i); rcc->last_qscale_for[rce->pict_type] = qscale[i]; } - assert(filter_size % 2 == 1); + av_assert0(filter_size % 2 == 1); /* fixed I/B QP relative to P mode */ + for (i = FFMAX(0, rcc->num_entries - 300); i < rcc->num_entries; i++) { + RateControlEntry *rce = &rcc->entry[i]; + + qscale[i] = get_diff_limited_q(s, rce, qscale[i]); + } + for (i = rcc->num_entries - 1; i >= 0; i--) { RateControlEntry *rce = &rcc->entry[i]; @@ -418,11 +443,11 @@ static int init_pass2(MpegEncContext *s) qscale_sum += av_clip(rcc->entry[i].new_qscale / FF_QP2LAMBDA, s->avctx->qmin, s->avctx->qmax); } - assert(toobig <= 40); + av_assert0(toobig <= 40); av_log(s->avctx, AV_LOG_DEBUG, - "[lavc rc] requested bitrate: %d bps expected bitrate: %d bps\n", + "[lavc rc] requested bitrate: %"PRId64" bps expected bitrate: %"PRId64" bps\n", s->bit_rate, - (int)(expected_bits / ((double)all_available_bits / s->bit_rate))); + (int64_t)(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); @@ -483,6 +508,13 @@ av_cold int ff_rate_control_init(MpegEncContext *s) }; emms_c(); + if (!s->avctx->rc_max_available_vbv_use && s->avctx->rc_buffer_size) { + if (s->avctx->rc_max_rate) { + s->avctx->rc_max_available_vbv_use = av_clipf(s->avctx->rc_max_rate/(s->avctx->rc_buffer_size*get_fps(s->avctx)), 1.0/3, 1.0); + } else + s->avctx->rc_max_available_vbv_use = 1.0; + } + res = av_expr_parse(&rcc->rc_eq_eval, s->rc_eq ? s->rc_eq : "tex^qComp", const_names, func1_names, func1, @@ -506,6 +538,8 @@ av_cold int ff_rate_control_init(MpegEncContext *s) rcc->last_qscale_for[i] = FF_QP2LAMBDA * 5; } rcc->buffer_index = s->avctx->rc_initial_buffer_occupancy; + if (!rcc->buffer_index) + rcc->buffer_index = s->avctx->rc_buffer_size * 3 / 4; if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { int i; @@ -519,9 +553,9 @@ av_cold int ff_rate_control_init(MpegEncContext *s) if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry)) return -1; rcc->entry = av_mallocz(i * sizeof(RateControlEntry)); - rcc->num_entries = i; if (!rcc->entry) return AVERROR(ENOMEM); + rcc->num_entries = i; /* init all to skipped P-frames * (with B-frames we might have a not encoded frame at the end FIXME) */ @@ -549,11 +583,11 @@ av_cold int ff_rate_control_init(MpegEncContext *s) } e = sscanf(p, " in:%d ", &picture_number); - assert(picture_number >= 0); - assert(picture_number < rcc->num_entries); + av_assert0(picture_number >= 0); + av_assert0(picture_number < rcc->num_entries); rce = &rcc->entry[picture_number]; - e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d", + e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%"SCNd64" var:%"SCNd64" icount:%d skipcount:%d hbits:%d", &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits, &rce->f_code, &rce->b_code, @@ -627,7 +661,7 @@ av_cold int ff_rate_control_init(MpegEncContext *s) get_qscale(s, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i); // FIXME misbehaves a little for variable fps - rcc->pass1_wanted_bits += s->bit_rate / (1 / av_q2d(s->avctx->time_base)); + rcc->pass1_wanted_bits += s->bit_rate / get_fps(s->avctx); } } } @@ -647,7 +681,7 @@ av_cold void ff_rate_control_uninit(MpegEncContext *s) int ff_vbv_update(MpegEncContext *s, int frame_size) { RateControlContext *rcc = &s->rc_context; - const double fps = 1 / av_q2d(s->avctx->time_base); + const double fps = get_fps(s->avctx); const int buffer_size = s->avctx->rc_buffer_size; const double min_rate = s->avctx->rc_min_rate / fps; const double max_rate = s->avctx->rc_max_rate / fps; @@ -661,6 +695,9 @@ int ff_vbv_update(MpegEncContext *s, int frame_size) rcc->buffer_index -= frame_size; if (rcc->buffer_index < 0) { av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n"); + if (frame_size > max_rate && s->qscale == s->avctx->qmax) { + av_log(s->avctx, AV_LOG_ERROR, "max bitrate possibly too small or try trellis with large lmax or increase qmax\n"); + } rcc->buffer_index = 0; } @@ -843,26 +880,32 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) RateControlEntry local_rce, *rce; double bits; double rate_factor; - int var; + int64_t var; const int pict_type = s->pict_type; Picture * const pic = &s->current_picture; emms_c(); get_qminmax(&qmin, &qmax, s, pict_type); - fps = 1 / av_q2d(s->avctx->time_base); + 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; + const int64_t 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); + sqrt(last_var), + s->frame_bits - s->stuffing_bits); } if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { - assert(picture_number >= 0); - assert(picture_number < rcc->num_entries); + av_assert0(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 { @@ -893,10 +936,10 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) short_term_q = 0; /* avoid warning */ if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { if (pict_type != AV_PICTURE_TYPE_I) - assert(pict_type == rce->new_pict_type); + av_assert0(pict_type == rce->new_pict_type); q = rce->new_qscale / br_compensation; - ff_dlog(s, "%f %f %f last:%d var:%d type:%d//\n", q, rce->new_qscale, + ff_dlog(s, "%f %f %f last:%d var:%"PRId64" type:%d//\n", q, rce->new_qscale, br_compensation, s->frame_bits, var, pict_type); } else { rce->pict_type = @@ -925,7 +968,6 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) 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; @@ -933,9 +975,9 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) if (q < 0) return -1; - assert(q > 0.0); + av_assert0(q > 0.0); q = get_diff_limited_q(s, rce, q); - assert(q > 0.0); + av_assert0(q > 0.0); // FIXME type dependent blur like in 2-pass if (pict_type == AV_PICTURE_TYPE_P || s->intra_only) { @@ -946,19 +988,19 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run) rcc->short_term_qcount++; q = short_term_q = rcc->short_term_qsum / rcc->short_term_qcount; } - assert(q > 0.0); + av_assert0(q > 0.0); q = modify_qscale(s, rce, q, picture_number); rcc->pass1_wanted_bits += s->bit_rate / fps; - assert(q > 0.0); + av_assert0(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", + "size:%d var:%"PRId64"/%"PRId64" br:%"PRId64" fps:%d\n", av_get_picture_type_char(pict_type), qmin, q, qmax, picture_number, (int)wanted_bits / 1000, (int)s->total_bits / 1000, |