2 Copyright (C) 2013-2019 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.
37 #include "mono_picture_asset.h"
38 #include "stereo_picture_asset.h"
39 #include "picture_asset_writer.h"
40 #include "sound_asset_writer.h"
41 #include "sound_asset.h"
42 #include "atmos_asset.h"
46 #include "reel_mono_picture_asset.h"
47 #include "reel_stereo_picture_asset.h"
48 #include "reel_sound_asset.h"
49 #include "reel_atmos_asset.h"
50 #include <asdcp/KM_util.h>
52 #include <boost/test/unit_test.hpp>
55 using boost::shared_ptr;
57 static shared_ptr<dcp::DCP>
58 make_simple (boost::filesystem::path path)
60 /* Some known metadata */
61 dcp::XMLMetadata xml_meta;
62 xml_meta.annotation_text = "A Test DCP";
63 xml_meta.issuer = "OpenDCP 0.0.25";
64 xml_meta.creator = "OpenDCP 0.0.25";
65 xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
66 dcp::MXFMetadata mxf_meta;
67 mxf_meta.company_name = "OpenDCP";
68 mxf_meta.product_name = "OpenDCP";
69 mxf_meta.product_version = "0.0.25";
71 /* We're making build/test/DCP/dcp_test1 */
72 boost::filesystem::remove_all (path);
73 boost::filesystem::create_directories (path);
74 shared_ptr<dcp::DCP> d (new dcp::DCP (path));
75 shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
76 cpl->set_content_version_id ("urn:uuid:75ac29aa-42ac-1234-ecae-49251abefd11");
77 cpl->set_content_version_label_text ("content-version-label-text");
78 cpl->set_metadata (xml_meta);
80 shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset (dcp::Fraction (24, 1), dcp::SMPTE));
81 mp->set_metadata (mxf_meta);
82 shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write (path / "video.mxf", false);
83 dcp::File j2c ("test/data/32x32_red_square.j2c");
84 for (int i = 0; i < 24; ++i) {
85 picture_writer->write (j2c.data (), j2c.size ());
87 picture_writer->finalize ();
89 shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1, dcp::SMPTE));
90 ms->set_metadata (mxf_meta);
91 shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write (path / "audio.mxf");
95 SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
96 BOOST_CHECK (sndfile);
101 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
102 sound_writer->write (channels, N);
108 sound_writer->finalize ();
110 cpl->add (shared_ptr<dcp::Reel> (
112 shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mp, 0)),
113 shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0))
121 /** Test creation of a 2D SMPTE DCP from very simple inputs */
122 BOOST_AUTO_TEST_CASE (dcp_test1)
126 dcp::XMLMetadata xml_meta;
127 xml_meta.annotation_text = "Created by libdcp";
128 xml_meta.issuer = "OpenDCP 0.0.25";
129 xml_meta.creator = "OpenDCP 0.0.25";
130 xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
131 make_simple("build/test/DCP/dcp_test1")->write_xml (dcp::SMPTE, xml_meta);
132 /* build/test/DCP/dcp_test1 is checked against test/ref/DCP/dcp_test1 by run/tests */
135 /** Test creation of a 3D DCP from very simple inputs */
136 BOOST_AUTO_TEST_CASE (dcp_test2)
140 /* Some known metadata */
141 dcp::XMLMetadata xml_meta;
142 xml_meta.annotation_text = "A Test DCP";
143 xml_meta.issuer = "OpenDCP 0.0.25";
144 xml_meta.creator = "OpenDCP 0.0.25";
145 xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
146 dcp::MXFMetadata mxf_meta;
147 mxf_meta.company_name = "OpenDCP";
148 mxf_meta.product_name = "OpenDCP";
149 mxf_meta.product_version = "0.0.25";
151 /* We're making build/test/DCP/dcp_test2 */
152 boost::filesystem::remove_all ("build/test/DCP/dcp_test2");
153 boost::filesystem::create_directories ("build/test/DCP/dcp_test2");
154 dcp::DCP d ("build/test/DCP/dcp_test2");
155 shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
156 cpl->set_content_version_id ("urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
157 cpl->set_content_version_label_text ("81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
158 cpl->set_metadata (xml_meta);
160 shared_ptr<dcp::StereoPictureAsset> mp (new dcp::StereoPictureAsset (dcp::Fraction (24, 1), dcp::SMPTE));
161 mp->set_metadata (mxf_meta);
162 shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test2/video.mxf", false);
163 dcp::File j2c ("test/data/32x32_red_square.j2c");
164 for (int i = 0; i < 24; ++i) {
166 picture_writer->write (j2c.data (), j2c.size ());
168 picture_writer->write (j2c.data (), j2c.size ());
170 picture_writer->finalize ();
172 shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1, dcp::SMPTE));
173 ms->set_metadata (mxf_meta);
174 shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test2/audio.mxf");
178 SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
179 BOOST_CHECK (sndfile);
180 float buffer[4096*6];
182 channels[0] = buffer;
184 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
185 sound_writer->write (channels, N);
191 sound_writer->finalize ();
193 cpl->add (shared_ptr<dcp::Reel> (
195 shared_ptr<dcp::ReelStereoPictureAsset> (new dcp::ReelStereoPictureAsset (mp, 0)),
196 shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0))
202 xml_meta.annotation_text = "Created by libdcp";
203 d.write_xml (dcp::SMPTE, xml_meta);
205 /* build/test/DCP/dcp_test2 is checked against test/ref/DCP/dcp_test2 by run/tests */
209 note (dcp::NoteType, string)
214 /** Test comparison of a DCP with itself */
215 BOOST_AUTO_TEST_CASE (dcp_test3)
217 dcp::DCP A ("test/ref/DCP/dcp_test1");
219 dcp::DCP B ("test/ref/DCP/dcp_test1");
222 BOOST_CHECK (A.equals (B, dcp::EqualityOptions(), boost::bind (¬e, _1, _2)));
225 /** Test comparison of a DCP with a different DCP */
226 BOOST_AUTO_TEST_CASE (dcp_test4)
228 dcp::DCP A ("test/ref/DCP/dcp_test1");
230 dcp::DCP B ("test/ref/DCP/dcp_test2");
233 BOOST_CHECK (!A.equals (B, dcp::EqualityOptions(), boost::bind (¬e, _1, _2)));
236 /** Test creation of a 2D DCP with an Atmos track */
237 BOOST_AUTO_TEST_CASE (dcp_test5)
241 /* Some known metadata */
242 dcp::XMLMetadata xml_meta;
243 xml_meta.annotation_text = "A Test DCP";
244 xml_meta.issuer = "OpenDCP 0.0.25";
245 xml_meta.creator = "OpenDCP 0.0.25";
246 xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
247 dcp::MXFMetadata mxf_meta;
248 mxf_meta.company_name = "OpenDCP";
249 mxf_meta.product_name = "OpenDCP";
250 mxf_meta.product_version = "0.0.25";
252 /* We're making build/test/DCP/dcp_test5 */
253 boost::filesystem::remove_all ("build/test/DCP/dcp_test5");
254 boost::filesystem::create_directories ("build/test/DCP/dcp_test5");
255 dcp::DCP d ("build/test/DCP/dcp_test5");
256 shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
257 cpl->set_content_version_id ("urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
258 cpl->set_content_version_label_text ("81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
259 cpl->set_metadata (xml_meta);
261 shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset (dcp::Fraction (24, 1), dcp::SMPTE));
262 mp->set_metadata (mxf_meta);
263 shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test5/video.mxf", false);
264 dcp::File j2c ("test/data/32x32_red_square.j2c");
265 for (int i = 0; i < 24; ++i) {
266 picture_writer->write (j2c.data (), j2c.size ());
268 picture_writer->finalize ();
270 shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1, dcp::SMPTE));
271 ms->set_metadata (mxf_meta);
272 shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test5/audio.mxf");
276 SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
277 BOOST_CHECK (sndfile);
278 float buffer[4096*6];
280 channels[0] = buffer;
282 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
283 sound_writer->write (channels, N);
289 sound_writer->finalize ();
291 shared_ptr<dcp::AtmosAsset> am (new dcp::AtmosAsset (private_test / "20160218_NameOfFilm_FTR_OV_EN_A_dcs_r01.mxf"));
293 cpl->add (shared_ptr<dcp::Reel> (
295 shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mp, 0)),
296 shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0)),
297 shared_ptr<dcp::ReelSubtitleAsset> (),
298 shared_ptr<dcp::ReelMarkersAsset> (),
299 shared_ptr<dcp::ReelAtmosAsset> (new dcp::ReelAtmosAsset (am, 0))
305 xml_meta.annotation_text = "Created by libdcp";
306 d.write_xml (dcp::SMPTE, xml_meta);
308 /* build/test/DCP/dcp_test5 is checked against test/ref/DCP/dcp_test5 by run/tests */
311 /** Basic tests of reading a 2D DCP with an Atmos track */
312 BOOST_AUTO_TEST_CASE (dcp_test6)
314 dcp::DCP dcp ("test/ref/DCP/dcp_test5");
317 BOOST_REQUIRE_EQUAL (dcp.cpls().size(), 1);
318 BOOST_REQUIRE_EQUAL (dcp.cpls().front()->reels().size(), 1);
319 BOOST_CHECK (dcp.cpls().front()->reels().front()->main_picture());
320 BOOST_CHECK (dcp.cpls().front()->reels().front()->main_sound());
321 BOOST_CHECK (!dcp.cpls().front()->reels().front()->main_subtitle());
322 BOOST_CHECK (dcp.cpls().front()->reels().front()->atmos());
325 /** Test creation of a 2D Interop DCP from very simple inputs */
326 BOOST_AUTO_TEST_CASE (dcp_test7)
330 dcp::XMLMetadata xml_meta;
331 xml_meta.annotation_text = "Created by libdcp";
332 xml_meta.issuer = "OpenDCP 0.0.25";
333 xml_meta.creator = "OpenDCP 0.0.25";
334 xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
335 make_simple("build/test/DCP/dcp_test7")->write_xml (dcp::INTEROP, xml_meta);
336 /* build/test/DCP/dcp_test7 is checked against test/ref/DCP/dcp_test7 by run/tests */
339 /** Test reading of a DCP with multiple PKLs */
340 BOOST_AUTO_TEST_CASE (dcp_test8)
342 dcp::DCP dcp (private_test / "data/SMPTE_TST-B1PB2P_S_EN-EN-CCAP_5171-HI-VI_2K_ISDCF_20151123_DPPT_SMPTE_combo/");
345 BOOST_REQUIRE_EQUAL (dcp.cpls().size(), 2);