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. Changes beyond the cherry-pick: - Deleted the line "cfg_.use_fixed_qp_offsets = 2;" because use_fixed_qp_offsets == 2 is not supported on the opaline branch. - Changed AOM_TUNE_IQ to AOM_TUNE_SSIM because AOM_TUNE_IQ cannot be used in good-quality mode on the opaline branch. Change-Id: Iaae2bed44a112ac16c11b8561024e5166587a9b6 (cherry picked from commit 4cc0867f261f46d00b2ddb27b4de70d8e8e4552e)
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c index fb6a13a..2ffd6ee 100644 --- a/av1/encoder/ethread.c +++ b/av1/encoder/ethread.c
@@ -834,9 +834,7 @@ 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 901bc12..4923d4e 100644 --- a/test/resize_test.cc +++ b/test/resize_test.cc
@@ -348,6 +348,67 @@ } #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_SSIM); + 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; + + 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 +1239,7 @@ 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,