mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-24 02:24:07 +00:00
Fix setting QP when rate control is disabled.
When rate control is disabled, QP and lambda are now selected like they were before rate control was implemented.
This commit is contained in:
parent
b0435d37a9
commit
984e7cb4e0
16
src/config.c
16
src/config.c
|
@ -537,35 +537,35 @@ static int config_parse(config_t *cfg, const char *name, const char *value)
|
|||
if(atoi(value) == 8) {
|
||||
// GOP
|
||||
cfg->gop_len = 8;
|
||||
cfg->gop[0].poc_offset = 8; cfg->gop[0].layer = 1; cfg->gop[0].is_ref = 1;
|
||||
cfg->gop[0].poc_offset = 8; cfg->gop[0].qp_offset = 1; cfg->gop[0].layer = 1; cfg->gop[0].qp_factor = 0.442; cfg->gop[0].is_ref = 1;
|
||||
cfg->gop[0].ref_pos_count = 0;
|
||||
cfg->gop[0].ref_neg_count = 3; cfg->gop[0].ref_neg[0] = 8; cfg->gop[0].ref_neg[1] = 12; cfg->gop[0].ref_neg[2] = 16;
|
||||
|
||||
cfg->gop[1].poc_offset = 4; cfg->gop[1].layer = 2; cfg->gop[1].is_ref = 1;
|
||||
cfg->gop[1].poc_offset = 4; cfg->gop[1].qp_offset = 2; cfg->gop[1].layer = 2; cfg->gop[1].qp_factor = 0.3536; cfg->gop[1].is_ref = 1;
|
||||
cfg->gop[1].ref_neg_count = 2; cfg->gop[1].ref_neg[0] = 4; cfg->gop[1].ref_neg[1] = 8;
|
||||
cfg->gop[1].ref_pos_count = 1; cfg->gop[1].ref_pos[0] = 4;
|
||||
|
||||
cfg->gop[2].poc_offset = 2; cfg->gop[2].layer = 3; cfg->gop[2].is_ref = 1;
|
||||
cfg->gop[2].poc_offset = 2; cfg->gop[2].qp_offset = 3; cfg->gop[2].layer = 3; cfg->gop[2].qp_factor = 0.3536; cfg->gop[2].is_ref = 1;
|
||||
cfg->gop[2].ref_neg_count = 2; cfg->gop[2].ref_neg[0] = 2; cfg->gop[2].ref_neg[1] = 6;
|
||||
cfg->gop[2].ref_pos_count = 2; cfg->gop[2].ref_pos[0] = 2; cfg->gop[2].ref_pos[1] = 6;
|
||||
|
||||
cfg->gop[3].poc_offset = 1; cfg->gop[3].layer = 4; cfg->gop[3].is_ref = 0;
|
||||
cfg->gop[3].poc_offset = 1; cfg->gop[3].qp_offset = 4; cfg->gop[3].layer = 4; cfg->gop[3].qp_factor = 0.68; cfg->gop[3].is_ref = 0;
|
||||
cfg->gop[3].ref_neg_count = 1; cfg->gop[3].ref_neg[0] = 1;
|
||||
cfg->gop[3].ref_pos_count = 3; cfg->gop[3].ref_pos[0] = 1; cfg->gop[3].ref_pos[1] = 3; cfg->gop[3].ref_pos[2] = 7;
|
||||
|
||||
cfg->gop[4].poc_offset = 3; cfg->gop[4].layer = 4; cfg->gop[4].is_ref = 0;
|
||||
cfg->gop[4].poc_offset = 3; cfg->gop[4].qp_offset = 4; cfg->gop[4].layer = 4; cfg->gop[4].qp_factor = 0.68; cfg->gop[4].is_ref = 0;
|
||||
cfg->gop[4].ref_neg_count = 2; cfg->gop[4].ref_neg[0] = 1; cfg->gop[4].ref_neg[1] = 3;
|
||||
cfg->gop[4].ref_pos_count = 2; cfg->gop[4].ref_pos[0] = 1; cfg->gop[4].ref_pos[1] = 5;
|
||||
|
||||
cfg->gop[5].poc_offset = 6; cfg->gop[5].layer = 3; cfg->gop[5].is_ref = 1;
|
||||
cfg->gop[5].poc_offset = 6; cfg->gop[5].qp_offset = 3; cfg->gop[5].layer = 3; cfg->gop[5].qp_factor = 0.3536; cfg->gop[5].is_ref = 1;
|
||||
cfg->gop[5].ref_neg_count = 2; cfg->gop[5].ref_neg[0] = 2; cfg->gop[5].ref_neg[1] = 6;
|
||||
cfg->gop[5].ref_pos_count = 1; cfg->gop[5].ref_pos[0] = 2;
|
||||
|
||||
cfg->gop[6].poc_offset = 5; cfg->gop[6].layer = 4; cfg->gop[6].is_ref = 0;
|
||||
cfg->gop[6].poc_offset = 5; cfg->gop[6].qp_offset = 4; cfg->gop[6].layer = 4; cfg->gop[6].qp_factor = 0.68; cfg->gop[6].is_ref = 0;
|
||||
cfg->gop[6].ref_neg_count = 2; cfg->gop[6].ref_neg[0] = 1; cfg->gop[6].ref_neg[1] = 5;
|
||||
cfg->gop[6].ref_pos_count = 2; cfg->gop[6].ref_pos[0] = 1; cfg->gop[6].ref_pos[1] = 3;
|
||||
|
||||
cfg->gop[7].poc_offset = 7; cfg->gop[7].layer = 4; cfg->gop[7].is_ref = 0;
|
||||
cfg->gop[7].poc_offset = 7; cfg->gop[7].qp_offset = 4; cfg->gop[7].layer = 4; cfg->gop[7].qp_factor = 0.68; cfg->gop[7].is_ref = 0;
|
||||
cfg->gop[7].ref_neg_count = 3; cfg->gop[7].ref_neg[0] = 1; cfg->gop[7].ref_neg[1] = 3; cfg->gop[7].ref_neg[2] = 7;
|
||||
cfg->gop[7].ref_pos_count = 1; cfg->gop[7].ref_pos[0] = 1;
|
||||
} else if(atoi(value)) {
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
double qp_factor;
|
||||
int8_t qp_offset; /*!< \brief QP offset */
|
||||
int8_t poc_offset; /*!< \brief POC offset */
|
||||
int8_t layer; /*!< \brief Current layer */
|
||||
int8_t is_ref; /*!< \brief Flag if this picture is used as a reference */
|
||||
|
|
|
@ -45,10 +45,6 @@
|
|||
#include "rdo.h"
|
||||
#include "rate_control.h"
|
||||
|
||||
#ifndef LMBD
|
||||
# define LMBD 1.0
|
||||
#endif
|
||||
|
||||
int encoder_state_match_children_of_previous_frame(encoder_state_t * const state) {
|
||||
int i;
|
||||
for (i = 0; state->children[i].encoder_control; ++i) {
|
||||
|
@ -771,10 +767,24 @@ static void encoder_state_new_frame(encoder_state_t * const state) {
|
|||
encoder_state_ref_sort(state);
|
||||
}
|
||||
|
||||
double lambda = select_picture_lambda(state);
|
||||
double lambda;
|
||||
if (encoder->cfg->target_bitrate > 0) {
|
||||
// Rate control enabled.
|
||||
lambda = select_picture_lambda(state);
|
||||
state->global->QP = lambda_to_QP(lambda);
|
||||
} else {
|
||||
if (encoder->cfg->gop_len > 0 && state->global->slicetype != SLICE_I) {
|
||||
gop_config_t const * const gop =
|
||||
encoder->cfg->gop + state->global->gop_offset;
|
||||
state->global->QP = encoder->cfg->qp + gop->qp_offset;
|
||||
state->global->QP_factor = gop->qp_factor;
|
||||
} else {
|
||||
state->global->QP = encoder->cfg->qp;
|
||||
}
|
||||
lambda = select_picture_lambda_from_qp(state);
|
||||
}
|
||||
state->global->cur_lambda_cost = lambda;
|
||||
state->global->cur_lambda_cost_sqrt = sqrt(lambda);
|
||||
state->global->QP = lambda_to_QP(lambda);
|
||||
|
||||
} else {
|
||||
//Clear the bitstream if it's not the main encoder
|
||||
|
|
|
@ -108,22 +108,23 @@ static double pic_allocate_bits(const encoder_state_t * const state)
|
|||
* \brief Select a lambda value for encoding the next picture
|
||||
* \param state the main encoder state
|
||||
* \return lambda for the next picture
|
||||
*
|
||||
* Rate control must be enabled (i.e. cfg->target_bitrate > 0) when this
|
||||
* function is called.
|
||||
*/
|
||||
double select_picture_lambda(encoder_state_t * const state)
|
||||
{
|
||||
const encoder_control_t * const encoder = state->encoder_control;
|
||||
|
||||
if (encoder->cfg->target_bitrate <= 0) {
|
||||
// Rate control disabled.
|
||||
return exp((encoder->cfg->qp - 13.7223 - 0.5) / 4.2005);
|
||||
}
|
||||
assert(encoder->cfg->target_bitrate > 0);
|
||||
|
||||
if (state->global->frame > encoder->cfg->owf) {
|
||||
// At least one frame has been written.
|
||||
update_rc_parameters(state);
|
||||
}
|
||||
|
||||
if (encoder->cfg->gop_len == 0 || state->global->gop_offset == 0) {
|
||||
// a new GOP begins at this frame
|
||||
// A new GOP begins at this frame.
|
||||
gop_allocate_bits(state);
|
||||
} else {
|
||||
state->global->cur_gop_target_bits =
|
||||
|
@ -141,6 +142,34 @@ double select_picture_lambda(encoder_state_t * const state)
|
|||
|
||||
int8_t lambda_to_QP(const double lambda)
|
||||
{
|
||||
int8_t qp = 4.2005 * log(lambda) + 13.7223 + 0.5;
|
||||
const int8_t qp = 4.2005 * log(lambda) + 13.7223 + 0.5;
|
||||
return CLIP(0, 51, qp);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Select a lambda value according to current QP value
|
||||
* \param state the main encoder state
|
||||
* \return lambda for the next picture
|
||||
*
|
||||
* This function should be used to select lambda when rate control is
|
||||
* disabled.
|
||||
*/
|
||||
double select_picture_lambda_from_qp(encoder_state_t const * const state)
|
||||
{
|
||||
const int gop_len = state->encoder_control->cfg->gop_len;
|
||||
const double qp_temp = state->global->QP - 12;
|
||||
|
||||
double qp_factor;
|
||||
if (state->global->slicetype == SLICE_I) {
|
||||
const double lambda_scale = 1.0 - CLIP(0.0, 0.5, 0.05 * gop_len);
|
||||
qp_factor = 0.57 * lambda_scale;
|
||||
} else if (gop_len > 0) {
|
||||
qp_factor = 0.95 * state->global->QP_factor;
|
||||
} else {
|
||||
// default QP factor from HM config
|
||||
qp_factor = 0.95 * 0.4624;
|
||||
}
|
||||
|
||||
const double lambda = qp_factor * pow(2.0, qp_temp / 3.0);
|
||||
return lambda;
|
||||
}
|
||||
|
|
|
@ -31,4 +31,6 @@ double select_picture_lambda(encoder_state_t * const state);
|
|||
|
||||
int8_t lambda_to_QP(const double lambda);
|
||||
|
||||
double select_picture_lambda_from_qp(encoder_state_t const * const state);
|
||||
|
||||
#endif // RATE_CONTROL_H_
|
||||
|
|
Loading…
Reference in a new issue