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));