diff options
author | James Zern <jzern@google.com> | 2022-10-10 12:06:13 -0700 |
---|---|---|
committer | James Zern <jzern@google.com> | 2022-10-31 12:51:13 -0700 |
commit | 454a764ae320171563937d7a6101487526716f31 (patch) | |
tree | 4dec0d179abf24b3fa620ceabab9f9ffa9bc9013 | |
parent | 5ba4ac997025a70152e20f400bbccf6fd83bb0ea (diff) | |
download | libgav1-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.cc | 6 | ||||
-rw-r--r-- | src/post_filter/post_filter.cc | 27 |
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); |