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 (
93 cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
99 BOOST_AUTO_TEST_CASE (error_test)
101 libdcp::DCP d ("build/test/bar");
103 p.push_back ("frobozz");
105 BOOST_CHECK_THROW (new libdcp::MonoPictureAsset (p, "build/test/bar", "video.mxf", &d.Progress, 24, 24, 32, 32), libdcp::FileError);
106 BOOST_CHECK_THROW (new libdcp::SoundAsset (p, "build/test/bar", "audio.mxf", &d.Progress, 24, 24, 0), libdcp::FileError);
109 BOOST_AUTO_TEST_CASE (read_dcp)
111 libdcp::DCP d ("test/ref/DCP");
114 list<shared_ptr<const libdcp::CPL> > cpls = d.cpls ();
115 BOOST_CHECK_EQUAL (cpls.size(), 1);
117 BOOST_CHECK_EQUAL (cpls.front()->name(), "A Test DCP");
118 BOOST_CHECK_EQUAL (cpls.front()->content_kind(), libdcp::FEATURE);
119 BOOST_CHECK_EQUAL (cpls.front()->frames_per_second(), 24);
120 BOOST_CHECK_EQUAL (cpls.front()->length(), 24);
123 BOOST_AUTO_TEST_CASE (subtitles1)
125 libdcp::SubtitleAsset subs ("test/data", "subs1.xml");
127 BOOST_CHECK_EQUAL (subs.language(), "French");
129 list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 6, 1));
130 BOOST_CHECK_EQUAL (s.size(), 1);
131 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
134 libdcp::Color (255, 255, 255),
136 libdcp::Time (0, 0, 5, 198),
137 libdcp::Time (0, 0, 7, 115),
140 "My jacket was Idi Amin's",
142 libdcp::Color (0, 0, 0),
143 libdcp::Time (0, 0, 0, 1),
144 libdcp::Time (0, 0, 0, 1)
147 s = subs.subtitles_at (libdcp::Time (0, 0, 7, 190));
148 BOOST_CHECK_EQUAL (s.size(), 2);
149 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
152 libdcp::Color (255, 255, 255),
154 libdcp::Time (0, 0, 7, 177),
155 libdcp::Time (0, 0, 11, 31),
158 "My corset was H.M. The Queen's",
160 libdcp::Color (0, 0, 0),
161 libdcp::Time (0, 0, 0, 1),
162 libdcp::Time (0, 0, 0, 1)
164 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
167 libdcp::Color (255, 255, 255),
169 libdcp::Time (0, 0, 7, 177),
170 libdcp::Time (0, 0, 11, 31),
173 "My large wonderbra",
175 libdcp::Color (0, 0, 0),
176 libdcp::Time (0, 0, 0, 1),
177 libdcp::Time (0, 0, 0, 1)
180 s = subs.subtitles_at (libdcp::Time (0, 0, 11, 95));
181 BOOST_CHECK_EQUAL (s.size(), 1);
182 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
185 libdcp::Color (255, 255, 255),
187 libdcp::Time (0, 0, 11, 94),
188 libdcp::Time (0, 0, 13, 63),
191 "Once belonged to the Shah",
193 libdcp::Color (0, 0, 0),
194 libdcp::Time (0, 0, 0, 1),
195 libdcp::Time (0, 0, 0, 1)
198 s = subs.subtitles_at (libdcp::Time (0, 0, 14, 42));
199 BOOST_CHECK_EQUAL (s.size(), 1);
200 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
203 libdcp::Color (255, 255, 255),
205 libdcp::Time (0, 0, 13, 104),
206 libdcp::Time (0, 0, 15, 177),
209 "And these are Roy Hattersley's jeans",
211 libdcp::Color (0, 0, 0),
212 libdcp::Time (0, 0, 0, 1),
213 libdcp::Time (0, 0, 0, 1)
217 BOOST_AUTO_TEST_CASE (subtitles2)
219 libdcp::SubtitleAsset subs ("test/data", "subs2.xml");
221 list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 42, 100));
222 BOOST_CHECK_EQUAL (s.size(), 2);
223 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
226 libdcp::Color (255, 255, 255),
228 libdcp::Time (0, 0, 41, 62),
229 libdcp::Time (0, 0, 43, 52),
232 "At afternoon tea with John Peel",
234 libdcp::Color (0, 0, 0),
235 libdcp::Time (0, 0, 0, 0),
236 libdcp::Time (0, 0, 0, 0)
238 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
241 libdcp::Color (255, 255, 255),
243 libdcp::Time (0, 0, 41, 62),
244 libdcp::Time (0, 0, 43, 52),
247 "I enquired if his accent was real",
249 libdcp::Color (0, 0, 0),
250 libdcp::Time (0, 0, 0, 0),
251 libdcp::Time (0, 0, 0, 0)
254 s = subs.subtitles_at (libdcp::Time (0, 0, 50, 50));
255 BOOST_CHECK_EQUAL (s.size(), 2);
256 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
259 libdcp::Color (255, 255, 255),
261 libdcp::Time (0, 0, 50, 42),
262 libdcp::Time (0, 0, 52, 21),
265 "He said \"out of the house",
267 libdcp::Color (0, 0, 0),
268 libdcp::Time (0, 0, 0, 0),
269 libdcp::Time (0, 0, 0, 0)
271 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
274 libdcp::Color (255, 255, 255),
276 libdcp::Time (0, 0, 50, 42),
277 libdcp::Time (0, 0, 52, 21),
280 "I'm incredibly scouse",
282 libdcp::Color (0, 0, 0),
283 libdcp::Time (0, 0, 0, 0),
284 libdcp::Time (0, 0, 0, 0)
287 s = subs.subtitles_at (libdcp::Time (0, 1, 2, 300));
288 BOOST_CHECK_EQUAL (s.size(), 2);
289 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
292 libdcp::Color (255, 255, 255),
294 libdcp::Time (0, 1, 2, 208),
295 libdcp::Time (0, 1, 4, 10),
298 "At home it depends how I feel.\"",
300 libdcp::Color (0, 0, 0),
301 libdcp::Time (0, 0, 0, 0),
302 libdcp::Time (0, 0, 0, 0)
304 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
307 libdcp::Color (255, 255, 255),
309 libdcp::Time (0, 1, 2, 208),
310 libdcp::Time (0, 1, 4, 10),
313 "I spent a long weekend in Brighton",
315 libdcp::Color (0, 0, 0),
316 libdcp::Time (0, 0, 0, 0),
317 libdcp::Time (0, 0, 0, 0)
320 s = subs.subtitles_at (libdcp::Time (0, 1, 15, 50));
321 BOOST_CHECK_EQUAL (s.size(), 2);
322 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
325 libdcp::Color (255, 255, 255),
327 libdcp::Time (0, 1, 15, 42),
328 libdcp::Time (0, 1, 16, 42),
331 "With the legendary Miss Enid Blyton",
333 libdcp::Color (0, 0, 0),
334 libdcp::Time (0, 0, 0, 0),
335 libdcp::Time (0, 0, 0, 0)
337 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
340 libdcp::Color (255, 255, 255),
342 libdcp::Time (0, 1, 15, 42),
343 libdcp::Time (0, 1, 16, 42),
346 "She said \"you be Noddy",
348 libdcp::Color (0, 0, 0),
349 libdcp::Time (0, 0, 0, 0),
350 libdcp::Time (0, 0, 0, 0)
353 s = subs.subtitles_at (libdcp::Time (0, 1, 27, 200));
354 BOOST_CHECK_EQUAL (s.size(), 2);
355 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
358 libdcp::Color (255, 255, 255),
360 libdcp::Time (0, 1, 27, 115),
361 libdcp::Time (0, 1, 28, 208),
364 "That curious creature the Sphinx",
366 libdcp::Color (0, 0, 0),
367 libdcp::Time (0, 0, 0, 0),
368 libdcp::Time (0, 0, 0, 0)
370 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
373 libdcp::Color (255, 255, 255),
375 libdcp::Time (0, 1, 27, 115),
376 libdcp::Time (0, 1, 28, 208),
379 "Is smarter than anyone thinks",
381 libdcp::Color (0, 0, 0),
382 libdcp::Time (0, 0, 0, 0),
383 libdcp::Time (0, 0, 0, 0)
386 s = subs.subtitles_at (libdcp::Time (0, 1, 42, 300));
387 BOOST_CHECK_EQUAL (s.size(), 2);
388 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
391 libdcp::Color (255, 255, 255),
393 libdcp::Time (0, 1, 42, 229),
394 libdcp::Time (0, 1, 45, 62),
397 "It sits there and smirks",
399 libdcp::Color (0, 0, 0),
400 libdcp::Time (0, 0, 0, 0),
401 libdcp::Time (0, 0, 0, 0)
403 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
406 libdcp::Color (255, 255, 255),
408 libdcp::Time (0, 1, 42, 229),
409 libdcp::Time (0, 1, 45, 62),
412 "And you don't think it works",
414 libdcp::Color (0, 0, 0),
415 libdcp::Time (0, 0, 0, 0),
416 libdcp::Time (0, 0, 0, 0)
419 s = subs.subtitles_at (libdcp::Time (0, 1, 45, 200));
420 BOOST_CHECK_EQUAL (s.size(), 2);
421 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
424 libdcp::Color (255, 255, 255),
426 libdcp::Time (0, 1, 45, 146),
427 libdcp::Time (0, 1, 47, 94),
430 "Then when you're not looking, it winks.",
432 libdcp::Color (0, 0, 0),
433 libdcp::Time (0, 0, 0, 0),
434 libdcp::Time (0, 0, 0, 0)
436 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
439 libdcp::Color (255, 255, 255),
441 libdcp::Time (0, 1, 45, 146),
442 libdcp::Time (0, 1, 47, 94),
445 "When it snows you will find Sister Sledge",
447 libdcp::Color (0, 0, 0),
448 libdcp::Time (0, 0, 0, 0),
449 libdcp::Time (0, 0, 0, 0)
452 s = subs.subtitles_at (libdcp::Time (0, 1, 47, 249));
453 BOOST_CHECK_EQUAL (s.size(), 2);
454 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
457 libdcp::Color (255, 255, 255),
459 libdcp::Time (0, 1, 47, 146),
460 libdcp::Time (0, 1, 48, 167),
463 "Out mooning, at night, on the ledge",
465 libdcp::Color (0, 0, 0),
466 libdcp::Time (0, 0, 0, 0),
467 libdcp::Time (0, 0, 0, 0)
469 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
472 libdcp::Color (255, 255, 255),
474 libdcp::Time (0, 1, 47, 146),
475 libdcp::Time (0, 1, 48, 167),
480 libdcp::Color (0, 0, 0),
481 libdcp::Time (0, 0, 0, 0),
482 libdcp::Time (0, 0, 0, 0)
485 s = subs.subtitles_at (libdcp::Time (0, 2, 6, 210));
486 BOOST_CHECK_EQUAL (s.size(), 2);
487 BOOST_CHECK_EQUAL (*(s.front().get()), libdcp::Subtitle (
490 libdcp::Color (255, 255, 255),
492 libdcp::Time (0, 2, 5, 208),
493 libdcp::Time (0, 2, 7, 31),
498 libdcp::Color (0, 0, 0),
499 libdcp::Time (0, 0, 0, 0),
500 libdcp::Time (0, 0, 0, 0)
502 BOOST_CHECK_EQUAL (*(s.back().get()), libdcp::Subtitle (
505 libdcp::Color (255, 255, 255),
507 libdcp::Time (0, 2, 5, 208),
508 libdcp::Time (0, 2, 7, 31),
513 libdcp::Color (0, 0, 0),
514 libdcp::Time (0, 0, 0, 0),
515 libdcp::Time (0, 0, 0, 0)
522 BOOST_AUTO_TEST_CASE (dcp_time)
524 libdcp::Time t (977143, 24);
526 BOOST_CHECK_EQUAL (t.t, 73);
527 BOOST_CHECK_EQUAL (t.s, 34);
528 BOOST_CHECK_EQUAL (t.m, 18);
529 BOOST_CHECK_EQUAL (t.h, 11);
530 BOOST_CHECK_EQUAL (t.to_string(), "11:18:34:73");
531 BOOST_CHECK_EQUAL (t.to_ticks(), 1017923);
533 libdcp::Time a (3, 2, 3, 4);
534 libdcp::Time b (2, 3, 4, 5);
536 libdcp::Time r = a - b;
537 BOOST_CHECK_EQUAL (r.h, 0);
538 BOOST_CHECK_EQUAL (r.m, 58);
539 BOOST_CHECK_EQUAL (r.s, 58);
540 BOOST_CHECK_EQUAL (r.t, 249);
541 BOOST_CHECK_EQUAL (r.to_string(), "0:58:58:249");
542 BOOST_CHECK_EQUAL (r.to_ticks(), 88699);
544 a = libdcp::Time (1, 58, 56, 240);
545 b = libdcp::Time (1, 7, 12, 120);
547 BOOST_CHECK_EQUAL (r.h, 3);
548 BOOST_CHECK_EQUAL (r.m, 6);
549 BOOST_CHECK_EQUAL (r.s, 9);
550 BOOST_CHECK_EQUAL (r.t, 110);
551 BOOST_CHECK_EQUAL (r.to_string(), "3:6:9:110");
552 BOOST_CHECK_EQUAL (r.to_ticks(), 279335);
554 a = libdcp::Time (24, 12, 6, 3);
555 b = libdcp::Time (16, 8, 4, 2);
556 BOOST_CHECK_CLOSE (a / b, 1.5, 1e-5);
559 BOOST_AUTO_TEST_CASE (color)
561 libdcp::Color c ("FFFF0000");
563 BOOST_CHECK_EQUAL (c.r, 255);
564 BOOST_CHECK_EQUAL (c.g, 0);
565 BOOST_CHECK_EQUAL (c.b, 0);
566 BOOST_CHECK_EQUAL (c.to_argb_string(), "FFFF0000");
568 c = libdcp::Color ("FF00FF00");
570 BOOST_CHECK_EQUAL (c.r, 0);
571 BOOST_CHECK_EQUAL (c.g, 255);
572 BOOST_CHECK_EQUAL (c.b, 0);
573 BOOST_CHECK_EQUAL (c.to_argb_string(), "FF00FF00");
575 c = libdcp::Color ("FF0000FF");
577 BOOST_CHECK_EQUAL (c.r, 0);
578 BOOST_CHECK_EQUAL (c.g, 0);
579 BOOST_CHECK_EQUAL (c.b, 255);
580 BOOST_CHECK_EQUAL (c.to_argb_string(), "FF0000FF");