mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +00:00
Changes to refence lists to behave more like L0/L1 lists from the specification
This commit is contained in:
parent
00c9f52bd4
commit
f8b6234fdb
2
src/cu.h
2
src/cu.h
|
@ -144,7 +144,7 @@ typedef struct
|
|||
} intra;
|
||||
struct {
|
||||
int16_t mv[2][2]; // \brief Motion vectors for L0 and L1
|
||||
uint8_t mv_ref[2]; // \brief Index of the encoder_control.ref array.
|
||||
uint8_t mv_ref[2]; // \brief Index of the L0 and L1 array.
|
||||
uint8_t mv_cand0 : 3; // \brief selected MV candidate
|
||||
uint8_t mv_cand1 : 3; // \brief selected MV candidate
|
||||
uint8_t mv_dir : 2; // \brief Probably describes if mv_ref is L0, L1 or both (bi-pred)
|
||||
|
|
|
@ -551,15 +551,6 @@ static void encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
}
|
||||
} else {
|
||||
uint32_t ref_list_idx;
|
||||
uint32_t j;
|
||||
int ref_list[2] = { 0, 0 };
|
||||
for (j = 0; j < state->frame->ref->used_size; j++) {
|
||||
if (state->frame->ref->pocs[j] < state->frame->poc) {
|
||||
ref_list[0]++;
|
||||
} else {
|
||||
ref_list[1]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Void TEncSbac::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx )
|
||||
if (state->frame->slicetype == KVZ_SLICE_B)
|
||||
|
@ -583,16 +574,20 @@ static void encode_inter_prediction_unit(encoder_state_t * const state,
|
|||
|
||||
for (ref_list_idx = 0; ref_list_idx < 2; ref_list_idx++) {
|
||||
if (cur_cu->inter.mv_dir & (1 << ref_list_idx)) {
|
||||
if (ref_list[ref_list_idx] > 1) {
|
||||
|
||||
// size of the current reference index list (L0/L1)
|
||||
uint8_t ref_LX_size = state->frame->ref_LX_size[ref_list_idx];
|
||||
|
||||
if (ref_LX_size > 1) {
|
||||
// parseRefFrmIdx
|
||||
int32_t ref_frame = state->frame->refmap[cur_cu->inter.mv_ref[ref_list_idx]].idx;
|
||||
int32_t ref_frame = cur_cu->inter.mv_ref[ref_list_idx];
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.cu_ref_pic_model[0]);
|
||||
CABAC_BIN(cabac, (ref_frame != 0), "ref_idx_lX");
|
||||
|
||||
if (ref_frame > 0) {
|
||||
int32_t i;
|
||||
int32_t ref_num = ref_list[ref_list_idx] - 2;
|
||||
int32_t ref_num = ref_LX_size - 2;
|
||||
|
||||
cabac->cur_ctx = &(cabac->ctx.cu_ref_pic_model[1]);
|
||||
ref_frame--;
|
||||
|
|
|
@ -787,81 +787,51 @@ static void encoder_state_encode(encoder_state_t * const main_state) {
|
|||
}
|
||||
|
||||
|
||||
static void encoder_ref_insertion_sort(int reflist[16], int length) {
|
||||
static void encoder_ref_insertion_sort(const encoder_state_t *const state, uint8_t reflist[16], uint8_t length) {
|
||||
|
||||
for (uint8_t i = 1; i < length; ++i) {
|
||||
const int16_t cur_poc = reflist[i];
|
||||
int16_t j = i;
|
||||
while (j > 0 && cur_poc < reflist[j - 1]) {
|
||||
const int32_t cur_poc = state->frame->ref->pocs[reflist[i]];
|
||||
uint8_t cur_idx = reflist[i];
|
||||
int8_t j = i;
|
||||
while (j > 0 && cur_poc < state->frame->ref->pocs[reflist[j - 1]]) {
|
||||
reflist[j] = reflist[j - 1];
|
||||
--j;
|
||||
}
|
||||
reflist[j] = cur_poc;
|
||||
reflist[j] = cur_idx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return reference picture lists.
|
||||
* \brief Generate reference picture lists.
|
||||
*
|
||||
* \param state main encoder state
|
||||
* \param ref_list_len_out Returns the lengths of the reference lists.
|
||||
* \param ref_list_poc_out Returns two lists of POCs of the reference pictures.
|
||||
*/
|
||||
void kvz_encoder_get_ref_lists(const encoder_state_t *const state,
|
||||
int ref_list_len_out[2],
|
||||
int ref_list_poc_out[2][16])
|
||||
void kvz_encoder_create_ref_lists(const encoder_state_t *const state)
|
||||
{
|
||||
FILL_ARRAY(ref_list_len_out, 0, 2);
|
||||
// TODO check possibility to add L0 references to L1 list also
|
||||
|
||||
FILL_ARRAY(state->frame->ref_LX_size, 0, 2);
|
||||
|
||||
// List all pocs of lists
|
||||
int j = 0;
|
||||
for (j = 0; j < state->frame->ref->used_size; j++) {
|
||||
if (state->frame->ref->pocs[j] < state->frame->poc) {
|
||||
ref_list_poc_out[0][ref_list_len_out[0]] = state->frame->ref->pocs[j];
|
||||
ref_list_len_out[0]++;
|
||||
state->frame->ref_LX[0][state->frame->ref_LX_size[0]] = state->frame->ref->pocs[j];
|
||||
state->frame->ref_LX_size[0] += 1;
|
||||
} else {
|
||||
ref_list_poc_out[1][ref_list_len_out[1]] = state->frame->ref->pocs[j];
|
||||
ref_list_len_out[1]++;
|
||||
state->frame->ref_LX[1][state->frame->ref_LX_size[1]] = state->frame->ref->pocs[j];
|
||||
state->frame->ref_LX_size[1] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the rest of ref_list_poc_out array with -1s.
|
||||
for (; j < 16; j++) {
|
||||
ref_list_poc_out[0][j] = -1;
|
||||
ref_list_poc_out[1][j] = -1;
|
||||
state->frame->ref_LX[0][j] = (uint8_t) -1;
|
||||
state->frame->ref_LX[1][j] = (uint8_t) -1;
|
||||
}
|
||||
|
||||
encoder_ref_insertion_sort(ref_list_poc_out[0], ref_list_len_out[0]);
|
||||
encoder_ref_insertion_sort(ref_list_poc_out[1], ref_list_len_out[1]);
|
||||
}
|
||||
|
||||
static void encoder_state_ref_sort(encoder_state_t *state) {
|
||||
int ref_list_len[2];
|
||||
int ref_list_poc[2][16];
|
||||
|
||||
kvz_encoder_get_ref_lists(state, ref_list_len, ref_list_poc);
|
||||
|
||||
for (int j = 0; j < state->frame->ref->used_size; j++) {
|
||||
if (state->frame->ref->pocs[j] < state->frame->poc) {
|
||||
for (int ref_idx = 0; ref_idx < ref_list_len[0]; ref_idx++) {
|
||||
if (ref_list_poc[0][ref_idx] == state->frame->ref->pocs[j]) {
|
||||
state->frame->refmap[j].idx = ref_list_len[0] - ref_idx - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
state->frame->refmap[j].list = 1;
|
||||
|
||||
} else {
|
||||
for (int ref_idx = 0; ref_idx < ref_list_len[1]; ref_idx++) {
|
||||
if (ref_list_poc[1][ref_idx] == state->frame->ref->pocs[j]) {
|
||||
state->frame->refmap[j].idx = ref_idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
state->frame->refmap[j].list = 2;
|
||||
}
|
||||
state->frame->refmap[j].poc = state->frame->ref->pocs[j];
|
||||
}
|
||||
encoder_ref_insertion_sort(state, state->frame->ref_LX[0], state->frame->ref_LX_size[0]);
|
||||
encoder_ref_insertion_sort(state, state->frame->ref_LX[1], state->frame->ref_LX_size[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1037,7 +1007,7 @@ static void encoder_state_init_new_frame(encoder_state_t * const state, kvz_pict
|
|||
}
|
||||
|
||||
encoder_state_remove_refs(state);
|
||||
encoder_state_ref_sort(state);
|
||||
kvz_encoder_create_ref_lists(state);
|
||||
|
||||
normalize_lcu_weights(state);
|
||||
kvz_set_picture_lambda_and_qp(state);
|
||||
|
|
|
@ -91,15 +91,14 @@ typedef struct encoder_state_config_frame_t {
|
|||
//! \brief quantization factor
|
||||
double QP_factor;
|
||||
|
||||
//Current picture available references
|
||||
//! Current pictures available for references
|
||||
image_list_t *ref;
|
||||
int8_t ref_list;
|
||||
|
||||
struct {
|
||||
int32_t poc;
|
||||
int8_t list;
|
||||
int8_t idx;
|
||||
} refmap[16];
|
||||
//! L0 and L1 reference index list
|
||||
uint8_t ref_LX[2][16];
|
||||
//! L0 reference index list size
|
||||
uint8_t ref_LX_size[2];
|
||||
|
||||
bool is_idr_frame;
|
||||
uint8_t pictype;
|
||||
|
@ -282,9 +281,7 @@ int kvz_encoder_state_match_children_of_previous_frame(encoder_state_t * const s
|
|||
|
||||
coeff_scan_order_t kvz_get_scan_order(int8_t cu_type, int intra_mode, int depth);
|
||||
|
||||
void kvz_encoder_get_ref_lists(const encoder_state_t *const state,
|
||||
int ref_list_len_out[2],
|
||||
int ref_list_poc_out[2][16]);
|
||||
void kvz_encoder_create_ref_lists(const encoder_state_t *const state);
|
||||
|
||||
lcu_stats_t* kvz_get_lcu_stats(encoder_state_t *state, int lcu_x, int lcu_y);
|
||||
|
||||
|
|
15
src/filter.c
15
src/filter.c
|
@ -401,10 +401,13 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
|
|||
// Non-zero residual/coeffs and transform boundary
|
||||
// Neither CU is intra so tr_depth <= MAX_DEPTH.
|
||||
strength = 1;
|
||||
} else if (cu_p->inter.mv_dir != 3 && cu_q->inter.mv_dir != 3 && ((abs(cu_q->inter.mv[cu_q->inter.mv_dir - 1][0] - cu_p->inter.mv[cu_p->inter.mv_dir - 1][0]) >= 4) || (abs(cu_q->inter.mv[cu_q->inter.mv_dir - 1][1] - cu_p->inter.mv[cu_p->inter.mv_dir - 1][1]) >= 4))) {
|
||||
} else if (cu_p->inter.mv_dir != 3 && cu_q->inter.mv_dir != 3 &&
|
||||
((abs(cu_q->inter.mv[cu_q->inter.mv_dir - 1][0] - cu_p->inter.mv[cu_p->inter.mv_dir - 1][0]) >= 4) ||
|
||||
(abs(cu_q->inter.mv[cu_q->inter.mv_dir - 1][1] - cu_p->inter.mv[cu_p->inter.mv_dir - 1][1]) >= 4))) {
|
||||
// Absolute motion vector diff between blocks >= 1 (Integer pixel)
|
||||
strength = 1;
|
||||
} else if (cu_p->inter.mv_dir != 3 && cu_q->inter.mv_dir != 3 && cu_q->inter.mv_ref[cu_q->inter.mv_dir - 1] != cu_p->inter.mv_ref[cu_p->inter.mv_dir - 1]) {
|
||||
} else if (cu_p->inter.mv_dir != 3 && cu_q->inter.mv_dir != 3 &&
|
||||
cu_q->inter.mv_ref[cu_q->inter.mv_dir - 1] != cu_p->inter.mv_ref[cu_p->inter.mv_dir - 1]) {
|
||||
strength = 1;
|
||||
}
|
||||
|
||||
|
@ -429,10 +432,10 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
|
|||
cu_p->inter.mv[1][0] = 0;
|
||||
cu_p->inter.mv[1][1] = 0;
|
||||
}
|
||||
const int refP0 = (cu_p->inter.mv_dir & 1) ? cu_p->inter.mv_ref[0] : -1;
|
||||
const int refP1 = (cu_p->inter.mv_dir & 2) ? cu_p->inter.mv_ref[1] : -1;
|
||||
const int refQ0 = (cu_q->inter.mv_dir & 1) ? cu_q->inter.mv_ref[0] : -1;
|
||||
const int refQ1 = (cu_q->inter.mv_dir & 2) ? cu_q->inter.mv_ref[1] : -1;
|
||||
const int refP0 = (cu_p->inter.mv_dir & 1) ? state->frame->ref_LX[0][cu_p->inter.mv_ref[0]] : -1;
|
||||
const int refP1 = (cu_p->inter.mv_dir & 2) ? state->frame->ref_LX[1][cu_p->inter.mv_ref[1]] : -1;
|
||||
const int refQ0 = (cu_q->inter.mv_dir & 1) ? state->frame->ref_LX[0][cu_q->inter.mv_ref[0]] : -1;
|
||||
const int refQ1 = (cu_q->inter.mv_dir & 2) ? state->frame->ref_LX[1][cu_q->inter.mv_ref[1]] : -1;
|
||||
const int16_t* mvQ0 = cu_q->inter.mv[0];
|
||||
const int16_t* mvQ1 = cu_q->inter.mv[1];
|
||||
|
||||
|
|
58
src/inter.c
58
src/inter.c
|
@ -652,11 +652,13 @@ static bool is_b0_cand_coded(int x, int y, int width, int height)
|
|||
/**
|
||||
* \brief Get merge candidates for current block
|
||||
*
|
||||
* \param encoder encoder control struct to use
|
||||
* \param state encoder control state to use
|
||||
* \param x block x position in SCU
|
||||
* \param y block y position in SCU
|
||||
* \param width current block width
|
||||
* \param height current block height
|
||||
* \param ref_list which reference list, L0 is 1 and L1 is 2
|
||||
* \param ref_idx index in the reference list
|
||||
* \param cand_out will be filled with C3 and H candidates
|
||||
*/
|
||||
static void get_temporal_merge_candidates(const encoder_state_t * const state,
|
||||
|
@ -682,17 +684,15 @@ static void get_temporal_merge_candidates(const encoder_state_t * const state,
|
|||
|
||||
// Find temporal reference
|
||||
if (state->frame->ref->used_size) {
|
||||
uint32_t colocated_ref = UINT_MAX;
|
||||
uint32_t colocated_ref;
|
||||
|
||||
// Select L0/L1 ref_idx reference
|
||||
for (int temporal_cand = 0; temporal_cand < state->frame->ref->used_size; temporal_cand++) {
|
||||
if (state->frame->refmap[temporal_cand].list == ref_list && state->frame->refmap[temporal_cand].idx == ref_idx) {
|
||||
colocated_ref = temporal_cand;
|
||||
break;
|
||||
}
|
||||
if (state->frame->ref_LX_size[ref_list-1] > ref_idx) {
|
||||
colocated_ref = state->frame->ref_LX[ref_list - 1][ref_idx];
|
||||
} else {
|
||||
// not found
|
||||
return;
|
||||
}
|
||||
|
||||
if (colocated_ref == UINT_MAX) return;
|
||||
|
||||
cu_array_t *ref_cu_array = state->frame->ref->cu_arrays[colocated_ref];
|
||||
int cu_per_width = ref_cu_array->width / SCU_WIDTH;
|
||||
|
@ -938,9 +938,13 @@ static INLINE void apply_mv_scaling(const encoder_state_t *state,
|
|||
int16_t mv_cand[2])
|
||||
{
|
||||
apply_mv_scaling_pocs(state->frame->poc,
|
||||
state->frame->ref->pocs[current_cu->inter.mv_ref[current_reflist]],
|
||||
state->frame->ref->pocs[
|
||||
state->frame->ref_LX[current_reflist][
|
||||
current_cu->inter.mv_ref[current_reflist]]],
|
||||
state->frame->poc,
|
||||
state->frame->ref->pocs[neighbor_cu->inter.mv_ref[neighbor_reflist]],
|
||||
state->frame->ref->pocs[
|
||||
state->frame->ref_LX[current_reflist][
|
||||
neighbor_cu->inter.mv_ref[neighbor_reflist]]],
|
||||
mv_cand);
|
||||
}
|
||||
|
||||
|
@ -966,23 +970,21 @@ static bool add_temporal_candidate(const encoder_state_t *state,
|
|||
{
|
||||
if (!colocated) return false;
|
||||
|
||||
int colocated_ref = -1;
|
||||
for (int i = 0; i < state->frame->ref->used_size; i++) {
|
||||
if (state->frame->refmap[i].list == 1 &&
|
||||
state->frame->refmap[i].idx == 0) {
|
||||
colocated_ref = i;
|
||||
break;
|
||||
}
|
||||
int colocated_ref;
|
||||
if (state->frame->ref_LX_size[0] > 0) {
|
||||
// get the first reference from L0 if it exists
|
||||
colocated_ref = state->frame->ref_LX[0][0];
|
||||
} else {
|
||||
// otherwise no candidate added
|
||||
return false;
|
||||
}
|
||||
|
||||
if (colocated_ref < 0) return false;
|
||||
|
||||
int cand_list = colocated->inter.mv_dir & (1 << reflist) ? reflist : !reflist;
|
||||
|
||||
// The reference id the colocated block is using
|
||||
uint32_t colocated_ref_mv_ref = colocated->inter.mv_ref[cand_list];
|
||||
uint32_t colocated_ref_mv_ref = state->frame->ref_LX[cand_list][colocated->inter.mv_ref[cand_list]];
|
||||
|
||||
if (ref_out) *ref_out = colocated_ref;
|
||||
if (ref_out) *ref_out = 0; //colocated_ref;
|
||||
|
||||
mv_out[0] = colocated->inter.mv[cand_list][0];
|
||||
mv_out[1] = colocated->inter.mv[cand_list][1];
|
||||
|
@ -1105,7 +1107,7 @@ static void get_mv_cand_from_candidates(const encoder_state_t * const state,
|
|||
(h != NULL || c3 != NULL);
|
||||
|
||||
if (can_use_tmvp && add_temporal_candidate(state,
|
||||
cur_cu->inter.mv_ref[reflist],
|
||||
state->frame->ref_LX[reflist][cur_cu->inter.mv_ref[reflist]],
|
||||
(h != NULL) ? h : c3,
|
||||
reflist,
|
||||
mv_cand[candidates],
|
||||
|
@ -1220,7 +1222,7 @@ static bool add_merge_candidate(const cu_info_t *cand,
|
|||
merge_cand_out->mv[0][1] = cand->inter.mv[0][1];
|
||||
merge_cand_out->mv[1][0] = cand->inter.mv[1][0];
|
||||
merge_cand_out->mv[1][1] = cand->inter.mv[1][1];
|
||||
merge_cand_out->ref[0] = cand->inter.mv_ref[0];
|
||||
merge_cand_out->ref[0] = cand->inter.mv_ref[0]; // L0/L1 references
|
||||
merge_cand_out->ref[1] = cand->inter.mv_ref[1];
|
||||
merge_cand_out->dir = cand->inter.mv_dir;
|
||||
return true;
|
||||
|
@ -1325,9 +1327,11 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
mv_cand[candidates].ref[0] = mv_cand[i].ref[0];
|
||||
mv_cand[candidates].ref[1] = mv_cand[j].ref[1];
|
||||
|
||||
if (mv_cand[i].ref[0] == mv_cand[j].ref[1] &&
|
||||
mv_cand[i].mv[0][0] == mv_cand[j].mv[1][0] &&
|
||||
mv_cand[i].mv[0][1] == mv_cand[j].mv[1][1]) {
|
||||
if (state->frame->ref_LX[0][mv_cand[i].ref[0]] ==
|
||||
state->frame->ref_LX[1][mv_cand[j].ref[1]]
|
||||
&&
|
||||
mv_cand[i].mv[0][0] == mv_cand[j].mv[1][0] &&
|
||||
mv_cand[i].mv[0][1] == mv_cand[j].mv[1][1]) {
|
||||
// Not a candidate
|
||||
} else {
|
||||
candidates++;
|
||||
|
|
|
@ -141,7 +141,12 @@ static void set_frame_info(kvz_frame_info *const info, const encoder_state_t *co
|
|||
info->qp = state->frame->QP;
|
||||
info->nal_unit_type = state->frame->pictype;
|
||||
info->slice_type = state->frame->slicetype;
|
||||
kvz_encoder_get_ref_lists(state, info->ref_list_len, info->ref_list);
|
||||
|
||||
memcpy(info->ref_list[0], state->frame->ref_LX[0], 16);
|
||||
memcpy(info->ref_list[1], state->frame->ref_LX[1], 16);
|
||||
info->ref_list_len[0] = state->frame->ref_LX_size[0];
|
||||
info->ref_list_len[1] = state->frame->ref_LX_size[1];
|
||||
//kvz_encoder_create_ref_lists(state);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -915,7 +915,10 @@ int kvz_calc_mvd_cost_cabac(encoder_state_t * const state, int x, int y, int mv_
|
|||
if (merge_cand[merge_idx].dir == 3) continue;
|
||||
if (merge_cand[merge_idx].mv[merge_cand[merge_idx].dir - 1][0] == x &&
|
||||
merge_cand[merge_idx].mv[merge_cand[merge_idx].dir - 1][1] == y &&
|
||||
merge_cand[merge_idx].ref[merge_cand[merge_idx].dir - 1] == ref_idx) {
|
||||
state->frame->ref_LX[merge_cand[merge_idx].dir - 1][
|
||||
merge_cand[merge_idx].ref[merge_cand[merge_idx].dir - 1]
|
||||
] == ref_idx)
|
||||
{
|
||||
merged = 1;
|
||||
break;
|
||||
}
|
||||
|
|
14
src/search.c
14
src/search.c
|
@ -553,8 +553,12 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
|
|||
|
||||
if (cur_pu->inter.mv_dir == 3) {
|
||||
const kvz_picture *const refs[2] = {
|
||||
state->frame->ref->images[cur_pu->inter.mv_ref[0]],
|
||||
state->frame->ref->images[cur_pu->inter.mv_ref[1]],
|
||||
state->frame->ref->images[
|
||||
state->frame->ref_LX[0][
|
||||
cur_pu->inter.mv_ref[0]]],
|
||||
state->frame->ref->images[
|
||||
state->frame->ref_LX[1][
|
||||
cur_pu->inter.mv_ref[1]]],
|
||||
};
|
||||
kvz_inter_recon_lcu_bipred(state,
|
||||
refs[0], refs[1],
|
||||
|
@ -564,8 +568,12 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
|
|||
lcu);
|
||||
} else {
|
||||
const int mv_idx = cur_pu->inter.mv_dir - 1;
|
||||
|
||||
const kvz_picture *const ref =
|
||||
state->frame->ref->images[cur_pu->inter.mv_ref[mv_idx]];
|
||||
state->frame->ref->images[
|
||||
state->frame->ref_LX[mv_idx][
|
||||
cur_pu->inter.mv_ref[mv_idx]]];
|
||||
|
||||
kvz_inter_recon_lcu(state,
|
||||
ref,
|
||||
pu_x, pu_y,
|
||||
|
|
|
@ -229,7 +229,9 @@ static int calc_mvd_cost(encoder_state_t * const state, int x, int y, int mv_shi
|
|||
if (merge_cand[merge_idx].dir == 3) continue;
|
||||
if (merge_cand[merge_idx].mv[merge_cand[merge_idx].dir - 1][0] == x &&
|
||||
merge_cand[merge_idx].mv[merge_cand[merge_idx].dir - 1][1] == y &&
|
||||
merge_cand[merge_idx].ref[merge_cand[merge_idx].dir - 1] == ref_idx) {
|
||||
state->frame->ref_LX[merge_cand[merge_idx].dir - 1][
|
||||
merge_cand[merge_idx].ref[merge_cand[merge_idx].dir - 1]
|
||||
] == ref_idx) {
|
||||
temp_bitcost += merge_idx;
|
||||
merged = 1;
|
||||
break;
|
||||
|
@ -1241,10 +1243,37 @@ static void search_pu_inter_ref(encoder_state_t * const state,
|
|||
int32_t merged = 0;
|
||||
uint8_t cu_mv_cand = 0;
|
||||
int8_t merge_idx = 0;
|
||||
int8_t ref_list = state->frame->refmap[ref_idx].list-1;
|
||||
|
||||
// which list, L0 or L1, ref_idx is in and in what index
|
||||
int8_t ref_list = -1;
|
||||
// the index of the ref_idx in L0 or L1 list
|
||||
int8_t LX_idx;
|
||||
// max value of LX_idx plus one
|
||||
const int8_t LX_IDX_MAX_PLUS_1 = max(state->frame->ref_LX_size[0],
|
||||
state->frame->ref_LX_size[1]);
|
||||
|
||||
for (LX_idx = 0; LX_idx < LX_IDX_MAX_PLUS_1; LX_idx++)
|
||||
{
|
||||
// check if ref_idx is in L0
|
||||
if (LX_idx < state->frame->ref_LX_size[0] &&
|
||||
state->frame->ref_LX[0][LX_idx] == ref_idx) {
|
||||
ref_list = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// check if ref_idx is in L1
|
||||
if (LX_idx < state->frame->ref_LX_size[1] &&
|
||||
state->frame->ref_LX[1][LX_idx] == ref_idx) {
|
||||
ref_list = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ref_idx has to be found in either L0 or L1
|
||||
assert(LX_idx < LX_IDX_MAX_PLUS_1);
|
||||
|
||||
int8_t temp_ref_idx = cur_cu->inter.mv_ref[ref_list];
|
||||
// Get MV candidates
|
||||
cur_cu->inter.mv_ref[ref_list] = ref_idx;
|
||||
cur_cu->inter.mv_ref[ref_list] = LX_idx;
|
||||
kvz_inter_get_mv_cand(state, x, y, width, height, mv_cand, cur_cu, lcu, ref_list);
|
||||
cur_cu->inter.mv_ref[ref_list] = temp_ref_idx;
|
||||
|
||||
|
@ -1352,7 +1381,8 @@ static void search_pu_inter_ref(encoder_state_t * const state,
|
|||
if (merge_cand[merge_idx].dir != 3 &&
|
||||
merge_cand[merge_idx].mv[merge_cand[merge_idx].dir - 1][0] == mv.x &&
|
||||
merge_cand[merge_idx].mv[merge_cand[merge_idx].dir - 1][1] == mv.y &&
|
||||
(uint32_t)merge_cand[merge_idx].ref[merge_cand[merge_idx].dir - 1] == ref_idx) {
|
||||
(uint32_t)state->frame->ref_LX[merge_cand[merge_idx].dir - 1][
|
||||
merge_cand[merge_idx].ref[merge_cand[merge_idx].dir - 1]] == ref_idx) {
|
||||
merged = 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1380,11 +1410,11 @@ static void search_pu_inter_ref(encoder_state_t * const state,
|
|||
if (temp_cost < *inter_cost) {
|
||||
// Map reference index to L0/L1 pictures
|
||||
cur_cu->inter.mv_dir = ref_list+1;
|
||||
uint8_t mv_ref_coded = state->frame->refmap[ref_idx].idx;
|
||||
uint8_t mv_ref_coded = LX_idx;
|
||||
|
||||
cur_cu->merged = merged;
|
||||
cur_cu->merge_idx = merge_idx;
|
||||
cur_cu->inter.mv_ref[ref_list] = ref_idx;
|
||||
cur_cu->inter.mv_ref[ref_list] = LX_idx;
|
||||
cur_cu->inter.mv[ref_list][0] = (int16_t)mv.x;
|
||||
cur_cu->inter.mv[ref_list][1] = (int16_t)mv.y;
|
||||
CU_SET_MV_CAND(cur_cu, ref_list, cu_mv_cand);
|
||||
|
@ -1512,17 +1542,18 @@ static void search_pu_inter(encoder_state_t * const state,
|
|||
|
||||
// Find one L0 and L1 candidate according to the priority list
|
||||
if ((merge_cand[i].dir & 0x1) && (merge_cand[j].dir & 0x2)) {
|
||||
if (merge_cand[i].ref[0] != merge_cand[j].ref[1] ||
|
||||
merge_cand[i].mv[0][0] != merge_cand[j].mv[1][0] ||
|
||||
merge_cand[i].mv[0][1] != merge_cand[j].mv[1][1]) {
|
||||
if (state->frame->ref_LX[0][merge_cand[i].ref[0]] !=
|
||||
state->frame->ref_LX[1][merge_cand[j].ref[1]] ||
|
||||
|
||||
merge_cand[i].mv[0][0] != merge_cand[j].mv[1][0] ||
|
||||
merge_cand[i].mv[0][1] != merge_cand[j].mv[1][1])
|
||||
{
|
||||
uint32_t bitcost[2];
|
||||
uint32_t cost = 0;
|
||||
int8_t cu_mv_cand = 0;
|
||||
int16_t mv[2][2];
|
||||
kvz_pixel tmp_block[64 * 64];
|
||||
kvz_pixel tmp_pic[64 * 64];
|
||||
// Force L0 and L1 references
|
||||
if (state->frame->refmap[merge_cand[i].ref[0]].list == 2 || state->frame->refmap[merge_cand[j].ref[1]].list == 1) continue;
|
||||
|
||||
mv[0][0] = merge_cand[i].mv[0][0];
|
||||
mv[0][1] = merge_cand[i].mv[0][1];
|
||||
|
@ -1540,8 +1571,12 @@ static void search_pu_inter(encoder_state_t * const state,
|
|||
}
|
||||
|
||||
kvz_inter_recon_lcu_bipred(state,
|
||||
state->frame->ref->images[merge_cand[i].ref[0]],
|
||||
state->frame->ref->images[merge_cand[j].ref[1]],
|
||||
state->frame->ref->images[
|
||||
state->frame->ref_LX[0][merge_cand[i].ref[0]]
|
||||
],
|
||||
state->frame->ref->images[
|
||||
state->frame->ref_LX[1][merge_cand[j].ref[1]]
|
||||
],
|
||||
x, y,
|
||||
width,
|
||||
height,
|
||||
|
@ -1566,8 +1601,8 @@ static void search_pu_inter(encoder_state_t * const state,
|
|||
|
||||
cur_cu->inter.mv_dir = 3;
|
||||
uint8_t mv_ref_coded[2] = {
|
||||
state->frame->refmap[merge_cand[i].ref[0]].idx,
|
||||
state->frame->refmap[merge_cand[j].ref[1]].idx
|
||||
state->frame->ref_LX[0][merge_cand[i].ref[0]],
|
||||
state->frame->ref_LX[1][merge_cand[j].ref[1]]
|
||||
};
|
||||
|
||||
cur_cu->inter.mv_ref[0] = merge_cand[i].ref[0];
|
||||
|
@ -1586,8 +1621,9 @@ static void search_pu_inter(encoder_state_t * const state,
|
|||
merge_cand[merge_idx].mv[0][1] == cur_cu->inter.mv[0][1] &&
|
||||
merge_cand[merge_idx].mv[1][0] == cur_cu->inter.mv[1][0] &&
|
||||
merge_cand[merge_idx].mv[1][1] == cur_cu->inter.mv[1][1] &&
|
||||
merge_cand[merge_idx].ref[0] == cur_cu->inter.mv_ref[0] &&
|
||||
merge_cand[merge_idx].ref[1] == cur_cu->inter.mv_ref[1]) {
|
||||
merge_cand[merge_idx].ref[0] == cur_cu->inter.mv_ref[0] &&
|
||||
merge_cand[merge_idx].ref[1] == cur_cu->inter.mv_ref[1])
|
||||
{
|
||||
cur_cu->merged = 1;
|
||||
cur_cu->merge_idx = merge_idx;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue