2 Copyright (C) 2015-2017 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic 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.
11 DCP-o-matic 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.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
22 /** @file test/dcpomatic_time_test.cc
23 * @brief Test dcpomatic::Time and dcpomatic::TimePeriod classes.
24 * @ingroup selfcontained
28 #include "lib/dcpomatic_time.h"
29 #include "lib/dcpomatic_time_coalesce.h"
30 #include "lib/dcpomatic_time_overlap.h"
31 #include <boost/test/unit_test.hpp>
38 using namespace dcpomatic;
41 BOOST_AUTO_TEST_CASE (dcpomatic_time_test)
43 FrameRateChange frc (24, 48);
46 for (int64_t i = 0; i < 62000; i += 2000) {
48 ContentTime c (d, frc);
49 BOOST_CHECK_EQUAL (c.frames_floor (24.0), j);
59 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_overlaps_test)
61 /* Taking times as the start of a sampling interval
63 |--|--|--|--|--|--|--|--|--|--|
65 |--|--|--|--|--|--|--|--|--|--|
67 <------a----><----b----->
69 and saying `from' is the start of the first sampling
70 interval and `to' is the start of the interval after
71 the period... a and b do not overlap.
74 TimePeriod<DCPTime> a (DCPTime(0), DCPTime(4));
75 TimePeriod<DCPTime> b (DCPTime (4), DCPTime (8));
76 BOOST_CHECK (!a.overlap (b));
78 /* Some more obvious non-overlaps */
79 a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
80 b = TimePeriod<DCPTime> (DCPTime (5), DCPTime (8));
81 BOOST_CHECK (!a.overlap (b));
84 a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
85 b = TimePeriod<DCPTime> (DCPTime (3), DCPTime (8));
86 BOOST_CHECK (a.overlap(b));
87 BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(3), DCPTime(4)));
88 a = TimePeriod<DCPTime> (DCPTime (1), DCPTime (9));
89 b = TimePeriod<DCPTime> (DCPTime (0), DCPTime (10));
90 BOOST_CHECK (a.overlap(b));
91 BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(1), DCPTime(9)));
95 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test1)
97 DCPTimePeriod A (DCPTime (0), DCPTime (106));
98 list<DCPTimePeriod> B = {
99 DCPTimePeriod(DCPTime(0), DCPTime(42)),
100 DCPTimePeriod(DCPTime(52), DCPTime(91)),
101 DCPTimePeriod(DCPTime(94), DCPTime(106))
103 auto r = subtract ({A}, B);
105 BOOST_REQUIRE (i != r.end ());
106 BOOST_CHECK (i->from == DCPTime (42));
107 BOOST_CHECK (i->to == DCPTime (52));
109 BOOST_REQUIRE (i != r.end ());
110 BOOST_CHECK (i->from == DCPTime (91));
111 BOOST_CHECK (i->to == DCPTime (94));
113 BOOST_REQUIRE (i == r.end ());
117 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test2)
119 DCPTimePeriod A (DCPTime (0), DCPTime (106));
120 list<DCPTimePeriod> B = {
121 DCPTimePeriod(DCPTime(14), DCPTime(42)),
122 DCPTimePeriod(DCPTime(52), DCPTime(91)),
123 DCPTimePeriod(DCPTime(94), DCPTime(106))
125 auto r = subtract ({A}, B);
127 BOOST_REQUIRE (i != r.end ());
128 BOOST_CHECK (i->from == DCPTime (0));
129 BOOST_CHECK (i->to == DCPTime (14));
131 BOOST_REQUIRE (i != r.end ());
132 BOOST_CHECK (i->from == DCPTime (42));
133 BOOST_CHECK (i->to == DCPTime (52));
135 BOOST_REQUIRE (i != r.end ());
136 BOOST_CHECK (i->from == DCPTime (91));
137 BOOST_CHECK (i->to == DCPTime (94));
139 BOOST_REQUIRE (i == r.end ());
143 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test3)
145 DCPTimePeriod A (DCPTime (0), DCPTime (106));
146 list<DCPTimePeriod> B = {
147 DCPTimePeriod(DCPTime(14), DCPTime(42)),
148 DCPTimePeriod(DCPTime(52), DCPTime(91)),
149 DCPTimePeriod(DCPTime(94), DCPTime(99))
151 auto r = subtract ({A}, B);
153 BOOST_REQUIRE (i != r.end ());
154 BOOST_CHECK (i->from == DCPTime (0));
155 BOOST_CHECK (i->to == DCPTime (14));
157 BOOST_REQUIRE (i != r.end ());
158 BOOST_CHECK (i->from == DCPTime (42));
159 BOOST_CHECK (i->to == DCPTime (52));
161 BOOST_REQUIRE (i != r.end ());
162 BOOST_CHECK (i->from == DCPTime (91));
163 BOOST_CHECK (i->to == DCPTime (94));
165 BOOST_REQUIRE (i != r.end ());
166 BOOST_CHECK (i->from == DCPTime (99));
167 BOOST_CHECK (i->to == DCPTime (106));
169 BOOST_REQUIRE (i == r.end ());
173 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test4)
175 DCPTimePeriod A (DCPTime (0), DCPTime (106));
176 list<DCPTimePeriod> B;
177 auto r = subtract ({A}, B);
179 BOOST_REQUIRE (i != r.end ());
180 BOOST_CHECK (i->from == DCPTime (0));
181 BOOST_CHECK (i->to == DCPTime (106));
183 BOOST_REQUIRE (i == r.end ());
187 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test5)
189 DCPTimePeriod A (DCPTime (0), DCPTime (106));
190 list<DCPTimePeriod> B = {
191 DCPTimePeriod(DCPTime(14), DCPTime(42)),
192 DCPTimePeriod(DCPTime(42), DCPTime(91)),
193 DCPTimePeriod(DCPTime(94), DCPTime(99))
195 auto r = subtract ({A}, B);
197 BOOST_REQUIRE (i != r.end ());
198 BOOST_CHECK (i->from == DCPTime (0));
199 BOOST_CHECK (i->to == DCPTime (14));
201 BOOST_REQUIRE (i != r.end ());
202 BOOST_CHECK (i->from ==DCPTime (91));
203 BOOST_CHECK (i->to == DCPTime (94));
205 BOOST_REQUIRE (i != r.end ());
206 BOOST_CHECK (i->from == DCPTime (99));
207 BOOST_CHECK (i->to == DCPTime (106));
209 BOOST_REQUIRE (i == r.end ());
213 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test6)
215 DCPTimePeriod A (DCPTime (0), DCPTime (106));
216 list<DCPTimePeriod> B = {
217 DCPTimePeriod(DCPTime(0), DCPTime(42)),
218 DCPTimePeriod(DCPTime(42), DCPTime(91)),
219 DCPTimePeriod(DCPTime(91), DCPTime(106))
221 auto r = subtract ({A}, B);
222 BOOST_CHECK (r.empty());
226 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test7)
228 DCPTimePeriod A (DCPTime (228), DCPTime (356));
229 list<DCPTimePeriod> B = {
230 DCPTimePeriod(DCPTime(34), DCPTime(162))
232 auto r = subtract ({A}, B);
234 BOOST_REQUIRE (i != r.end ());
235 BOOST_CHECK (i->from == DCPTime (228));
236 BOOST_CHECK (i->to == DCPTime (356));
238 BOOST_REQUIRE (i == r.end ());
242 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test8)
244 DCPTimePeriod A (DCPTime(0), DCPTime(32000));
245 list<DCPTimePeriod> B = {
246 DCPTimePeriod(DCPTime(8000), DCPTime(20000)),
247 DCPTimePeriod(DCPTime(28000), DCPTime(32000))
249 auto r = subtract ({A}, B);
251 BOOST_REQUIRE (i != r.end ());
252 BOOST_CHECK (*i == DCPTimePeriod(DCPTime(0), DCPTime(8000)));
254 BOOST_REQUIRE (i != r.end ());
255 BOOST_CHECK (*i == DCPTimePeriod(DCPTime(20000), DCPTime(28000)));
257 BOOST_REQUIRE (i == r.end ());
261 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_list_from_list_test1)
263 list<DCPTimePeriod> A = {
264 DCPTimePeriod(DCPTime(0), DCPTime(2000)),
265 DCPTimePeriod(DCPTime(4000), DCPTime(6000))
268 list<DCPTimePeriod> B = {
269 DCPTimePeriod(DCPTime(1000), DCPTime(3000)),
270 DCPTimePeriod(DCPTime(5000), DCPTime(7000))
273 auto result = subtract(A, B);
274 list<DCPTimePeriod> reference = {
275 DCPTimePeriod(DCPTime(0), DCPTime(1000)),
276 DCPTimePeriod(DCPTime(4000), DCPTime(5000))
279 BOOST_CHECK (result == reference);
283 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_list_from_list_test2)
285 list<DCPTimePeriod> A = {
286 DCPTimePeriod(DCPTime(0), DCPTime(2000)),
287 DCPTimePeriod(DCPTime(4000), DCPTime(6000))
290 list<DCPTimePeriod> B = {
291 DCPTimePeriod(DCPTime(500), DCPTime(1500)),
292 DCPTimePeriod(DCPTime(4500), DCPTime(5500))
295 auto result = subtract(A, B);
296 list<DCPTimePeriod> reference = {
297 DCPTimePeriod(DCPTime(0), DCPTime(500)),
298 DCPTimePeriod(DCPTime(1500), DCPTime(2000)),
299 DCPTimePeriod(DCPTime(4000), DCPTime(4500)),
300 DCPTimePeriod(DCPTime(5500), DCPTime(6000)),
303 BOOST_CHECK (result == reference);
307 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_list_from_list_test3)
309 list<DCPTimePeriod> A = {
310 DCPTimePeriod(DCPTime(500), DCPTime(1500)),
311 DCPTimePeriod(DCPTime(4500), DCPTime(5500))
314 list<DCPTimePeriod> B = {
315 DCPTimePeriod(DCPTime(0), DCPTime(2000)),
316 DCPTimePeriod(DCPTime(4000), DCPTime(6000))
319 auto result = subtract(A, B);
320 BOOST_CHECK (result.empty());
324 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test1)
326 DCPTimePeriod A (DCPTime(14), DCPTime(29));
327 DCPTimePeriod B (DCPTime(45), DCPTime(91));
328 list<DCPTimePeriod> p = { A, B };
329 auto q = coalesce (p);
330 BOOST_REQUIRE_EQUAL (q.size(), 2U);
331 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(29)));
332 BOOST_CHECK (q.back () == DCPTimePeriod(DCPTime(45), DCPTime(91)));
336 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test2)
338 DCPTimePeriod A (DCPTime(14), DCPTime(29));
339 DCPTimePeriod B (DCPTime(26), DCPTime(91));
340 list<DCPTimePeriod> p = { A, B };
341 auto q = coalesce (p);
342 BOOST_REQUIRE_EQUAL (q.size(), 1U);
343 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
347 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test3)
349 DCPTimePeriod A (DCPTime(14), DCPTime(29));
350 DCPTimePeriod B (DCPTime(29), DCPTime(91));
351 list<DCPTimePeriod> p = { A, B };
352 auto q = coalesce (p);
353 BOOST_REQUIRE_EQUAL (q.size(), 1U);
354 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
358 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test4)
360 DCPTimePeriod A (DCPTime(14), DCPTime(29));
361 DCPTimePeriod B (DCPTime(20), DCPTime(91));
362 DCPTimePeriod C (DCPTime(35), DCPTime(106));
363 list<DCPTimePeriod> p = { A, B, C };
364 auto q = coalesce (p);
365 BOOST_REQUIRE_EQUAL (q.size(), 1U);
366 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(106)));
370 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test5)
372 DCPTimePeriod A (DCPTime(14), DCPTime(29));
373 DCPTimePeriod B (DCPTime(20), DCPTime(91));
374 DCPTimePeriod C (DCPTime(100), DCPTime(106));
375 list<DCPTimePeriod> p = { A, B, C };
376 auto q = coalesce (p);
377 BOOST_REQUIRE_EQUAL (q.size(), 2U);
378 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
379 BOOST_CHECK (q.back() == DCPTimePeriod(DCPTime(100), DCPTime(106)));
383 BOOST_AUTO_TEST_CASE (test_coalesce_with_overlapping_periods)
385 DCPTimePeriod A (DCPTime(0), DCPTime(10));
386 DCPTimePeriod B (DCPTime(2), DCPTime(8));
387 list<DCPTimePeriod> p = { A, B };
388 auto q = coalesce(p);
389 BOOST_REQUIRE_EQUAL (q.size(), 1U);
390 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(0), DCPTime(10)));
394 /* Straightforward test of DCPTime::ceil */
395 BOOST_AUTO_TEST_CASE (dcpomatic_time_ceil_test)
397 BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 2).get(), 0);
398 BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 2).get(), 2);
399 BOOST_CHECK_EQUAL (DCPTime(2).ceil(DCPTime::HZ / 2).get(), 2);
400 BOOST_CHECK_EQUAL (DCPTime(3).ceil(DCPTime::HZ / 2).get(), 4);
402 BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 42).get(), 0);
403 BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 42).get(), 42);
404 BOOST_CHECK_EQUAL (DCPTime(42).ceil(DCPTime::HZ / 42).get(), 42);
405 BOOST_CHECK_EQUAL (DCPTime(43).ceil(DCPTime::HZ / 42).get(), 84);
407 /* Check that rounding up to non-integer frame rates works */
408 BOOST_CHECK_EQUAL (DCPTime(45312).ceil(29.976).get(), 48038);
410 /* Check another tricky case that used to fail */
411 BOOST_CHECK_EQUAL (DCPTime(212256039).ceil(23.976).get(), 212256256);
415 /* Straightforward test of DCPTime::floor */
416 BOOST_AUTO_TEST_CASE (dcpomatic_time_floor_test)
418 BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 2).get(), 0);
419 BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 2).get(), 0);
420 BOOST_CHECK_EQUAL (DCPTime(2).floor(DCPTime::HZ / 2).get(), 2);
421 BOOST_CHECK_EQUAL (DCPTime(3).floor(DCPTime::HZ / 2).get(), 2);
423 BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 42).get(), 0);
424 BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 42).get(), 0);
425 BOOST_CHECK_EQUAL (DCPTime(42).floor(DCPTime::HZ / 42.0).get(), 42);
426 BOOST_CHECK_EQUAL (DCPTime(43).floor(DCPTime::HZ / 42.0).get(), 42);
428 /* Check that rounding down to non-integer frame rates works */
429 BOOST_CHECK_EQUAL (DCPTime(45312).floor(29.976).get(), 44836);
433 BOOST_AUTO_TEST_CASE (dcpomatic_time_overlap_test1)
435 list<DCPTimePeriod> A = {
436 { DCPTime(0), DCPTime(5) }
439 BOOST_CHECK (overlap(A, std::list<DCPTimePeriod>()).empty());
440 BOOST_CHECK (overlap(std::list<DCPTimePeriod>(), A).empty());
444 BOOST_AUTO_TEST_CASE (dcpomatic_time_overlap_test2)
446 list<DCPTimePeriod> A = {
447 { DCPTime(0), DCPTime(5) }
450 list<DCPTimePeriod> B = {
451 { DCPTime(6), DCPTime(10) }
454 BOOST_CHECK (overlap(A, B).empty());
455 BOOST_CHECK (overlap(B, A).empty());
459 BOOST_AUTO_TEST_CASE (dcpomatic_time_overlap_test3)
461 list<DCPTimePeriod> A = {
462 { DCPTime(0), DCPTime(5) }
465 list<DCPTimePeriod> B = {
466 { DCPTime(2), DCPTime(3) }
469 std::list<DCPTimePeriod> correct = {
470 { DCPTime(2), DCPTime(3) }
473 BOOST_CHECK (overlap(A, B) == correct);
474 BOOST_CHECK (overlap(B, A) == correct);
478 BOOST_AUTO_TEST_CASE (dcpomatic_time_overlap_test4)
480 list<DCPTimePeriod> A = {
481 { DCPTime(0), DCPTime(5) }
484 list<DCPTimePeriod> B = {
485 { DCPTime(0), DCPTime(5) }
488 std::list<DCPTimePeriod> correct = {
489 { DCPTime(0), DCPTime(5) }
492 BOOST_CHECK (overlap(A, B) == correct);
493 BOOST_CHECK (overlap(B, A) == correct);
497 BOOST_AUTO_TEST_CASE (dcpomatic_time_overlap_test5)
499 list<DCPTimePeriod> A = {
500 { DCPTime(0), DCPTime(5) },
501 { DCPTime(7), DCPTime(12) }
504 list<DCPTimePeriod> B = {
505 { DCPTime(0), DCPTime(15) }
508 std::list<DCPTimePeriod> correct = {
509 { DCPTime(0), DCPTime(5) },
510 { DCPTime(7), DCPTime(12) }
513 BOOST_CHECK (overlap(A, B) == correct);
514 BOOST_CHECK (overlap(B, A) == correct);
518 BOOST_AUTO_TEST_CASE (dcpomatic_time_overlap_test6)
520 list<DCPTimePeriod> A = {
521 { DCPTime(0), DCPTime(5) },
522 { DCPTime(7), DCPTime(12) }
525 list<DCPTimePeriod> B = {
526 { DCPTime(3), DCPTime(10) }
529 std::list<DCPTimePeriod> correct = {
530 { DCPTime(3), DCPTime(5) },
531 { DCPTime(7), DCPTime(10) }
534 BOOST_CHECK (overlap(A, B) == correct);
535 BOOST_CHECK (overlap(B, A) == correct);