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