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