aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Zern <jzern@google.com>2022-10-10 12:06:13 -0700
committerJames Zern <jzern@google.com>2022-10-31 12:51:13 -0700
commit454a764ae320171563937d7a6101487526716f31 (patch)
tree4dec0d179abf24b3fa620ceabab9f9ffa9bc9013
parent5ba4ac997025a70152e20f400bbccf6fd83bb0ea (diff)
downloadlibgav1-454a764ae320171563937d7a6101487526716f31.tar.gz
PostFilter: further extend right border w/msan
Optimized loop restoration may read into the next row's left border depending on the start of the last superblock and the size of the right border. This is safe as the post filter is applied after reconstruction is complete and the threaded implementations do not read from the left border. PiperOrigin-RevId: 480145288 Change-Id: Ia915ebd7a7f09924cb9c4bf550c3fd14f34ea437
-rw-r--r--src/post_filter/loop_restoration.cc6
-rw-r--r--src/post_filter/post_filter.cc27
2 files changed, 30 insertions, 3 deletions
diff --git a/src/post_filter/loop_restoration.cc b/src/post_filter/loop_restoration.cc
index 2e6982c..b5e1432 100644
--- a/src/post_filter/loop_restoration.cc
+++ b/src/post_filter/loop_restoration.cc
@@ -79,7 +79,13 @@ void PostFilter::ApplyLoopRestorationForOneRow(
bottom_border_stride = border_stride;
}
}
+#if LIBGAV1_MSAN
+ // The optimized loop filter may read past initialized values within the
+ // buffer.
+ RestorationBuffer restoration_buffer = {};
+#else
RestorationBuffer restoration_buffer;
+#endif
const LoopRestorationType type = restoration_info[unit_column].type;
assert(type == kLoopRestorationTypeSgrProj ||
type == kLoopRestorationTypeWiener);
diff --git a/src/post_filter/post_filter.cc b/src/post_filter/post_filter.cc
index bc71410..9745a01 100644
--- a/src/post_filter/post_filter.cc
+++ b/src/post_filter/post_filter.cc
@@ -372,17 +372,38 @@ void PostFilter::CopyBordersForOneSuperBlockRow(int row4x4, int sb4x4,
uint8_t* const start = (for_loop_restoration ? superres_buffer_[plane]
: frame_buffer_.data(plane)) +
row * stride;
- const int left_border = for_loop_restoration
+#if LIBGAV1_MSAN
+ const int right_padding =
+ (frame_buffer_.stride(plane) >> static_cast<int>(bitdepth_ > 8)) -
+ ((frame_buffer_.left_border(plane) + frame_buffer_.width(plane) +
+ frame_buffer_.right_border(plane)));
+ const int padded_right_border_size =
+ frame_buffer_.right_border(plane) + right_padding;
+ // The optimized loop restoration code may read into the next row's left
+ // border depending on the start of the last superblock and the size of the
+ // right border. This is safe as the post filter is applied after
+ // reconstruction is complete and the threaded implementations do not read
+ // from the left border.
+ const int left_border_overread =
+ (for_loop_restoration && padded_right_border_size < 64)
+ ? 63 - padded_right_border_size
+ : 0;
+ assert(!for_loop_restoration || left_border_overread == 0 ||
+ (frame_buffer_.bottom_border(plane) > 0 &&
+ left_border_overread <= frame_buffer_.left_border(plane)));
+ const int left_border = (for_loop_restoration && left_border_overread == 0)
? kRestorationHorizontalBorder
: frame_buffer_.left_border(plane);
-#if LIBGAV1_MSAN
// The optimized loop restoration code will overread the visible frame
// buffer into the right border. Extend the right boundary further to
// prevent msan warnings.
const int right_border = for_loop_restoration
- ? kRestorationHorizontalBorder + 16
+ ? std::min(padded_right_border_size, 63)
: frame_buffer_.right_border(plane);
#else
+ const int left_border = for_loop_restoration
+ ? kRestorationHorizontalBorder
+ : frame_buffer_.left_border(plane);
const int right_border = for_loop_restoration
? kRestorationHorizontalBorder
: frame_buffer_.right_border(plane);