[mip] Fix error which caused asan CI test to fail. Was caused by an uninitialized intra CU mip value.

This commit is contained in:
siivonek 2022-01-25 00:44:31 +02:00
parent 6b33957978
commit a4366dbcc5
2 changed files with 54 additions and 28 deletions

View file

@ -161,6 +161,8 @@ static void lcu_fill_cu_info(lcu_t *lcu, int x_local, int y_local, int width, in
to->intra.mode = cu->intra.mode; to->intra.mode = cu->intra.mode;
to->intra.mode_chroma = cu->intra.mode_chroma; to->intra.mode_chroma = cu->intra.mode_chroma;
to->intra.multi_ref_idx = cu->intra.multi_ref_idx; to->intra.multi_ref_idx = cu->intra.multi_ref_idx;
to->intra.mip_flag = cu->intra.mip_flag;
to->intra.mip_is_transposed = cu->intra.mip_is_transposed;
} else { } else {
to->skipped = cu->skipped; to->skipped = cu->skipped;
to->merged = cu->merged; to->merged = cu->merged;
@ -728,8 +730,8 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
int8_t intra_trafo; int8_t intra_trafo;
double intra_cost; double intra_cost;
uint8_t multi_ref_index = 0; uint8_t multi_ref_index = 0;
bool mip_flag; bool mip_flag = false;
bool mip_transposed; bool mip_transposed = false;
kvz_search_cu_intra(state, x, y, depth, lcu, kvz_search_cu_intra(state, x, y, depth, lcu,
&intra_mode, &intra_trafo, &intra_cost, &multi_ref_index, &mip_flag, &mip_transposed); &intra_mode, &intra_trafo, &intra_cost, &multi_ref_index, &mip_flag, &mip_transposed);
if (intra_cost < cost) { if (intra_cost < cost) {
@ -754,7 +756,10 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
// mode search of adjacent CUs. // mode search of adjacent CUs.
if (cur_cu->type == CU_INTRA) { if (cur_cu->type == CU_INTRA) {
assert(cur_cu->part_size == SIZE_2Nx2N || cur_cu->part_size == SIZE_NxN); assert(cur_cu->part_size == SIZE_2Nx2N || cur_cu->part_size == SIZE_NxN);
// Chroma mode must be planar if mip_flag is set.
if (!cur_cu->intra.mip_flag) {
cur_cu->intra.mode_chroma = cur_cu->intra.mode; cur_cu->intra.mode_chroma = cur_cu->intra.mode;
}
lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu); lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu);
kvz_intra_recon_cu(state, kvz_intra_recon_cu(state,
x, y, x, y,

View file

@ -829,10 +829,15 @@ static int8_t search_intra_rdo(encoder_state_t * const state,
} }
// Update order according to new costs // Update order according to new costs
kvz_sort_modes_intra_luma(modes, trafo, costs, modes_to_check);
bool use_mip = false;
if (num_mip_modes) { if (num_mip_modes) {
kvz_sort_modes_intra_luma(mip_modes, mip_trafo, mip_costs, num_mip_modes); kvz_sort_modes_intra_luma(mip_modes, mip_trafo, mip_costs, num_mip_modes);
if (costs[0] > mip_costs[0]) {
use_mip = true;
} }
kvz_sort_modes_intra_luma(modes, trafo, costs, modes_to_check); }
// The best transform split hierarchy is not saved anywhere, so to get the // The best transform split hierarchy is not saved anywhere, so to get the
// transform split hierarchy the search has to be performed again with the // transform split hierarchy the search has to be performed again with the
@ -842,9 +847,25 @@ static int8_t search_intra_rdo(encoder_state_t * const state,
pred_cu.depth = depth; pred_cu.depth = depth;
pred_cu.type = CU_INTRA; pred_cu.type = CU_INTRA;
pred_cu.part_size = ((depth == MAX_PU_DEPTH) ? SIZE_NxN : SIZE_2Nx2N); pred_cu.part_size = ((depth == MAX_PU_DEPTH) ? SIZE_NxN : SIZE_2Nx2N);
if (use_mip) {
pred_cu.intra.mode = mip_modes[0];
pred_cu.intra.mode_chroma = 0;
pred_cu.intra.multi_ref_idx = 0;
int transp_off = num_mip_modes >> 1;
bool is_transposed = (mip_modes[0] >= transp_off ? true : false);
int8_t pred_mode = (is_transposed ? mip_modes[0] - transp_off : mip_modes[0]);
pred_cu.intra.mode = pred_mode;
pred_cu.intra.mode_chroma = 0;
pred_cu.intra.mip_flag = true;
pred_cu.intra.mip_is_transposed = is_transposed;
}
else {
pred_cu.intra.mode = modes[0]; pred_cu.intra.mode = modes[0];
pred_cu.intra.mode_chroma = modes[0]; pred_cu.intra.mode_chroma = modes[0];
pred_cu.intra.multi_ref_idx = multi_ref_idx; pred_cu.intra.multi_ref_idx = multi_ref_idx;
pred_cu.intra.mip_flag = false;
pred_cu.intra.mip_is_transposed = false;
}
FILL(pred_cu.cbf, 0); FILL(pred_cu.cbf, 0);
search_intra_trdepth(state, x_px, y_px, depth, tr_depth, modes[0], MAX_INT, &pred_cu, lcu, NULL, trafo[0]); search_intra_trdepth(state, x_px, y_px, depth, tr_depth, modes[0], MAX_INT, &pred_cu, lcu, NULL, trafo[0]);
} }
@ -1170,36 +1191,36 @@ void kvz_search_cu_intra(encoder_state_t * const state,
double costs[MAX_REF_LINE_IDX][67]; double costs[MAX_REF_LINE_IDX][67];
bool enable_mip = state->encoder_control->cfg.mip; bool enable_mip = state->encoder_control->cfg.mip;
int8_t mip_modes[32]; // Modes [0, 15] are non-transposed. Modes [16,31] are transposed. // The maximum number of mip modes is 32. Max modes can be less depending on block size.
// Half of the possible modes are transposed, which is indicated by a separate transpose flag
int8_t mip_modes[32];
int8_t mip_trafo[32]; int8_t mip_trafo[32];
double mip_costs[32]; double mip_costs[32];
// The maximum number of possible MIP modes depend on block size & shape
int width = LCU_WIDTH >> depth;
int height = width; // TODO: proper height for non-square blocks.
int num_mip_modes = 0;
if (enable_mip) { if (enable_mip) {
for (int i = 0; i < 32; ++i) { for (int i = 0; i < 32; ++i) {
mip_modes[i] = i; mip_modes[i] = i;
mip_costs[i] = MAX_INT; mip_costs[i] = MAX_INT;
} }
}
// The maximum number of possible MIP modes depend on block size & shape
int width = LCU_WIDTH >> depth;
int height = width; // TODO: proper height for non-square blocks.
int tmp_modes;
// MIP_TODO: check for illegal block sizes. // MIP_TODO: check for illegal block sizes.
if (width == 4 && height == 4) { if (width == 4 && height == 4) {
// Mip size_id = 0. Num modes = 32 // Mip size_id = 0. Num modes = 32
tmp_modes = 32; num_mip_modes = 32;
} }
else if (width == 4 || height == 4 || (width == 8 && height == 8)) { else if (width == 4 || height == 4 || (width == 8 && height == 8)) {
// Mip size_id = 0. Num modes = 16 // Mip size_id = 0. Num modes = 16
tmp_modes = 16; num_mip_modes = 16;
} }
else { else {
// Mip size_id = 0. Num modes = 12 // Mip size_id = 0. Num modes = 12
tmp_modes = 12; num_mip_modes = 12;
}
} }
uint8_t num_mip_modes = enable_mip ? tmp_modes : 0;
// Find best intra mode for 2Nx2N. // Find best intra mode for 2Nx2N.
kvz_pixel *ref_pixels = &lcu->ref.y[lcu_px.x + lcu_px.y * LCU_WIDTH]; kvz_pixel *ref_pixels = &lcu->ref.y[lcu_px.x + lcu_px.y * LCU_WIDTH];