diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-03-19 17:07:26 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-03-19 20:50:22 +0100 |
| commit | 7c9fdd71ebe24ea926d90fc70ad8afa24719e6e0 (patch) | |
| tree | 838c85db7c6f53428fe5c512f494e8a7a09bf928 | |
| parent | cdf97239b1d5d4e6f8db7e909df9c5045fc4f65f (diff) | |
Move most of the create CLI into create_cli.cc to make it more testable.
| -rw-r--r-- | src/lib/create_cli.cc | 84 | ||||
| -rw-r--r-- | src/lib/create_cli.h | 2 | ||||
| -rw-r--r-- | src/tools/dcpomatic_create.cc | 87 | ||||
| -rw-r--r-- | test/create_cli_test.cc | 83 |
4 files changed, 145 insertions, 111 deletions
diff --git a/src/lib/create_cli.cc b/src/lib/create_cli.cc index de53600a0..c7a49ada9 100644 --- a/src/lib/create_cli.cc +++ b/src/lib/create_cli.cc @@ -19,21 +19,29 @@ */ +#include "audio_content.h" #include "compose.hpp" #include "config.h" +#include "content_factory.h" #include "create_cli.h" +#include "cross.h" +#include "dcp_content.h" #include "dcp_content_type.h" #include "dcpomatic_log.h" #include "film.h" +#include "image_content.h" +#include "job_manager.h" #include "ratio.h" #include "variant.h" +#include "video_content.h" #include <dcp/raw_convert.h> #include <fmt/format.h> #include <iostream> #include <string> -using std::cout; +using std::dynamic_pointer_cast; +using std::function; using std::make_shared; using std::shared_ptr; using std::string; @@ -386,7 +394,7 @@ CreateCLI::CreateCLI(int argc, char* argv[]) shared_ptr<Film> -CreateCLI::make_film() const +CreateCLI::make_film(function<void (string)> error) const { auto film = std::make_shared<Film>(output_dir); dcpomatic_log = film->log(); @@ -436,6 +444,78 @@ CreateCLI::make_film() const film->set_audio_channels(_audio_channels); + auto jm = JobManager::instance(); + + for (auto cli_content: content) { + auto const can = dcp::filesystem::canonical(cli_content.path); + vector<shared_ptr<::Content>> film_content_list; + + if (dcp::filesystem::exists(can / "ASSETMAP") || (dcp::filesystem::exists(can / "ASSETMAP.xml"))) { + auto dcp = make_shared<DCPContent>(can); + film_content_list.push_back(dcp); + if (cli_content.kdm) { + dcp->add_kdm(dcp::EncryptedKDM(dcp::file_to_string(*cli_content.kdm))); + } + if (cli_content.cpl) { + dcp->set_cpl(*cli_content.cpl); + } + } else { + /* I guess it's not a DCP */ + film_content_list = content_factory(can); + } + + for (auto film_content: film_content_list) { + film->examine_and_add_content(film_content); + } + + while (jm->work_to_do()) { + dcpomatic_sleep_seconds(1); + } + + while (signal_manager->ui_idle() > 0) {} + + for (auto film_content: film_content_list) { + if (film_content->video) { + film_content->video->set_frame_type(cli_content.frame_type); + } + if (film_content->audio && cli_content.channel) { + for (auto stream: film_content->audio->streams()) { + AudioMapping mapping(stream->channels(), film->audio_channels()); + for (int channel = 0; channel < stream->channels(); ++channel) { + mapping.set(channel, *cli_content.channel, 1.0f); + } + stream->set_mapping(mapping); + } + } + if (film_content->audio && cli_content.gain) { + film_content->audio->set_gain(*cli_content.gain); + } + } + } + + if (dcp_frame_rate) { + film->set_video_frame_rate(*dcp_frame_rate); + } + + for (auto i: film->content()) { + auto ic = dynamic_pointer_cast<ImageContent>(i); + if (ic && ic->still()) { + ic->video->set_length(still_length.get_value_or(10) * 24); + } + } + + if (jm->errors()) { + for (auto i: jm->get()) { + if (i->finished_in_error()) { + error(fmt::format("{}\n", i->error_summary())); + if (!i->error_details().empty()) { + error(fmt::format("{}\n", i->error_details())); + } + } + } + return {}; + } + return film; } diff --git a/src/lib/create_cli.h b/src/lib/create_cli.h index 18115b4ca..0c4d97b6c 100644 --- a/src/lib/create_cli.h +++ b/src/lib/create_cli.h @@ -55,7 +55,7 @@ public: boost::optional<std::string> error; std::vector<Content> content; - std::shared_ptr<Film> make_film() const; + std::shared_ptr<Film> make_film(std::function<void (std::string)> error) const; private: friend struct ::create_cli_test; diff --git a/src/tools/dcpomatic_create.cc b/src/tools/dcpomatic_create.cc index e0d5b3973..44bed75a9 100644 --- a/src/tools/dcpomatic_create.cc +++ b/src/tools/dcpomatic_create.cc @@ -18,23 +18,14 @@ */ -#include "lib/audio_content.h" -#include "lib/config.h" -#include "lib/content_factory.h" + #include "lib/create_cli.h" #include "lib/cross.h" -#include "lib/dcp_content.h" -#include "lib/dcp_content_type.h" #include "lib/film.h" -#include "lib/image_content.h" -#include "lib/job.h" -#include "lib/job_manager.h" -#include "lib/ratio.h" #include "lib/signal_manager.h" +#include "lib/state.h" #include "lib/util.h" #include "lib/version.h" -#include "lib/version.h" -#include "lib/video_content.h" #include <dcp/exceptions.h> #include <dcp/filesystem.h> #include <libxml++/libxml++.h> @@ -91,79 +82,11 @@ main (int argc, char* argv[]) } signal_manager = new SimpleSignalManager (); - auto jm = JobManager::instance (); try { - auto film = cc.make_film(); - - for (auto cli_content: cc.content) { - auto const can = dcp::filesystem::canonical(cli_content.path); - vector<shared_ptr<Content>> film_content_list; - - if (dcp::filesystem::exists(can / "ASSETMAP") || (dcp::filesystem::exists(can / "ASSETMAP.xml"))) { - auto dcp = make_shared<DCPContent>(can); - film_content_list.push_back (dcp); - if (cli_content.kdm) { - dcp->add_kdm (dcp::EncryptedKDM(dcp::file_to_string(*cli_content.kdm))); - } - if (cli_content.cpl) { - dcp->set_cpl(*cli_content.cpl); - } - } else { - /* I guess it's not a DCP */ - film_content_list = content_factory (can); - } - - for (auto film_content: film_content_list) { - film->examine_and_add_content (film_content); - } - - while (jm->work_to_do ()) { - dcpomatic_sleep_seconds (1); - } - - while (signal_manager->ui_idle() > 0) {} - - for (auto film_content: film_content_list) { - if (film_content->video) { - film_content->video->set_frame_type (cli_content.frame_type); - } - if (film_content->audio && cli_content.channel) { - for (auto stream: film_content->audio->streams()) { - AudioMapping mapping(stream->channels(), film->audio_channels()); - for (int channel = 0; channel < stream->channels(); ++channel) { - mapping.set(channel, *cli_content.channel, 1.0f); - } - stream->set_mapping (mapping); - } - } - if (film_content->audio && cli_content.gain) { - film_content->audio->set_gain (*cli_content.gain); - } - } - } - - if (cc.dcp_frame_rate) { - film->set_video_frame_rate (*cc.dcp_frame_rate); - } - - for (auto i: film->content()) { - auto ic = dynamic_pointer_cast<ImageContent> (i); - if (ic && ic->still()) { - ic->video->set_length(cc.still_length.get_value_or(10) * 24); - } - } - - if (jm->errors ()) { - for (auto i: jm->get()) { - if (i->finished_in_error()) { - cerr << i->error_summary() << "\n"; - if (!i->error_details().empty()) { - cout << i->error_details() << "\n"; - } - } - } - exit (EXIT_FAILURE); + auto film = cc.make_film([](string s) { cerr << s; }); + if (!film) { + exit(EXIT_FAILURE); } if (cc.output_dir) { diff --git a/test/create_cli_test.cc b/test/create_cli_test.cc index ac184203d..9716fbef3 100644 --- a/test/create_cli_test.cc +++ b/test/create_cli_test.cc @@ -60,6 +60,11 @@ run (string cmd) BOOST_AUTO_TEST_CASE (create_cli_test) { + string collected_error; + auto error = [&collected_error](string s) { + collected_error += s; + }; + CreateCLI cc = run ("dcpomatic2_create --version"); BOOST_CHECK (!cc.error); BOOST_CHECK (cc.version); @@ -73,12 +78,14 @@ BOOST_AUTO_TEST_CASE (create_cli_test) cc = run ("dcpomatic2_create -h"); BOOST_REQUIRE (cc.error); + BOOST_CHECK(collected_error.empty()); cc = run ("dcpomatic2_create x --name frobozz --template bar"); BOOST_CHECK (!cc.error); BOOST_CHECK_EQUAL(cc._name, "frobozz"); BOOST_REQUIRE(cc._template_name); BOOST_CHECK_EQUAL(*cc._template_name, "bar"); + BOOST_CHECK(collected_error.empty()); cc = run ("dcpomatic2_create x --dcp-content-type FTR"); BOOST_CHECK (!cc.error); @@ -186,18 +193,19 @@ BOOST_AUTO_TEST_CASE (create_cli_test) BOOST_CHECK_EQUAL(*cc._video_bit_rate, 120000000); BOOST_CHECK (!cc.error); - cc = run ("dcpomatic2_create --channel L fred.wav --channel R jim.wav sheila.wav"); + cc = run ("dcpomatic2_create --channel L test/data/L.wav --channel R test/data/R.wav test/data/Lfe.wav"); BOOST_REQUIRE_EQUAL (cc.content.size(), 3U); - BOOST_CHECK_EQUAL (cc.content[0].path, "fred.wav"); + BOOST_CHECK_EQUAL (cc.content[0].path, "test/data/L.wav"); BOOST_CHECK (cc.content[0].channel); BOOST_CHECK (*cc.content[0].channel == dcp::Channel::LEFT); - BOOST_CHECK_EQUAL (cc.content[1].path, "jim.wav"); + BOOST_CHECK_EQUAL (cc.content[1].path, "test/data/R.wav"); BOOST_CHECK (cc.content[1].channel); BOOST_CHECK (*cc.content[1].channel == dcp::Channel::RIGHT); - BOOST_CHECK_EQUAL (cc.content[2].path, "sheila.wav"); + BOOST_CHECK_EQUAL (cc.content[2].path, "test/data/Lfe.wav"); BOOST_CHECK (!cc.content[2].channel); - auto film = cc.make_film(); + auto film = cc.make_film(out, error); BOOST_CHECK_EQUAL(film->audio_channels(), 6); + BOOST_CHECK(collected_error.empty()); cc = run ("dcpomatic2_create --channel foo fred.wav"); BOOST_REQUIRE (cc.error); @@ -230,20 +238,23 @@ BOOST_AUTO_TEST_CASE (create_cli_test) BOOST_REQUIRE(cc.error); BOOST_CHECK_EQUAL(*cc.error, "dcpomatic2_create: audio channel count must be even"); - cc = run("dcpomatic2_create --channel L fred.wav --channel R jim.wav --channel C sheila.wav"); + cc = run("dcpomatic2_create --channel L test/data/L.wav --channel R test/data/R.wav --channel C test/data/C.wav"); BOOST_CHECK(!cc.error); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK_EQUAL(film->audio_channels(), 6); + BOOST_CHECK(collected_error.empty()); - cc = run("dcpomatic2_create --channel L fred.wav --channel R jim.wav --channel HI sheila.wav"); + cc = run("dcpomatic2_create --channel L test/data/L.wav --channel R test/data/R.wav --channel HI test/data/sine_440.wav"); BOOST_CHECK(!cc.error); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK_EQUAL(film->audio_channels(), 8); + BOOST_CHECK(collected_error.empty()); - cc = run("dcpomatic2_create --channel L fred.wav --channel R jim.wav --channel C sheila.wav --audio-channels 16"); + cc = run("dcpomatic2_create --channel L test/data/L.wav --channel R test/data/R.wav --channel C test/data/C.wav --audio-channels 16"); BOOST_CHECK(!cc.error); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK_EQUAL(film->audio_channels(), 16); + BOOST_CHECK(collected_error.empty()); } @@ -251,63 +262,83 @@ BOOST_AUTO_TEST_CASE(create_cli_template_test) { ConfigRestorer cr("test/data"); + string collected_error; + auto error = [&collected_error](string s) { + collected_error += s; + }; + auto cc = run("dcpomatic2_create test/data/flat_red.png"); - auto film = cc.make_film(); + auto film = cc.make_film(error); BOOST_CHECK(!film->three_d()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template 2d"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(!film->three_d()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template 2d --threed"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(film->three_d()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template 3d"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(film->three_d()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template 3d --twod"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(!film->three_d()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(!film->encrypted()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template unencrypted"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(!film->encrypted()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template unencrypted --encrypt"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(film->encrypted()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template encrypted"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(film->encrypted()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template encrypted --no-encrypt"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(!film->encrypted()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(!film->interop()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template interop"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(film->interop()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template interop --standard SMPTE"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(!film->interop()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template smpte"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(!film->interop()); + BOOST_CHECK(collected_error.empty()); cc = run("dcpomatic2_create test/data/flat_red.png --template smpte --standard interop"); - film = cc.make_film(); + film = cc.make_film(error); BOOST_CHECK(film->interop()); + BOOST_CHECK(collected_error.empty()); } |
