2 Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 #include "lib/version.h"
24 #include "lib/content_factory.h"
25 #include "lib/job_manager.h"
26 #include "lib/signal_manager.h"
28 #include "lib/dcp_content_type.h"
29 #include "lib/ratio.h"
30 #include "lib/image_content.h"
31 #include "lib/video_content.h"
32 #include "lib/cross.h"
33 #include "lib/config.h"
34 #include "lib/dcp_content.h"
35 #include "lib/create_cli.h"
36 #include "lib/version.h"
37 #include "lib/dcpomatic_log.h"
38 #include <dcp/exceptions.h>
39 #include <libxml++/libxml++.h>
40 #include <boost/filesystem.hpp>
41 #include <boost/foreach.hpp>
53 using boost::shared_ptr;
54 using boost::dynamic_pointer_cast;
55 using boost::optional;
57 class SimpleSignalManager : public SignalManager
60 /* Do nothing in this method so that UI events happen in our thread
61 when we call SignalManager::ui_idle().
67 main (int argc, char* argv[])
69 dcpomatic_setup_path_encoding ();
72 CreateCLI cc (argc, argv);
74 cerr << *cc.error << "\n";
79 cout << "dcpomatic version " << dcpomatic_version << " " << dcpomatic_git_commit << "\n";
84 State::override_path = *cc.config_dir;
87 signal_manager = new SimpleSignalManager ();
88 JobManager* jm = JobManager::instance ();
91 shared_ptr<Film> film (new Film(cc.output_dir));
92 dcpomatic_log = film->log ();
93 dcpomatic_log->set_types (Config::instance()->log_types());
94 if (cc.template_name) {
95 film->use_template (cc.template_name.get());
97 film->set_name (cc.name);
99 if (cc.container_ratio) {
100 film->set_container (cc.container_ratio);
102 film->set_dcp_content_type (cc.dcp_content_type);
103 film->set_interop (cc.standard == dcp::INTEROP);
104 film->set_use_isdcf_name (!cc.no_use_isdcf_name);
105 film->set_encrypted (cc.encrypt);
106 film->set_three_d (cc.threed);
108 film->set_resolution (RESOLUTION_4K);
110 if (cc.j2k_bandwidth) {
111 film->set_j2k_bandwidth (*cc.j2k_bandwidth);
114 BOOST_FOREACH (CreateCLI::Content i, cc.content) {
115 boost::filesystem::path const can = boost::filesystem::canonical (i.path);
116 list<shared_ptr<Content> > content;
118 if (boost::filesystem::exists (can / "ASSETMAP") || (boost::filesystem::exists (can / "ASSETMAP.xml"))) {
119 content.push_back (shared_ptr<DCPContent>(new DCPContent(can)));
121 /* I guess it's not a DCP */
122 content = content_factory (can);
125 BOOST_FOREACH (shared_ptr<Content> j, content) {
126 film->examine_and_add_content (j);
129 while (jm->work_to_do ()) {
130 dcpomatic_sleep_seconds (1);
133 while (signal_manager->ui_idle() > 0) {}
135 BOOST_FOREACH (shared_ptr<Content> j, content) {
137 j->video->set_frame_type (i.frame_type);
142 if (cc.dcp_frame_rate) {
143 film->set_video_frame_rate (*cc.dcp_frame_rate);
146 BOOST_FOREACH (shared_ptr<Content> i, film->content()) {
147 shared_ptr<ImageContent> ic = dynamic_pointer_cast<ImageContent> (i);
148 if (ic && ic->still()) {
149 ic->video->set_length (cc.still_length * 24);
154 BOOST_FOREACH (shared_ptr<Job> i, jm->get()) {
155 if (i->finished_in_error()) {
156 cerr << i->error_summary() << "\n"
157 << i->error_details() << "\n";
164 film->write_metadata ();
166 film->metadata()->write_to_stream_formatted(cout, "UTF-8");
168 } catch (exception& e) {
169 cerr << argv[0] << ": " << e.what() << "\n";