[ibc] Fix some git merge issues and IBC merge candidate selection

This commit is contained in:
Marko Viitanen 2022-08-03 10:46:02 +03:00
parent 6a0e2a062d
commit 6de2e2d581
2 changed files with 56 additions and 29 deletions

View file

@ -985,11 +985,10 @@ static void get_temporal_merge_candidates(const encoder_state_t * const state,
}
}
static INLINE int16_t get_scaled_mv(int16_t mv, int scale)
static INLINE mv_t get_scaled_mv(mv_t mv, int scale)
{
int32_t scaled = scale * mv;
return CLIP(-32768, 32767, (scaled + 127 + (scaled < 0)) >> 8);
return CLIP(-131072, 131071, (scaled + 127 + (scaled < 0)) >> 8);
}
#define MV_EXPONENT_BITCOUNT 4
@ -1108,6 +1107,19 @@ static INLINE bool add_mvp_candidate(const encoder_state_t *state,
}
static bool is_duplicate_candidate_ibc(const cu_info_t* cu1, const cu_info_t* cu2)
{
if (!cu2) return false;
if (cu1->inter.mv[0][0] != cu2->inter.mv[0][0] ||
cu1->inter.mv[0][1] != cu2->inter.mv[0][1]) {
return false;
}
return true;
}
/**
* \brief Get merge candidates for current block.
*
@ -1175,10 +1187,12 @@ static void get_ibc_merge_candidates(const encoder_state_t * const state,
// before the current one and the flag is not set when searching an SMP
// block.
if (b1->type == CU_IBC) {
inter_clear_cu_unused(b1);
mv_cand[candidates][0] = b1->inter.mv[0][0];
mv_cand[candidates][1] = b1->inter.mv[0][1];
candidates++;
if(!is_duplicate_candidate_ibc(b1, a1)) {
inter_clear_cu_unused(b1);
mv_cand[candidates][0] = b1->inter.mv[0][0];
mv_cand[candidates][1] = b1->inter.mv[0][1];
candidates++;
}
} else {
b1 = NULL;
}
@ -1196,12 +1210,22 @@ static void get_ibc_merge_candidates(const encoder_state_t * const state,
int32_t num_cand = state->tile->frame->hmvp_size_ibc[ctu_row];
for (int i = 0; i < MIN(MAX_NUM_HMVP_CANDS,num_cand); i++) {
cu_info_t* cand = &state->tile->frame->hmvp_lut_ibc[ctu_row_mul_five + i];
bool duplicate = false;
// Check that the HMVP candidate is not duplicate
if (is_duplicate_candidate_ibc(cand, a1)) {
duplicate = true;
} else if(is_duplicate_candidate_ibc(cand, b1)) {
duplicate = true;
}
mv_cand[candidates][0] = cand->inter.mv[0][0];
mv_cand[candidates][1] = cand->inter.mv[0][1];
candidates++;
if (candidates == IBC_MRG_MAX_NUM_CANDS) return;
// allow duplicates after the first hmvp lut item
if (!duplicate || i > 0) {
mv_cand[candidates][0] = cand->inter.mv[0][0];
mv_cand[candidates][1] = cand->inter.mv[0][1];
candidates++;
if (candidates == IBC_MRG_MAX_NUM_CANDS) return;
}
}
}
@ -1390,12 +1414,6 @@ static void get_spatial_merge_candidates_cua(const cu_array_t *cua,
}
}
static INLINE mv_t get_scaled_mv(mv_t mv, int scale)
{
int32_t scaled = scale * mv;
return CLIP(-131072, 131071, (scaled + 127 + (scaled < 0)) >> 8);
}
/**
* \brief Try to add a temporal MVP or merge candidate.
*
@ -1697,14 +1715,23 @@ static void hmvp_shift_lut(cu_info_t* lut, int32_t size, int32_t start, int32_t
}
}
static bool hmvp_push_lut_item(cu_info_t* lut, int32_t size, const cu_info_t* cu) {
static bool hmvp_push_lut_item(cu_info_t* lut, int32_t size, const cu_info_t* cu, bool ibc) {
int8_t duplicate = -1;
for (int i = 0; i < size; i++) {
if (is_duplicate_candidate(cu, (const cu_info_t*)&lut[i])) {
duplicate = i;
break;
if (ibc) {
for (int i = 0; i < size; i++) {
if (is_duplicate_candidate_ibc(cu, (const cu_info_t *)&lut[i])) {
duplicate = i;
break;
}
}
} else {
for (int i = 0; i < size; i++) {
if (is_duplicate_candidate(cu, (const cu_info_t *)&lut[i])) {
duplicate = i;
break;
}
}
}
// If duplicate found, shift the whole lut up to the duplicate, otherwise to the end
@ -1741,12 +1768,12 @@ void uvg_hmvp_add_mv(const encoder_state_t* const state, uint32_t pic_x, uint32_
if (cu->type == CU_IBC) {
bool add_row = hmvp_push_lut_item(&state->tile->frame->hmvp_lut_ibc[ctu_row_mul_five], state->tile->frame->hmvp_size_ibc[ctu_row], cu);
bool add_row = hmvp_push_lut_item(&state->tile->frame->hmvp_lut_ibc[ctu_row_mul_five], state->tile->frame->hmvp_size_ibc[ctu_row], cu, true);
if(add_row && state->tile->frame->hmvp_size_ibc[ctu_row] < MAX_NUM_HMVP_CANDS) {
state->tile->frame->hmvp_size_ibc[ctu_row]++;
}
} else {
bool add_row = hmvp_push_lut_item(&state->tile->frame->hmvp_lut[ctu_row_mul_five], state->tile->frame->hmvp_size[ctu_row], cu);
bool add_row = hmvp_push_lut_item(&state->tile->frame->hmvp_lut[ctu_row_mul_five], state->tile->frame->hmvp_size[ctu_row], cu, false);
if(add_row && state->tile->frame->hmvp_size[ctu_row] < MAX_NUM_HMVP_CANDS) {
state->tile->frame->hmvp_size[ctu_row]++;
}

View file

@ -93,7 +93,8 @@ static INLINE bool intmv_within_ibc_range(const ibc_search_info_t *info, int x,
bool negative_values = x <= 0 && y <= 0;
bool mv_range_valid = ((-y >= info->height) || (-x >= info->width)) && // Must be block height/width away from the block
SUB_SCU(info->origin.y) >= -y && // Y vector must be inside the current CTU
(-x <= IBC_BUFFER_WIDTH-LCU_WIDTH); // X must be inside the buffer
(-x <= IBC_BUFFER_WIDTH-LCU_WIDTH) && // X must be inside the buffer
info->origin.x + x >= 0; // Don't go outside of the frame
return negative_values && mv_range_valid;
@ -406,7 +407,6 @@ static int select_ibc_mv_cand(const encoder_state_t *state,
return cand2_cost < cand1_cost ? 1 : 0;
}
static double calc_ibc_mvd_cost(const encoder_state_t *state,
int x,
int y,
@ -878,9 +878,9 @@ static void search_pu_ibc(encoder_state_t * const state,
cur_pu->inter.mv_dir = info->merge_cand[merge_idx].dir;
cur_pu->inter.mv[0][0] = info->merge_cand[merge_idx].mv[0][0];
cur_pu->inter.mv[0][1] = info->merge_cand[merge_idx].mv[0][1];
uvg_lcu_fill_trdepth(lcu, x, y, depth, MAX(1, depth));
uvg_lcu_fill_trdepth(lcu, x, y, depth, MAX(1, depth), UVG_BOTH_T);
uvg_inter_recon_cu(state, lcu, x, y, width, true, false);
uvg_quantize_lcu_residual(state, true, false, false, x, y, depth, cur_pu, lcu, true);
uvg_quantize_lcu_residual(state, true, false, false, x, y, depth, cur_pu, lcu, true, UVG_BOTH_T);
if (cbf_is_set(cur_pu->cbf, depth, COLOR_Y)) {
continue;
@ -889,7 +889,7 @@ static void search_pu_ibc(encoder_state_t * const state,
uvg_inter_recon_cu(state, lcu, x, y, width, false, has_chroma);
uvg_quantize_lcu_residual(state, false, has_chroma,
false, /*we are only checking for lack of coeffs so no need to check jccr*/
x, y, depth, cur_pu, lcu, true);
x, y, depth, cur_pu, lcu, true, UVG_BOTH_T);
if (!cbf_is_set_any(cur_pu->cbf, depth)) {
cur_pu->type = CU_IBC;
cur_pu->merge_idx = merge_idx;