mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 11:24:05 +00:00
[inter] MVP candidate order fix and limit b0 with wpp
This commit is contained in:
parent
5b3d87f6c1
commit
b0e6ab9f96
89
src/inter.c
89
src/inter.c
|
@ -900,7 +900,9 @@ static void get_spatial_merge_candidates(int32_t x,
|
|||
int32_t picture_height,
|
||||
lcu_t *lcu,
|
||||
merge_candidates_t *cand_out,
|
||||
uint8_t parallel_merge_level)
|
||||
uint8_t parallel_merge_level,
|
||||
bool wpp
|
||||
)
|
||||
{
|
||||
/*
|
||||
Predictor block locations
|
||||
|
@ -916,47 +918,47 @@ static void get_spatial_merge_candidates(int32_t x,
|
|||
int32_t y_local = SUB_SCU(y);
|
||||
// A0 and A1 availability testing
|
||||
if (x != 0) {
|
||||
cu_info_t *a0 = LCU_GET_CU_AT_PX(lcu, x_local - 1, y_local + height - 1);
|
||||
cu_info_t *a1 = LCU_GET_CU_AT_PX(lcu, x_local - 1, y_local + height - 1);
|
||||
// Do not check a1->coded because the block above is always coded before
|
||||
// the current one and the flag is not set when searching an SMP block.
|
||||
if (a0->type == CU_INTER) {
|
||||
inter_clear_cu_unused(a0);
|
||||
cand_out->a[0] = a0;
|
||||
cand_out->mer_a0[0] = parallel_merge_level;
|
||||
if (a1->type == CU_INTER) {
|
||||
inter_clear_cu_unused(a1);
|
||||
cand_out->a[1] = a1;
|
||||
cand_out->mer_a1[0] = parallel_merge_level;
|
||||
}
|
||||
|
||||
if (y_local + height < LCU_WIDTH && y + height < picture_height) {
|
||||
cu_info_t *a1 = LCU_GET_CU_AT_PX(lcu, x_local - 1, y_local + height);
|
||||
if (a1->type == CU_INTER && is_a0_cand_coded(x, y, width, height)) {
|
||||
inter_clear_cu_unused(a1);
|
||||
cand_out->a[1] = a1;
|
||||
cu_info_t *a0 = LCU_GET_CU_AT_PX(lcu, x_local - 1, y_local + height);
|
||||
if (a0->type == CU_INTER && is_a0_cand_coded(x, y, width, height)) {
|
||||
inter_clear_cu_unused(a0);
|
||||
cand_out->a[0] = a0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// B0, B1 and B2 availability testing
|
||||
if (y != 0) {
|
||||
cu_info_t *b1 = NULL;
|
||||
if (x + width < picture_width) { // ToDo: do not use B1 when WPP enabled
|
||||
cu_info_t *b0 = NULL;
|
||||
if (x + width < picture_width) {
|
||||
if (x_local + width < LCU_WIDTH) {
|
||||
b1 = LCU_GET_CU_AT_PX(lcu, x_local + width, y_local - 1);
|
||||
} else if (y_local == 0) {
|
||||
b0 = LCU_GET_CU_AT_PX(lcu, x_local + width, y_local - 1);
|
||||
} else if (!wpp && y_local == 0) {
|
||||
// Special case, top-right CU
|
||||
b1 = LCU_GET_TOP_RIGHT_CU(lcu);
|
||||
b0 = LCU_GET_TOP_RIGHT_CU(lcu);
|
||||
}
|
||||
}
|
||||
if (b1 && b1->type == CU_INTER && is_b0_cand_coded(x, y, width, height)) {
|
||||
inter_clear_cu_unused(b1);
|
||||
cand_out->b[1] = b1;
|
||||
if (b0 && b0->type == CU_INTER && is_b0_cand_coded(x, y, width, height)) {
|
||||
inter_clear_cu_unused(b0);
|
||||
cand_out->b[0] = b0;
|
||||
}
|
||||
|
||||
cu_info_t *b0 = LCU_GET_CU_AT_PX(lcu, x_local + width - 1, y_local - 1);
|
||||
cu_info_t *b1 = LCU_GET_CU_AT_PX(lcu, x_local + width - 1, y_local - 1);
|
||||
// Do not check b0->coded because the block to the left is always coded
|
||||
// before the current one and the flag is not set when searching an SMP
|
||||
// block.
|
||||
if (b0->type == CU_INTER) {
|
||||
inter_clear_cu_unused(b0);
|
||||
cand_out->b[0] = b0;
|
||||
if (b1->type == CU_INTER) {
|
||||
inter_clear_cu_unused(b1);
|
||||
cand_out->b[1] = b1;
|
||||
}
|
||||
|
||||
if (x != 0) {
|
||||
|
@ -994,7 +996,8 @@ static void get_spatial_merge_candidates_cua(const cu_array_t *cua,
|
|||
int32_t height,
|
||||
int32_t picture_width,
|
||||
int32_t picture_height,
|
||||
merge_candidates_t *cand_out)
|
||||
merge_candidates_t *cand_out,
|
||||
bool wpp)
|
||||
{
|
||||
/*
|
||||
Predictor block locations
|
||||
|
@ -1010,33 +1013,33 @@ static void get_spatial_merge_candidates_cua(const cu_array_t *cua,
|
|||
int32_t y_local = SUB_SCU(y);
|
||||
// A0 and A1 availability testing
|
||||
if (x != 0) {
|
||||
const cu_info_t *a0 = kvz_cu_array_at_const(cua, x - 1, y + height - 1);
|
||||
const cu_info_t *a1 = kvz_cu_array_at_const(cua, x - 1, y + height - 1);
|
||||
// The block above is always coded before the current one.
|
||||
if (a0->type == CU_INTER) {
|
||||
cand_out->a[0] = a0;
|
||||
if (a1->type == CU_INTER) {
|
||||
cand_out->a[1] = a1;
|
||||
}
|
||||
|
||||
if (y_local + height < LCU_WIDTH && y + height < picture_height) {
|
||||
const cu_info_t *a1 = kvz_cu_array_at_const(cua, x - 1, y + height);
|
||||
if (a1->type == CU_INTER && is_a0_cand_coded(x, y, width, height)) {
|
||||
cand_out->a[1] = a1;
|
||||
const cu_info_t *a0 = kvz_cu_array_at_const(cua, x - 1, y + height);
|
||||
if (a0->type == CU_INTER && is_a0_cand_coded(x, y, width, height)) {
|
||||
cand_out->a[0] = a0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// B0, B1 and B2 availability testing
|
||||
if (y != 0) {
|
||||
if (x + width < picture_width && (x_local + width < LCU_WIDTH || y_local == 0)) {
|
||||
const cu_info_t *b1 = kvz_cu_array_at_const(cua, x + width, y - 1);
|
||||
if (b1->type == CU_INTER && is_b0_cand_coded(x, y, width, height)) {
|
||||
cand_out->b[1] = b1;
|
||||
if (x + width < picture_width && (x_local + width < LCU_WIDTH || (!wpp && y_local == 0))) {
|
||||
const cu_info_t *b0 = kvz_cu_array_at_const(cua, x + width, y - 1);
|
||||
if (b0->type == CU_INTER && is_b0_cand_coded(x, y, width, height)) {
|
||||
cand_out->b[0] = b0;
|
||||
}
|
||||
}
|
||||
|
||||
const cu_info_t *b0 = kvz_cu_array_at_const(cua, x + width - 1, y - 1);
|
||||
const cu_info_t* b1 = kvz_cu_array_at_const(cua, x + width - 1, y - 1);
|
||||
// The block to the left is always coded before the current one.
|
||||
if (b0->type == CU_INTER) {
|
||||
cand_out->b[0] = b0;
|
||||
if (b1->type == CU_INTER) {
|
||||
cand_out->b[1] = b1;
|
||||
}
|
||||
|
||||
if (x != 0) {
|
||||
|
@ -1216,17 +1219,17 @@ static void get_mv_cand_from_candidates(const encoder_state_t * const state,
|
|||
uint8_t b_candidates = 0;
|
||||
|
||||
// Left predictors without scaling
|
||||
if (add_mvp_candidate(state, cur_cu, a[1], reflist, false, mv_cand[candidates])) {
|
||||
if (add_mvp_candidate(state, cur_cu, a[0], reflist, false, mv_cand[candidates])) {
|
||||
candidates++;
|
||||
} else if (add_mvp_candidate(state, cur_cu, a[0], reflist, false, mv_cand[candidates])) {
|
||||
} else if (add_mvp_candidate(state, cur_cu, a[1], reflist, false, mv_cand[candidates])) {
|
||||
candidates++;
|
||||
}
|
||||
|
||||
|
||||
// Top predictors without scaling
|
||||
if (add_mvp_candidate(state, cur_cu, b[1], reflist, false, mv_cand[candidates])) {
|
||||
if (add_mvp_candidate(state, cur_cu, b[0], reflist, false, mv_cand[candidates])) {
|
||||
b_candidates++;
|
||||
} else if (add_mvp_candidate(state, cur_cu, b[0], reflist, false, mv_cand[candidates])) {
|
||||
} else if (add_mvp_candidate(state, cur_cu, b[1], reflist, false, mv_cand[candidates])) {
|
||||
b_candidates++;
|
||||
}
|
||||
else if (add_mvp_candidate(state, cur_cu, b[2], reflist, false, mv_cand[candidates])) {
|
||||
|
@ -1309,7 +1312,7 @@ void kvz_inter_get_mv_cand(const encoder_state_t * const state,
|
|||
state->tile->frame->width,
|
||||
state->tile->frame->height,
|
||||
lcu,
|
||||
&merge_cand, parallel_merge_level);
|
||||
&merge_cand, parallel_merge_level,state->encoder_control->cfg.wpp);
|
||||
get_temporal_merge_candidates(state, x, y, width, height, 1, 0, &merge_cand);
|
||||
get_mv_cand_from_candidates(state, x, y, width, height, &merge_cand, cur_cu, reflist, mv_cand);
|
||||
}
|
||||
|
@ -1341,7 +1344,7 @@ void kvz_inter_get_mv_cand_cua(const encoder_state_t * const state,
|
|||
get_spatial_merge_candidates_cua(cua,
|
||||
x, y, width, height,
|
||||
state->tile->frame->width, state->tile->frame->height,
|
||||
&merge_cand);
|
||||
&merge_cand, state->encoder_control->cfg.wpp);
|
||||
get_temporal_merge_candidates(state, x, y, width, height, 1, 0, &merge_cand);
|
||||
get_mv_cand_from_candidates(state, x, y, width, height, &merge_cand, cur_cu, reflist, mv_cand);
|
||||
}
|
||||
|
@ -1487,7 +1490,7 @@ uint8_t kvz_inter_get_merge_cand(const encoder_state_t * const state,
|
|||
state->tile->frame->width,
|
||||
state->tile->frame->height,
|
||||
lcu,
|
||||
&merge_cand, parallel_merge_level);
|
||||
&merge_cand, parallel_merge_level, state->encoder_control->cfg.wpp);
|
||||
|
||||
const cu_info_t **a = merge_cand.a;
|
||||
const cu_info_t **b = merge_cand.b;
|
||||
|
|
|
@ -38,7 +38,7 @@ TEST test_get_spatial_merge_cand(void)
|
|||
1920, 1080, // picture size
|
||||
&lcu,
|
||||
&cand,
|
||||
2);
|
||||
2, 0);
|
||||
|
||||
ASSERT_EQ(cand.b[1], &lcu.cu[289]);
|
||||
ASSERT_EQ(cand.b[0], &lcu.cu[ 16]);
|
||||
|
|
Loading…
Reference in a new issue