mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
Set QP completely at CU level as the name '--set-qp-in-cu' implies
-Move slice delta QP to CU level when using --set-qp-in-cu -Separate functionality from roi
This commit is contained in:
parent
87a9208db8
commit
9339845e8b
|
@ -138,7 +138,7 @@ Video structure:
|
||||||
QP values in raster order. The map can be of any
|
QP values in raster order. The map can be of any
|
||||||
size and will be scaled to the video size.
|
size and will be scaled to the video size.
|
||||||
--set-qp-in-cu : Set QP at CU level keeping pic_init_qp_minus26.
|
--set-qp-in-cu : Set QP at CU level keeping pic_init_qp_minus26.
|
||||||
in PPS zero.
|
in PPS and slice_qp_delta in slize header zero.
|
||||||
--(no-)erp-aqp : Use adaptive QP for 360 degree video with
|
--(no-)erp-aqp : Use adaptive QP for 360 degree video with
|
||||||
equirectangular projection. [disabled]
|
equirectangular projection. [disabled]
|
||||||
--level <number> : Use the given HEVC level in the output and give
|
--level <number> : Use the given HEVC level in the output and give
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.TH KVAZAAR "1" "October 2018" "kvazaar v1.2.0" "User Commands"
|
.TH KVAZAAR "1" "May 2019" "kvazaar v1.2.0" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
kvazaar \- open source HEVC encoder
|
kvazaar \- open source HEVC encoder
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -157,7 +157,7 @@ size and will be scaled to the video size.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-set\-qp\-in\-cu
|
\fB\-\-set\-qp\-in\-cu
|
||||||
Set QP at CU level keeping pic_init_qp_minus26.
|
Set QP at CU level keeping pic_init_qp_minus26.
|
||||||
in PPS zero.
|
in PPS and slice_qp_delta in slize header zero.
|
||||||
.TP
|
.TP
|
||||||
\fB\-\-(no\-)erp\-aqp
|
\fB\-\-(no\-)erp\-aqp
|
||||||
Use adaptive QP for 360 degree video with
|
Use adaptive QP for 360 degree video with
|
||||||
|
|
|
@ -420,7 +420,7 @@ void print_help(void)
|
||||||
" QP values in raster order. The map can be of any\n"
|
" QP values in raster order. The map can be of any\n"
|
||||||
" size and will be scaled to the video size.\n"
|
" size and will be scaled to the video size.\n"
|
||||||
" --set-qp-in-cu : Set QP at CU level keeping pic_init_qp_minus26.\n"
|
" --set-qp-in-cu : Set QP at CU level keeping pic_init_qp_minus26.\n"
|
||||||
" in PPS zero.\n"
|
" in PPS and slice_qp_delta in slize header zero.\n"
|
||||||
" --(no-)erp-aqp : Use adaptive QP for 360 degree video with\n"
|
" --(no-)erp-aqp : Use adaptive QP for 360 degree video with\n"
|
||||||
" equirectangular projection. [disabled]\n"
|
" equirectangular projection. [disabled]\n"
|
||||||
" --level <number> : Use the given HEVC level in the output and give\n"
|
" --level <number> : Use the given HEVC level in the output and give\n"
|
||||||
|
|
|
@ -352,32 +352,11 @@ encoder_control_t* kvz_encoder_control_init(const kvz_config *const cfg)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If QP will be set at CU level instead of PPS,
|
|
||||||
// encoder is given qp 26 making pic_init_qp_minus26
|
|
||||||
// zero. The difference is added to the delta QP map.
|
|
||||||
if (cfg->set_qp_in_cu) {
|
|
||||||
|
|
||||||
encoder->cfg.qp = 26;
|
|
||||||
|
|
||||||
// If delta QP map does not already exist, it has to be created.
|
|
||||||
if (encoder->cfg.roi.dqps == NULL) {
|
|
||||||
encoder->cfg.roi.width = 1;
|
|
||||||
encoder->cfg.roi.height = 1;
|
|
||||||
encoder->cfg.roi.dqps = calloc(1, sizeof(cfg->roi.dqps[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t roi_size = encoder->cfg.roi.width * encoder->cfg.roi.height;
|
|
||||||
for (int i = 0; i < roi_size; ++i) {
|
|
||||||
encoder->cfg.roi.dqps[i] += cfg->qp - 26;
|
|
||||||
encoder->cfg.roi.dqps[i] = CLIP(-51, 51, encoder->cfg.roi.dqps[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: When tr_depth_inter is equal to 0, the transform is still split
|
// NOTE: When tr_depth_inter is equal to 0, the transform is still split
|
||||||
// for SMP and AMP partition units.
|
// for SMP and AMP partition units.
|
||||||
encoder->tr_depth_inter = 0;
|
encoder->tr_depth_inter = 0;
|
||||||
|
|
||||||
if (encoder->cfg.target_bitrate > 0 || encoder->cfg.roi.dqps) {
|
if (encoder->cfg.target_bitrate > 0 || encoder->cfg.roi.dqps || encoder->cfg.set_qp_in_cu) {
|
||||||
encoder->max_qp_delta_depth = 0;
|
encoder->max_qp_delta_depth = 0;
|
||||||
} else {
|
} else {
|
||||||
encoder->max_qp_delta_depth = -1;
|
encoder->max_qp_delta_depth = -1;
|
||||||
|
|
|
@ -456,8 +456,9 @@ static void encoder_state_write_bitstream_pic_parameter_set(bitstream_t* stream,
|
||||||
WRITE_UE(stream, 0, "num_ref_idx_l1_default_active_minus1");
|
WRITE_UE(stream, 0, "num_ref_idx_l1_default_active_minus1");
|
||||||
|
|
||||||
// If tiles and slices = tiles is enabled, signal QP in the slice header. Keeping the PPS constant for OMAF etc
|
// If tiles and slices = tiles is enabled, signal QP in the slice header. Keeping the PPS constant for OMAF etc
|
||||||
bool signal_qp_in_slice_header = (encoder->cfg.slices & KVZ_SLICES_TILES) && encoder->tiles_enable;
|
// Keep QP constant here also if it will be only set at CU level.
|
||||||
WRITE_SE(stream, signal_qp_in_slice_header ?0:(((int8_t)encoder->cfg.qp) - 26), "pic_init_qp_minus26");
|
bool constant_qp_in_pps = ((encoder->cfg.slices & KVZ_SLICES_TILES) && encoder->tiles_enable) || encoder->cfg.set_qp_in_cu;
|
||||||
|
WRITE_SE(stream, constant_qp_in_pps ? 0 : (((int8_t)encoder->cfg.qp) - 26), "pic_init_qp_minus26");
|
||||||
|
|
||||||
WRITE_U(stream, 0, 1, "constrained_intra_pred_flag");
|
WRITE_U(stream, 0, 1, "constrained_intra_pred_flag");
|
||||||
WRITE_U(stream, encoder->cfg.trskip_enable, 1, "transform_skip_enabled_flag");
|
WRITE_U(stream, encoder->cfg.trskip_enable, 1, "transform_skip_enabled_flag");
|
||||||
|
@ -812,8 +813,10 @@ static void kvz_encoder_state_write_bitstream_slice_header_independent(
|
||||||
|
|
||||||
{
|
{
|
||||||
// If tiles are enabled, signal the full QP here (relative to the base value of 26)
|
// If tiles are enabled, signal the full QP here (relative to the base value of 26)
|
||||||
|
// If QP is to be set only at CU level, force slice_qp_delta zero
|
||||||
bool signal_qp_in_slice_header = (encoder->cfg.slices & KVZ_SLICES_TILES) && encoder->tiles_enable;
|
bool signal_qp_in_slice_header = (encoder->cfg.slices & KVZ_SLICES_TILES) && encoder->tiles_enable;
|
||||||
int slice_qp_delta = state->frame->QP - (signal_qp_in_slice_header ? 26 : encoder->cfg.qp);
|
int slice_qp_delta = state->frame->QP - (signal_qp_in_slice_header ? 26 : encoder->cfg.qp);
|
||||||
|
if(encoder->cfg.set_qp_in_cu) slice_qp_delta = 0;
|
||||||
WRITE_SE(stream, slice_qp_delta, "slice_qp_delta");
|
WRITE_SE(stream, slice_qp_delta, "slice_qp_delta");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -726,7 +726,8 @@ static void encoder_state_encode_leaf(encoder_state_t * const state)
|
||||||
const encoder_control_t *ctrl = state->encoder_control;
|
const encoder_control_t *ctrl = state->encoder_control;
|
||||||
const kvz_config *cfg = &ctrl->cfg;
|
const kvz_config *cfg = &ctrl->cfg;
|
||||||
|
|
||||||
state->last_qp = state->frame->QP;
|
// Signaled slice QP may be different to frame QP with set-qp-in-cu enabled.
|
||||||
|
state->last_qp = ctrl->cfg.set_qp_in_cu ? 26 : state->frame->QP;
|
||||||
|
|
||||||
if (cfg->crypto_features) {
|
if (cfg->crypto_features) {
|
||||||
state->crypto_hdl = kvz_crypto_create(cfg);
|
state->crypto_hdl = kvz_crypto_create(cfg);
|
||||||
|
@ -1140,7 +1141,7 @@ static void encoder_state_init_children(encoder_state_t * const state) {
|
||||||
if (state->is_leaf) {
|
if (state->is_leaf) {
|
||||||
//Leaf states have cabac and context
|
//Leaf states have cabac and context
|
||||||
kvz_cabac_start(&state->cabac);
|
kvz_cabac_start(&state->cabac);
|
||||||
kvz_init_contexts(state, state->frame->QP, state->frame->slicetype);
|
kvz_init_contexts(state, state->encoder_control->cfg.set_qp_in_cu ? 26 : state->frame->QP, state->frame->slicetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clear the jobs
|
//Clear the jobs
|
||||||
|
|
|
@ -272,7 +272,8 @@ static int8_t get_qp_y_pred(const encoder_state_t* state, int x, int y, edge_dir
|
||||||
} else if (dir == EDGE_VER && x > 0) {
|
} else if (dir == EDGE_VER && x > 0) {
|
||||||
qp_p = kvz_cu_array_at_const(state->tile->frame->cu_array, x - 1, y)->qp;
|
qp_p = kvz_cu_array_at_const(state->tile->frame->cu_array, x - 1, y)->qp;
|
||||||
} else {
|
} else {
|
||||||
qp_p = state->frame->QP;
|
// TODO: This seems to be dead code. Investigate.
|
||||||
|
qp_p = state->encoder_control->cfg.set_qp_in_cu ? 26 : state->frame->QP;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int32_t qp_q =
|
const int32_t qp_q =
|
||||||
|
|
Loading…
Reference in a new issue