Commit 4cc0867f26 for aom
commit 4cc0867f261f46d00b2ddb27b4de70d8e8e4552e
Author: Julio Barba <juliobbv@gmail.com>
Date: Thu Mar 19 14:44:34 2026 -0400
Frame scaling loop restoration crash fix
`av1_init_lr_mt_buffers()`: Get the actual number of workers from
`lr_sync` struct instead of recomputing the value with
`av1_get_num_mod_workers_for_alloc()`, which might be incorrect.
Added unit test that verifies this fix.
Fix was proposed by Wan-Teh Chang.
Change-Id: Iaae2bed44a112ac16c11b8561024e5166587a9b6
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index 4f5fe5d5f9..636a4186fb 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -834,9 +834,7 @@ void av1_init_lr_mt_buffers(AV1_COMP *cpi) {
if (lr_sync->sync_range) {
if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0)
return;
- int num_lr_workers =
- av1_get_num_mod_workers_for_alloc(&cpi->ppi->p_mt_info, MOD_LR);
- assert(num_lr_workers <= lr_sync->num_workers);
+ int num_lr_workers = lr_sync->num_workers;
lr_sync->lrworkerdata[num_lr_workers - 1].rst_tmpbuf = cm->rst_tmpbuf;
lr_sync->lrworkerdata[num_lr_workers - 1].rlbs = cm->rlbs;
}
diff --git a/test/resize_test.cc b/test/resize_test.cc
index 901bc129b0..92369cd0ad 100644
--- a/test/resize_test.cc
+++ b/test/resize_test.cc
@@ -348,6 +348,68 @@ TEST_P(ResizeTest, TestExternalResizeWorks4Threads) {
}
#if !CONFIG_REALTIME_ONLY
+class ResizeCrashTest : public ::libaom_test::CodecTestWithParam<int>,
+ public ::libaom_test::EncoderTest {
+ protected:
+ ResizeCrashTest() : EncoderTest(GET_PARAM(0)) {}
+
+ ~ResizeCrashTest() override = default;
+
+ void SetUp() override {
+ cpu_used_ = GET_PARAM(1);
+
+ InitializeConfig(::libaom_test::kOnePassGood);
+ }
+
+ void PreEncodeFrameHook(libaom_test::VideoSource *video,
+ libaom_test::Encoder *encoder) override {
+ if (video->frame() == 0) {
+ encoder->Control(AOME_SET_CPUUSED, cpu_used_);
+ encoder->Control(AOME_SET_TUNING, AOM_TUNE_IQ);
+ encoder->Control(AOME_SET_CQ_LEVEL, first_frame_cq_level_);
+ encoder->Control(AV1E_SET_ROW_MT, 1);
+ encoder->Control(AV1E_SET_TILE_COLUMNS, first_tile_rows_cols_);
+ encoder->Control(AV1E_SET_TILE_ROWS, first_tile_rows_cols_);
+ encoder->Control(AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE);
+
+ struct aom_scaling_mode mode = { AOME_ONETWO, AOME_ONETWO };
+ encoder->Control(AOME_SET_SCALEMODE, &mode);
+ } else {
+ encoder->Control(AOME_SET_CQ_LEVEL, second_frame_cq_level_);
+ encoder->Control(AV1E_SET_TILE_COLUMNS, second_tile_rows_cols_);
+ encoder->Control(AV1E_SET_TILE_ROWS, second_tile_rows_cols_);
+ struct aom_scaling_mode mode = { AOME_NORMAL, AOME_NORMAL };
+ encoder->Control(AOME_SET_SCALEMODE, &mode);
+ }
+ }
+
+ int cpu_used_;
+ int first_frame_cq_level_;
+ int second_frame_cq_level_;
+ int first_tile_rows_cols_;
+ int second_tile_rows_cols_;
+};
+
+// Recreate the restoration filter crash that was
+// fixed by https://aomedia-review.googlesource.com/c/aom/+/208901
+TEST_P(ResizeCrashTest, TestRestorationFilterCrash) {
+ ::libaom_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 2);
+ cfg_.g_lag_in_frames = 0;
+ cfg_.g_profile = 1;
+ cfg_.g_bit_depth = AOM_BITS_8;
+ cfg_.g_input_bit_depth = 8;
+ cfg_.g_threads = 14;
+ cfg_.rc_end_usage = AOM_Q;
+ cfg_.use_fixed_qp_offsets = 2;
+
+ first_frame_cq_level_ = 59;
+ second_frame_cq_level_ = 59;
+ first_tile_rows_cols_ = 1;
+ second_tile_rows_cols_ = 0;
+
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+}
+
const unsigned int kStepDownFrame = 3;
const unsigned int kStepUpFrame = 6;
@@ -1178,6 +1240,7 @@ AV1_INSTANTIATE_TEST_SUITE(ResizeTest,
AV1_INSTANTIATE_TEST_SUITE(ResizeTest,
::testing::Values(::libaom_test::kRealTime,
::libaom_test::kOnePassGood));
+AV1_INSTANTIATE_TEST_SUITE(ResizeCrashTest, ::testing::Values(3));
#endif
AV1_INSTANTIATE_TEST_SUITE(ResizeRealtimeTest,