Move make_simple() into test.{cc,h}
[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
58 /** Test creation of a 2D SMPTE DCP from very simple inputs */
59 BOOST_AUTO_TEST_CASE (dcp_test1)
60 {
61         RNGFixer fixer;
62
63         dcp::XMLMetadata xml_meta;
64         xml_meta.annotation_text = "Created by libdcp";
65         xml_meta.issuer = "OpenDCP 0.0.25";
66         xml_meta.creator = "OpenDCP 0.0.25";
67         xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
68         make_simple("build/test/DCP/dcp_test1")->write_xml (dcp::SMPTE, xml_meta);
69         /* build/test/DCP/dcp_test1 is checked against test/ref/DCP/dcp_test1 by run/tests */
70 }
71
72 /** Test creation of a 3D DCP from very simple inputs */
73 BOOST_AUTO_TEST_CASE (dcp_test2)
74 {
75         RNGFixer fix;
76
77         /* Some known metadata */
78         dcp::XMLMetadata xml_meta;
79         xml_meta.annotation_text = "A Test DCP";
80         xml_meta.issuer = "OpenDCP 0.0.25";
81         xml_meta.creator = "OpenDCP 0.0.25";
82         xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
83         dcp::MXFMetadata mxf_meta;
84         mxf_meta.company_name = "OpenDCP";
85         mxf_meta.product_name = "OpenDCP";
86         mxf_meta.product_version = "0.0.25";
87
88         /* We're making build/test/DCP/dcp_test2 */
89         boost::filesystem::remove_all ("build/test/DCP/dcp_test2");
90         boost::filesystem::create_directories ("build/test/DCP/dcp_test2");
91         dcp::DCP d ("build/test/DCP/dcp_test2");
92         shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
93         cpl->set_content_version_id ("urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
94         cpl->set_content_version_label_text ("81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
95         cpl->set_metadata (xml_meta);
96
97         shared_ptr<dcp::StereoPictureAsset> mp (new dcp::StereoPictureAsset (dcp::Fraction (24, 1), dcp::SMPTE));
98         mp->set_metadata (mxf_meta);
99         shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test2/video.mxf", false);
100         dcp::File j2c ("test/data/32x32_red_square.j2c");
101         for (int i = 0; i < 24; ++i) {
102                 /* Left */
103                 picture_writer->write (j2c.data (), j2c.size ());
104                 /* Right */
105                 picture_writer->write (j2c.data (), j2c.size ());
106         }
107         picture_writer->finalize ();
108
109         shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1, dcp::SMPTE));
110         ms->set_metadata (mxf_meta);
111         shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test2/audio.mxf");
112
113         SF_INFO info;
114         info.format = 0;
115         SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
116         BOOST_CHECK (sndfile);
117         float buffer[4096*6];
118         float* channels[1];
119         channels[0] = buffer;
120         while (1) {
121                 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
122                 sound_writer->write (channels, N);
123                 if (N < 4096) {
124                         break;
125                 }
126         }
127
128         sound_writer->finalize ();
129
130         cpl->add (shared_ptr<dcp::Reel> (
131                           new dcp::Reel (
132                                   shared_ptr<dcp::ReelStereoPictureAsset> (new dcp::ReelStereoPictureAsset (mp, 0)),
133                                   shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0))
134                                   )
135                           ));
136
137         d.add (cpl);
138
139         xml_meta.annotation_text = "Created by libdcp";
140         d.write_xml (dcp::SMPTE, xml_meta);
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::XMLMetadata xml_meta;
180         xml_meta.annotation_text = "A Test DCP";
181         xml_meta.issuer = "OpenDCP 0.0.25";
182         xml_meta.creator = "OpenDCP 0.0.25";
183         xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
184         dcp::MXFMetadata mxf_meta;
185         mxf_meta.company_name = "OpenDCP";
186         mxf_meta.product_name = "OpenDCP";
187         mxf_meta.product_version = "0.0.25";
188
189         /* We're making build/test/DCP/dcp_test5 */
190         boost::filesystem::remove_all ("build/test/DCP/dcp_test5");
191         boost::filesystem::create_directories ("build/test/DCP/dcp_test5");
192         dcp::DCP d ("build/test/DCP/dcp_test5");
193         shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
194         cpl->set_content_version_id ("urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
195         cpl->set_content_version_label_text ("81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00");
196         cpl->set_metadata (xml_meta);
197
198         shared_ptr<dcp::MonoPictureAsset> mp (new dcp::MonoPictureAsset (dcp::Fraction (24, 1), dcp::SMPTE));
199         mp->set_metadata (mxf_meta);
200         shared_ptr<dcp::PictureAssetWriter> picture_writer = mp->start_write ("build/test/DCP/dcp_test5/video.mxf", false);
201         dcp::File j2c ("test/data/32x32_red_square.j2c");
202         for (int i = 0; i < 24; ++i) {
203                 picture_writer->write (j2c.data (), j2c.size ());
204         }
205         picture_writer->finalize ();
206
207         shared_ptr<dcp::SoundAsset> ms (new dcp::SoundAsset (dcp::Fraction (24, 1), 48000, 1, dcp::SMPTE));
208         ms->set_metadata (mxf_meta);
209         shared_ptr<dcp::SoundAssetWriter> sound_writer = ms->start_write ("build/test/DCP/dcp_test5/audio.mxf");
210
211         SF_INFO info;
212         info.format = 0;
213         SNDFILE* sndfile = sf_open ("test/data/1s_24-bit_48k_silence.wav", SFM_READ, &info);
214         BOOST_CHECK (sndfile);
215         float buffer[4096*6];
216         float* channels[1];
217         channels[0] = buffer;
218         while (true) {
219                 sf_count_t N = sf_readf_float (sndfile, buffer, 4096);
220                 sound_writer->write (channels, N);
221                 if (N < 4096) {
222                         break;
223                 }
224         }
225
226         sound_writer->finalize ();
227
228         shared_ptr<dcp::AtmosAsset> am (new dcp::AtmosAsset (private_test / "20160218_NameOfFilm_FTR_OV_EN_A_dcs_r01.mxf"));
229
230         cpl->add (shared_ptr<dcp::Reel> (
231                           new dcp::Reel (
232                                   shared_ptr<dcp::ReelMonoPictureAsset> (new dcp::ReelMonoPictureAsset (mp, 0)),
233                                   shared_ptr<dcp::ReelSoundAsset> (new dcp::ReelSoundAsset (ms, 0)),
234                                   shared_ptr<dcp::ReelSubtitleAsset> (),
235                                   shared_ptr<dcp::ReelMarkersAsset> (),
236                                   shared_ptr<dcp::ReelAtmosAsset> (new dcp::ReelAtmosAsset (am, 0))
237                                   )
238                           ));
239
240         d.add (cpl);
241
242         xml_meta.annotation_text = "Created by libdcp";
243         d.write_xml (dcp::SMPTE, xml_meta);
244
245         /* build/test/DCP/dcp_test5 is checked against test/ref/DCP/dcp_test5 by run/tests */
246 }
247
248 /** Basic tests of reading a 2D DCP with an Atmos track */
249 BOOST_AUTO_TEST_CASE (dcp_test6)
250 {
251         dcp::DCP dcp ("test/ref/DCP/dcp_test5");
252         dcp.read ();
253
254         BOOST_REQUIRE_EQUAL (dcp.cpls().size(), 1);
255         BOOST_REQUIRE_EQUAL (dcp.cpls().front()->reels().size(), 1);
256         BOOST_CHECK (dcp.cpls().front()->reels().front()->main_picture());
257         BOOST_CHECK (dcp.cpls().front()->reels().front()->main_sound());
258         BOOST_CHECK (!dcp.cpls().front()->reels().front()->main_subtitle());
259         BOOST_CHECK (dcp.cpls().front()->reels().front()->atmos());
260 }
261
262 /** Test creation of a 2D Interop DCP from very simple inputs */
263 BOOST_AUTO_TEST_CASE (dcp_test7)
264 {
265         RNGFixer fix;
266
267         dcp::XMLMetadata xml_meta;
268         xml_meta.annotation_text = "Created by libdcp";
269         xml_meta.issuer = "OpenDCP 0.0.25";
270         xml_meta.creator = "OpenDCP 0.0.25";
271         xml_meta.issue_date = "2012-07-17T04:45:18+00:00";
272         make_simple("build/test/DCP/dcp_test7")->write_xml (dcp::INTEROP, xml_meta);
273         /* build/test/DCP/dcp_test7 is checked against test/ref/DCP/dcp_test7 by run/tests */
274 }
275
276 /** Test reading of a DCP with multiple CPLs */
277 BOOST_AUTO_TEST_CASE (dcp_test8)
278 {
279         dcp::DCP dcp (private_test / "data/SMPTE_TST-B1PB2P_S_EN-EN-CCAP_5171-HI-VI_2K_ISDCF_20151123_DPPT_SMPTE_combo/");
280         dcp.read ();
281
282         BOOST_REQUIRE_EQUAL (dcp.cpls().size(), 2);
283 }