Resolve issue 3491 BUG=aomedia:3491 Change-Id: I54916846c9dadc7263826c4d0dc8601880bab4fb
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index a3bd682..fe195f3 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -3126,8 +3126,10 @@ if (ppi->p_mt_info.prev_num_enc_workers < num_enc_workers && num_enc_workers <= ppi->p_mt_info.num_workers) { free_thread_data(ppi); - for (int j = 0; j < ppi->num_fp_contexts; j++) + for (int j = 0; j < ppi->num_fp_contexts; j++) { aom_free(ppi->parallel_cpi[j]->td.tctx); + ppi->parallel_cpi[j]->td.tctx = NULL; + } av1_init_tile_thread_data(ppi, cpi->oxcf.pass == AOM_RC_FIRST_PASS); }
diff --git a/av1/common/thread_common.c b/av1/common/thread_common.c index 54d78f7..c215ee7 100644 --- a/av1/common/thread_common.c +++ b/av1/common/thread_common.c
@@ -631,7 +631,7 @@ } // Deallocate loop restoration synchronization related mutex and data -void av1_loop_restoration_dealloc(AV1LrSync *lr_sync, int num_workers) { +void av1_loop_restoration_dealloc(AV1LrSync *lr_sync) { if (lr_sync != NULL) { int j; #if CONFIG_MULTITHREAD @@ -662,7 +662,8 @@ aom_free(lr_sync->job_queue); if (lr_sync->lrworkerdata) { - for (int worker_idx = 0; worker_idx < num_workers - 1; worker_idx++) { + for (int worker_idx = 0; worker_idx < lr_sync->num_workers - 1; + worker_idx++) { LRWorkerData *const workerdata_data = lr_sync->lrworkerdata + worker_idx; @@ -856,7 +857,7 @@ if (!lr_sync->sync_range || num_rows_lr > lr_sync->rows || num_workers > lr_sync->num_workers || num_planes > lr_sync->num_planes) { - av1_loop_restoration_dealloc(lr_sync, num_workers); + av1_loop_restoration_dealloc(lr_sync); av1_loop_restoration_alloc(lr_sync, cm, num_workers, num_rows_lr, num_planes, cm->width); }
diff --git a/av1/common/thread_common.h b/av1/common/thread_common.h index e38b9a8..cfbdc2f 100644 --- a/av1/common/thread_common.h +++ b/av1/common/thread_common.h
@@ -186,7 +186,7 @@ int optimized_lr, AVxWorker *workers, int num_workers, AV1LrSync *lr_sync, void *lr_ctxt, int do_extend_border); -void av1_loop_restoration_dealloc(AV1LrSync *lr_sync, int num_workers); +void av1_loop_restoration_dealloc(AV1LrSync *lr_sync); void av1_loop_restoration_alloc(AV1LrSync *lr_sync, AV1_COMMON *cm, int num_workers, int num_rows_lr, int num_planes, int width);
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c index 4559dc6..33554a6 100644 --- a/av1/decoder/decoder.c +++ b/av1/decoder/decoder.c
@@ -217,7 +217,7 @@ if (pbi->num_workers > 0) { av1_loop_filter_dealloc(&pbi->lf_row_sync); - av1_loop_restoration_dealloc(&pbi->lr_row_sync, pbi->num_workers); + av1_loop_restoration_dealloc(&pbi->lr_row_sync); av1_dealloc_dec_jobs(&pbi->tile_mt_info); }
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 3d2e8f8..9bb9482 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -1728,9 +1728,7 @@ av1_loop_filter_dealloc(&mt_info->lf_row_sync); av1_cdef_mt_dealloc(&mt_info->cdef_sync); #if !CONFIG_REALTIME_ONLY - int num_lr_workers = - av1_get_num_mod_workers_for_alloc(&cpi->ppi->p_mt_info, MOD_LR); - av1_loop_restoration_dealloc(&mt_info->lr_row_sync, num_lr_workers); + av1_loop_restoration_dealloc(&mt_info->lr_row_sync); av1_tf_mt_dealloc(&mt_info->tf_sync); #endif }
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c index fb9b85a..6f3cbd7 100644 --- a/av1/encoder/ethread.c +++ b/av1/encoder/ethread.c
@@ -896,7 +896,7 @@ if (!lr_sync->sync_range || num_rows_lr > lr_sync->rows || num_lr_workers > lr_sync->num_workers || MAX_MB_PLANE > lr_sync->num_planes) { - av1_loop_restoration_dealloc(lr_sync, num_lr_workers); + av1_loop_restoration_dealloc(lr_sync); av1_loop_restoration_alloc(lr_sync, cm, num_lr_workers, num_rows_lr, MAX_MB_PLANE, cm->width); } @@ -3273,7 +3273,8 @@ return AOMMIN(num_mb_rows, cpi->oxcf.max_threads); } -int compute_num_mod_workers(AV1_COMP *cpi, MULTI_THREADED_MODULES mod_name) { +static int compute_num_mod_workers(AV1_COMP *cpi, + MULTI_THREADED_MODULES mod_name) { int num_mod_workers = 0; switch (mod_name) { case MOD_FP: @@ -3313,7 +3314,8 @@ } // Computes the number of workers for each MT modules in the encoder void av1_compute_num_workers_for_mt(AV1_COMP *cpi) { - for (int i = MOD_FP; i < NUM_MT_MODULES; i++) + for (int i = MOD_FP; i < NUM_MT_MODULES; i++) { cpi->ppi->p_mt_info.num_mod_workers[i] = compute_num_mod_workers(cpi, (MULTI_THREADED_MODULES)i); + } }
diff --git a/test/resize_test.cc b/test/resize_test.cc index dbfabe0..8083163 100644 --- a/test/resize_test.cc +++ b/test/resize_test.cc
@@ -1054,4 +1054,91 @@ EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc)); } +TEST(ResizeSimpleTest, TemporarySmallerFrameSizeMultiThread) { + constexpr int kWidth = 512; + constexpr int kHeight = 512; + constexpr int kFirstWidth = 256; + constexpr int kFirstHeight = 256; + // Buffer of zero samples. + constexpr size_t kBufferSize = 3 * kWidth * kHeight; + std::vector<unsigned char> buffer(kBufferSize, static_cast<unsigned char>(0)); + + aom_image_t img1; + EXPECT_EQ(&img1, aom_img_wrap(&img1, AOM_IMG_FMT_I420, kFirstWidth, + kFirstHeight, 1, buffer.data())); + + aom_image_t img2; + EXPECT_EQ(&img2, aom_img_wrap(&img2, AOM_IMG_FMT_I420, kWidth, kHeight, 1, + buffer.data())); + + aom_codec_iface_t *iface = aom_codec_av1_cx(); + aom_codec_enc_cfg_t cfg; + EXPECT_EQ(AOM_CODEC_OK, + aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY)); + cfg.g_threads = 4; + cfg.g_lag_in_frames = 1; + cfg.g_w = kFirstWidth; + cfg.g_h = kFirstHeight; + cfg.g_forced_max_frame_width = kWidth; + cfg.g_forced_max_frame_height = kHeight; + aom_codec_ctx_t enc; + EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 6)); + + EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img1, 0, 1, 0)); + + cfg.g_w = kWidth; + cfg.g_h = kHeight; + EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_set(&enc, &cfg)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img2, 1, 1, 0)); + + EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 0, 0)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc)); +} + +// This test differs from "TemporarySmallerFrameSizeMultiThread" in that +// it changes the number of threads from 4 to 2 before coding the second frame. +TEST(ResizeSimpleTest, TemporarySmallerFrameSizeMultiThread2) { + constexpr int kWidth = 512; + constexpr int kHeight = 512; + constexpr int kFirstWidth = 256; + constexpr int kFirstHeight = 256; + // Buffer of zero samples. + constexpr size_t kBufferSize = 3 * kWidth * kHeight; + std::vector<unsigned char> buffer(kBufferSize, static_cast<unsigned char>(0)); + + aom_image_t img1; + EXPECT_EQ(&img1, aom_img_wrap(&img1, AOM_IMG_FMT_I420, kFirstWidth, + kFirstHeight, 1, buffer.data())); + + aom_image_t img2; + EXPECT_EQ(&img2, aom_img_wrap(&img2, AOM_IMG_FMT_I420, kWidth, kHeight, 1, + buffer.data())); + + aom_codec_iface_t *iface = aom_codec_av1_cx(); + aom_codec_enc_cfg_t cfg; + EXPECT_EQ(AOM_CODEC_OK, + aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY)); + cfg.g_threads = 4; + cfg.g_lag_in_frames = 1; + cfg.g_w = kFirstWidth; + cfg.g_h = kFirstHeight; + cfg.g_forced_max_frame_width = kWidth; + cfg.g_forced_max_frame_height = kHeight; + aom_codec_ctx_t enc; + EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 6)); + + EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img1, 0, 1, 0)); + + cfg.g_threads = 2; + cfg.g_w = kWidth; + cfg.g_h = kHeight; + EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_set(&enc, &cfg)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img2, 1, 1, 0)); + + EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 0, 0)); + EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc)); +} + } // namespace