mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-24 02:24:07 +00:00
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:
parent
367f1b2129
commit
8d2581e58c
23
src/cabac.c
23
src/cabac.c
|
@ -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;
|
||||
|
|
|
@ -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)];*/
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue