Added new experiment EXT_INTRA_MOD2.
HW simplifications for intra predicition.
Changed from 256 points interpolation to 32 points.
Changed values in dr_intra_derivative to be upscaled by 64
instead of 256 and adjusted the angles to be more evenly
spread out. Values are also kept within 10-bits.
AWCY results:
objective-1-fast-1, key-frame only, cpu-used=0
--disable-ext-partition --disable-ext-partition-types
PSNR | PSNR Cb | PSNR Cr | PSNR HVS | SSIM | MS SSIM | CIEDE 2000
-0.0476 | N/A | 0.2705 | -0.0741 | -0.1357 | -0.1960 | N/A
Change-Id: I1e1712ab71dc47a3e898b1799ba9e648153735eb
diff --git a/av1/common/blockd.c b/av1/common/blockd.c
index a412b95..9d2fdbd 100644
--- a/av1/common/blockd.c
+++ b/av1/common/blockd.c
@@ -180,6 +180,41 @@
}
#if CONFIG_EXT_INTRA
+#if CONFIG_EXT_INTRA_MOD2
+const int16_t dr_intra_derivative[90] = {
+ // More evenly spread out angles and limited to 10-bit
+ // Values that are 0 will never be used
+ // Approx angle
+ 0, 0, 0, //
+ 1023, 0, 0, // 3, ...
+ 547, 0, 0, // 6, ...
+ 372, 0, 0, 0, 0, // 9, ...
+ 273, 0, 0, // 14, ...
+ 215, 0, 0, // 17, ...
+ 178, 0, 0, // 20, ...
+ 151, 0, 0, // 23, ... (113 & 203 are base angles)
+ 132, 0, 0, // 26, ...
+ 116, 0, 0, // 29, ...
+ 102, 0, 0, 0, // 32, ...
+ 90, 0, 0, // 36, ...
+ 80, 0, 0, // 39, ...
+ 71, 0, 0, // 42, ...
+ 64, 0, 0, // 45, ... (45 & 135 are base angles)
+ 57, 0, 0, // 48, ...
+ 51, 0, 0, // 51, ...
+ 45, 0, 0, 0, // 54, ...
+ 40, 0, 0, // 58, ...
+ 35, 0, 0, // 61, ...
+ 31, 0, 0, // 64, ...
+ 27, 0, 0, // 67, ... (67 & 157 are base angles)
+ 23, 0, 0, // 70, ...
+ 19, 0, 0, // 73, ...
+ 15, 0, 0, 0, 0, // 76, ...
+ 11, 0, 0, // 81, ...
+ 7, 0, 0, // 84, ...
+ 3, 0, 0, // 87, ...
+};
+#else
const int16_t dr_intra_derivative[90] = {
1, 14666, 7330, 4884, 3660, 2926, 2435, 2084, 1821, 1616, 1451, 1317, 1204,
1108, 1026, 955, 892, 837, 787, 743, 703, 666, 633, 603, 574, 548,
@@ -189,4 +224,5 @@
119, 113, 108, 103, 98, 93, 88, 83, 78, 73, 68, 63, 59,
54, 49, 45, 40, 35, 31, 26, 22, 17, 13, 8, 4,
};
+#endif // CONFIG_EXT_INTRA_MOD2
#endif // CONFIG_EXT_INTRA
diff --git a/av1/common/reconintra.c b/av1/common/reconintra.c
index 33c71e8..0b41123 100644
--- a/av1/common/reconintra.c
+++ b/av1/common/reconintra.c
@@ -773,12 +773,20 @@
const int upsample_above = 0;
#endif // !CONFIG_INTRA_EDGE_UPSAMPLE
const int max_base_x = ((bw + bh) - 1) << upsample_above;
+#if CONFIG_EXT_INTRA_MOD2
+ const int frac_bits = 6 - upsample_above;
+#else
const int frac_bits = 8 - upsample_above;
+#endif
const int base_inc = 1 << upsample_above;
x = dx;
for (r = 0; r < bh; ++r, dst += stride, x += dx) {
base = x >> frac_bits;
+#if CONFIG_EXT_INTRA_MOD2
+ shift = ((x << upsample_above) & 0x3F) >> 1;
+#else
shift = (x << upsample_above) & 0xFF;
+#endif
if (base >= max_base_x) {
for (int i = r; i < bh; ++i) {
@@ -790,8 +798,13 @@
for (c = 0; c < bw; ++c, base += base_inc) {
if (base < max_base_x) {
+#if CONFIG_EXT_INTRA_MOD2
+ val = above[base] * (32 - shift) + above[base + 1] * shift;
+ val = ROUND_POWER_OF_TWO(val, 5);
+#else
val = above[base] * (256 - shift) + above[base + 1] * shift;
val = ROUND_POWER_OF_TWO(val, 8);
+#endif
dst[c] = clip_pixel(val);
} else {
dst[c] = above[max_base_x];
@@ -817,24 +830,45 @@
const int upsample_left = 0;
#endif // !CONFIG_INTRA_EDGE_UPSAMPLE
const int min_base_x = -(1 << upsample_above);
+#if CONFIG_EXT_INTRA_MOD2
+ const int frac_bits_x = 6 - upsample_above;
+ const int frac_bits_y = 6 - upsample_left;
+#else
const int frac_bits_x = 8 - upsample_above;
const int frac_bits_y = 8 - upsample_left;
+#endif
const int base_inc_x = 1 << upsample_above;
x = -dx;
for (r = 0; r < bh; ++r, x -= dx, dst += stride) {
base1 = x >> frac_bits_x;
+#if CONFIG_EXT_INTRA_MOD2
+ y = (r << 6) - dy;
+#else
y = (r << 8) - dy;
+#endif
for (c = 0; c < bw; ++c, base1 += base_inc_x, y -= dy) {
if (base1 >= min_base_x) {
+#if CONFIG_EXT_INTRA_MOD2
+ shift1 = ((x * (1 << upsample_above)) & 0x3F) >> 1;
+ val = above[base1] * (32 - shift1) + above[base1 + 1] * shift1;
+ val = ROUND_POWER_OF_TWO(val, 5);
+#else
shift1 = (x * (1 << upsample_above)) & 0xFF;
val = above[base1] * (256 - shift1) + above[base1 + 1] * shift1;
val = ROUND_POWER_OF_TWO(val, 8);
+#endif
} else {
base2 = y >> frac_bits_y;
assert(base2 >= -(1 << upsample_left));
+#if CONFIG_EXT_INTRA_MOD2
+ shift2 = ((y * (1 << upsample_left)) & 0x3F) >> 1;
+ val = left[base2] * (32 - shift2) + left[base2 + 1] * shift2;
+ val = ROUND_POWER_OF_TWO(val, 5);
+#else
shift2 = (y * (1 << upsample_left)) & 0xFF;
val = left[base2] * (256 - shift2) + left[base2 + 1] * shift2;
val = ROUND_POWER_OF_TWO(val, 8);
+#endif
}
dst[c] = clip_pixel(val);
}
@@ -860,17 +894,30 @@
const int upsample_left = 0;
#endif // !CONFIG_INTRA_EDGE_UPSAMPLE
const int max_base_y = (bw + bh - 1) << upsample_left;
+#if CONFIG_EXT_INTRA_MOD2
+ const int frac_bits = 6 - upsample_left;
+#else
const int frac_bits = 8 - upsample_left;
+#endif
const int base_inc = 1 << upsample_left;
y = dy;
for (c = 0; c < bw; ++c, y += dy) {
base = y >> frac_bits;
+#if CONFIG_EXT_INTRA_MOD2
+ shift = ((y << upsample_left) & 0x3F) >> 1;
+#else
shift = (y << upsample_left) & 0xFF;
+#endif
for (r = 0; r < bh; ++r, base += base_inc) {
if (base < max_base_y) {
+#if CONFIG_EXT_INTRA_MOD2
+ val = left[base] * (32 - shift) + left[base + 1] * shift;
+ val = ROUND_POWER_OF_TWO(val, 5);
+#else
val = left[base] * (256 - shift) + left[base + 1] * shift;
val = ROUND_POWER_OF_TWO(val, 8);
+#endif
dst[r * stride + c] = clip_pixel(val);
} else {
for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
@@ -967,12 +1014,20 @@
const int upsample_above = 0;
#endif // !CONFIG_INTRA_EDGE_UPSAMPLE
const int max_base_x = ((bw + bh) - 1) << upsample_above;
+#if CONFIG_EXT_INTRA_MOD2
+ const int frac_bits = 6 - upsample_above;
+#else
const int frac_bits = 8 - upsample_above;
+#endif
const int base_inc = 1 << upsample_above;
x = dx;
for (r = 0; r < bh; ++r, dst += stride, x += dx) {
base = x >> frac_bits;
+#if CONFIG_EXT_INTRA_MOD2
+ shift = ((x << upsample_above) & 0x3F) >> 1;
+#else
shift = (x << upsample_above) & 0xFF;
+#endif
if (base >= max_base_x) {
for (int i = r; i < bh; ++i) {
@@ -984,8 +1039,13 @@
for (c = 0; c < bw; ++c, base += base_inc) {
if (base < max_base_x) {
+#if CONFIG_EXT_INTRA_MOD2
+ val = above[base] * (32 - shift) + above[base + 1] * shift;
+ val = ROUND_POWER_OF_TWO(val, 5);
+#else
val = above[base] * (256 - shift) + above[base + 1] * shift;
val = ROUND_POWER_OF_TWO(val, 8);
+#endif
dst[c] = clip_pixel_highbd(val, bd);
} else {
dst[c] = above[max_base_x];
@@ -1012,24 +1072,49 @@
const int upsample_left = 0;
#endif // !CONFIG_INTRA_EDGE_UPSAMPLE
const int min_base_x = -(1 << upsample_above);
+#if CONFIG_EXT_INTRA_MOD2
+ const int frac_bits_x = 6 - upsample_above;
+ const int frac_bits_y = 6 - upsample_left;
+#else
const int frac_bits_x = 8 - upsample_above;
const int frac_bits_y = 8 - upsample_left;
+#endif
for (r = 0; r < bh; ++r) {
for (c = 0; c < bw; ++c) {
y = r + 1;
+#if CONFIG_EXT_INTRA_MOD2
+ x = (c << 6) - y * dx;
+#else
x = (c << 8) - y * dx;
+#endif
base = x >> frac_bits_x;
if (base >= min_base_x) {
+#if CONFIG_EXT_INTRA_MOD2
+ shift = ((x * (1 << upsample_above)) & 0x3F) >> 1;
+ val = above[base] * (32 - shift) + above[base + 1] * shift;
+ val = ROUND_POWER_OF_TWO(val, 5);
+#else
shift = (x * (1 << upsample_above)) & 0xFF;
val = above[base] * (256 - shift) + above[base + 1] * shift;
val = ROUND_POWER_OF_TWO(val, 8);
+#endif
} else {
x = c + 1;
+#if CONFIG_EXT_INTRA_MOD2
+ y = (r << 6) - x * dy;
+#else
y = (r << 8) - x * dy;
+#endif
base = y >> frac_bits_y;
+#if CONFIG_EXT_INTRA_MOD2
+ shift = ((y * (1 << upsample_left)) & 0x3F) >> 1;
+ val = left[base] * (32 - shift) + left[base + 1] * shift;
+ val = ROUND_POWER_OF_TWO(val, 5);
+#else
shift = (y * (1 << upsample_left)) & 0xFF;
val = left[base] * (256 - shift) + left[base + 1] * shift;
val = ROUND_POWER_OF_TWO(val, 8);
+#endif
}
dst[c] = clip_pixel_highbd(val, bd);
}
@@ -1056,17 +1141,30 @@
const int upsample_left = 0;
#endif // !CONFIG_INTRA_EDGE_UPSAMPLE
const int max_base_y = (bw + bh - 1) << upsample_left;
+#if CONFIG_EXT_INTRA_MOD2
+ const int frac_bits = 6 - upsample_left;
+#else
const int frac_bits = 8 - upsample_left;
+#endif
const int base_inc = 1 << upsample_left;
y = dy;
for (c = 0; c < bw; ++c, y += dy) {
base = y >> frac_bits;
+#if CONFIG_EXT_INTRA_MOD2
+ shift = ((y << upsample_left) & 0x3F) >> 1;
+#else
shift = (y << upsample_left) & 0xFF;
+#endif
for (r = 0; r < bh; ++r, base += base_inc) {
if (base < max_base_y) {
+#if CONFIG_EXT_INTRA_MOD2
+ val = left[base] * (32 - shift) + left[base + 1] * shift;
+ val = ROUND_POWER_OF_TWO(val, 5);
+#else
val = left[base] * (256 - shift) + left[base + 1] * shift;
val = ROUND_POWER_OF_TWO(val, 8);
+#endif
dst[r * stride + c] = clip_pixel_highbd(val, bd);
} else {
for (; r < bh; ++r) dst[r * stride + c] = left[max_base_y];
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index 8564940..43d9e71 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -134,6 +134,7 @@
set(CONFIG_EXT_DELTA_Q 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EXT_INTRA 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EXT_INTRA_MOD 1 CACHE NUMBER "AV1 experiment flag.")
+set(CONFIG_EXT_INTRA_MOD2 0 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EXT_PARTITION 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EXT_PARTITION_TYPES 1 CACHE NUMBER "AV1 experiment flag.")
set(CONFIG_EXT_PARTITION_TYPES_AB 0 CACHE NUMBER "AV1 experiment flag.")
diff --git a/configure b/configure
index 0ffd515..a13efcf 100755
--- a/configure
+++ b/configure
@@ -259,6 +259,7 @@
filter_intra
intra_edge
ext_intra_mod
+ ext_intra_mod2
intrabc
new_quant
loop_restoration