summaryrefslogtreecommitdiffstats
path: root/libavcodec/ratecontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/ratecontrol.c')
-rw-r--r--libavcodec/ratecontrol.c122
1 files changed, 82 insertions, 40 deletions
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 097da2e..49d169b 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,
OpenPOWER on IntegriCloud