Enable merge analysis for smp and amp

This commit is contained in:
Ari Lemmetti 2019-09-02 17:31:51 +03:00
parent 557bcbc6aa
commit 3bc510712f

View file

@ -1551,87 +1551,84 @@ static void search_pu_inter(encoder_state_t * const state,
mrg_costs[i] = MAX_DOUBLE; mrg_costs[i] = MAX_DOUBLE;
} }
if (cur_cu->part_size == SIZE_2Nx2N) { int num_rdo_cands = 0;
int num_rdo_cands = 0; // Check motion vector constraints and perform rough search
for (int merge_idx = 0; merge_idx < info.num_merge_cand; ++merge_idx) {
// Check motion vector constraints and perform rough search inter_merge_cand_t *cur_cand = &info.merge_cand[merge_idx];
for (int merge_idx = 0; merge_idx < info.num_merge_cand; ++merge_idx) { cur_cu->inter.mv_dir = cur_cand->dir;
cur_cu->inter.mv_ref[0] = cur_cand->ref[0];
cur_cu->inter.mv_ref[1] = cur_cand->ref[1];
cur_cu->inter.mv[0][0] = cur_cand->mv[0][0];
cur_cu->inter.mv[0][1] = cur_cand->mv[0][1];
cur_cu->inter.mv[1][0] = cur_cand->mv[1][0];
cur_cu->inter.mv[1][1] = cur_cand->mv[1][1];
inter_merge_cand_t *cur_cand = &info.merge_cand[merge_idx]; if (cur_cu->inter.mv_dir == 3 && !state->encoder_control->cfg.bipred) continue;
cur_cu->inter.mv_dir = cur_cand->dir; bool is_duplicate = merge_candidate_in_list(info.merge_cand, cur_cand,
cur_cu->inter.mv_ref[0] = cur_cand->ref[0]; mrg_cands,
cur_cu->inter.mv_ref[1] = cur_cand->ref[1]; num_rdo_cands);
cur_cu->inter.mv[0][0] = cur_cand->mv[0][0];
cur_cu->inter.mv[0][1] = cur_cand->mv[0][1];
cur_cu->inter.mv[1][0] = cur_cand->mv[1][0];
cur_cu->inter.mv[1][1] = cur_cand->mv[1][1];
if (cur_cu->inter.mv_dir == 3 && !state->encoder_control->cfg.bipred) continue; // Don't try merge candidates that don't satisfy mv constraints.
bool is_duplicate = merge_candidate_in_list(info.merge_cand, cur_cand, // Don't add duplicates to list
mrg_cands, if (!fracmv_within_tile(&info, cur_cu->inter.mv[0][0], cur_cu->inter.mv[0][1]) ||
num_rdo_cands); !fracmv_within_tile(&info, cur_cu->inter.mv[1][0], cur_cu->inter.mv[1][1]) ||
is_duplicate)
// Don't try merge candidates that don't satisfy mv constraints. {
// Don't add duplicates to list continue;
if (!fracmv_within_tile(&info, cur_cu->inter.mv[0][0], cur_cu->inter.mv[0][1]) ||
!fracmv_within_tile(&info, cur_cu->inter.mv[1][0], cur_cu->inter.mv[1][1]) ||
is_duplicate)
{
continue;
}
kvz_inter_recon_cu(state, lcu, x, y, width, true, false);
mrg_costs[num_rdo_cands] = kvz_satd_any_size(width, height,
lcu->rec.y + y_local * LCU_WIDTH + x_local, LCU_WIDTH,
lcu->ref.y + y_local * LCU_WIDTH + x_local, LCU_WIDTH);
mrg_cands[num_rdo_cands] = merge_idx;
num_rdo_cands++;
} }
// Sort candidates by cost kvz_inter_recon_cu(state, lcu, x, y, width, true, false);
kvz_sort_modes(mrg_cands, mrg_costs, num_rdo_cands); mrg_costs[num_rdo_cands] = kvz_satd_any_size(width, height,
lcu->rec.y + y_local * LCU_WIDTH + x_local, LCU_WIDTH,
lcu->ref.y + y_local * LCU_WIDTH + x_local, LCU_WIDTH);
// Limit by availability mrg_cands[num_rdo_cands] = merge_idx;
// TODO: Do not limit to just 1 num_rdo_cands++;
num_rdo_cands = MIN(1, num_rdo_cands); }
// Early Skip Mode Decision // Sort candidates by cost
bool has_chroma = state->encoder_control->chroma_format != KVZ_CSP_400; kvz_sort_modes(mrg_cands, mrg_costs, num_rdo_cands);
if (cfg->early_skip) {
for (int merge_rdo_idx = 0; merge_rdo_idx < num_rdo_cands; ++merge_rdo_idx) {
// Reconstruct blocks with merge candidate. // Limit by availability
// Check luma CBF. Then, check chroma CBFs if luma CBF is not set // TODO: Do not limit to just 1
// and chroma exists. num_rdo_cands = MIN(1, num_rdo_cands);
// Early terminate if merge candidate with zero CBF is found.
int merge_idx = mrg_cands[merge_rdo_idx];
cur_cu->inter.mv_dir = info.merge_cand[merge_idx].dir;
cur_cu->inter.mv_ref[0] = info.merge_cand[merge_idx].ref[0];
cur_cu->inter.mv_ref[1] = info.merge_cand[merge_idx].ref[1];
cur_cu->inter.mv[0][0] = info.merge_cand[merge_idx].mv[0][0];
cur_cu->inter.mv[0][1] = info.merge_cand[merge_idx].mv[0][1];
cur_cu->inter.mv[1][0] = info.merge_cand[merge_idx].mv[1][0];
cur_cu->inter.mv[1][1] = info.merge_cand[merge_idx].mv[1][1];
kvz_lcu_fill_trdepth(lcu, x, y, depth, MAX(1, depth));
kvz_inter_recon_cu(state, lcu, x, y, width, true, false);
kvz_quantize_lcu_residual(state, true, false, x, y, depth, cur_cu, lcu);
if (cbf_is_set(cur_cu->cbf, depth, COLOR_Y)) { // Early Skip Mode Decision
continue; bool has_chroma = state->encoder_control->chroma_format != KVZ_CSP_400;
} if (cfg->early_skip && cur_cu->part_size == SIZE_2Nx2N) {
else if (has_chroma) { for (int merge_rdo_idx = 0; merge_rdo_idx < num_rdo_cands; ++merge_rdo_idx) {
kvz_inter_recon_cu(state, lcu, x, y, width, false, has_chroma);
kvz_quantize_lcu_residual(state, false, has_chroma, x, y, depth, cur_cu, lcu); // Reconstruct blocks with merge candidate.
if (!cbf_is_set_any(cur_cu->cbf, depth)) { // Check luma CBF. Then, check chroma CBFs if luma CBF is not set
cur_cu->type = CU_INTER; // and chroma exists.
cur_cu->merge_idx = merge_idx; // Early terminate if merge candidate with zero CBF is found.
cur_cu->skipped = true; int merge_idx = mrg_cands[merge_rdo_idx];
*inter_cost = 0.0; // TODO: Check this cur_cu->inter.mv_dir = info.merge_cand[merge_idx].dir;
*inter_bitcost = 0; // TODO: Check this cur_cu->inter.mv_ref[0] = info.merge_cand[merge_idx].ref[0];
return; cur_cu->inter.mv_ref[1] = info.merge_cand[merge_idx].ref[1];
} cur_cu->inter.mv[0][0] = info.merge_cand[merge_idx].mv[0][0];
cur_cu->inter.mv[0][1] = info.merge_cand[merge_idx].mv[0][1];
cur_cu->inter.mv[1][0] = info.merge_cand[merge_idx].mv[1][0];
cur_cu->inter.mv[1][1] = info.merge_cand[merge_idx].mv[1][1];
kvz_lcu_fill_trdepth(lcu, x, y, depth, MAX(1, depth));
kvz_inter_recon_cu(state, lcu, x, y, width, true, false);
kvz_quantize_lcu_residual(state, true, false, x, y, depth, cur_cu, lcu);
if (cbf_is_set(cur_cu->cbf, depth, COLOR_Y)) {
continue;
}
else if (has_chroma) {
kvz_inter_recon_cu(state, lcu, x, y, width, false, has_chroma);
kvz_quantize_lcu_residual(state, false, has_chroma, x, y, depth, cur_cu, lcu);
if (!cbf_is_set_any(cur_cu->cbf, depth)) {
cur_cu->type = CU_INTER;
cur_cu->merge_idx = merge_idx;
cur_cu->skipped = true;
*inter_cost = 0.0; // TODO: Check this
*inter_bitcost = 0; // TODO: Check this
return;
} }
} }
} }