/* Copyright (C) 2023 Carl Hetherington This file is part of DCP-o-matic. DCP-o-matic is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. DCP-o-matic is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DCP-o-matic. If not, see . */ #include "lib/config.h" #include "lib/content_factory.h" #include "lib/dcp_film_encoder.h" #include "lib/dcp_transcode_job.h" #include "lib/encode_server_description.h" #include "lib/film.h" #ifdef DCPOMATIC_GROK #include "lib/grok/context.h" #endif #include "lib/j2k_encoder.h" #include "lib/job_manager.h" #include "lib/make_dcp.h" #include "lib/transcode_job.h" #include "test.h" #include #include #include #include #include using std::dynamic_pointer_cast; using std::list; BOOST_AUTO_TEST_CASE(local_threads_created_and_destroyed) { auto film = new_test_film("local_threads_created_and_destroyed", {}); Writer writer(film, {}, "foo"); J2KEncoder encoder(film, writer); encoder.remake_threads(32, 0, 0, {}); BOOST_CHECK_EQUAL(encoder._threads.size(), 32U); encoder.remake_threads(9, 0, 0, {}); BOOST_CHECK_EQUAL(encoder._threads.size(), 9U); encoder.end(); BOOST_CHECK_EQUAL(encoder._threads.size(), 0U); } BOOST_AUTO_TEST_CASE(remote_threads_created_and_destroyed) { auto film = new_test_film("remote_threads_created_and_destroyed", {}); Writer writer(film, {}, "foo"); J2KEncoder encoder(film, writer); list servers = { { "fred", 7, SERVER_LINK_VERSION }, { "jim", 2, SERVER_LINK_VERSION }, { "sheila", 14, SERVER_LINK_VERSION }, }; encoder.remake_threads(0, 0, 0, servers); BOOST_CHECK_EQUAL(encoder._threads.size(), 7U + 2U + 14U); servers = { { "fred", 7, SERVER_LINK_VERSION }, { "jim", 5, SERVER_LINK_VERSION }, { "sheila", 14, SERVER_LINK_VERSION }, }; encoder.remake_threads(0, 0, 0, servers); BOOST_CHECK_EQUAL(encoder._threads.size(), 7U + 5U + 14U); servers = { { "fred", 0, SERVER_LINK_VERSION }, { "jim", 0, SERVER_LINK_VERSION }, { "sheila", 11, SERVER_LINK_VERSION }, }; encoder.remake_threads(0, 0, 0, servers); BOOST_CHECK_EQUAL(encoder._threads.size(), 11U); } BOOST_AUTO_TEST_CASE(frames_not_lost_when_threads_disappear) { auto content = content_factory(TestPaths::private_data() / "clapperboard.mp4"); auto film = new_test_film("frames_not_lost", content); film->write_metadata(); auto job = make_dcp(film, TranscodeJob::ChangedBehaviour::IGNORE); auto encoder = dynamic_cast(dynamic_pointer_cast(job->_encoder)->_encoder.get()); while (JobManager::instance()->work_to_do()) { encoder->remake_threads((rand() % 7) + 1, 0, 0, {}); dcpomatic_sleep_seconds(1); } BOOST_CHECK(!JobManager::instance()->errors()); dcp::DCP dcp(film->dir(film->dcp_name())); dcp.read(); BOOST_REQUIRE_EQUAL(dcp.cpls().size(), 1U); BOOST_REQUIRE_EQUAL(dcp.cpls()[0]->reels().size(), 1U); BOOST_REQUIRE_EQUAL(dcp.cpls()[0]->reels()[0]->main_picture()->intrinsic_duration(), 423U); } #ifdef DCPOMATIC_GROK BOOST_AUTO_TEST_CASE(transcode_stops_when_gpu_enabled_with_no_gpu) { ConfigRestorer cr; grk_plugin::setMessengerLogger(new grk_plugin::GrokLogger("[GROK] ")); Config::instance()->set_gpu_type(Config::GPUType::GROK); auto content = content_factory(TestPaths::private_data() / "clapperboard.mp4"); auto film = new_test_film("transcode_stops_when_gpu_enabled_with_no_gpu", content); film->write_metadata(); auto job = make_dcp(film, TranscodeJob::ChangedBehaviour::IGNORE); int slept = 0; while (JobManager::instance()->work_to_do() && slept < 10) { dcpomatic_sleep_seconds(1); ++slept; } BOOST_REQUIRE(slept < 10); JobManager::drop(); } #endif