Fix parameters when running tests with valgrind.
[libdcp.git] / test / dcp_test.cc
1 /*
2     Copyright (C) 2013-2019 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 boost::shared_ptr;
56
57 static shared_ptr<dcp::DCP>
58 make_simple (boost::filesystem::path path)
59 {
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";
70
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);
79
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 ());
86         }
87         picture_writer->finalize ();
88
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");
92
93         SF_INFO info;
94         info.format = 0;
95         SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
96         BOOST_CHECK (sndfile);
97         float buffer[4096*6];
98         float* channels[1];
99         channels[0] = buffer;
100         while (1) {
101                 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
102                 sound_writer->write (channels, N);
103                 if (N < 4096) {
104                         break;
105                 }
106         }
107
108         sound_writer->finalize ();
109
110         cpl->add (shared_ptr<dcp::Reel> (
111                           new dcp::Reel (
112                                   shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mp, 0)),
113                                   shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0))
114                                   )
115                           ));
116
117         d->add (cpl);
118         return d;
119 }
120
121 /** Test creation of a 2D SMPTE DCP from very simple inputs */
122 BOOST_AUTO_TEST_CASE (dcp_test1)
123 {
124         RNGFixer fixer;
125
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 */
133 }
134
135 /** Test creation of a 3D DCP from very simple inputs */
136 BOOST_AUTO_TEST_CASE (dcp_test2)
137 {
138         RNGFixer fix;
139
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";
150
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);
159
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) {
165                 /* Left */
166                 picture_writer->write (j2c.data (), j2c.size ());
167                 /* Right */
168                 picture_writer->write (j2c.data (), j2c.size ());
169         }
170         picture_writer->finalize ();
171
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");
175
176         SF_INFO info;
177         info.format = 0;
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];
181         float* channels[1];
182         channels[0] = buffer;
183         while (1) {
184                 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
185                 sound_writer->write (channels, N);
186                 if (N < 4096) {
187                         break;
188                 }
189         }
190
191         sound_writer->finalize ();
192
193         cpl->add (shared_ptr<dcp::Reel> (
194                           new dcp::Reel (
195                                   shared_ptr<dcp::ReelStereoPictureAsset> (new dcp::ReelStereoPictureAsset (mp, 0)),
196                                   shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0))
197                                   )
198                           ));
199
200         d.add (cpl);
201
202         xml_meta.annotation_text = "Created by libdcp";
203         d.write_xml (dcp::SMPTE, xml_meta);
204
205         /* build/test/DCP/dcp_test2 is checked against test/ref/DCP/dcp_test2 by run/tests */
206 }
207
208 static void
209 note (dcp::NoteType, string)
210 {
211
212 }
213
214 /** Test comparison of a DCP with itself */
215 BOOST_AUTO_TEST_CASE (dcp_test3)
216 {
217         dcp::DCP A ("test/ref/DCP/dcp_test1");
218         A.read ();
219         dcp::DCP B ("test/ref/DCP/dcp_test1");
220         B.read ();
221
222         BOOST_CHECK (A.equals (B, dcp::EqualityOptions(), boost::bind (&note, _1, _2)));
223 }
224
225 /** Test comparison of a DCP with a different DCP */
226 BOOST_AUTO_TEST_CASE (dcp_test4)
227 {
228         dcp::DCP A ("test/ref/DCP/dcp_test1");
229         A.read ();
230         dcp::DCP B ("test/ref/DCP/dcp_test2");
231         B.read ();
232
233         BOOST_CHECK (!A.equals (B, dcp::EqualityOptions(), boost::bind (&note, _1, _2)));
234 }
235
236 /** Test creation of a 2D DCP with an Atmos track */
237 BOOST_AUTO_TEST_CASE (dcp_test5)
238 {
239         RNGFixer fix;
240
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";
251
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);
260
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 ());
267         }
268         picture_writer->finalize ();
269
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");
273
274         SF_INFO info;
275         info.format = 0;
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];
279         float* channels[1];
280         channels[0] = buffer;
281         while (true) {
282                 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
283                 sound_writer->write (channels, N);
284                 if (N < 4096) {
285                         break;
286                 }
287         }
288
289         sound_writer->finalize ();
290
291         shared_ptr<dcp::AtmosAsset> am (new dcp::AtmosAsset (private_test / "20160218_NameOfFilm_FTR_OV_EN_A_dcs_r01.mxf"));
292
293         cpl->add (shared_ptr<dcp::Reel> (
294                           new 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))
300                                   )
301                           ));
302
303         d.add (cpl);
304
305         xml_meta.annotation_text = "Created by libdcp";
306         d.write_xml (dcp::SMPTE, xml_meta);
307
308         /* build/test/DCP/dcp_test5 is checked against test/ref/DCP/dcp_test5 by run/tests */
309 }
310
311 /** Basic tests of reading a 2D DCP with an Atmos track */
312 BOOST_AUTO_TEST_CASE (dcp_test6)
313 {
314         dcp::DCP dcp ("test/ref/DCP/dcp_test5");
315         dcp.read ();
316
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());
323 }
324
325 /** Test creation of a 2D Interop DCP from very simple inputs */
326 BOOST_AUTO_TEST_CASE (dcp_test7)
327 {
328         RNGFixer fix;
329
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 */
337 }
338
339 /** Test reading of a DCP with multiple PKLs */
340 BOOST_AUTO_TEST_CASE (dcp_test8)
341 {
342         dcp::DCP dcp (private_test / "data/SMPTE_TST-B1PB2P_S_EN-EN-CCAP_5171-HI-VI_2K_ISDCF_20151123_DPPT_SMPTE_combo/");
343         dcp.read ();
344
345         BOOST_REQUIRE_EQUAL (dcp.cpls().size(), 2);
346 }