mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-30 12:44:07 +00:00
Enable TMVP with B-frames
This commit is contained in:
parent
363b8b49a2
commit
e538a94eda
|
@ -955,10 +955,6 @@ int kvz_config_parse(kvz_config *cfg, const char *name, const char *value)
|
|||
cfg->lossless = (bool)atobool(value);
|
||||
else if OPT("tmvp") {
|
||||
cfg->tmvp_enable = atobool(value);
|
||||
if (cfg->gop_len && cfg->tmvp_enable) {
|
||||
fprintf(stderr, "Cannot enable TMVP because GOP is used.\n");
|
||||
cfg->tmvp_enable = false;
|
||||
}
|
||||
if (cfg->tiles_width_count > 1 || cfg->tiles_height_count > 1) {
|
||||
fprintf(stderr, "Cannot enable TMVP because tiles are used.\n");
|
||||
cfg->tmvp_enable = false;
|
||||
|
|
|
@ -786,10 +786,19 @@ static void kvz_encoder_state_write_bitstream_slice_header_independent(
|
|||
WRITE_U(stream, 0, 1, "mvd_l1_zero_flag");
|
||||
}
|
||||
|
||||
// ToDo: handle B-frames with TMVP
|
||||
if (state->encoder_control->cfg.tmvp_enable && ref_negative > 1) {
|
||||
// Temporal Motion Vector Prediction flags
|
||||
if (state->encoder_control->cfg->tmvp_enable && ref_negative > 1) {
|
||||
if (state->frame->slicetype == KVZ_SLICE_B) {
|
||||
// Always use L0 for prediction
|
||||
WRITE_U(stream, 1, 1, "collocated_from_l0_flag");
|
||||
}
|
||||
|
||||
if (ref_negative > 1) {
|
||||
// Use first reference from L0
|
||||
// ToDo: use better reference
|
||||
WRITE_UE(stream, 0, "collocated_ref_idx");
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_UE(stream, 5-MRG_MAX_NUM_CANDS, "five_minus_max_num_merge_cand");
|
||||
}
|
||||
|
|
36
src/inter.c
36
src/inter.c
|
@ -679,7 +679,7 @@ static void kvz_inter_get_temporal_merge_candidates(const encoder_state_t * cons
|
|||
for (int temporal_cand = 0; temporal_cand < state->frame->ref->used_size; temporal_cand++) {
|
||||
int td = state->frame->poc - state->frame->ref->pocs[temporal_cand];
|
||||
|
||||
td = td < 0 ? -td : td;
|
||||
td = td < 0 ? UINT_MAX : td;
|
||||
if (td < poc_diff) {
|
||||
closest_ref = temporal_cand;
|
||||
poc_diff = td;
|
||||
|
@ -1088,7 +1088,7 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
|
|||
if (state->encoder_control->cfg.tmvp_enable) {
|
||||
/*
|
||||
Predictor block locations
|
||||
_________
|
||||
__________
|
||||
|CurrentPU|
|
||||
| |C0|__ |
|
||||
| |C3| |
|
||||
|
@ -1102,7 +1102,7 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
|
|||
|
||||
for (int temporal_cand = 0; temporal_cand < state->frame->ref->used_size; temporal_cand++) {
|
||||
int td = state->frame->poc - state->frame->ref->pocs[temporal_cand];
|
||||
td = td < 0 ? -td : td;
|
||||
td = td < 0 ? UINT_MAX : td;
|
||||
if (td < poc_diff) {
|
||||
poc_diff = td;
|
||||
}
|
||||
|
@ -1113,6 +1113,10 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
|
|||
if (selected_CU) {
|
||||
int td = selected_CU->inter.mv_ref[reflist] + 1;
|
||||
int tb = cur_cu->inter.mv_ref[reflist] + 1;
|
||||
// If the selected CU does not have the correct list (L0/L1) vector, use the other
|
||||
if (!selected_CU->inter.mv_dir & (1 << reflist)) {
|
||||
td = selected_CU->inter.mv_ref[reflist2nd] + 1;
|
||||
}
|
||||
|
||||
int scale = CALCULATE_SCALE(NULL, tb, td);
|
||||
mv_cand[candidates][0] = ((scale * selected_CU->inter.mv[0][0] + 127 + (scale * selected_CU->inter.mv[0][0] < 0)) >> 8);
|
||||
|
@ -1330,18 +1334,32 @@ 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;
|
||||
|
||||
if (selected_CU) {
|
||||
uint32_t poc_diff = UINT_MAX;
|
||||
for (int temporal_cand = 0; temporal_cand < state->frame->ref->used_size; temporal_cand++) {
|
||||
int td = state->frame->poc - state->frame->ref->pocs[temporal_cand];
|
||||
td = td < 0 ? UINT_MAX : td;
|
||||
if (td < poc_diff) {
|
||||
poc_diff = td;
|
||||
}
|
||||
}
|
||||
|
||||
int td = selected_CU->inter.mv_ref[0] + 1;
|
||||
int tb = 1;
|
||||
int tb = poc_diff;
|
||||
|
||||
int scale = CALCULATE_SCALE(NULL, tb, td);
|
||||
|
||||
// L0 list
|
||||
if (selected_CU->inter.mv_dir & 0x1) {
|
||||
mv_cand[candidates].mv[0][0] = ((scale * selected_CU->inter.mv[0][0] + 127 + (scale * selected_CU->inter.mv[0][0] < 0)) >> 8);
|
||||
mv_cand[candidates].mv[0][1] = ((scale * selected_CU->inter.mv[0][1] + 127 + (scale * selected_CU->inter.mv[0][1] < 0)) >> 8);
|
||||
}
|
||||
|
||||
// L1 list
|
||||
if (selected_CU->inter.mv_dir & 0x2) {
|
||||
mv_cand[candidates].mv[1][0] = ((scale * selected_CU->inter.mv[1][0] + 127 + (scale * selected_CU->inter.mv[1][0] < 0)) >> 8);
|
||||
mv_cand[candidates].mv[1][1] = ((scale * selected_CU->inter.mv[1][1] + 127 + (scale * selected_CU->inter.mv[1][1] < 0)) >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
ToDo: temporal prediction in B-pictures
|
||||
mv_cand[candidates].mv[1][0] = selected_CU->inter.mv[1][0];
|
||||
mv_cand[candidates].mv[1][1] = selected_CU->inter.mv[1][1];
|
||||
*/
|
||||
mv_cand[candidates].dir = selected_CU->inter.mv_dir;
|
||||
mv_cand[candidates].ref[0] = 0;
|
||||
candidates++;
|
||||
|
|
Loading…
Reference in a new issue