2 Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <boost/filesystem.hpp>
27 #include "exceptions.h"
28 #include "subtitle_asset.h"
29 #include "picture_asset.h"
30 #include "sound_asset.h"
33 #define BOOST_TEST_DYN_LINK
34 #define BOOST_TEST_MODULE libdcp_test
35 #include <boost/test/unit_test.hpp>
40 using boost::shared_ptr;
45 return "test/data/32x32_red_square.j2c";
51 return "test/data/1s_24-bit_48k_silence.wav";
55 BOOST_AUTO_TEST_CASE (dcp_test)
57 Kumu::libdcp_test = true;
59 libdcp::Metadata* t = libdcp::Metadata::instance ();
60 t->issuer = "OpenDCP 0.0.25";
61 t->creator = "OpenDCP 0.0.25";
62 t->company_name = "OpenDCP";
63 t->product_name = "OpenDCP";
64 t->product_version = "0.0.25";
65 t->issue_date = "2012-07-17T04:45:18+00:00";
66 boost::filesystem::remove_all ("build/test/foo");
67 boost::filesystem::create_directories ("build/test/foo");
68 libdcp::DCP d ("build/test/foo");
69 shared_ptr<libdcp::CPL> cpl (new libdcp::CPL ("build/test/foo", "A Test DCP", libdcp::FEATURE, 24, 24));
71 shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset (
82 shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset (
92 cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
98 BOOST_AUTO_TEST_CASE (error_test)
100 libdcp::DCP d ("build/test/bar");
102 p.push_back ("frobozz");
104 BOOST_CHECK_THROW (new libdcp::MonoPictureAsset (p, "build/test/bar", "video.mxf", &d.Progress, 24, 24, 32, 32), libdcp::FileError);
105 BOOST_CHECK_THROW (new libdcp::SoundAsset (p, "build/test/bar", "audio.mxf", &d.Progress, 24, 24), libdcp::FileError);
108 BOOST_AUTO_TEST_CASE (read_dcp)
110 libdcp::DCP d ("test/ref/DCP");
113 list<shared_ptr<const libdcp::CPL> > cpls = d.cpls ();
114 BOOST_CHECK_EQUAL (cpls.size(), 1);
116 BOOST_CHECK_EQUAL (cpls.front()->name(), "A Test DCP");
117 BOOST_CHECK_EQUAL (cpls.front()->content_kind(), libdcp::FEATURE);
118 BOOST_CHECK_EQUAL (cpls.front()->frames_per_second(), 24);
119 BOOST_CHECK_EQUAL (cpls.front()->length(), 24);
122 BOOST_AUTO_TEST_CASE (subtitles1)
124 libdcp::SubtitleAsset subs ("test/data", "subs1.xml");
126 BOOST_CHECK_EQUAL (subs.language(), "French");
128 list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 6, 1));
129 BOOST_CHECK_EQUAL (s.size(), 1);
130 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
133 libdcp::Color (255, 255, 255),
135 libdcp::Time (0, 0, 5, 198),
136 libdcp::Time (0, 0, 7, 115),
139 "My jacket was Idi Amin's",
141 libdcp::Color (0, 0, 0),
142 libdcp::Time (0, 0, 0, 1),
143 libdcp::Time (0, 0, 0, 1)
146 s = subs.subtitles_at (libdcp::Time (0, 0, 7, 190));
147 BOOST_CHECK_EQUAL (s.size(), 2);
148 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
151 libdcp::Color (255, 255, 255),
153 libdcp::Time (0, 0, 7, 177),
154 libdcp::Time (0, 0, 11, 31),
157 "My corset was H.M. The Queen's",
159 libdcp::Color (0, 0, 0),
160 libdcp::Time (0, 0, 0, 1),
161 libdcp::Time (0, 0, 0, 1)
163 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
166 libdcp::Color (255, 255, 255),
168 libdcp::Time (0, 0, 7, 177),
169 libdcp::Time (0, 0, 11, 31),
172 "My large wonderbra",
174 libdcp::Color (0, 0, 0),
175 libdcp::Time (0, 0, 0, 1),
176 libdcp::Time (0, 0, 0, 1)
179 s = subs.subtitles_at (libdcp::Time (0, 0, 11, 95));
180 BOOST_CHECK_EQUAL (s.size(), 1);
181 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
184 libdcp::Color (255, 255, 255),
186 libdcp::Time (0, 0, 11, 94),
187 libdcp::Time (0, 0, 13, 63),
190 "Once belonged to the Shah",
192 libdcp::Color (0, 0, 0),
193 libdcp::Time (0, 0, 0, 1),
194 libdcp::Time (0, 0, 0, 1)
197 s = subs.subtitles_at (libdcp::Time (0, 0, 14, 42));
198 BOOST_CHECK_EQUAL (s.size(), 1);
199 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
202 libdcp::Color (255, 255, 255),
204 libdcp::Time (0, 0, 13, 104),
205 libdcp::Time (0, 0, 15, 177),
208 "And these are Roy Hattersley's jeans",
210 libdcp::Color (0, 0, 0),
211 libdcp::Time (0, 0, 0, 1),
212 libdcp::Time (0, 0, 0, 1)
216 BOOST_AUTO_TEST_CASE (subtitles2)
218 libdcp::SubtitleAsset subs ("test/data", "subs2.xml");
220 list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 42, 100));
221 BOOST_CHECK_EQUAL (s.size(), 2);
222 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
225 libdcp::Color (255, 255, 255),
227 libdcp::Time (0, 0, 41, 62),
228 libdcp::Time (0, 0, 43, 52),
231 "At afternoon tea with John Peel",
233 libdcp::Color (0, 0, 0),
234 libdcp::Time (0, 0, 0, 0),
235 libdcp::Time (0, 0, 0, 0)
237 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
240 libdcp::Color (255, 255, 255),
242 libdcp::Time (0, 0, 41, 62),
243 libdcp::Time (0, 0, 43, 52),
246 "I enquired if his accent was real",
248 libdcp::Color (0, 0, 0),
249 libdcp::Time (0, 0, 0, 0),
250 libdcp::Time (0, 0, 0, 0)
253 s = subs.subtitles_at (libdcp::Time (0, 0, 50, 50));
254 BOOST_CHECK_EQUAL (s.size(), 2);
255 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
258 libdcp::Color (255, 255, 255),
260 libdcp::Time (0, 0, 50, 42),
261 libdcp::Time (0, 0, 52, 21),
264 "He said \"out of the house",
266 libdcp::Color (0, 0, 0),
267 libdcp::Time (0, 0, 0, 0),
268 libdcp::Time (0, 0, 0, 0)
270 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
273 libdcp::Color (255, 255, 255),
275 libdcp::Time (0, 0, 50, 42),
276 libdcp::Time (0, 0, 52, 21),
279 "I'm incredibly scouse",
281 libdcp::Color (0, 0, 0),
282 libdcp::Time (0, 0, 0, 0),
283 libdcp::Time (0, 0, 0, 0)
286 s = subs.subtitles_at (libdcp::Time (0, 1, 2, 300));
287 BOOST_CHECK_EQUAL (s.size(), 2);
288 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
291 libdcp::Color (255, 255, 255),
293 libdcp::Time (0, 1, 2, 208),
294 libdcp::Time (0, 1, 4, 10),
297 "At home it depends how I feel.\"",
299 libdcp::Color (0, 0, 0),
300 libdcp::Time (0, 0, 0, 0),
301 libdcp::Time (0, 0, 0, 0)
303 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
306 libdcp::Color (255, 255, 255),
308 libdcp::Time (0, 1, 2, 208),
309 libdcp::Time (0, 1, 4, 10),
312 "I spent a long weekend in Brighton",
314 libdcp::Color (0, 0, 0),
315 libdcp::Time (0, 0, 0, 0),
316 libdcp::Time (0, 0, 0, 0)
319 s = subs.subtitles_at (libdcp::Time (0, 1, 15, 50));
320 BOOST_CHECK_EQUAL (s.size(), 2);
321 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
324 libdcp::Color (255, 255, 255),
326 libdcp::Time (0, 1, 15, 42),
327 libdcp::Time (0, 1, 16, 42),
330 "With the legendary Miss Enid Blyton",
332 libdcp::Color (0, 0, 0),
333 libdcp::Time (0, 0, 0, 0),
334 libdcp::Time (0, 0, 0, 0)
336 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
339 libdcp::Color (255, 255, 255),
341 libdcp::Time (0, 1, 15, 42),
342 libdcp::Time (0, 1, 16, 42),
345 "She said \"you be Noddy",
347 libdcp::Color (0, 0, 0),
348 libdcp::Time (0, 0, 0, 0),
349 libdcp::Time (0, 0, 0, 0)
352 s = subs.subtitles_at (libdcp::Time (0, 1, 27, 200));
353 BOOST_CHECK_EQUAL (s.size(), 2);
354 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
357 libdcp::Color (255, 255, 255),
359 libdcp::Time (0, 1, 27, 115),
360 libdcp::Time (0, 1, 28, 208),
363 "That curious creature the Sphinx",
365 libdcp::Color (0, 0, 0),
366 libdcp::Time (0, 0, 0, 0),
367 libdcp::Time (0, 0, 0, 0)
369 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
372 libdcp::Color (255, 255, 255),
374 libdcp::Time (0, 1, 27, 115),
375 libdcp::Time (0, 1, 28, 208),
378 "Is smarter than anyone thinks",
380 libdcp::Color (0, 0, 0),
381 libdcp::Time (0, 0, 0, 0),
382 libdcp::Time (0, 0, 0, 0)
385 s = subs.subtitles_at (libdcp::Time (0, 1, 42, 300));
386 BOOST_CHECK_EQUAL (s.size(), 2);
387 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
390 libdcp::Color (255, 255, 255),
392 libdcp::Time (0, 1, 42, 229),
393 libdcp::Time (0, 1, 45, 62),
396 "It sits there and smirks",
398 libdcp::Color (0, 0, 0),
399 libdcp::Time (0, 0, 0, 0),
400 libdcp::Time (0, 0, 0, 0)
402 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
405 libdcp::Color (255, 255, 255),
407 libdcp::Time (0, 1, 42, 229),
408 libdcp::Time (0, 1, 45, 62),
411 "And you don't think it works",
413 libdcp::Color (0, 0, 0),
414 libdcp::Time (0, 0, 0, 0),
415 libdcp::Time (0, 0, 0, 0)
418 s = subs.subtitles_at (libdcp::Time (0, 1, 45, 200));
419 BOOST_CHECK_EQUAL (s.size(), 2);
420 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
423 libdcp::Color (255, 255, 255),
425 libdcp::Time (0, 1, 45, 146),
426 libdcp::Time (0, 1, 47, 94),
429 "Then when you're not looking, it winks.",
431 libdcp::Color (0, 0, 0),
432 libdcp::Time (0, 0, 0, 0),
433 libdcp::Time (0, 0, 0, 0)
435 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
438 libdcp::Color (255, 255, 255),
440 libdcp::Time (0, 1, 45, 146),
441 libdcp::Time (0, 1, 47, 94),
444 "When it snows you will find Sister Sledge",
446 libdcp::Color (0, 0, 0),
447 libdcp::Time (0, 0, 0, 0),
448 libdcp::Time (0, 0, 0, 0)
451 s = subs.subtitles_at (libdcp::Time (0, 1, 47, 249));
452 BOOST_CHECK_EQUAL (s.size(), 2);
453 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
456 libdcp::Color (255, 255, 255),
458 libdcp::Time (0, 1, 47, 146),
459 libdcp::Time (0, 1, 48, 167),
462 "Out mooning, at night, on the ledge",
464 libdcp::Color (0, 0, 0),
465 libdcp::Time (0, 0, 0, 0),
466 libdcp::Time (0, 0, 0, 0)
468 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
471 libdcp::Color (255, 255, 255),
473 libdcp::Time (0, 1, 47, 146),
474 libdcp::Time (0, 1, 48, 167),
479 libdcp::Color (0, 0, 0),
480 libdcp::Time (0, 0, 0, 0),
481 libdcp::Time (0, 0, 0, 0)
484 s = subs.subtitles_at (libdcp::Time (0, 2, 6, 210));
485 BOOST_CHECK_EQUAL (s.size(), 2);
486 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
489 libdcp::Color (255, 255, 255),
491 libdcp::Time (0, 2, 5, 208),
492 libdcp::Time (0, 2, 7, 31),
497 libdcp::Color (0, 0, 0),
498 libdcp::Time (0, 0, 0, 0),
499 libdcp::Time (0, 0, 0, 0)
501 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
504 libdcp::Color (255, 255, 255),
506 libdcp::Time (0, 2, 5, 208),
507 libdcp::Time (0, 2, 7, 31),
512 libdcp::Color (0, 0, 0),
513 libdcp::Time (0, 0, 0, 0),
514 libdcp::Time (0, 0, 0, 0)
521 BOOST_AUTO_TEST_CASE (dcp_time)
523 libdcp::Time t (977143, 24);
525 BOOST_CHECK_EQUAL (t.t, 73);
526 BOOST_CHECK_EQUAL (t.s, 34);
527 BOOST_CHECK_EQUAL (t.m, 18);
528 BOOST_CHECK_EQUAL (t.h, 11);
529 BOOST_CHECK_EQUAL (t.to_string(), "11:18:34:73");
530 BOOST_CHECK_EQUAL (t.to_ticks(), 1017923);
532 libdcp::Time a (3, 2, 3, 4);
533 libdcp::Time b (2, 3, 4, 5);
535 libdcp::Time r = a - b;
536 BOOST_CHECK_EQUAL (r.h, 0);
537 BOOST_CHECK_EQUAL (r.m, 58);
538 BOOST_CHECK_EQUAL (r.s, 58);
539 BOOST_CHECK_EQUAL (r.t, 249);
540 BOOST_CHECK_EQUAL (r.to_string(), "0:58:58:249");
541 BOOST_CHECK_EQUAL (r.to_ticks(), 88699);
543 a = libdcp::Time (1, 58, 56, 240);
544 b = libdcp::Time (1, 7, 12, 120);
546 BOOST_CHECK_EQUAL (r.h, 3);
547 BOOST_CHECK_EQUAL (r.m, 6);
548 BOOST_CHECK_EQUAL (r.s, 9);
549 BOOST_CHECK_EQUAL (r.t, 110);
550 BOOST_CHECK_EQUAL (r.to_string(), "3:6:9:110");
551 BOOST_CHECK_EQUAL (r.to_ticks(), 279335);
553 a = libdcp::Time (24, 12, 6, 3);
554 b = libdcp::Time (16, 8, 4, 2);
555 BOOST_CHECK_CLOSE (a / b, 1.5, 1e-5);
558 BOOST_AUTO_TEST_CASE (color)
560 libdcp::Color c ("FFFF0000");
562 BOOST_CHECK_EQUAL (c.r, 255);
563 BOOST_CHECK_EQUAL (c.g, 0);
564 BOOST_CHECK_EQUAL (c.b, 0);
565 BOOST_CHECK_EQUAL (c.to_argb_string(), "FFFF0000");
567 c = libdcp::Color ("FF00FF00");
569 BOOST_CHECK_EQUAL (c.r, 0);
570 BOOST_CHECK_EQUAL (c.g, 255);
571 BOOST_CHECK_EQUAL (c.b, 0);
572 BOOST_CHECK_EQUAL (c.to_argb_string(), "FF00FF00");
574 c = libdcp::Color ("FF0000FF");
576 BOOST_CHECK_EQUAL (c.r, 0);
577 BOOST_CHECK_EQUAL (c.g, 0);
578 BOOST_CHECK_EQUAL (c.b, 255);
579 BOOST_CHECK_EQUAL (c.to_argb_string(), "FF0000FF");