mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
WIP: add list of POCs used in the image when pushing to reference
This commit is contained in:
parent
6a25cd3248
commit
d65d2ec88d
|
@ -129,6 +129,16 @@ encoder_control_t* kvz_encoder_control_init(const kvz_config *const cfg)
|
|||
goto init_failed;
|
||||
}
|
||||
|
||||
if (cfg->threads == -1) {
|
||||
cfg->threads = cfg_num_threads();
|
||||
}
|
||||
|
||||
if (cfg->gop_len > 0) {
|
||||
if (cfg->gop_lowdelay) {
|
||||
kvz_config_process_lp_gop(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that the parameters make sense.
|
||||
if (!kvz_config_validate(cfg)) {
|
||||
goto init_failed;
|
||||
|
|
|
@ -114,6 +114,9 @@ int kvz_image_list_add(image_list_t *list, kvz_picture *im, cu_array_t *cua, int
|
|||
unsigned new_size = MAX(list->size + 1, list->size * 2);
|
||||
if (!kvz_image_list_resize(list, new_size)) return 0;
|
||||
}
|
||||
|
||||
// Store current list of POCs for used in TMVP derivation
|
||||
memcpy(im->ref_pocs, list->pocs, sizeof(int32_t)*list->used_size);
|
||||
|
||||
for (i = list->used_size; i > 0; i--) {
|
||||
list->images[i] = list->images[i - 1];
|
||||
|
|
90
src/inter.c
90
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 ? UINT_MAX : td;
|
||||
td = td < 0 ? -td : td;
|
||||
if (td < poc_diff) {
|
||||
closest_ref = temporal_cand;
|
||||
poc_diff = td;
|
||||
|
@ -1081,7 +1081,7 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
|
|||
}
|
||||
|
||||
// Remove identical candidate
|
||||
if(candidates == 2 && mv_cand[0][0] == mv_cand[1][0] && mv_cand[0][1] == mv_cand[1][1]) {
|
||||
if (candidates == 2 && mv_cand[0][0] == mv_cand[1][0] && mv_cand[0][1] == mv_cand[1][1]) {
|
||||
candidates = 1;
|
||||
}
|
||||
|
||||
|
@ -1101,11 +1101,14 @@ static void get_mv_cand_from_spatial(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;
|
||||
uint32_t closest_ref = 0;
|
||||
uint32_t closest_ref_poc = 0;
|
||||
int td, tb;
|
||||
|
||||
// ToDo: allow custom reference lists
|
||||
// Without GOP, assume that every frame is a reference frame in an order
|
||||
if (!state->encoder_control->cfg->gop_len) {
|
||||
if (state->encoder_control->cfg->gop_len) {
|
||||
td = selected_CU->inter.mv_ref[reflist] + 1;
|
||||
tb = cur_cu->inter.mv_ref[reflist] + 1;
|
||||
} else {
|
||||
|
@ -1114,29 +1117,31 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
|
|||
//ToDo: allow other than L0[0] for prediction
|
||||
|
||||
//Fetch ref idx of the selected CU in L0[0] ref list
|
||||
uint32_t poc_diff = UINT_MAX;
|
||||
uint32_t closest_ref = 0;
|
||||
uint32_t closest_ref_poc = 0;
|
||||
|
||||
|
||||
for (int temporal_cand = 0; temporal_cand < state->frame->ref->used_size; temporal_cand++) {
|
||||
int ref_poc = state->frame->ref->pocs[temporal_cand];
|
||||
int td = state->frame->poc - ref_poc;
|
||||
|
||||
td = td < 0 ? UINT_MAX : td;
|
||||
if (td < poc_diff) {
|
||||
//td = td < 0 ? UINT_MAX : td;
|
||||
//if (td < poc_diff) {
|
||||
if (td > 0) {
|
||||
closest_ref = temporal_cand;
|
||||
poc_diff = td;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
closest_ref_poc = state->frame->ref->pocs[closest_ref];
|
||||
|
||||
uint32_t colocated_ref_mv_ref = selected_CU->inter.mv_ref[reflist];
|
||||
|
||||
if (!selected_CU->inter.mv_dir & (1 << reflist)) {
|
||||
if (!(selected_CU->inter.mv_dir & (1 << reflist))) {
|
||||
colocated_ref_mv_ref = selected_CU->inter.mv_ref[reflist2nd];
|
||||
}
|
||||
|
||||
/*
|
||||
int32_t colocated_ref_frame = state->frame->num+1;
|
||||
uint32_t gop_len = state->encoder_control->cfg->gop_len;
|
||||
uint32_t base_POC = state->frame->poc - (state->frame->poc % gop_len);
|
||||
|
@ -1149,10 +1154,11 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
|
|||
if (colocated_ref_frame % gop_len == 0) base_POC -= gop_len;
|
||||
}
|
||||
|
||||
uint32_t colocated_pocs[MAX_REF_PIC_COUNT];
|
||||
//uint32_t colocated_pocs[MAX_REF_PIC_COUNT];
|
||||
base_POC = closest_ref_poc - (closest_ref_poc % gop_len);
|
||||
|
||||
// Reconstruct ref list
|
||||
|
||||
uint32_t max_refs = (state->encoder_control->cfg->gop[colocated_ref_frame % gop_len].ref_neg_count + state->encoder_control->cfg->gop[colocated_ref_frame % gop_len].ref_pos_count);
|
||||
uint32_t current_ref = 0;
|
||||
for (int32_t temp_frame = colocated_ref_frame-1; temp_frame >= 0; temp_frame--) {
|
||||
|
@ -1168,8 +1174,9 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
|
|||
}
|
||||
if (temp_frame % gop_len == 0) base_POC -= gop_len;
|
||||
}
|
||||
*/
|
||||
|
||||
td = closest_ref_poc - colocated_pocs[selected_CU->inter.mv_ref[colocated_ref_mv_ref]];
|
||||
td = closest_ref_poc - state->frame->ref->images[closest_ref]->ref_pocs[colocated_ref_mv_ref];
|
||||
tb = state->frame->poc - state->frame->ref->pocs[cur_cu->inter.mv_ref[reflist]];
|
||||
|
||||
}
|
||||
|
@ -1178,19 +1185,28 @@ static void get_mv_cand_from_spatial(const encoder_state_t * const state,
|
|||
int used_reflist = reflist;
|
||||
|
||||
// If the selected CU does not have the correct list (L0/L1) vector, use the other
|
||||
if (!selected_CU->inter.mv_dir & (1 << reflist)) {
|
||||
|
||||
if (!(selected_CU->inter.mv_dir & (1 << reflist))) {
|
||||
//td = state->frame->poc - state->previous_encoder_state->frame->ref->pocs[selected_CU->inter.mv_ref[reflist2nd]];
|
||||
used_reflist = reflist2nd;
|
||||
}
|
||||
|
||||
|
||||
mv_cand[candidates][0] = ((scale * selected_CU->inter.mv[used_reflist][0] + 127 + (scale * selected_CU->inter.mv[used_reflist][0] < 0)) >> 8);
|
||||
mv_cand[candidates][1] = ((scale * selected_CU->inter.mv[used_reflist][1] + 127 + (scale * selected_CU->inter.mv[used_reflist][1] < 0)) >> 8);
|
||||
|
||||
//if (poc_diff != UINT_MAX) {
|
||||
|
||||
{
|
||||
int td = selected_CU->inter.mv_ref[reflist] + 1;
|
||||
int tb = cur_cu->inter.mv_ref[reflist] + 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);
|
||||
mv_cand[candidates][1] = ((scale * selected_CU->inter.mv[0][1] + 127 + (scale * selected_CU->inter.mv[0][1] < 0)) >> 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
candidates++;
|
||||
candidates++;
|
||||
//}
|
||||
}
|
||||
#undef CALCULATE_SCALE
|
||||
}
|
||||
|
@ -1401,6 +1417,7 @@ 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];
|
||||
|
@ -1408,22 +1425,53 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
if (td < poc_diff) {
|
||||
poc_diff = td;
|
||||
}
|
||||
}*/
|
||||
|
||||
mv_cand[candidates].dir = 0;
|
||||
|
||||
// Find LIST_0 reference
|
||||
if (h != NULL && h->inter.mv_dir & 1) {
|
||||
mv_cand[candidates].dir |= 1;
|
||||
mv_cand[candidates].ref[0] = h->inter.mv_ref[0];
|
||||
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] = c3->inter.mv_ref[0];
|
||||
mv_cand[candidates].mv[0][0] = c3->inter.mv[0][0];
|
||||
mv_cand[candidates].mv[0][1] = c3->inter.mv[0][1];
|
||||
}
|
||||
|
||||
int tb = state->frame->poc - state->frame->ref->pocs[selected_CU->inter.mv_ref[0]];
|
||||
int td = poc_diff;
|
||||
// Find LIST_1 reference
|
||||
if (h != NULL && h->inter.mv_dir & 2) {
|
||||
mv_cand[candidates].dir |= 2;
|
||||
mv_cand[candidates].ref[1] = h->inter.mv_ref[1];
|
||||
mv_cand[candidates].mv[1][0] = h->inter.mv[1][0];
|
||||
mv_cand[candidates].mv[1][1] = h->inter.mv[1][1];
|
||||
} else if (c3 != NULL && c3->inter.mv_dir & 2) {
|
||||
mv_cand[candidates].dir |= 2;
|
||||
mv_cand[candidates].ref[1] = c3->inter.mv_ref[1];
|
||||
mv_cand[candidates].mv[1][0] = c3->inter.mv[1][0];
|
||||
mv_cand[candidates].mv[1][1] = c3->inter.mv[1][1];
|
||||
}
|
||||
/*
|
||||
int tb = state->frame->poc - state->frame->ref->pocs[selected_CU->inter.mv_ref[0]];
|
||||
int td = 1;
|
||||
|
||||
int scale = ((tb * ((0x4000 + (abs(td) >> 1)) / td) + 32) >> 6);
|
||||
|
||||
*/
|
||||
/*
|
||||
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);
|
||||
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);
|
||||
|
||||
|
||||
mv_cand[candidates].dir = selected_CU->inter.mv_dir;
|
||||
mv_cand[candidates].dir = tmvp_dir;
|
||||
mv_cand[candidates].ref[0] = selected_CU->inter.mv_ref[0];
|
||||
mv_cand[candidates].ref[1] = selected_CU->inter.mv_ref[1];
|
||||
*/
|
||||
candidates++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -365,6 +365,8 @@ typedef struct kvz_picture {
|
|||
|
||||
enum kvz_interlacing interlacing; //!< \since 3.2.0 \brief Field order for interlaced pictures.
|
||||
enum kvz_chroma_format chroma_format;
|
||||
|
||||
int32_t ref_pocs[16];
|
||||
} kvz_picture;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue