Move lpf thread data init to lpf_pipeline_mt_init() Add unit tests that trigger heap overflow. Bug: aomedia:3429 Change-Id: I6db5be04a2f961c96e6115e982beec50b345d087 (cherry picked from commit 826ce59b303ece48f1b0e8aff1f54998e445e32b)
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c index c0b0e30..209636d 100644 --- a/av1/encoder/ethread.c +++ b/av1/encoder/ethread.c
@@ -1314,16 +1314,10 @@ int num_workers) { MultiThreadInfo *const mt_info = &cpi->mt_info; AV1_COMMON *const cm = &cpi->common; - MACROBLOCKD *xd = &cpi->td.mb.e_mbd; for (int i = num_workers - 1; i >= 0; i--) { AVxWorker *const worker = &mt_info->workers[i]; EncWorkerData *const thread_data = &mt_info->tile_thr_data[i]; - // Initialize loopfilter data - thread_data->lf_sync = &mt_info->lf_row_sync; - thread_data->lf_data = &thread_data->lf_sync->lfdata[i]; - loop_filter_data_reset(thread_data->lf_data, &cm->cur_frame->buf, cm, xd); - worker->hook = hook; worker->data1 = thread_data; worker->data2 = NULL; @@ -1613,7 +1607,7 @@ } #endif -static void lpf_pipeline_mt_init(AV1_COMP *cpi) { +static void lpf_pipeline_mt_init(AV1_COMP *cpi, int num_workers) { // Pipelining of loop-filtering after encoding is enabled when loop-filter // level is chosen based on quantizer and frame type. It is disabled in case // of 'LOOPFILTER_SELECTIVELY' as the stats collected during encoding stage @@ -1624,18 +1618,20 @@ const int use_superres = av1_superres_scaled(cm); const int use_cdef = is_cdef_used(cm); const int use_restoration = is_restoration_used(cm); + MultiThreadInfo *const mt_info = &cpi->mt_info; + MACROBLOCKD *xd = &cpi->td.mb.e_mbd; const unsigned int skip_apply_postproc_filters = derive_skip_apply_postproc_filters(cpi, use_loopfilter, use_cdef, use_superres, use_restoration); - cpi->mt_info.pipeline_lpf_mt_with_enc = + mt_info->pipeline_lpf_mt_with_enc = (cpi->oxcf.mode == REALTIME) && (cpi->oxcf.speed >= 5) && (cpi->sf.lpf_sf.lpf_pick == LPF_PICK_FROM_Q) && (cpi->oxcf.algo_cfg.loopfilter_control != LOOPFILTER_SELECTIVELY) && !cpi->ppi->rtc_ref.non_reference_frame && !cm->features.allow_intrabc && ((skip_apply_postproc_filters & SKIP_APPLY_LOOPFILTER) == 0); - if (!cpi->mt_info.pipeline_lpf_mt_with_enc) return; + if (!mt_info->pipeline_lpf_mt_with_enc) return; set_postproc_filter_default_params(cm); @@ -1661,12 +1657,20 @@ av1_loop_filter_frame_init(cm, plane_start, plane_end); - assert(cpi->mt_info.num_mod_workers[MOD_ENC] == - cpi->mt_info.num_mod_workers[MOD_LPF]); + assert(mt_info->num_mod_workers[MOD_ENC] == + mt_info->num_mod_workers[MOD_LPF]); loop_filter_frame_mt_init(cm, start_mi_row, end_mi_row, planes_to_lf, - cpi->mt_info.num_mod_workers[MOD_LPF], - &cpi->mt_info.lf_row_sync, lpf_opt_level, + mt_info->num_mod_workers[MOD_LPF], + &mt_info->lf_row_sync, lpf_opt_level, cm->seq_params->mib_size_log2); + + for (int i = num_workers - 1; i >= 0; i--) { + EncWorkerData *const thread_data = &mt_info->tile_thr_data[i]; + // Initialize loopfilter data + thread_data->lf_sync = &mt_info->lf_row_sync; + thread_data->lf_data = &thread_data->lf_sync->lfdata[i]; + loop_filter_data_reset(thread_data->lf_data, &cm->cur_frame->buf, cm, xd); + } } } @@ -1701,7 +1705,9 @@ cpi->oxcf.algo_cfg.cdf_update_mode); } - lpf_pipeline_mt_init(cpi); + num_workers = AOMMIN(num_workers, mt_info->num_workers); + + lpf_pipeline_mt_init(cpi, num_workers); av1_init_tile_data(cpi); @@ -1731,8 +1737,6 @@ } } - num_workers = AOMMIN(num_workers, mt_info->num_workers); - assign_tile_to_thread(thread_id_to_tile_id, tile_cols * tile_rows, num_workers); prepare_enc_workers(cpi, enc_row_mt_worker_hook, num_workers);
diff --git a/test/resize_test.cc b/test/resize_test.cc index d015ff0..e21f4bf 100644 --- a/test/resize_test.cc +++ b/test/resize_test.cc
@@ -377,13 +377,15 @@ ::testing::Values(::libaom_test::kOnePassGood)); #endif +// Parameters: test mode, speed, threads class ResizeRealtimeTest - : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>, + : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode, int, + int>, public ::libaom_test::EncoderTest { protected: ResizeRealtimeTest() - : EncoderTest(GET_PARAM(0)), set_scale_mode_(false), - set_scale_mode2_(false) {} + : EncoderTest(GET_PARAM(0)), num_threads_(GET_PARAM(3)), + set_scale_mode_(false), set_scale_mode2_(false) {} virtual ~ResizeRealtimeTest() {} virtual void PreEncodeFrameHook(libaom_test::VideoSource *video, @@ -457,6 +459,7 @@ cfg_.rc_dropframe_thresh = 1; // Disable error_resilience mode. cfg_.g_error_resilient = 0; + cfg_.g_threads = num_threads_; // Run at low bitrate. cfg_.rc_target_bitrate = 200; // We use max(kInitialWidth, kInitialHeight) because during the test @@ -472,6 +475,7 @@ std::vector<FrameInfo> frame_info_list_; int set_cpu_used_; + int num_threads_; bool change_bitrate_; unsigned int frame_change_bitrate_; double mismatch_psnr_; @@ -864,7 +868,7 @@ ::testing::Values(::libaom_test::kRealTime)); AV1_INSTANTIATE_TEST_SUITE(ResizeRealtimeTest, ::testing::Values(::libaom_test::kRealTime), - ::testing::Range(6, 10)); + ::testing::Range(6, 10), ::testing::Values(1, 2, 4)); AV1_INSTANTIATE_TEST_SUITE(ResizeCspTest, ::testing::Values(::libaom_test::kRealTime));