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
59
src/inter.c
59
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 use_b1 true, if candidate b1 can be used
|
||||||
* \param mv_cand Returns the merge candidates.
|
* \param mv_cand Returns the merge candidates.
|
||||||
* \param lcu lcu containing the block
|
* \param lcu lcu containing the block
|
||||||
|
* \param ref_idx current reference index (used only by TMVP)
|
||||||
* \return number of merge candidates
|
* \return number of merge candidates
|
||||||
*/
|
*/
|
||||||
uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
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,
|
int32_t width, int32_t height,
|
||||||
bool use_a1, bool use_b1,
|
bool use_a1, bool use_b1,
|
||||||
inter_merge_cand_t mv_cand[MRG_MAX_NUM_CANDS],
|
inter_merge_cand_t mv_cand[MRG_MAX_NUM_CANDS],
|
||||||
lcu_t *lcu)
|
lcu_t *lcu,
|
||||||
|
uint8_t ref_idx)
|
||||||
{
|
{
|
||||||
uint8_t candidates = 0;
|
uint8_t candidates = 0;
|
||||||
int8_t duplicate = 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) {
|
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 *c3 = NULL;
|
||||||
cu_info_t *h = 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;
|
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) {
|
if (selected_CU) {
|
||||||
|
|
||||||
mv_cand[candidates].dir = 0;
|
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
|
// Find LIST_0 reference
|
||||||
if (h != NULL && h->inter.mv_dir & 1) {
|
if (h != NULL && h->inter.mv_dir & 1) {
|
||||||
mv_cand[candidates].dir |= 1;
|
mv_cand[candidates].dir |= 1;
|
||||||
mv_cand[candidates].ref[0] = 0;
|
|
||||||
mv_cand[candidates].mv[0][0] = h->inter.mv[0][0];
|
if (td == tb) {
|
||||||
mv_cand[candidates].mv[0][1] = h->inter.mv[0][1];
|
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) {
|
} else if (c3 != NULL && c3->inter.mv_dir & 1) {
|
||||||
mv_cand[candidates].dir |= 1;
|
mv_cand[candidates].dir |= 1;
|
||||||
mv_cand[candidates].ref[0] = 0;
|
|
||||||
mv_cand[candidates].mv[0][0] = c3->inter.mv[0][0];
|
if (td == tb) {
|
||||||
mv_cand[candidates].mv[0][1] = c3->inter.mv[0][1];
|
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) {
|
if (state->frame->slicetype == KVZ_SLICE_B) {
|
||||||
// Find LIST_1 reference
|
// 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].mv[1][1] = c3->inter.mv[1][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//mv_cand[candidates].ref[0] = 0;
|
mv_cand[candidates].ref[0] = colocated_ref;
|
||||||
candidates++;
|
candidates++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,5 +85,6 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
||||||
int32_t width, int32_t height,
|
int32_t width, int32_t height,
|
||||||
bool use_a1, bool use_b1,
|
bool use_a1, bool use_b1,
|
||||||
inter_merge_cand_t mv_cand[MRG_MAX_NUM_CANDS],
|
inter_merge_cand_t mv_cand[MRG_MAX_NUM_CANDS],
|
||||||
lcu_t *lcu);
|
lcu_t *lcu,
|
||||||
|
uint8_t ref_idx);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1439,12 +1439,16 @@ static void search_pu_inter(encoder_state_t * const state,
|
||||||
// Search for merge mode candidate
|
// Search for merge mode candidate
|
||||||
inter_merge_cand_t merge_cand[MRG_MAX_NUM_CANDS];
|
inter_merge_cand_t merge_cand[MRG_MAX_NUM_CANDS];
|
||||||
// Get list of candidates
|
// Get list of candidates
|
||||||
int16_t num_cand = kvz_inter_get_merge_cand(state,
|
int16_t num_cand;
|
||||||
x, y,
|
if (!state->encoder_control->cfg->tmvp_enable) {
|
||||||
width, height,
|
num_cand = kvz_inter_get_merge_cand(state,
|
||||||
merge_a1, merge_b1,
|
x, y,
|
||||||
merge_cand,
|
width, height,
|
||||||
lcu);
|
merge_a1, merge_b1,
|
||||||
|
merge_cand,
|
||||||
|
lcu,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t(*get_mvd_cost)(encoder_state_t * const state, vector2d_t *, const cabac_data_t*) = get_mvd_coding_cost;
|
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) {
|
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;
|
uint32_t ref_idx;
|
||||||
for (ref_idx = 0; ref_idx < state->frame->ref->used_size; 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,
|
search_pu_inter_ref(state,
|
||||||
x, y,
|
x, y,
|
||||||
width, height,
|
width, height,
|
||||||
|
|
Loading…
Reference in a new issue