macOS / new boost build fixes.
[libdcp.git] / test / dcp_test.cc
1 /*
2     Copyright (C) 2013-2020 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
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.
10
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.
15
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/>.
18
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
23     including the two.
24
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.
32 */
33
34 #include "dcp.h"
35 #include "metadata.h"
36 #include "cpl.h"
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"
43 #include "reel.h"
44 #include "test.h"
45 #include "file.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>
51 #include <sndfile.h>
52 #include <boost/test/unit_test.hpp>
53
54 using std::string;
55 using std::vector;
56 using boost::shared_ptr;
57 #if BOOST_VERSION >= 106100
58 using namespace boost::placeholders;
59 #endif
60
61
62 /** Test creation of a 2D SMPTE DCP from very simple inputs */
63 BOOST_AUTO_TEST_CASE (dcp_test1)
64 {
65         RNGFixer fixer;
66
67         make_simple("build/test/DCP/dcp_test1")->write_xml(
68                 dcp::SMPTE, "OpenDCP 0.0.25", "OpenDCP 0.0.25", "2012-07-17T04:45:18+00:00", "Created by libdcp"
69                 );
70
71         /* build/test/DCP/dcp_test1 is checked against test/ref/DCP/dcp_test1 by run/tests */
72 }
73
74 /** Test creation of a 3D DCP from very simple inputs */
75 BOOST_AUTO_TEST_CASE (dcp_test2)
76 {
77         RNGFixer fix;
78
79         /* Some known metadata */
80         dcp::MXFMetadata mxf_meta;
81         mxf_meta.company_name = "OpenDCP";
82         mxf_meta.product_name = "OpenDCP";
83         mxf_meta.product_version = "0.0.25";
84
85         /* We're making build/test/DCP/dcp_test2 */
86         boost::filesystem::remove_all ("build/test/DCP/dcp_test2");
87         boost::filesystem::create_directories ("build/test/DCP/dcp_test2");
88         dcp::DCP d ("build/test/DCP/dcp_test2");
89         shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
90         cpl->set_content_version (
91                 dcp::ContentVersion("urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00", "81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00")
92                 );
93         cpl->set_issuer ("OpenDCP 0.0.25");
94         cpl->set_creator ("OpenDCP 0.0.25");
95         cpl->set_issue_date ("2012-07-17T04:45:18+00:00");
96         cpl->set_annotation_text ("A Test DCP");
97
98         shared_ptr<dcp::StereoPictureAsset> mp (new dcp::StereoPictureAsset (dcp::Fraction (24, 1), dcp::SMPTE));
99         mp->set_metadata (mxf_meta);
100         shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test2/video.mxf", false);
101         dcp::File j2c ("test/data/32x32_red_square.j2c");
102         for (int i = 0; i < 24; ++i) {
103                 /* Left */
104                 picture_writer->write (j2c.data (), j2c.size ());
105                 /* Right */
106                 picture_writer->write (j2c.data (), j2c.size ());
107         }
108         picture_writer->finalize ();
109
110         shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset(dcp::Fraction(24, 1), 48000, 1, dcp::LanguageTag("en-GB"), dcp::SMPTE));
111         ms->set_metadata (mxf_meta);
112         shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test2/audio.mxf", vector<dcp::Channel>());
113
114         SF_INFO info;
115         info.format = 0;
116         SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
117         BOOST_CHECK (sndfile);
118         float buffer[4096*6];
119         float* channels[1];
120         channels[0] = buffer;
121         while (1) {
122                 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
123                 sound_writer->write (channels, N);
124                 if (N < 4096) {
125                         break;
126                 }
127         }
128
129         sound_writer->finalize ();
130
131         cpl->add (shared_ptr<dcp::Reel> (
132                           new dcp::Reel (
133                                   shared_ptr<dcp::ReelStereoPictureAsset> (new dcp::ReelStereoPictureAsset (mp, 0)),
134                                   shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0))
135                                   )
136                           ));
137
138         d.add (cpl);
139
140         d.write_xml (dcp::SMPTE, "OpenDCP 0.0.25", "OpenDCP 0.0.25", "2012-07-17T04:45:18+00:00", "Created by libdcp");
141
142         /* build/test/DCP/dcp_test2 is checked against test/ref/DCP/dcp_test2 by run/tests */
143 }
144
145 static void
146 note (dcp::NoteType, string)
147 {
148
149 }
150
151 /** Test comparison of a DCP with itself */
152 BOOST_AUTO_TEST_CASE (dcp_test3)
153 {
154         dcp::DCP A ("test/ref/DCP/dcp_test1");
155         A.read ();
156         dcp::DCP B ("test/ref/DCP/dcp_test1");
157         B.read ();
158
159         BOOST_CHECK (A.equals (B, dcp::EqualityOptions(), boost::bind (&note, _1, _2)));
160 }
161
162 /** Test comparison of a DCP with a different DCP */
163 BOOST_AUTO_TEST_CASE (dcp_test4)
164 {
165         dcp::DCP A ("test/ref/DCP/dcp_test1");
166         A.read ();
167         dcp::DCP B ("test/ref/DCP/dcp_test2");
168         B.read ();
169
170         BOOST_CHECK (!A.equals (B, dcp::EqualityOptions(), boost::bind (&note, _1, _2)));
171 }
172
173 /** Test creation of a 2D DCP with an Atmos track */
174 BOOST_AUTO_TEST_CASE (dcp_test5)
175 {
176         RNGFixer fix;
177
178         /* Some known metadata */
179         dcp::MXFMetadata mxf_meta;
180         mxf_meta.company_name = "OpenDCP";
181         mxf_meta.product_name = "OpenDCP";
182         mxf_meta.product_version = "0.0.25";
183
184         /* We're making build/test/DCP/dcp_test5 */
185         boost::filesystem::remove_all ("build/test/DCP/dcp_test5");
186         boost::filesystem::create_directories ("build/test/DCP/dcp_test5");
187         dcp::DCP d ("build/test/DCP/dcp_test5");
188         shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
189         cpl->set_content_version (
190                 dcp::ContentVersion("urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00", "81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00")
191                 );
192         cpl->set_issuer ("OpenDCP 0.0.25");
193         cpl->set_creator ("OpenDCP 0.0.25");
194         cpl->set_issue_date ("2012-07-17T04:45:18+00:00");
195         cpl->set_annotation_text ("A Test DCP");
196
197         shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset (dcp::Fraction (24, 1), dcp::SMPTE));
198         mp->set_metadata (mxf_meta);
199         shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test5/video.mxf", false);
200         dcp::File j2c ("test/data/32x32_red_square.j2c");
201         for (int i = 0; i < 24; ++i) {
202                 picture_writer->write (j2c.data (), j2c.size ());
203         }
204         picture_writer->finalize ();
205
206         shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset(dcp::Fraction(24, 1), 48000, 1, dcp::LanguageTag("en-GB"), dcp::SMPTE));
207         ms->set_metadata (mxf_meta);
208         shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test5/audio.mxf", vector<dcp::Channel>());
209
210         SF_INFO info;
211         info.format = 0;
212         SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
213         BOOST_CHECK (sndfile);
214         float buffer[4096*6];
215         float* channels[1];
216         channels[0] = buffer;
217         while (true) {
218                 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
219                 sound_writer->write (channels, N);
220                 if (N < 4096) {
221                         break;
222                 }
223         }
224
225         sound_writer->finalize ();
226
227         shared_ptr<dcp::AtmosAsset> am (new dcp::AtmosAsset (private_test / "20160218_NameOfFilm_FTR_OV_EN_A_dcs_r01.mxf"));
228
229         cpl->add (shared_ptr<dcp::Reel> (
230                           new dcp::Reel (
231                                   shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mp, 0)),
232                                   shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0)),
233                                   shared_ptr<dcp::ReelSubtitleAsset> (),
234                                   shared_ptr<dcp::ReelMarkersAsset> (),
235                                   shared_ptr<dcp::ReelAtmosAsset> (new dcp::ReelAtmosAsset (am, 0))
236                                   )
237                           ));
238
239         d.add (cpl);
240
241         d.write_xml (dcp::SMPTE, "OpenDCP 0.0.25", "OpenDCP 0.0.25", "2012-07-17T04:45:18+00:00", "Created by libdcp");
242
243         /* build/test/DCP/dcp_test5 is checked against test/ref/DCP/dcp_test5 by run/tests */
244 }
245
246 /** Basic tests of reading a 2D DCP with an Atmos track */
247 BOOST_AUTO_TEST_CASE (dcp_test6)
248 {
249         dcp::DCP dcp ("test/ref/DCP/dcp_test5");
250         dcp.read ();
251
252         BOOST_REQUIRE_EQUAL (dcp.cpls().size(), 1);
253         BOOST_REQUIRE_EQUAL (dcp.cpls().front()->reels().size(), 1);
254         BOOST_CHECK (dcp.cpls().front()->reels().front()->main_picture());
255         BOOST_CHECK (dcp.cpls().front()->reels().front()->main_sound());
256         BOOST_CHECK (!dcp.cpls().front()->reels().front()->main_subtitle());
257         BOOST_CHECK (dcp.cpls().front()->reels().front()->atmos());
258 }
259
260 /** Test creation of a 2D Interop DCP from very simple inputs */
261 BOOST_AUTO_TEST_CASE (dcp_test7)
262 {
263         RNGFixer fix;
264
265         make_simple("build/test/DCP/dcp_test7")->write_xml(
266                 dcp::INTEROP,  "OpenDCP 0.0.25", "OpenDCP 0.0.25", "2012-07-17T04:45:18+00:00", "Created by libdcp"
267                 );
268
269         /* build/test/DCP/dcp_test7 is checked against test/ref/DCP/dcp_test7 by run/tests */
270 }
271
272 /** Test reading of a DCP with multiple CPLs */
273 BOOST_AUTO_TEST_CASE (dcp_test8)
274 {
275         dcp::DCP dcp (private_test / "data/SMPTE_TST-B1PB2P_S_EN-EN-CCAP_5171-HI-VI_2K_ISDCF_20151123_DPPT_SMPTE_combo/");
276         dcp.read ();
277
278         BOOST_REQUIRE_EQUAL (dcp.cpls().size(), 2);
279 }
280
281
282 /** Test reading a DCP whose ASSETMAP contains assets not used by any PKL */
283 BOOST_AUTO_TEST_CASE (dcp_things_in_assetmap_not_in_pkl)
284 {
285         dcp::DCP dcp ("test/data/extra_assetmap");
286         BOOST_CHECK_NO_THROW (dcp.read());
287 }