mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Added TMVP merge candidate scaling for L0
This commit is contained in:
parent
e6aa1b9b9a
commit
23be633ad7
51
src/inter.c
51
src/inter.c
|
@ -1238,6 +1238,7 @@ void kvz_inter_get_mv_cand_cua(const encoder_state_t * const state,
|
|||
* \param use_b1 true, if candidate b1 can be used
|
||||
* \param mv_cand Returns the merge candidates.
|
||||
* \param lcu lcu containing the block
|
||||
* \param ref_idx current reference index (used only by TMVP)
|
||||
* \return number of merge candidates
|
||||
*/
|
||||
uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
||||
|
@ -1245,7 +1246,8 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
int32_t width, int32_t height,
|
||||
bool use_a1, bool use_b1,
|
||||
inter_merge_cand_t mv_cand[MRG_MAX_NUM_CANDS],
|
||||
lcu_t *lcu)
|
||||
lcu_t *lcu,
|
||||
uint8_t ref_idx)
|
||||
{
|
||||
uint8_t candidates = 0;
|
||||
int8_t duplicate = 0;
|
||||
|
@ -1348,6 +1350,11 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
|
||||
if (candidates < MRG_MAX_NUM_CANDS && state->frame->ref->used_size) {
|
||||
|
||||
uint32_t colocated_ref = UINT_MAX;
|
||||
uint32_t colocated_ref_poc = 0;
|
||||
int32_t td, tb;
|
||||
|
||||
|
||||
cu_info_t *c3 = NULL;
|
||||
cu_info_t *h = NULL;
|
||||
|
||||
|
@ -1355,22 +1362,58 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
|
||||
const cu_info_t *selected_CU = (h != NULL) ? h : (c3 != NULL) ? c3 : NULL;
|
||||
|
||||
//ToDo: allow other than L0[0] for prediction
|
||||
|
||||
//Fetch ref idx of the selected CU in L0[0] ref list
|
||||
for (int temporal_cand = 0; temporal_cand < state->frame->ref->used_size; temporal_cand++) {
|
||||
if (state->frame->refmap[temporal_cand].list == 1 && state->frame->refmap[temporal_cand].idx == 0) {
|
||||
colocated_ref = temporal_cand;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
colocated_ref_poc = state->frame->ref->pocs[colocated_ref];
|
||||
|
||||
if (selected_CU) {
|
||||
|
||||
mv_cand[candidates].dir = 0;
|
||||
|
||||
// The reference id the colocated block is using
|
||||
uint32_t colocated_ref_mv_ref = selected_CU->inter.mv_ref[0];
|
||||
|
||||
td = colocated_ref_poc - state->frame->ref->images[0]->ref_pocs[colocated_ref_mv_ref];
|
||||
tb = state->frame->poc - state->frame->ref->pocs[ref_idx];
|
||||
|
||||
// Find LIST_0 reference
|
||||
if (h != NULL && h->inter.mv_dir & 1) {
|
||||
mv_cand[candidates].dir |= 1;
|
||||
mv_cand[candidates].ref[0] = 0;
|
||||
|
||||
if (td == tb) {
|
||||
mv_cand[candidates].mv[0][0] = h->inter.mv[0][0];
|
||||
mv_cand[candidates].mv[0][1] = h->inter.mv[0][1];
|
||||
} else {
|
||||
int scale = ((tb * ((0x4000 + (abs(td) >> 1)) / td) + 32) >> 6);
|
||||
mv_cand[candidates].mv[0][0] = ((scale * h->inter.mv[0][0] + 127 + ((scale * h->inter.mv[0][0]) < 0)) >> 8);
|
||||
mv_cand[candidates].mv[0][1] = ((scale * h->inter.mv[0][1] + 127 + ((scale * h->inter.mv[0][1]) < 0)) >> 8);
|
||||
}
|
||||
|
||||
//mv_cand[candidates].mv[0][0] = h->inter.mv[0][0];
|
||||
//mv_cand[candidates].mv[0][1] = h->inter.mv[0][1];
|
||||
|
||||
} else if (c3 != NULL && c3->inter.mv_dir & 1) {
|
||||
mv_cand[candidates].dir |= 1;
|
||||
mv_cand[candidates].ref[0] = 0;
|
||||
|
||||
if (td == tb) {
|
||||
mv_cand[candidates].mv[0][0] = c3->inter.mv[0][0];
|
||||
mv_cand[candidates].mv[0][1] = c3->inter.mv[0][1];
|
||||
} else {
|
||||
int scale = ((tb * ((0x4000 + (abs(td) >> 1)) / td) + 32) >> 6);
|
||||
mv_cand[candidates].mv[0][0] = ((scale * c3->inter.mv[0][0] + 127 + ((scale * c3->inter.mv[0][0]) < 0)) >> 8);
|
||||
mv_cand[candidates].mv[0][1] = ((scale * c3->inter.mv[0][1] + 127 + ((scale * c3->inter.mv[0][1]) < 0)) >> 8);
|
||||
}
|
||||
|
||||
//mv_cand[candidates].mv[0][0] = c3->inter.mv[0][0];
|
||||
//mv_cand[candidates].mv[0][1] = c3->inter.mv[0][1];
|
||||
}
|
||||
if (state->frame->slicetype == KVZ_SLICE_B) {
|
||||
// Find LIST_1 reference
|
||||
|
@ -1386,7 +1429,7 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
mv_cand[candidates].mv[1][1] = c3->inter.mv[1][1];
|
||||
}
|
||||
}
|
||||
//mv_cand[candidates].ref[0] = 0;
|
||||
mv_cand[candidates].ref[0] = colocated_ref;
|
||||
candidates++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,5 +85,6 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
int32_t width, int32_t height,
|
||||
bool use_a1, bool use_b1,
|
||||
inter_merge_cand_t mv_cand[MRG_MAX_NUM_CANDS],
|
||||
lcu_t *lcu);
|
||||
lcu_t *lcu,
|
||||
uint8_t ref_idx);
|
||||
#endif
|
||||
|
|
|
@ -1439,12 +1439,16 @@ static void search_pu_inter(encoder_state_t * const state,
|
|||
// Search for merge mode candidate
|
||||
inter_merge_cand_t merge_cand[MRG_MAX_NUM_CANDS];
|
||||
// Get list of candidates
|
||||
int16_t num_cand = kvz_inter_get_merge_cand(state,
|
||||
int16_t num_cand;
|
||||
if (!state->encoder_control->cfg->tmvp_enable) {
|
||||
num_cand = kvz_inter_get_merge_cand(state,
|
||||
x, y,
|
||||
width, height,
|
||||
merge_a1, merge_b1,
|
||||
merge_cand,
|
||||
lcu);
|
||||
lcu,
|
||||
0);
|
||||
}
|
||||
|
||||
uint32_t(*get_mvd_cost)(encoder_state_t * const state, vector2d_t *, const cabac_data_t*) = get_mvd_coding_cost;
|
||||
if (state->encoder_control->cfg.mv_rdo) {
|
||||
|
@ -1457,6 +1461,16 @@ static void search_pu_inter(encoder_state_t * const state,
|
|||
|
||||
uint32_t ref_idx;
|
||||
for (ref_idx = 0; ref_idx < state->frame->ref->used_size; ref_idx++) {
|
||||
if (state->encoder_control->cfg->tmvp_enable) {
|
||||
// Get list of candidates, TMVP required MV scaling for each reference
|
||||
num_cand = kvz_inter_get_merge_cand(state,
|
||||
x, y,
|
||||
width, height,
|
||||
merge_a1, merge_b1,
|
||||
merge_cand,
|
||||
lcu,
|
||||
ref_idx);
|
||||
}
|
||||
search_pu_inter_ref(state,
|
||||
x, y,
|
||||
width, height,
|
||||
|
|
Loading…
Reference in a new issue