mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Refactor inter merge candidate selection
Adds helper function add_merge_candidate and replaces macro CHECK_DUPLICATE with function is_duplicate_candidate.
This commit is contained in:
parent
f12e09bc40
commit
ef6503c728
139
src/inter.c
139
src/inter.c
|
@ -1246,6 +1246,45 @@ void kvz_inter_get_mv_cand_cua(const encoder_state_t * const state,
|
||||||
get_mv_cand_from_candidates(state, x, y, width, height, b0, b1, b2, a0, a1, c3, h, cur_cu, reflist, mv_cand);
|
get_mv_cand_from_candidates(state, x, y, width, height, b0, b1, b2, a0, a1, c3, h, cur_cu, reflist, mv_cand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_duplicate_candidate(const cu_info_t* cu1, const cu_info_t* cu2)
|
||||||
|
{
|
||||||
|
if (!cu2) return false;
|
||||||
|
if (cu1->inter.mv_dir != cu2->inter.mv_dir) return false;
|
||||||
|
|
||||||
|
for (int reflist = 0; reflist < 2; reflist++) {
|
||||||
|
if (cu1->inter.mv_dir & (1 << reflist)) {
|
||||||
|
if (cu1->inter.mv[reflist][0] != cu2->inter.mv[reflist][0] ||
|
||||||
|
cu1->inter.mv[reflist][1] != cu2->inter.mv[reflist][1] ||
|
||||||
|
cu1->inter.mv_ref[reflist] != cu2->inter.mv_ref[reflist]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool add_merge_candidate(const cu_info_t *cand,
|
||||||
|
const cu_info_t *possible_duplicate1,
|
||||||
|
const cu_info_t *possible_duplicate2,
|
||||||
|
inter_merge_cand_t *merge_cand_out)
|
||||||
|
{
|
||||||
|
if (!cand ||
|
||||||
|
is_duplicate_candidate(cand, possible_duplicate1) ||
|
||||||
|
is_duplicate_candidate(cand, possible_duplicate2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
merge_cand_out->mv[0][0] = cand->inter.mv[0][0];
|
||||||
|
merge_cand_out->mv[0][1] = cand->inter.mv[0][1];
|
||||||
|
merge_cand_out->mv[1][0] = cand->inter.mv[1][0];
|
||||||
|
merge_cand_out->mv[1][1] = cand->inter.mv[1][1];
|
||||||
|
merge_cand_out->ref[0] = cand->inter.mv_ref[0];
|
||||||
|
merge_cand_out->ref[1] = cand->inter.mv_ref[1];
|
||||||
|
merge_cand_out->dir = cand->inter.mv_dir;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get merge predictions for current block
|
* \brief Get merge predictions for current block
|
||||||
* \param state the encoder state
|
* \param state the encoder state
|
||||||
|
@ -1269,101 +1308,23 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
||||||
uint8_t ref_idx)
|
uint8_t ref_idx)
|
||||||
{
|
{
|
||||||
uint8_t candidates = 0;
|
uint8_t candidates = 0;
|
||||||
int8_t duplicate = 0;
|
|
||||||
|
|
||||||
cu_info_t *b0, *b1, *b2, *a0, *a1;
|
|
||||||
int8_t zero_idx = 0;
|
int8_t zero_idx = 0;
|
||||||
|
cu_info_t *b0, *b1, *b2, *a0, *a1;
|
||||||
b0 = b1 = b2 = a0 = a1 = NULL;
|
b0 = b1 = b2 = a0 = a1 = NULL;
|
||||||
get_spatial_merge_candidates(x, y, width, height,
|
get_spatial_merge_candidates(x, y, width, height,
|
||||||
state->tile->frame->width, state->tile->frame->height,
|
state->tile->frame->width,
|
||||||
|
state->tile->frame->height,
|
||||||
&b0, &b1, &b2, &a0, &a1, lcu);
|
&b0, &b1, &b2, &a0, &a1, lcu);
|
||||||
|
|
||||||
if (!use_a1) a1 = NULL;
|
if (!use_a1) a1 = NULL;
|
||||||
if (!use_b1) b1 = NULL;
|
if (!use_b1) b1 = NULL;
|
||||||
|
|
||||||
#define CHECK_DUPLICATE(CU1,CU2) {duplicate = 0; if ((CU2) && \
|
if (add_merge_candidate(a1, NULL, NULL, &mv_cand[candidates])) candidates++;
|
||||||
(CU1)->inter.mv_dir == (CU2)->inter.mv_dir && \
|
if (add_merge_candidate(b1, a1, NULL, &mv_cand[candidates])) candidates++;
|
||||||
(!(((CU1)->inter.mv_dir & 1) && ((CU2)->inter.mv_dir & 1)) || \
|
if (add_merge_candidate(b0, b1, NULL, &mv_cand[candidates])) candidates++;
|
||||||
((CU1)->inter.mv[0][0] == (CU2)->inter.mv[0][0] && \
|
if (add_merge_candidate(a0, a1, NULL, &mv_cand[candidates])) candidates++;
|
||||||
(CU1)->inter.mv[0][1] == (CU2)->inter.mv[0][1] && \
|
if (candidates < 4 &&
|
||||||
(CU1)->inter.mv_ref[0] == (CU2)->inter.mv_ref[0]) ) && \
|
add_merge_candidate(b2, a1, b1, &mv_cand[candidates])) candidates++;
|
||||||
(!(((CU1)->inter.mv_dir & 2) && ((CU2)->inter.mv_dir & 2) ) || \
|
|
||||||
((CU1)->inter.mv[1][0] == (CU2)->inter.mv[1][0] && \
|
|
||||||
(CU1)->inter.mv[1][1] == (CU2)->inter.mv[1][1] && \
|
|
||||||
(CU1)->inter.mv_ref[1] == (CU2)->inter.mv_ref[1]) ) \
|
|
||||||
) duplicate = 1; }
|
|
||||||
|
|
||||||
if (a1) {
|
|
||||||
mv_cand[candidates].mv[0][0] = a1->inter.mv[0][0];
|
|
||||||
mv_cand[candidates].mv[0][1] = a1->inter.mv[0][1];
|
|
||||||
mv_cand[candidates].mv[1][0] = a1->inter.mv[1][0];
|
|
||||||
mv_cand[candidates].mv[1][1] = a1->inter.mv[1][1];
|
|
||||||
mv_cand[candidates].ref[0] = a1->inter.mv_ref[0];
|
|
||||||
mv_cand[candidates].ref[1] = a1->inter.mv_ref[1];
|
|
||||||
mv_cand[candidates].dir = a1->inter.mv_dir;
|
|
||||||
candidates++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b1) {
|
|
||||||
if(candidates) CHECK_DUPLICATE(b1, a1);
|
|
||||||
if(!duplicate) {
|
|
||||||
mv_cand[candidates].mv[0][0] = b1->inter.mv[0][0];
|
|
||||||
mv_cand[candidates].mv[0][1] = b1->inter.mv[0][1];
|
|
||||||
mv_cand[candidates].mv[1][0] = b1->inter.mv[1][0];
|
|
||||||
mv_cand[candidates].mv[1][1] = b1->inter.mv[1][1];
|
|
||||||
mv_cand[candidates].ref[0] = b1->inter.mv_ref[0];
|
|
||||||
mv_cand[candidates].ref[1] = b1->inter.mv_ref[1];
|
|
||||||
mv_cand[candidates].dir = b1->inter.mv_dir;
|
|
||||||
candidates++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b0) {
|
|
||||||
if(candidates) CHECK_DUPLICATE(b0,b1);
|
|
||||||
if(!duplicate) {
|
|
||||||
mv_cand[candidates].mv[0][0] = b0->inter.mv[0][0];
|
|
||||||
mv_cand[candidates].mv[0][1] = b0->inter.mv[0][1];
|
|
||||||
mv_cand[candidates].mv[1][0] = b0->inter.mv[1][0];
|
|
||||||
mv_cand[candidates].mv[1][1] = b0->inter.mv[1][1];
|
|
||||||
mv_cand[candidates].ref[0] = b0->inter.mv_ref[0];
|
|
||||||
mv_cand[candidates].ref[1] = b0->inter.mv_ref[1];
|
|
||||||
mv_cand[candidates].dir = b0->inter.mv_dir;
|
|
||||||
candidates++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a0) {
|
|
||||||
if(candidates) CHECK_DUPLICATE(a0,a1);
|
|
||||||
if(!duplicate) {
|
|
||||||
mv_cand[candidates].mv[0][0] = a0->inter.mv[0][0];
|
|
||||||
mv_cand[candidates].mv[0][1] = a0->inter.mv[0][1];
|
|
||||||
mv_cand[candidates].mv[1][0] = a0->inter.mv[1][0];
|
|
||||||
mv_cand[candidates].mv[1][1] = a0->inter.mv[1][1];
|
|
||||||
mv_cand[candidates].ref[0] = a0->inter.mv_ref[0];
|
|
||||||
mv_cand[candidates].ref[1] = a0->inter.mv_ref[1];
|
|
||||||
mv_cand[candidates].dir = a0->inter.mv_dir;
|
|
||||||
candidates++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (candidates != 4) {
|
|
||||||
if (b2) {
|
|
||||||
CHECK_DUPLICATE(b2,a1);
|
|
||||||
if(!duplicate) {
|
|
||||||
CHECK_DUPLICATE(b2,b1);
|
|
||||||
if(!duplicate) {
|
|
||||||
mv_cand[candidates].mv[0][0] = b2->inter.mv[0][0];
|
|
||||||
mv_cand[candidates].mv[0][1] = b2->inter.mv[0][1];
|
|
||||||
mv_cand[candidates].mv[1][0] = b2->inter.mv[1][0];
|
|
||||||
mv_cand[candidates].mv[1][1] = b2->inter.mv[1][1];
|
|
||||||
mv_cand[candidates].ref[0] = b2->inter.mv_ref[0];
|
|
||||||
mv_cand[candidates].ref[1] = b2->inter.mv_ref[1];
|
|
||||||
mv_cand[candidates].dir = b2->inter.mv_dir;
|
|
||||||
candidates++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool can_use_tmvp =
|
bool can_use_tmvp =
|
||||||
state->encoder_control->cfg.tmvp_enable &&
|
state->encoder_control->cfg.tmvp_enable &&
|
||||||
|
@ -1444,12 +1405,12 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
||||||
}
|
}
|
||||||
num_ref = MIN(ref_negative, ref_positive);
|
num_ref = MIN(ref_negative, ref_positive);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add (0,0) prediction
|
// Add (0,0) prediction
|
||||||
while (candidates != MRG_MAX_NUM_CANDS) {
|
while (candidates != MRG_MAX_NUM_CANDS) {
|
||||||
mv_cand[candidates].mv[0][0] = 0;
|
mv_cand[candidates].mv[0][0] = 0;
|
||||||
mv_cand[candidates].mv[0][1] = 0;
|
mv_cand[candidates].mv[0][1] = 0;
|
||||||
mv_cand[candidates].ref[0] = (zero_idx>=num_ref-1)?0:zero_idx;
|
mv_cand[candidates].ref[0] = (zero_idx >= num_ref - 1) ? 0 : zero_idx;
|
||||||
mv_cand[candidates].ref[1] = mv_cand[candidates].ref[0];
|
mv_cand[candidates].ref[1] = mv_cand[candidates].ref[0];
|
||||||
mv_cand[candidates].dir = 1;
|
mv_cand[candidates].dir = 1;
|
||||||
if (state->frame->slicetype == KVZ_SLICE_B) {
|
if (state->frame->slicetype == KVZ_SLICE_B) {
|
||||||
|
|
Loading…
Reference in a new issue