2 Copyright (C) 2020 Carl Hetherington <cth@carlh.net>
4 This file is part of libdcp.
6 libdcp 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 libdcp 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 libdcp. If not, see <http://www.gnu.org/licenses/>.
19 In addition, as a special exception, the copyright holders give
20 permission to link the code of portions of this program with the
21 OpenSSL library under certain conditions as described in each
22 individual source file, and distribute linked combinations
25 You must obey the GNU General Public License in all respects
26 for all of the code used other than OpenSSL. If you modify
27 file(s) with this exception, you may extend this exception to your
28 version of the file(s), but you are not obligated to do so. If you
29 do not wish to do so, delete this exception statement from your
30 version. If you delete this exception statement from all source
31 files in the program, then also delete it here.
38 #include "interop_subtitle_asset.h"
39 #include "reel_subtitle_asset.h"
40 #include "reel_mono_picture_asset.h"
41 #include "reel_sound_asset.h"
45 #include <boost/algorithm/string.hpp>
46 #include <boost/foreach.hpp>
47 #include <boost/optional.hpp>
48 #include <boost/test/unit_test.hpp>
55 using boost::optional;
56 using boost::shared_ptr;
60 stage (string, optional<boost::filesystem::path>)
73 dump_notes (list<dcp::VerificationNote> const & notes)
75 BOOST_FOREACH (dcp::VerificationNote i, notes) {
76 std::cout << dcp::note_to_string(i) << "\n";
83 check_no_errors (boost::filesystem::path path)
85 vector<boost::filesystem::path> directories;
86 directories.push_back (path);
87 list<dcp::VerificationNote> notes = dcp::verify (directories, &stage, &progress, xsd_test);
89 BOOST_CHECK (notes.empty());
95 pointer_to_id_in_list (shared_ptr<T> needle, list<shared_ptr<T> > haystack)
97 BOOST_FOREACH (shared_ptr<T> i, haystack) {
98 if (i->id() == needle->id()) {
103 return shared_ptr<T>();
109 note_handler (dcp::NoteType, std::string)
111 // std::cout << "> " << n << "\n";
117 check_combined (vector<boost::filesystem::path> inputs, boost::filesystem::path output)
119 dcp::DCP output_dcp (output);
122 dcp::EqualityOptions options;
123 options.load_font_nodes_can_differ = true;
125 BOOST_FOREACH (boost::filesystem::path i, inputs)
127 dcp::DCP input_dcp (i);
130 BOOST_REQUIRE (input_dcp.cpls().size() == 1);
131 shared_ptr<dcp::CPL> input_cpl = input_dcp.cpls().front();
133 shared_ptr<dcp::CPL> output_cpl = pointer_to_id_in_list (input_cpl, output_dcp.cpls());
134 BOOST_REQUIRE (output_cpl);
136 BOOST_FOREACH (shared_ptr<dcp::Asset> i, input_dcp.assets(true)) {
137 shared_ptr<dcp::Asset> o = pointer_to_id_in_list(i, output_dcp.assets());
138 BOOST_REQUIRE_MESSAGE (o, "Could not find " << i->id() << " in combined DCP.");
139 BOOST_CHECK (i->equals(o, options, note_handler));
145 BOOST_AUTO_TEST_CASE (combine_single_dcp_test)
147 using namespace boost::algorithm;
148 using namespace boost::filesystem;
149 boost::filesystem::path const out = "build/test/combine_single_dcp_test";
153 inputs.push_back ("test/ref/DCP/dcp_test1");
154 dcp::combine (inputs, out);
156 check_no_errors (out);
157 check_combined (inputs, out);
161 BOOST_AUTO_TEST_CASE (combine_two_dcps_with_same_asset_filenames_test)
163 using namespace boost::algorithm;
164 using namespace boost::filesystem;
165 boost::filesystem::path const out = "build/test/combine_two_dcps_with_same_asset_filenames_test";
167 shared_ptr<dcp::DCP> second = make_simple ("build/test/combine_input2");
168 second->write_xml (dcp::SMPTE);
172 inputs.push_back ("test/ref/DCP/dcp_test1");
173 inputs.push_back ("build/test/combine_input2");
174 dcp::combine (inputs, out);
176 check_no_errors (out);
177 check_combined (inputs, out);
181 BOOST_AUTO_TEST_CASE (combine_two_dcps_with_interop_subs_test)
183 using namespace boost::algorithm;
184 using namespace boost::filesystem;
185 boost::filesystem::path const out = "build/test/combine_two_dcps_with_interop_subs_test";
187 shared_ptr<dcp::DCP> first = make_simple_with_interop_subs ("build/test/combine_input1");
188 first->write_xml (dcp::INTEROP);
190 shared_ptr<dcp::DCP> second = make_simple_with_interop_subs ("build/test/combine_input2");
191 second->write_xml (dcp::INTEROP);
195 inputs.push_back ("build/test/combine_input1");
196 inputs.push_back ("build/test/combine_input2");
197 dcp::combine (inputs, out);
199 check_no_errors (out);
200 check_combined (inputs, out);
204 BOOST_AUTO_TEST_CASE (combine_two_dcps_with_smpte_subs_test)
206 using namespace boost::algorithm;
207 using namespace boost::filesystem;
208 boost::filesystem::path const out = "build/test/combine_two_dcps_with_smpte_subs_test";
210 shared_ptr<dcp::DCP> first = make_simple_with_smpte_subs ("build/test/combine_input1");
211 first->write_xml (dcp::SMPTE);
213 shared_ptr<dcp::DCP> second = make_simple_with_smpte_subs ("build/test/combine_input2");
214 second->write_xml (dcp::SMPTE);
218 inputs.push_back ("build/test/combine_input1");
219 inputs.push_back ("build/test/combine_input2");
220 dcp::combine (inputs, out);
222 check_no_errors (out);
223 check_combined (inputs, out);
227 BOOST_AUTO_TEST_CASE (combine_two_dcps_with_interop_ccaps_test)
229 using namespace boost::algorithm;
230 using namespace boost::filesystem;
231 boost::filesystem::path const out = "build/test/combine_two_dcps_with_interop_ccaps_test";
233 shared_ptr<dcp::DCP> first = make_simple_with_interop_ccaps ("build/test/combine_input1");
234 first->write_xml (dcp::INTEROP);
236 shared_ptr<dcp::DCP> second = make_simple_with_interop_ccaps ("build/test/combine_input2");
237 second->write_xml (dcp::INTEROP);
241 inputs.push_back ("build/test/combine_input1");
242 inputs.push_back ("build/test/combine_input2");
243 dcp::combine (inputs, out);
245 check_no_errors (out);
246 check_combined (inputs, out);
250 BOOST_AUTO_TEST_CASE (combine_two_dcps_with_smpte_ccaps_test)
252 using namespace boost::algorithm;
253 using namespace boost::filesystem;
254 boost::filesystem::path const out = "build/test/combine_two_dcps_with_interop_ccaps_test";
256 shared_ptr<dcp::DCP> first = make_simple_with_smpte_ccaps ("build/test/combine_input1");
257 first->write_xml (dcp::SMPTE);
259 shared_ptr<dcp::DCP> second = make_simple_with_smpte_ccaps ("build/test/combine_input2");
260 second->write_xml (dcp::SMPTE);
264 inputs.push_back ("build/test/combine_input1");
265 inputs.push_back ("build/test/combine_input2");
266 dcp::combine (inputs, out);
268 check_no_errors (out);
269 check_combined (inputs, out);
273 BOOST_AUTO_TEST_CASE (combine_two_multi_reel_dcps)
275 using namespace boost::algorithm;
276 using namespace boost::filesystem;
277 boost::filesystem::path const out = "build/test/combine_two_multi_reel_dcps";
279 shared_ptr<dcp::DCP> first = make_simple ("build/test/combine_input1", 4);
280 first->write_xml (dcp::SMPTE);
282 shared_ptr<dcp::DCP> second = make_simple ("build/test/combine_input2", 4);
283 second->write_xml (dcp::SMPTE);
287 inputs.push_back ("build/test/combine_input1");
288 inputs.push_back ("build/test/combine_input2");
289 dcp::combine (inputs, out);
291 check_no_errors (out);
292 check_combined (inputs, out);
296 BOOST_AUTO_TEST_CASE (combine_two_dcps_with_shared_asset)
298 using namespace boost::filesystem;
299 boost::filesystem::path const out = "build/test/combine_two_dcps_with_shared_asset";
301 shared_ptr<dcp::DCP> first = make_simple ("build/test/combine_input1", 1);
302 first->write_xml (dcp::SMPTE);
304 remove_all ("build/test/combine_input2");
305 shared_ptr<dcp::DCP> second(new dcp::DCP("build/test/combine_input2"));
307 dcp::MXFMetadata mxf_meta;
308 mxf_meta.company_name = "OpenDCP";
309 mxf_meta.product_version = "0.0.25";
311 shared_ptr<dcp::CPL> cpl (new dcp::CPL("A Test DCP", dcp::FEATURE));
312 cpl->set_content_version (
313 dcp::ContentVersion("urn:uuid:75ac29aa-42ac-1234-ecae-49251abefd11","content-version-label-text")
316 shared_ptr<dcp::ReelMonoPictureAsset> pic(new dcp::ReelMonoPictureAsset(simple_picture("build/test/combine_input2", ""), 0));
317 shared_ptr<dcp::ReelSoundAsset> sound(new dcp::ReelSoundAsset(first->cpls().front()->reels().front()->main_sound()->asset(), 0));
318 cpl->add (shared_ptr<dcp::Reel>(new dcp::Reel(pic, sound)));
320 second->write_xml (dcp::SMPTE);
324 inputs.push_back ("build/test/combine_input1");
325 inputs.push_back ("build/test/combine_input2");
326 dcp::combine (inputs, out);
328 check_no_errors (out);
329 check_combined (inputs, out);
333 /* XXX: same CPL names */
334 /* XXX: Interop PNG subs */