mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 19:24:06 +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,
|
int32_t picture_height,
|
||||||
lcu_t *lcu,
|
lcu_t *lcu,
|
||||||
merge_candidates_t *cand_out,
|
merge_candidates_t *cand_out,
|
||||||
uint8_t parallel_merge_level)
|
uint8_t parallel_merge_level,
|
||||||
|
bool wpp
|
||||||
|
)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Predictor block locations
|
Predictor block locations
|
||||||
|
@ -916,47 +918,47 @@ static void get_spatial_merge_candidates(int32_t x,
|
||||||
int32_t y_local = SUB_SCU(y);
|
int32_t y_local = SUB_SCU(y);
|
||||||
// A0 and A1 availability testing
|
// A0 and A1 availability testing
|
||||||
if (x != 0) {
|
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
|
// 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.
|
// the current one and the flag is not set when searching an SMP block.
|
||||||
if (a0->type == CU_INTER) {
|
if (a1->type == CU_INTER) {
|
||||||
inter_clear_cu_unused(a0);
|
inter_clear_cu_unused(a1);
|
||||||
cand_out->a[0] = a0;
|
cand_out->a[1] = a1;
|
||||||
cand_out->mer_a0[0] = parallel_merge_level;
|
cand_out->mer_a1[0] = parallel_merge_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y_local + height < LCU_WIDTH && y + height < picture_height) {
|
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);
|
cu_info_t *a0 = 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)) {
|
if (a0->type == CU_INTER && is_a0_cand_coded(x, y, width, height)) {
|
||||||
inter_clear_cu_unused(a1);
|
inter_clear_cu_unused(a0);
|
||||||
cand_out->a[1] = a1;
|
cand_out->a[0] = a0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// B0, B1 and B2 availability testing
|
// B0, B1 and B2 availability testing
|
||||||
if (y != 0) {
|
if (y != 0) {
|
||||||
cu_info_t *b1 = NULL;
|
cu_info_t *b0 = NULL;
|
||||||
if (x + width < picture_width) { // ToDo: do not use B1 when WPP enabled
|
if (x + width < picture_width) {
|
||||||
if (x_local + width < LCU_WIDTH) {
|
if (x_local + width < LCU_WIDTH) {
|
||||||
b1 = LCU_GET_CU_AT_PX(lcu, x_local + width, y_local - 1);
|
b0 = LCU_GET_CU_AT_PX(lcu, x_local + width, y_local - 1);
|
||||||
} else if (y_local == 0) {
|
} else if (!wpp && y_local == 0) {
|
||||||
// Special case, top-right CU
|
// 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)) {
|
if (b0 && b0->type == CU_INTER && is_b0_cand_coded(x, y, width, height)) {
|
||||||
inter_clear_cu_unused(b1);
|
inter_clear_cu_unused(b0);
|
||||||
cand_out->b[1] = b1;
|
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
|
// 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
|
// before the current one and the flag is not set when searching an SMP
|
||||||
// block.
|
// block.
|
||||||
if (b0->type == CU_INTER) {
|
if (b1->type == CU_INTER) {
|
||||||
inter_clear_cu_unused(b0);
|
inter_clear_cu_unused(b1);
|
||||||
cand_out->b[0] = b0;
|
cand_out->b[1] = b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x != 0) {
|
if (x != 0) {
|
||||||
|
@ -994,7 +996,8 @@ static void get_spatial_merge_candidates_cua(const cu_array_t *cua,
|
||||||
int32_t height,
|
int32_t height,
|
||||||
int32_t picture_width,
|
int32_t picture_width,
|
||||||
int32_t picture_height,
|
int32_t picture_height,
|
||||||
merge_candidates_t *cand_out)
|
merge_candidates_t *cand_out,
|
||||||
|
bool wpp)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Predictor block locations
|
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);
|
int32_t y_local = SUB_SCU(y);
|
||||||
// A0 and A1 availability testing
|
// A0 and A1 availability testing
|
||||||
if (x != 0) {
|
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.
|
// The block above is always coded before the current one.
|
||||||
if (a0->type == CU_INTER) {
|
if (a1->type == CU_INTER) {
|
||||||
cand_out->a[0] = a0;
|
cand_out->a[1] = a1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y_local + height < LCU_WIDTH && y + height < picture_height) {
|
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);
|
const cu_info_t *a0 = kvz_cu_array_at_const(cua, x - 1, y + height);
|
||||||
if (a1->type == CU_INTER && is_a0_cand_coded(x, y, width, height)) {
|
if (a0->type == CU_INTER && is_a0_cand_coded(x, y, width, height)) {
|
||||||
cand_out->a[1] = a1;
|
cand_out->a[0] = a0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// B0, B1 and B2 availability testing
|
// B0, B1 and B2 availability testing
|
||||||
if (y != 0) {
|
if (y != 0) {
|
||||||
if (x + width < picture_width && (x_local + width < LCU_WIDTH || y_local == 0)) {
|
if (x + width < picture_width && (x_local + width < LCU_WIDTH || (!wpp && y_local == 0))) {
|
||||||
const cu_info_t *b1 = kvz_cu_array_at_const(cua, x + width, y - 1);
|
const cu_info_t *b0 = kvz_cu_array_at_const(cua, x + width, y - 1);
|
||||||
if (b1->type == CU_INTER && is_b0_cand_coded(x, y, width, height)) {
|
if (b0->type == CU_INTER && is_b0_cand_coded(x, y, width, height)) {
|
||||||
cand_out->b[1] = b1;
|
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.
|
// The block to the left is always coded before the current one.
|
||||||
if (b0->type == CU_INTER) {
|
if (b1->type == CU_INTER) {
|
||||||
cand_out->b[0] = b0;
|
cand_out->b[1] = b1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x != 0) {
|
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;
|
uint8_t b_candidates = 0;
|
||||||
|
|
||||||
// Left predictors without scaling
|
// 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++;
|
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++;
|
candidates++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Top predictors without scaling
|
// 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++;
|
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++;
|
b_candidates++;
|
||||||
}
|
}
|
||||||
else if (add_mvp_candidate(state, cur_cu, b[2], reflist, false, mv_cand[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->width,
|
||||||
state->tile->frame->height,
|
state->tile->frame->height,
|
||||||
lcu,
|
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_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);
|
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,
|
get_spatial_merge_candidates_cua(cua,
|
||||||
x, y, width, height,
|
x, y, width, height,
|
||||||
state->tile->frame->width, state->tile->frame->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_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);
|
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->width,
|
||||||
state->tile->frame->height,
|
state->tile->frame->height,
|
||||||
lcu,
|
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 **a = merge_cand.a;
|
||||||
const cu_info_t **b = merge_cand.b;
|
const cu_info_t **b = merge_cand.b;
|
||||||
|
|
|
@ -38,7 +38,7 @@ TEST test_get_spatial_merge_cand(void)
|
||||||
1920, 1080, // picture size
|
1920, 1080, // picture size
|
||||||
&lcu,
|
&lcu,
|
||||||
&cand,
|
&cand,
|
||||||
2);
|
2, 0);
|
||||||
|
|
||||||
ASSERT_EQ(cand.b[1], &lcu.cu[289]);
|
ASSERT_EQ(cand.b[1], &lcu.cu[289]);
|
||||||
ASSERT_EQ(cand.b[0], &lcu.cu[ 16]);
|
ASSERT_EQ(cand.b[0], &lcu.cu[ 16]);
|
||||||
|
|
Loading…
Reference in a new issue