mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Fix bipred and temporal MVP
- Fixes two errors in calculating the POC for the reference frame for temporal candidate MV scaling. - Fixes using the MV for the wrong direction when the temporal MV predictor block uses bi-prediction. Fixes #160.
This commit is contained in:
parent
841597e123
commit
9974380cdd
33
src/inter.c
33
src/inter.c
|
@ -992,17 +992,31 @@ static bool add_temporal_candidate(const encoder_state_t *state,
|
|||
return false;
|
||||
}
|
||||
|
||||
int cand_list = colocated->inter.mv_dir & (1 << reflist) ? reflist : !reflist;
|
||||
// When there are reference pictures from the future (POC > current POC)
|
||||
// in L0 or L1, the primary list for the colocated PU is the inverse of
|
||||
// collocated_from_l0_flag. Otherwise it is equal to reflist.
|
||||
//
|
||||
// In Kvazaar, the L1 list is only used for future pictures and the slice
|
||||
// type is set to KVZ_SLICE_B if and only if L1 is used. Therefore we can
|
||||
// simply check the slice type here. Kvazaar always sets
|
||||
// collocated_from_l0_flag so the list is L1 for B-slices.
|
||||
int col_list = state->frame->slicetype == KVZ_SLICE_P ? reflist : 1;
|
||||
|
||||
mv_out[0] = colocated->inter.mv[cand_list][0];
|
||||
mv_out[1] = colocated->inter.mv[cand_list][1];
|
||||
if ((colocated->inter.mv_dir & (col_list + 1)) == 0) {
|
||||
// Use the other list if the colocated PU does not have a MV for the
|
||||
// primary list.
|
||||
col_list = 1 - col_list;
|
||||
}
|
||||
|
||||
mv_out[0] = colocated->inter.mv[col_list][0];
|
||||
mv_out[1] = colocated->inter.mv[col_list][1];
|
||||
apply_mv_scaling_pocs(
|
||||
state->frame->poc,
|
||||
state->frame->ref->pocs[current_ref],
|
||||
state->frame->ref->pocs[colocated_ref],
|
||||
state->frame->ref->images[colocated_ref]->ref_pocs[
|
||||
state->frame->ref->ref_LXs[colocated_ref]
|
||||
[cand_list][colocated->inter.mv_ref[cand_list]]],
|
||||
[col_list][colocated->inter.mv_ref[col_list]]],
|
||||
mv_out
|
||||
);
|
||||
|
||||
|
@ -1124,7 +1138,8 @@ static void get_mv_cand_from_candidates(const encoder_state_t * const state,
|
|||
state->frame->ref_LX[reflist][cur_cu->inter.mv_ref[reflist]],
|
||||
(h != NULL) ? h : c3,
|
||||
reflist,
|
||||
mv_cand[candidates])) {
|
||||
mv_cand[candidates]))
|
||||
{
|
||||
candidates++;
|
||||
}
|
||||
|
||||
|
@ -1252,7 +1267,6 @@ static bool add_merge_candidate(const cu_info_t *cand,
|
|||
* \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,
|
||||
|
@ -1260,8 +1274,7 @@ 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,
|
||||
uint8_t ref_idx)
|
||||
lcu_t *lcu)
|
||||
{
|
||||
uint8_t candidates = 0;
|
||||
int8_t zero_idx = 0;
|
||||
|
@ -1306,7 +1319,9 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
(merge_cand.h != NULL) ? merge_cand.h : merge_cand.c3;
|
||||
|
||||
if (add_temporal_candidate(state,
|
||||
ref_idx,
|
||||
// Reference index 0 is always used for
|
||||
// the temporal merge candidate.
|
||||
state->frame->ref_LX[reflist][0],
|
||||
temporal_cand,
|
||||
reflist,
|
||||
mv_cand[candidates].mv[reflist])) {
|
||||
|
|
|
@ -85,6 +85,5 @@ 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,
|
||||
uint8_t ref_idx);
|
||||
lcu_t *lcu);
|
||||
#endif
|
||||
|
|
|
@ -1303,35 +1303,20 @@ static void search_pu_inter(encoder_state_t * const state,
|
|||
};
|
||||
|
||||
// Search for merge mode candidates
|
||||
if (!cfg->tmvp_enable) {
|
||||
info.num_merge_cand = kvz_inter_get_merge_cand(
|
||||
state,
|
||||
x, y,
|
||||
width, height,
|
||||
merge_a1, merge_b1,
|
||||
info.merge_cand,
|
||||
lcu,
|
||||
0
|
||||
);
|
||||
}
|
||||
info.num_merge_cand = kvz_inter_get_merge_cand(
|
||||
state,
|
||||
x, y,
|
||||
width, height,
|
||||
merge_a1, merge_b1,
|
||||
info.merge_cand,
|
||||
lcu
|
||||
);
|
||||
|
||||
// Default to candidate 0
|
||||
CU_SET_MV_CAND(cur_cu, 0, 0);
|
||||
CU_SET_MV_CAND(cur_cu, 1, 0);
|
||||
|
||||
for (int ref_idx = 0; ref_idx < state->frame->ref->used_size; ref_idx++) {
|
||||
if (cfg->tmvp_enable) {
|
||||
// Get list of candidates, TMVP required MV scaling for each reference
|
||||
info.num_merge_cand = kvz_inter_get_merge_cand(
|
||||
state,
|
||||
x, y,
|
||||
width, height,
|
||||
merge_a1, merge_b1,
|
||||
info.merge_cand,
|
||||
lcu,
|
||||
ref_idx
|
||||
);
|
||||
}
|
||||
info.ref_idx = ref_idx;
|
||||
info.ref = state->frame->ref->images[ref_idx];
|
||||
|
||||
|
|
Loading…
Reference in a new issue