From 4a5698a6bad3980abbb8fcee481e934ce4bd5edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arttu=20Yl=C3=A4-Outinen?= Date: Fri, 13 Mar 2015 14:23:54 +0200 Subject: [PATCH] Implement basic rate control. --- src/Makefile | 1 + src/encoderstate.c | 3 +++ src/rate_control.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ src/rate_control.h | 32 ++++++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/rate_control.c create mode 100644 src/rate_control.h diff --git a/src/Makefile b/src/Makefile index 15e1994d..94991660 100644 --- a/src/Makefile +++ b/src/Makefile @@ -86,6 +86,7 @@ OBJS = \ cu.o \ encoder.o \ encoderstate.o \ + rate_control.o \ filter.o \ inter.o \ intra.o \ diff --git a/src/encoderstate.c b/src/encoderstate.c index d6491b81..1c8040dc 100644 --- a/src/encoderstate.c +++ b/src/encoderstate.c @@ -43,6 +43,7 @@ #include "search.h" #include "sao.h" #include "rdo.h" +#include "rate_control.h" #ifndef LMBD # define LMBD 1.0 @@ -812,6 +813,8 @@ static void encoder_state_new_frame(encoder_state_t * const state) { state->global->QP_factor = state->encoder_control->cfg->gop[state->global->gop_offset].qp_factor; } + } else { + state->global->QP = select_picture_QP(state); } } else { diff --git a/src/rate_control.c b/src/rate_control.c new file mode 100644 index 00000000..d3bfc9f6 --- /dev/null +++ b/src/rate_control.c @@ -0,0 +1,66 @@ +/***************************************************************************** + * This file is part of Kvazaar HEVC encoder. + * + * Copyright (C) 2013-2015 Tampere University of Technology and others (see + * COPYING file). + * + * Kvazaar 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. + * + * Kvazaar 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 General Public License along + * with Kvazaar. If not, see . + ****************************************************************************/ + +#include "rate_control.h" + +#include + +static const int SMOOTHING_WINDOW = 40; + +/** + * \brief Select a QP for encoding the next picture + * \param state the main encoder state + * \return the QP for the next picture, in range [0, 51] + */ +int8_t select_picture_QP(const encoder_state_t * const state) +{ + const encoder_control_t * const encoder = state->encoder_control; + + if (encoder->cfg->target_bitrate <= 0) { + // Rate control disabled. + return encoder->cfg->qp; + } + + // At this point, total_bits_coded of the current state contains the + // number of bits written encoder->owf frames before the current frame. + const int bits_coded = state->global->total_bits_coded; + const int pictures_coded = MAX(0, state->global->frame - encoder->owf); + + const double avg_bits_per_picture = + encoder->cfg->target_bitrate / encoder->cfg->framerate; + + // TODO: use picture weights + const double target_bits_current_picture = + (avg_bits_per_picture * (pictures_coded + SMOOTHING_WINDOW) - bits_coded) + / SMOOTHING_WINDOW; + + // TODO: take the picture headers into account + const int pixels_per_picture = encoder->in.width * encoder->in.height; + const double target_bits_per_pixel = target_bits_current_picture / pixels_per_picture; + + // The following magical constants, -5.7420835 and 18.598408755005686 are + // based on the values given in + // + // K. McCann et al., "High Effiency Video Coding (HEVC) Test Model 16 + // (HM 16) Improved Encoder Description", JCTVC-S1002, October 2014, + // (p. 52 - 54) + const int QP = (int)(-5.7420835 * log(MAX(target_bits_per_pixel, 0.001)) + 18.598408755005686); + return CLIP(0, 51, QP); +} diff --git a/src/rate_control.h b/src/rate_control.h new file mode 100644 index 00000000..520dc607 --- /dev/null +++ b/src/rate_control.h @@ -0,0 +1,32 @@ +#ifndef RATE_CONTROL_H_ +#define RATE_CONTROL_H_ +/***************************************************************************** + * This file is part of Kvazaar HEVC encoder. + * + * Copyright (C) 2013-2015 Tampere University of Technology and others (see + * COPYING file). + * + * Kvazaar 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. + * + * Kvazaar 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 General Public License along + * with Kvazaar. If not, see . + ****************************************************************************/ + +/* + * \file + * \brief Functions related with rate control + */ + +#include "encoderstate.h" + +int8_t select_picture_QP(const encoder_state_t * const state); + +#endif // RATE_CONTROL_H_