Use Round2() in filter_intra_predictor functions
Document why it is safe to use Round2() instead of Round2Signed() in
av1_filter_intra_predictor_c() and highbd_filter_intra_predictor().
Document ROUND_POWER_OF_TWO() and ROUND_POWER_OF_TWO_64() are usually
used with value >= 0, but can also be used with a negative value.
Change-Id: I23c22bc4980138bca2345938761da1d0dea5dd03
diff --git a/aom_ports/mem.h b/aom_ports/mem.h
index 9e3d424..5eeed99 100644
--- a/aom_ports/mem.h
+++ b/aom_ports/mem.h
@@ -38,7 +38,10 @@
#define __builtin_prefetch(x)
#endif
-/* Shift down with rounding for use when n >= 0, value >= 0 */
+/* Shift down with rounding for use when n >= 0. Usually value >= 0, but the
+ * macro can be used with a negative value if the direction of rounding is
+ * acceptable.
+ */
#define ROUND_POWER_OF_TWO(value, n) (((value) + (((1 << (n)) >> 1))) >> (n))
/* Shift down with rounding for signed integers, for use when n >= 0 */
@@ -46,10 +49,15 @@
(((value) < 0) ? -ROUND_POWER_OF_TWO(-(value), (n)) \
: ROUND_POWER_OF_TWO((value), (n)))
-/* Shift down with rounding for use when n >= 0, value >= 0 for (64 bit) */
+/* Shift down with rounding for use when n >= 0 (64-bit value). Usually
+ * value >= 0, but the macro can be used with a negative value if the direction
+ * of rounding is acceptable.
+ */
#define ROUND_POWER_OF_TWO_64(value, n) \
(((value) + ((((int64_t)1 << (n)) >> 1))) >> (n))
-/* Shift down with rounding for signed integers, for use when n >= 0 (64 bit) */
+/* Shift down with rounding for signed integers, for use when n >= 0 (64-bit
+ * value)
+ */
#define ROUND_POWER_OF_TWO_SIGNED_64(value, n) \
(((value) < 0) ? -ROUND_POWER_OF_TWO_64(-(value), (n)) \
: ROUND_POWER_OF_TWO_64((value), (n)))
diff --git a/av1/common/reconintra.c b/av1/common/reconintra.c
index 90ad8b7..0c01f92 100644
--- a/av1/common/reconintra.c
+++ b/av1/common/reconintra.c
@@ -882,16 +882,19 @@
for (int k = 0; k < 8; ++k) {
int r_offset = k >> 2;
int c_offset = k & 0x03;
+ int pr = av1_filter_intra_taps[mode][k][0] * p0 +
+ av1_filter_intra_taps[mode][k][1] * p1 +
+ av1_filter_intra_taps[mode][k][2] * p2 +
+ av1_filter_intra_taps[mode][k][3] * p3 +
+ av1_filter_intra_taps[mode][k][4] * p4 +
+ av1_filter_intra_taps[mode][k][5] * p5 +
+ av1_filter_intra_taps[mode][k][6] * p6;
+ // Section 7.11.2.3 specifies the right-hand side of the assignment as
+ // Clip1( Round2Signed( pr, INTRA_FILTER_SCALE_BITS ) ).
+ // Since Clip1() clips a negative value to 0, it is safe to replace
+ // Round2Signed() with Round2().
buffer[r + r_offset][c + c_offset] =
- clip_pixel(ROUND_POWER_OF_TWO_SIGNED(
- av1_filter_intra_taps[mode][k][0] * p0 +
- av1_filter_intra_taps[mode][k][1] * p1 +
- av1_filter_intra_taps[mode][k][2] * p2 +
- av1_filter_intra_taps[mode][k][3] * p3 +
- av1_filter_intra_taps[mode][k][4] * p4 +
- av1_filter_intra_taps[mode][k][5] * p5 +
- av1_filter_intra_taps[mode][k][6] * p6,
- FILTER_INTRA_SCALE_BITS));
+ clip_pixel(ROUND_POWER_OF_TWO(pr, FILTER_INTRA_SCALE_BITS));
}
}
@@ -929,17 +932,19 @@
for (int k = 0; k < 8; ++k) {
int r_offset = k >> 2;
int c_offset = k & 0x03;
- buffer[r + r_offset][c + c_offset] =
- clip_pixel_highbd(ROUND_POWER_OF_TWO_SIGNED(
- av1_filter_intra_taps[mode][k][0] * p0 +
- av1_filter_intra_taps[mode][k][1] * p1 +
- av1_filter_intra_taps[mode][k][2] * p2 +
- av1_filter_intra_taps[mode][k][3] * p3 +
- av1_filter_intra_taps[mode][k][4] * p4 +
- av1_filter_intra_taps[mode][k][5] * p5 +
- av1_filter_intra_taps[mode][k][6] * p6,
- FILTER_INTRA_SCALE_BITS),
- bd);
+ int pr = av1_filter_intra_taps[mode][k][0] * p0 +
+ av1_filter_intra_taps[mode][k][1] * p1 +
+ av1_filter_intra_taps[mode][k][2] * p2 +
+ av1_filter_intra_taps[mode][k][3] * p3 +
+ av1_filter_intra_taps[mode][k][4] * p4 +
+ av1_filter_intra_taps[mode][k][5] * p5 +
+ av1_filter_intra_taps[mode][k][6] * p6;
+ // Section 7.11.2.3 specifies the right-hand side of the assignment as
+ // Clip1( Round2Signed( pr, INTRA_FILTER_SCALE_BITS ) ).
+ // Since Clip1() clips a negative value to 0, it is safe to replace
+ // Round2Signed() with Round2().
+ buffer[r + r_offset][c + c_offset] = clip_pixel_highbd(
+ ROUND_POWER_OF_TWO(pr, FILTER_INTRA_SCALE_BITS), bd);
}
}