Fixed issue with kvz_go_rice_par_abs where passing a unsigned argument caused MIN function to return wrong value. Modified coefficient coding to match VTM 5.0. Some issues still remain.

This commit is contained in:
Sami Ahovainio 2019-06-05 15:57:18 +03:00
parent 367f1b2129
commit 8d2581e58c
4 changed files with 85 additions and 27 deletions

View file

@ -344,7 +344,7 @@ void kvz_cabac_encode_bins_ep(cabac_data_t * const data, uint32_t bin_values, in
*/
void kvz_cabac_write_coeff_remain(cabac_data_t * const cabac, const uint32_t remainder, const uint32_t rice_param)
{
const unsigned threshold = g_go_rice_range[rice_param] << rice_param;
const unsigned threshold = 5/*g_go_rice_range[rice_param]*/ << rice_param;
uint32_t bins = remainder;
if (bins < threshold) {
@ -353,6 +353,27 @@ void kvz_cabac_write_coeff_remain(cabac_data_t * const cabac, const uint32_t rem
CABAC_BINS_EP(cabac, bins & ((1 << rice_param) - 1), rice_param, "coeff_abs_level_remaining");
}
//ToDo: else if (useLimitedPrefixLength)
else if (true) {
const unsigned max_prefix_length = 32 - 5/*coef_remain_bin_reduction*/ - 15/*max_log2_tr_dynamic_range*/;
unsigned prefix_length = 0;
unsigned code_value = (bins >> rice_param) - 5/*coef_remain_bin_reduction*/;
unsigned suffix_length;
if (code_value >= ((1 << max_prefix_length) - 1)) {
prefix_length = max_prefix_length;
suffix_length = 15 /*max_log2_tr_dynamic_range*/;
} else {
while (code_value > ((2 << prefix_length) - 2)) {
prefix_length++;
}
suffix_length = prefix_length + rice_param + 1;
}
const unsigned total_prefix_length = prefix_length + 5/*coef_remain_bin_reduction*/;
const unsigned bit_mask = (1 << rice_param) - 1;
const unsigned prefix = (1 << total_prefix_length) - 1;
const unsigned suffix = ((code_value - ((1 << prefix_length) - 1)) << rice_param) | (bins & bit_mask);
CABAC_BINS_EP(cabac, prefix, total_prefix_length, "coeff_abs_level_remaining");
CABAC_BINS_EP(cabac, suffix, suffix_length, "coeff_abs_level_remaining");
}
else {
uint32_t length = rice_param;
uint32_t delta = 1 << length;

View file

@ -603,7 +603,7 @@ uint32_t kvz_abs_sum(const coeff_t* coeff, int32_t pos_x, int32_t pos_y,
}
}
#undef UPDATE
return MAX(MIN(sum - 5 * baselevel, 31),0);
return MAX(MIN(sum - 5 * (int32_t)baselevel, 31),0);
/*return MIN(sum, 31);*/
}
@ -644,6 +644,7 @@ uint32_t kvz_go_rice_par_abs(const coeff_t* coeff, int32_t pos_x, int32_t pos_y,
// }
// }
//#undef UPDATE
return g_go_rice_pars[kvz_abs_sum(coeff, pos_x, pos_y, height, width, baselevel)];
uint32_t check = kvz_abs_sum(coeff, pos_x, pos_y, height, width, baselevel);
return g_go_rice_pars[check];
/*return g_go_rice_pars[kvz_abs_sum(coeff, pos_x, pos_y, height, width, baselevel)];*/
}

View file

@ -64,15 +64,15 @@ static void encode_last_significant_xy(cabac_data_t * const cabac,
}
*/
const int group_idx_x = g_group_idx[MIN(32, width)-1];
const int group_idx_y = g_group_idx[MIN(32, height)-1];
const int group_idx_x = g_group_idx[lastpos_x];
const int group_idx_y = g_group_idx[lastpos_y];
// x prefix
for (int last_x = 0; last_x < group_idx_x; last_x++) {
cabac->cur_ctx = &base_ctx_x[ctx_offset + (last_x >> shift)];
CABAC_BIN(cabac, 1, "last_sig_coeff_x_prefix");
}
if (group_idx_x < g_group_idx[width - 1]) {
if (group_idx_x < ( width == 32 ? g_group_idx[15] : g_group_idx[MIN(32, width) - 1])) {
cabac->cur_ctx = &base_ctx_x[ctx_offset + (group_idx_x >> shift)];
CABAC_BIN(cabac, 0, "last_sig_coeff_x_prefix");
}
@ -82,7 +82,7 @@ static void encode_last_significant_xy(cabac_data_t * const cabac,
cabac->cur_ctx = &base_ctx_y[ctx_offset + (last_y >> shift)];
CABAC_BIN(cabac, 1, "last_sig_coeff_y_prefix");
}
if (group_idx_y < g_group_idx[height - 1]) {
if (group_idx_y < ( height == 32 ? g_group_idx[15] : g_group_idx[MIN(32, height) - 1])) {
cabac->cur_ctx = &base_ctx_y[ctx_offset + (group_idx_y >> shift)];
CABAC_BIN(cabac, 0, "last_sig_coeff_y_prefix");
}
@ -129,7 +129,7 @@ void kvz_encode_coeff_nxn(encoder_state_t * const state,
uint8_t last_coeff_y = 0;
int32_t i;
// ToDo: large block support in VVC?
uint32_t sig_coeffgroup_flag[8 * 8] = { 0 };
uint32_t sig_coeffgroup_flag[32 * 32] = { 0 };
int32_t scan_pos;
//int32_t next_sig_pos;
@ -148,6 +148,7 @@ void kvz_encode_coeff_nxn(encoder_state_t * const state,
// Scan all coeff groups to find out which of them have coeffs.
// Populate sig_coeffgroup_flag with that info.
/*
unsigned sig_cg_cnt = 0;
for (int cg_y = 0; cg_y < width / 4; ++cg_y) {
for (int cg_x = 0; cg_x < width / 4; ++cg_x) {
@ -171,6 +172,7 @@ void kvz_encode_coeff_nxn(encoder_state_t * const state,
// Rest of the code assumes at least one non-zero coeff.
assert(sig_cg_cnt > 0);
// Find the last coeff group by going backwards in scan order.
unsigned scan_cg_last = num_blk_side * num_blk_side - 1;
while (!sig_coeffgroup_flag[scan_cg[scan_cg_last]]) {
@ -178,11 +180,24 @@ void kvz_encode_coeff_nxn(encoder_state_t * const state,
}
// Find the last coeff by going backwards in scan order.
unsigned scan_pos_last = scan_cg_last * 16 + 15;
while (!coeff[scan[scan_pos_last]]) {
--scan_pos_last;
}
*/
unsigned scan_cg_last = -1;
unsigned scan_pos_last = -1;
for (int i = 0; i < width * width; i++) {
if (coeff[scan[i]]) {
scan_cg_last = i;
scan_pos_last = i;
sig_coeffgroup_flag[i >> (width + width)] = 1;
}
}
int pos_last = scan[scan_pos_last];
@ -194,8 +209,9 @@ void kvz_encode_coeff_nxn(encoder_state_t * const state,
}
*/
last_coeff_x = pos_last & (width - 1);
last_coeff_y = (uint8_t)(pos_last >> log2_block_size);
last_coeff_y = (uint8_t)(pos_last / width);
last_coeff_x = (uint8_t)(pos_last - (last_coeff_y * width));
// Code last_coeff_x and last_coeff_y
encode_last_significant_xy(cabac,
@ -294,7 +310,7 @@ void kvz_encode_coeff_nxn(encoder_state_t * const state,
int32_t remainder_abs_coeff = abs(coeff[blk_pos]) - 1;
// If shift sign pattern and add current sign
coeff_signs = 2 * coeff_signs + (coeff[blk_pos] < 0);
coeff_signs = (next_sig_pos != scan_cg_last ? 2 * coeff_signs : coeff_signs) + (coeff[blk_pos] < 0);
@ -988,6 +1004,9 @@ static void encode_intra_coding_unit(encoder_state_t * const state,
kvz_cabac_encode_bin_trm(cabac, 0); // IPCMFlag == 0
#endif
cabac->cur_ctx = &(cabac->ctx.bdpcm_mode[0]);
CABAC_BIN(cabac, 0, "bdpcm_mode");
const int num_pred_units = kvz_part_mode_num_parts[cur_cu->part_size];
//ToDo: update multi_ref_lines variable when it's something else than constant 3
@ -1356,13 +1375,13 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
bool no_split, qt_split, bh_split, bv_split, th_split, tv_split;
no_split = qt_split = bh_split = bv_split = th_split = tv_split = true;
bool allow_qt = cu_width > (LCU_WIDTH >> MAX_DEPTH);
bool allow_btt = false; //ToDo: Enable btt
bool allow_btt = false;
uint8_t implicit_split_mode = KVZ_NO_SPLIT;
//bool implicit_split = border;
bool bottom_left_available = (abs_x > 0) && (abs_y + cu_width - 1 > ctrl->in.height);
bool top_right_available = (abs_x + cu_width - 1 < ctrl->in.width) && (abs_y > 0);
bool bottom_left_available = (abs_x > 0) && ((abs_y + cu_width - 1) < ctrl->in.height);
bool top_right_available = ((abs_x + cu_width - 1) < ctrl->in.width) && (abs_y > 0);
/*
if((depth >= 1 && (border_x != border_y))) implicit_split = false;
if (state->frame->slicetype != KVZ_SLICE_I) {
@ -1373,11 +1392,11 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
*/
if (!bottom_left_available && !top_right_available && allow_qt) {
implicit_split_mode = KVZ_QUAD_SPLIT;
} else if (!bottom_left_available && allow_qt) {
} else if (!bottom_left_available && allow_btt) {
implicit_split_mode = KVZ_HORZ_SPLIT;
} else if (!top_right_available && allow_qt) {
} else if (!top_right_available && allow_btt) {
implicit_split_mode = KVZ_VERT_SPLIT;
} else if (!bottom_left_available && !top_right_available) {
} else if (!bottom_left_available || !top_right_available) {
implicit_split_mode = KVZ_QUAD_SPLIT;
}
@ -1388,11 +1407,9 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
bv_split = (implicit_split_mode == KVZ_VERT_SPLIT);
}
if (!allow_btt) {
bh_split = th_split = bv_split = tv_split = false;
}
bool allow_split = qt_split | bh_split | bv_split | th_split | tv_split;
//ToDo: Change MAX_DEPTH to MAX_BT_DEPTH
allow_btt = depth < MAX_DEPTH;
if (no_split && allow_split) {
split_model = 0;
@ -1422,12 +1439,19 @@ void kvz_encode_coding_tree(encoder_state_t * const state,
cabac->cur_ctx = &(cabac->ctx.split_flag_model[split_model]);
CABAC_BIN(cabac, !(implicit_split_mode == KVZ_NO_SPLIT), "SplitFlag");
}
if (implicit_split_mode == KVZ_NO_SPLIT) return;
if (!split_flag) return;
if (allow_qt && allow_btt) {
cabac->cur_ctx = &(cabac->ctx.split_flag_model[split_model]);
CABAC_BIN(cabac, qt_split, "QT_SplitFlag");
}
//if (qt_split) return;
// Only signal split when it is not implicit, currently only Qt split supported
if (bh_split || bv_split || th_split || tv_split) {
if (!qt_split && (bh_split | bv_split | th_split | tv_split)) {
split_model = 0;

View file

@ -341,7 +341,18 @@ static INLINE bool is_last_cu_in_qg(const encoder_state_t *state, int x, int y,
(bottom % qg_width == 0 || bottom >= state->tile->frame->height);
}
static const uint8_t g_group_idx[64] = {
0, 1, 2, 3, 4, 4, 5, 5,
6, 6, 6, 6, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9,
10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,
11,11,11,11,11,11,11,11,
11,11,11,11,11,11,11,11
};
/*
static const uint8_t g_group_idx[128] = {
0, 1, 2, 3, 4, 4, 5, 5, 6, 6,
6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
@ -356,9 +367,10 @@ static const uint8_t g_group_idx[128] = {
13,13,13,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13 };
*/
static const uint8_t g_min_in_group[10] = {
0, 1, 2, 3, 4, 6, 8, 12, 16, 24 };
static const uint8_t g_min_in_group[14] = {
0,1,2,3,4,6,8,12,16,24,32,48,64,96 };
#define C1FLAG_NUMBER 8 // maximum number of largerThan1 flag coded in one chunk