Skip to content

Commit 7669886

Browse files
committed
Merge branch 'ref-build-improvement' into 'master'
Ref build improvement See merge request cs/ultravideo/vvc/uvg266!15
2 parents 4fcd2ac + 3c54935 commit 7669886

File tree

3 files changed

+199
-93
lines changed

3 files changed

+199
-93
lines changed

src/intra.c

+129-43
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ static void intra_filter_reference(
198198
refs->filtered_initialized = true;
199199
}
200200

201-
const int_fast8_t ref_width = 2 * (1 << log2_width) + 1;
202-
const int_fast8_t ref_height = 2 * (1 << log2_height) + 1;
201+
const int_fast16_t ref_width = 2 * (1 << (log2_width)) + 1;
202+
const int_fast16_t ref_height = 2 * (1 << (log2_height)) + 1;
203203
uvg_intra_ref *ref = &refs->ref;
204204
uvg_intra_ref *filtered_ref = &refs->filtered_ref;
205205

@@ -208,15 +208,15 @@ static void intra_filter_reference(
208208
filtered_ref->top[0] = filtered_ref->left[0];
209209

210210
// Top to bottom
211-
for (int_fast8_t y = 1; y < ref_height - 1; ++y) {
211+
for (int_fast16_t y = 1; y < ref_height - 1; ++y) {
212212
uvg_pixel *p = &ref->left[y];
213213
filtered_ref->left[y] = (p[-1] + 2 * p[0] + p[1] + 2) >> 2;
214214
}
215215
// Bottom left (not filtered)
216216
filtered_ref->left[ref_height - 1] = ref->left[ref_height - 1];
217217

218218
// Left to right
219-
for (int_fast8_t x = 1; x < ref_width - 1; ++x) {
219+
for (int_fast16_t x = 1; x < ref_width - 1; ++x) {
220220
uvg_pixel *p = &ref->top[x];
221221
filtered_ref->top[x] = (p[-1] + 2 * p[0] + p[1] + 2) >> 2;
222222
}
@@ -713,7 +713,16 @@ static void intra_predict_regular(
713713
}
714714

715715
if (used_ref == &refs->filtered_ref && !refs->filtered_initialized) {
716-
intra_filter_reference(log2_width, log2_height, refs);
716+
int temp_log2_width = log2_width;
717+
int temp_log2_height = log2_height;
718+
if (color == COLOR_Y && isp_mode == ISP_MODE_NO_ISP) {
719+
temp_log2_width = cur_cu->log2_width;
720+
temp_log2_height = cur_cu->log2_height;
721+
} else if (color != COLOR_Y) {
722+
temp_log2_width = cur_cu->log2_chroma_width;
723+
temp_log2_height = cur_cu->log2_chroma_height;
724+
}
725+
intra_filter_reference(temp_log2_width, temp_log2_height, refs);
717726
}
718727

719728
if (mode == 0) {
@@ -780,7 +789,6 @@ void uvg_intra_build_reference_any(
780789

781790
const uvg_pixel dc_val = 1 << (UVG_BIT_DEPTH - 1); //TODO: add used bitdepth as a variable
782791
const int is_chroma = color != COLOR_Y ? 1 : 0;
783-
const int is_dual_tree = is_chroma && state->encoder_control->cfg.dual_tree && state->frame->is_irap;
784792

785793
// Get multi ref index from CU under prediction or reconstrcution. Do not use MRL if not luma
786794
const uint8_t multi_ref_index = !is_chroma ? multi_ref_idx : 0;
@@ -799,7 +807,7 @@ void uvg_intra_build_reference_any(
799807
// Init pointers to LCUs reconstruction buffers, such that index 0 refers to block coordinate 0.
800808
const uvg_pixel *left_ref;
801809
bool extra_ref = false;
802-
// On the left LCU edge, if left neighboring LCU is available,
810+
// On the left LCU edge, if left neighboring LCU is available,
803811
// left_ref needs to point to correct extra reference line if MRL is used.
804812
if (luma_px->x > 0 && lcu_px.x == 0 && multi_ref_index != 0) {
805813
left_ref = &extra_ref_lines[multi_ref_index * 128];
@@ -836,6 +844,9 @@ void uvg_intra_build_reference_any(
836844
left_stride = 1;
837845
}
838846

847+
const int log2_ratio = log2_width - log2_height;
848+
int s = MAX(0, -log2_ratio);
849+
int mrl_extension = (multi_ref_index << s) + (height << s) + 2;
839850
// Generate left reference.
840851
if (luma_px->x > 0) {
841852
// Get the number of reference pixels based on the PU coordinate within the LCU.
@@ -856,7 +867,7 @@ void uvg_intra_build_reference_any(
856867

857868
// Limit the number of available pixels based on block size and dimensions
858869
// of the picture.
859-
px_available_left = MIN(px_available_left, cu_height * 2 + multi_ref_index);
870+
px_available_left = MIN(px_available_left, cu_height + pu_loc->height);
860871
px_available_left = MIN(px_available_left, (pic_px->y - luma_px->y) >> is_chroma);
861872

862873
// Copy pixels from coded CUs.
@@ -869,15 +880,17 @@ void uvg_intra_build_reference_any(
869880

870881
// If first isp split, take samples as if it were normal square block
871882
int tmp_h = is_first_isp_block ? cu_height * 2 : (isp_mode ? cu_height + height : height * 2);
872-
for (int i = px_available_left; i < tmp_h + multi_ref_index * 2; ++i) {
883+
int total_height = MIN(tmp_h + mrl_extension, INTRA_REF_LENGTH);
884+
for (int i = px_available_left; i < total_height; ++i) {
873885
out_left_ref[i + 1 + multi_ref_index] = nearest_pixel;
874886
}
875887
} else {
876888
// If we are on the left edge, extend the first pixel of the top row.
877889
uvg_pixel nearest_pixel = luma_px->y > 0 ? top_border[0] : dc_val;
878890
// If first isp split, take samples as if it were normal square block
879891
int tmp_h = is_first_isp_block ? cu_height * 2 : (isp_mode ? cu_height + height : height * 2);
880-
for (int i = 0; i < tmp_h + multi_ref_index; i++) {
892+
int total_height = MIN(tmp_h + mrl_extension, INTRA_REF_LENGTH);
893+
for (int i = 0; i < total_height; i++) {
881894
// Reserve space for top left reference
882895
out_left_ref[i + 1 + multi_ref_index] = nearest_pixel;
883896
}
@@ -899,9 +912,22 @@ void uvg_intra_build_reference_any(
899912
else if (px.x == 0) {
900913
// LCU left border case
901914
uvg_pixel *top_left_corner = &extra_ref_lines[multi_ref_index * 128];
902-
for (int i = 0; i <= multi_ref_index; ++i) {
903-
out_left_ref[i] = left_border[(i - 1 - multi_ref_index) * left_stride];
904-
out_top_ref[i] = top_left_corner[(128 * -i) + MAX_REF_LINE_IDX - 1 - multi_ref_index];
915+
switch (multi_ref_index) {
916+
case 0:
917+
out_left_ref[0] = left_border[(-1) * left_stride];
918+
out_top_ref[0] = top_left_corner[MAX_REF_LINE_IDX - 1];
919+
break;
920+
case 1:
921+
for (int i = 0; i <= 1; ++i) {
922+
out_left_ref[i] = left_border[(i - 1 - 1) * left_stride];
923+
out_top_ref[i] = top_left_corner[(128 * -i) + MAX_REF_LINE_IDX - 1 - 1];
924+
} break;
925+
case 2:
926+
for (int i = 0; i <= 2; ++i) {
927+
out_left_ref[i] = left_border[(i - 1 - 2) * left_stride];
928+
out_top_ref[i] = top_left_corner[(128 * -i) + MAX_REF_LINE_IDX - 1 - 2];
929+
} break;
930+
default: break;
905931
}
906932
}
907933
else if (px.y == 0) {
@@ -911,9 +937,23 @@ void uvg_intra_build_reference_any(
911937
}
912938
else {
913939
// Inner case
914-
for (int i = 0; i <= multi_ref_index; ++i) {
915-
out_left_ref[i] = left_border[(i - 1 - multi_ref_index) * left_stride];
916-
out_top_ref[i] = top_border[i - 1 - multi_ref_index];
940+
switch (multi_ref_index) {
941+
case 0:
942+
for (int i = 0; i <= 0; ++i) {
943+
out_left_ref[i] = left_border[(i - 1 - 0) * left_stride];
944+
out_top_ref[i] = top_border[i - 1 - 0];
945+
} break;
946+
case 1:
947+
for (int i = 0; i <= 1; ++i) {
948+
out_left_ref[i] = left_border[(i - 1 - 1) * left_stride];
949+
out_top_ref[i] = top_border[i - 1 - 1];
950+
} break;
951+
case 2:
952+
for (int i = 0; i <= 2; ++i) {
953+
out_left_ref[i] = left_border[(i - 1 - 2) * left_stride];
954+
out_top_ref[i] = top_border[i - 1 - 2];
955+
} break;
956+
default: break;
917957
}
918958
}
919959
}
@@ -927,10 +967,22 @@ void uvg_intra_build_reference_any(
927967
else if (px.x == 0) {
928968
// Picture left border case. Reference pixel cannot be taken from outside LCU border
929969
uvg_pixel nearest = out_left_ref[1 + multi_ref_index];
930-
for (int i = 0; i <= multi_ref_index; ++i) {
931-
out_left_ref[i] = nearest;
932-
out_top_ref[i] = nearest;
970+
switch (multi_ref_index) {
971+
case 2:
972+
out_left_ref[2] = nearest;
973+
out_top_ref[2] = nearest;
974+
// Fall through
975+
case 1:
976+
out_left_ref[1] = nearest;
977+
out_top_ref[1] = nearest;
978+
// Fall through
979+
case 0:
980+
out_left_ref[0] = nearest;
981+
out_top_ref[0] = nearest;
982+
break;
983+
default: break;
933984
}
985+
934986
}
935987
else {
936988
// Picture top border case. Multi ref will be 0.
@@ -961,6 +1013,8 @@ void uvg_intra_build_reference_any(
9611013

9621014
// Generate top reference.
9631015
int px_available_top;
1016+
s = MAX(0, log2_ratio);
1017+
mrl_extension = (multi_ref_index << s) + (width << s) + 2;
9641018
if (luma_px->y > 0) {
9651019
// Get the number of reference pixels based on the PU coordinate within the LCU.
9661020
if (isp_mode && !is_first_isp_block && !is_chroma) {
@@ -976,10 +1030,10 @@ void uvg_intra_build_reference_any(
9761030
const int num_cus = uvg_count_available_edge_cus(cu_loc, lcu, false);
9771031
px_available_top = !is_chroma ? num_cus * 4 : num_cus * 2;
9781032
}
979-
1033+
9801034
// Limit the number of available pixels based on block size and dimensions
9811035
// of the picture.
982-
px_available_top = MIN(px_available_top, cu_width * 2 + multi_ref_index);
1036+
px_available_top = MIN(px_available_top, cu_width + pu_loc->width);
9831037
px_available_top = MIN(px_available_top, (pic_px->x - luma_px->x) >> is_chroma);
9841038

9851039
// Copy all the pixels we can.
@@ -991,7 +1045,8 @@ void uvg_intra_build_reference_any(
9911045

9921046
// If first isp split, take samples as if it were normal square block
9931047
int tmp_w = is_first_isp_block ? cu_width * 2 : (isp_mode ? cu_width + width : width * 2);
994-
for (int i = px_available_top; i < tmp_w + multi_ref_index * 2; ++i) {
1048+
int total_width = MIN(tmp_w + mrl_extension, INTRA_REF_LENGTH);
1049+
for (int i = px_available_top; i < total_width; ++i) {
9951050
out_top_ref[i + 1 + multi_ref_index] = nearest_pixel;
9961051
}
9971052
} else {
@@ -1000,7 +1055,8 @@ void uvg_intra_build_reference_any(
10001055

10011056
// If first isp split, take samples as if it were normal square block
10021057
int tmp_w = is_first_isp_block ? cu_width * 2 : (isp_mode ? cu_width + width : width * 2);
1003-
for (int i = 0; i < tmp_w + multi_ref_index * 2; i++) {
1058+
int total_width = MIN(tmp_w + mrl_extension, INTRA_REF_LENGTH);
1059+
for (int i = 0; i < total_width; i++) {
10041060
out_top_ref[i + 1] = nearest_pixel;
10051061
}
10061062
}
@@ -1111,9 +1167,22 @@ void uvg_intra_build_reference_inner(
11111167
else if (px.x == 0) {
11121168
// LCU left border case
11131169
uvg_pixel* top_left_corner = &extra_ref_lines[multi_ref_index * 128];
1114-
for (int i = 0; i <= multi_ref_index; ++i) {
1115-
out_left_ref[i] = left_border[(i - 1 - multi_ref_index) * left_stride];
1116-
out_top_ref[i] = top_left_corner[(128 * -i) + MAX_REF_LINE_IDX - 1 - multi_ref_index];
1170+
switch (multi_ref_index) {
1171+
case 0:
1172+
out_left_ref[0] = left_border[(-1) * left_stride];
1173+
out_top_ref[0] = top_left_corner[MAX_REF_LINE_IDX - 1];
1174+
break;
1175+
case 1:
1176+
for (int i = 0; i <= 1; ++i) {
1177+
out_left_ref[i] = left_border[(i - 1 - 1) * left_stride];
1178+
out_top_ref[i] = top_left_corner[(128 * -i) + MAX_REF_LINE_IDX - 1 - 1];
1179+
} break;
1180+
case 2:
1181+
for (int i = 0; i <= 2; ++i) {
1182+
out_left_ref[i] = left_border[(i - 1 - 2) * left_stride];
1183+
out_top_ref[i] = top_left_corner[(128 * -i) + MAX_REF_LINE_IDX - 1 - 2];
1184+
} break;
1185+
default: break;
11171186
}
11181187
}
11191188
else if (px.y == 0) {
@@ -1123,9 +1192,23 @@ void uvg_intra_build_reference_inner(
11231192
}
11241193
else {
11251194
// Inner case
1126-
for (int i = 0; i <= multi_ref_index; ++i) {
1127-
out_left_ref[i] = left_border[(i - 1 - multi_ref_index) * left_stride];
1128-
out_top_ref[i] = top_border[i - 1 - multi_ref_index];
1195+
switch (multi_ref_index) {
1196+
case 0:
1197+
for (int i = 0; i <= 0; ++i) {
1198+
out_left_ref[i] = left_border[(i - 1 - 0) * left_stride];
1199+
out_top_ref[i] = top_border[i - 1 - 0];
1200+
} break;
1201+
case 1:
1202+
for (int i = 0; i <= 1; ++i) {
1203+
out_left_ref[i] = left_border[(i - 1 - 1) * left_stride];
1204+
out_top_ref[i] = top_border[i - 1 - 1];
1205+
} break;
1206+
case 2:
1207+
for (int i = 0; i <= 2; ++i) {
1208+
out_left_ref[i] = left_border[(i - 1 - 2) * left_stride];
1209+
out_top_ref[i] = top_border[i - 1 - 2];
1210+
} break;
1211+
default: break;
11291212
}
11301213
}
11311214
}
@@ -1167,14 +1250,15 @@ void uvg_intra_build_reference_inner(
11671250

11681251
// Limit the number of available pixels based on block size and dimensions
11691252
// of the picture.
1170-
px_available_left = MIN(px_available_left, cu_height * 2);
1253+
px_available_left = MIN(px_available_left, cu_height + pu_loc->height);
1254+
// if (is_first_isp_block && isp_mode == ISP_MODE_HOR && px_available_left == cu_height * 2) px_available_left -= (pu_loc->height);
11711255
px_available_left = MIN(px_available_left, (pic_px->y - luma_px->y) >> is_chroma);
11721256

11731257
// Copy pixels from coded CUs.
11741258
int i = multi_ref_index; // Offset by multi_ref_index
11751259

11761260
// Do different loop for heights smaller than 4 (possible for some ISP splits)
1177-
if (px.y % 4 != 0 || px_available_left < 4) {
1261+
if (px.y % 4 != 0 || px_available_left % 4 != 0) {
11781262
do {
11791263
out_left_ref[i + 1] = left_border[(i + 0 - multi_ref_index) * left_stride];
11801264
i += 1;
@@ -1194,20 +1278,18 @@ void uvg_intra_build_reference_inner(
11941278
uvg_pixel nearest_pixel = out_left_ref[i];
11951279

11961280
// If first isp split, take samples as if it were normal square block
1281+
const int log2_ratio = log2_width - log2_height;
1282+
int s = MAX(0, -log2_ratio);
1283+
int mrl_extension = ((multi_ref_index + 0) << s) + (height << s) + 2;
11971284
int tmp_h = is_first_isp_block ? cu_height * 2 : (isp_mode ? cu_height + height : height * 2);
1198-
for (; i < tmp_h; i += 4) {
1285+
int total_height = MIN(tmp_h + mrl_extension, INTRA_REF_LENGTH - 2);
1286+
for (; i < total_height; i += 4) {
11991287
out_left_ref[i + 1] = nearest_pixel;
12001288
out_left_ref[i + 2] = nearest_pixel;
12011289
out_left_ref[i + 3] = nearest_pixel;
12021290
out_left_ref[i + 4] = nearest_pixel;
12031291
}
12041292

1205-
// Extend for MRL
1206-
if (multi_ref_index) {
1207-
for (; i < height * 2 + multi_ref_index; ++i) {
1208-
out_left_ref[i + 1] = nearest_pixel;
1209-
}
1210-
}
12111293

12121294
// Generate top reference.
12131295

@@ -1229,24 +1311,28 @@ void uvg_intra_build_reference_inner(
12291311

12301312
// Limit the number of available pixels based on block size and dimensions
12311313
// of the picture.
1232-
px_available_top = MIN(px_available_top, cu_width * 2 + multi_ref_index);
1314+
px_available_top = MIN(px_available_top, cu_width + pu_loc->width);
1315+
//if (is_first_isp_block && isp_mode == ISP_MODE_VER && px_available_top == cu_width * 2) px_available_top -= MIN(pu_loc->width, 4);
12331316
px_available_top = MIN(px_available_top, (pic_px->x - luma_px->x) >> is_chroma);
12341317

1235-
if (entropy_sync && px.y == 0) px_available_top = MIN(px_available_top, ((LCU_WIDTH >> is_chroma) - px.x) -1);
1318+
if (entropy_sync && px.y == 0) px_available_top = MIN(px_available_top, ((LCU_WIDTH >> is_chroma) - px.x));
12361319

12371320
// Copy all the pixels we can.
12381321
i = 0;
12391322
do {
1240-
memcpy(out_top_ref + i + 1 + multi_ref_index, top_border + i, 4 * sizeof(uvg_pixel));
1241-
i += 4;
1323+
memcpy(out_top_ref + i + 1 + multi_ref_index, top_border + i, sizeof(uvg_pixel));
1324+
i += 1;
12421325
} while (i < px_available_top);
12431326

12441327
// Extend the last pixel for the rest of the reference values.
12451328
nearest_pixel = out_top_ref[i + multi_ref_index];
12461329

12471330
// If first isp split, take samples as if it were normal square block
1331+
s = MAX(0, -log2_ratio);
1332+
mrl_extension = ((multi_ref_index + 0) << s) + (width << s) + 2;
12481333
int tmp_w = is_first_isp_block ? cu_width * 2 : (isp_mode ? cu_width + width : width * 2);
1249-
for (; i < tmp_w + (multi_ref_index * 2); i += 4) {
1334+
int total_width = MIN(tmp_w+ mrl_extension, INTRA_REF_LENGTH - 2);
1335+
for (; i < total_width; i += 4) {
12501336
out_top_ref[i + 1 + multi_ref_index] = nearest_pixel;
12511337
out_top_ref[i + 2 + multi_ref_index] = nearest_pixel;
12521338
out_top_ref[i + 3 + multi_ref_index] = nearest_pixel;

0 commit comments

Comments
 (0)