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 <boost/test/unit_test.hpp>
37 using namespace dcpomatic;
40 BOOST_AUTO_TEST_CASE (dcpomatic_time_test)
42 FrameRateChange frc (24, 48);
45 for (int64_t i = 0; i < 62000; i += 2000) {
47 ContentTime c (d, frc);
48 BOOST_CHECK_EQUAL (c.frames_floor (24.0), j);
58 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_overlaps_test)
60 /* Taking times as the start of a sampling interval
62 |--|--|--|--|--|--|--|--|--|--|
64 |--|--|--|--|--|--|--|--|--|--|
66 <------a----><----b----->
68 and saying `from' is the start of the first sampling
69 interval and `to' is the start of the interval after
70 the period... a and b do not overlap.
73 TimePeriod<DCPTime> a (DCPTime(0), DCPTime(4));
74 TimePeriod<DCPTime> b (DCPTime (4), DCPTime (8));
75 BOOST_CHECK (!a.overlap (b));
77 /* Some more obvious non-overlaps */
78 a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
79 b = TimePeriod<DCPTime> (DCPTime (5), DCPTime (8));
80 BOOST_CHECK (!a.overlap (b));
83 a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
84 b = TimePeriod<DCPTime> (DCPTime (3), DCPTime (8));
85 BOOST_CHECK (a.overlap(b));
86 BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(3), DCPTime(4)));
87 a = TimePeriod<DCPTime> (DCPTime (1), DCPTime (9));
88 b = TimePeriod<DCPTime> (DCPTime (0), DCPTime (10));
89 BOOST_CHECK (a.overlap(b));
90 BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(1), DCPTime(9)));
94 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test1)
96 DCPTimePeriod A (DCPTime (0), DCPTime (106));
97 list<DCPTimePeriod> B = {
98 DCPTimePeriod(DCPTime(0), DCPTime(42)),
99 DCPTimePeriod(DCPTime(52), DCPTime(91)),
100 DCPTimePeriod(DCPTime(94), DCPTime(106))
102 auto r = subtract ({A}, B);
104 BOOST_REQUIRE (i != r.end ());
105 BOOST_CHECK (i->from == DCPTime (42));
106 BOOST_CHECK (i->to == DCPTime (52));
108 BOOST_REQUIRE (i != r.end ());
109 BOOST_CHECK (i->from == DCPTime (91));
110 BOOST_CHECK (i->to == DCPTime (94));
112 BOOST_REQUIRE (i == r.end ());
116 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test2)
118 DCPTimePeriod A (DCPTime (0), DCPTime (106));
119 list<DCPTimePeriod> B = {
120 DCPTimePeriod(DCPTime(14), DCPTime(42)),
121 DCPTimePeriod(DCPTime(52), DCPTime(91)),
122 DCPTimePeriod(DCPTime(94), DCPTime(106))
124 auto r = subtract ({A}, B);
126 BOOST_REQUIRE (i != r.end ());
127 BOOST_CHECK (i->from == DCPTime (0));
128 BOOST_CHECK (i->to == DCPTime (14));
130 BOOST_REQUIRE (i != r.end ());
131 BOOST_CHECK (i->from == DCPTime (42));
132 BOOST_CHECK (i->to == DCPTime (52));
134 BOOST_REQUIRE (i != r.end ());
135 BOOST_CHECK (i->from == DCPTime (91));
136 BOOST_CHECK (i->to == DCPTime (94));
138 BOOST_REQUIRE (i == r.end ());
142 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test3)
144 DCPTimePeriod A (DCPTime (0), DCPTime (106));
145 list<DCPTimePeriod> B = {
146 DCPTimePeriod(DCPTime(14), DCPTime(42)),
147 DCPTimePeriod(DCPTime(52), DCPTime(91)),
148 DCPTimePeriod(DCPTime(94), DCPTime(99))
150 auto r = subtract ({A}, B);
152 BOOST_REQUIRE (i != r.end ());
153 BOOST_CHECK (i->from == DCPTime (0));
154 BOOST_CHECK (i->to == DCPTime (14));
156 BOOST_REQUIRE (i != r.end ());
157 BOOST_CHECK (i->from == DCPTime (42));
158 BOOST_CHECK (i->to == DCPTime (52));
160 BOOST_REQUIRE (i != r.end ());
161 BOOST_CHECK (i->from == DCPTime (91));
162 BOOST_CHECK (i->to == DCPTime (94));
164 BOOST_REQUIRE (i != r.end ());
165 BOOST_CHECK (i->from == DCPTime (99));
166 BOOST_CHECK (i->to == DCPTime (106));
168 BOOST_REQUIRE (i == r.end ());
172 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test4)
174 DCPTimePeriod A (DCPTime (0), DCPTime (106));
175 list<DCPTimePeriod> B;
176 auto r = subtract ({A}, B);
178 BOOST_REQUIRE (i != r.end ());
179 BOOST_CHECK (i->from == DCPTime (0));
180 BOOST_CHECK (i->to == DCPTime (106));
182 BOOST_REQUIRE (i == r.end ());
186 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test5)
188 DCPTimePeriod A (DCPTime (0), DCPTime (106));
189 list<DCPTimePeriod> B = {
190 DCPTimePeriod(DCPTime(14), DCPTime(42)),
191 DCPTimePeriod(DCPTime(42), DCPTime(91)),
192 DCPTimePeriod(DCPTime(94), DCPTime(99))
194 auto r = subtract ({A}, B);
196 BOOST_REQUIRE (i != r.end ());
197 BOOST_CHECK (i->from == DCPTime (0));
198 BOOST_CHECK (i->to == DCPTime (14));
200 BOOST_REQUIRE (i != r.end ());
201 BOOST_CHECK (i->from ==DCPTime (91));
202 BOOST_CHECK (i->to == DCPTime (94));
204 BOOST_REQUIRE (i != r.end ());
205 BOOST_CHECK (i->from == DCPTime (99));
206 BOOST_CHECK (i->to == DCPTime (106));
208 BOOST_REQUIRE (i == r.end ());
212 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test6)
214 DCPTimePeriod A (DCPTime (0), DCPTime (106));
215 list<DCPTimePeriod> B = {
216 DCPTimePeriod(DCPTime(0), DCPTime(42)),
217 DCPTimePeriod(DCPTime(42), DCPTime(91)),
218 DCPTimePeriod(DCPTime(91), DCPTime(106))
220 auto r = subtract ({A}, B);
221 BOOST_CHECK (r.empty());
225 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test7)
227 DCPTimePeriod A (DCPTime (228), DCPTime (356));
228 list<DCPTimePeriod> B = {
229 DCPTimePeriod(DCPTime(34), DCPTime(162))
231 auto r = subtract ({A}, B);
233 BOOST_REQUIRE (i != r.end ());
234 BOOST_CHECK (i->from == DCPTime (228));
235 BOOST_CHECK (i->to == DCPTime (356));
237 BOOST_REQUIRE (i == r.end ());
241 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test8)
243 DCPTimePeriod A (DCPTime(0), DCPTime(32000));
244 list<DCPTimePeriod> B = {
245 DCPTimePeriod(DCPTime(8000), DCPTime(20000)),
246 DCPTimePeriod(DCPTime(28000), DCPTime(32000))
248 auto r = subtract ({A}, B);
250 BOOST_REQUIRE (i != r.end ());
251 BOOST_CHECK (*i == DCPTimePeriod(DCPTime(0), DCPTime(8000)));
253 BOOST_REQUIRE (i != r.end ());
254 BOOST_CHECK (*i == DCPTimePeriod(DCPTime(20000), DCPTime(28000)));
256 BOOST_REQUIRE (i == r.end ());
260 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_list_from_list_test1)
262 list<DCPTimePeriod> A = {
263 DCPTimePeriod(DCPTime(0), DCPTime(2000)),
264 DCPTimePeriod(DCPTime(4000), DCPTime(6000))
267 list<DCPTimePeriod> B = {
268 DCPTimePeriod(DCPTime(1000), DCPTime(3000)),
269 DCPTimePeriod(DCPTime(5000), DCPTime(7000))
272 auto result = subtract(A, B);
273 list<DCPTimePeriod> reference = {
274 DCPTimePeriod(DCPTime(0), DCPTime(1000)),
275 DCPTimePeriod(DCPTime(4000), DCPTime(5000))
278 BOOST_CHECK (result == reference);
282 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_list_from_list_test2)
284 list<DCPTimePeriod> A = {
285 DCPTimePeriod(DCPTime(0), DCPTime(2000)),
286 DCPTimePeriod(DCPTime(4000), DCPTime(6000))
289 list<DCPTimePeriod> B = {
290 DCPTimePeriod(DCPTime(500), DCPTime(1500)),
291 DCPTimePeriod(DCPTime(4500), DCPTime(5500))
294 auto result = subtract(A, B);
295 list<DCPTimePeriod> reference = {
296 DCPTimePeriod(DCPTime(0), DCPTime(500)),
297 DCPTimePeriod(DCPTime(1500), DCPTime(2000)),
298 DCPTimePeriod(DCPTime(4000), DCPTime(4500)),
299 DCPTimePeriod(DCPTime(5500), DCPTime(6000)),
302 BOOST_CHECK (result == reference);
306 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_list_from_list_test3)
308 list<DCPTimePeriod> A = {
309 DCPTimePeriod(DCPTime(500), DCPTime(1500)),
310 DCPTimePeriod(DCPTime(4500), DCPTime(5500))
313 list<DCPTimePeriod> B = {
314 DCPTimePeriod(DCPTime(0), DCPTime(2000)),
315 DCPTimePeriod(DCPTime(4000), DCPTime(6000))
318 auto result = subtract(A, B);
319 BOOST_CHECK (result.empty());
323 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test1)
325 DCPTimePeriod A (DCPTime(14), DCPTime(29));
326 DCPTimePeriod B (DCPTime(45), DCPTime(91));
327 list<DCPTimePeriod> p = { A, B };
328 auto q = coalesce (p);
329 BOOST_REQUIRE_EQUAL (q.size(), 2U);
330 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(29)));
331 BOOST_CHECK (q.back () == DCPTimePeriod(DCPTime(45), DCPTime(91)));
335 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test2)
337 DCPTimePeriod A (DCPTime(14), DCPTime(29));
338 DCPTimePeriod B (DCPTime(26), DCPTime(91));
339 list<DCPTimePeriod> p = { A, B };
340 auto q = coalesce (p);
341 BOOST_REQUIRE_EQUAL (q.size(), 1U);
342 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
346 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test3)
348 DCPTimePeriod A (DCPTime(14), DCPTime(29));
349 DCPTimePeriod B (DCPTime(29), DCPTime(91));
350 list<DCPTimePeriod> p = { A, B };
351 auto q = coalesce (p);
352 BOOST_REQUIRE_EQUAL (q.size(), 1U);
353 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
357 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test4)
359 DCPTimePeriod A (DCPTime(14), DCPTime(29));
360 DCPTimePeriod B (DCPTime(20), DCPTime(91));
361 DCPTimePeriod C (DCPTime(35), DCPTime(106));
362 list<DCPTimePeriod> p = { A, B, C };
363 auto q = coalesce (p);
364 BOOST_REQUIRE_EQUAL (q.size(), 1U);
365 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(106)));
369 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test5)
371 DCPTimePeriod A (DCPTime(14), DCPTime(29));
372 DCPTimePeriod B (DCPTime(20), DCPTime(91));
373 DCPTimePeriod C (DCPTime(100), DCPTime(106));
374 list<DCPTimePeriod> p = { A, B, C };
375 auto q = coalesce (p);
376 BOOST_REQUIRE_EQUAL (q.size(), 2U);
377 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
378 BOOST_CHECK (q.back() == DCPTimePeriod(DCPTime(100), DCPTime(106)));
382 BOOST_AUTO_TEST_CASE (test_coalesce_with_overlapping_periods)
384 DCPTimePeriod A (DCPTime(0), DCPTime(10));
385 DCPTimePeriod B (DCPTime(2), DCPTime(8));
386 list<DCPTimePeriod> p = { A, B };
387 auto q = coalesce(p);
388 BOOST_REQUIRE_EQUAL (q.size(), 1U);
389 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(0), DCPTime(10)));
393 /* Straightforward test of DCPTime::ceil */
394 BOOST_AUTO_TEST_CASE (dcpomatic_time_ceil_test)
396 BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 2).get(), 0);
397 BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 2).get(), 2);
398 BOOST_CHECK_EQUAL (DCPTime(2).ceil(DCPTime::HZ / 2).get(), 2);
399 BOOST_CHECK_EQUAL (DCPTime(3).ceil(DCPTime::HZ / 2).get(), 4);
401 BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 42).get(), 0);
402 BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 42).get(), 42);
403 BOOST_CHECK_EQUAL (DCPTime(42).ceil(DCPTime::HZ / 42).get(), 42);
404 BOOST_CHECK_EQUAL (DCPTime(43).ceil(DCPTime::HZ / 42).get(), 84);
406 /* Check that rounding up to non-integer frame rates works */
407 BOOST_CHECK_EQUAL (DCPTime(45312).ceil(29.976).get(), 48038);
409 /* Check another tricky case that used to fail */
410 BOOST_CHECK_EQUAL (DCPTime(212256039).ceil(23.976).get(), 212256256);
414 /* Straightforward test of DCPTime::floor */
415 BOOST_AUTO_TEST_CASE (dcpomatic_time_floor_test)
417 BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 2).get(), 0);
418 BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 2).get(), 0);
419 BOOST_CHECK_EQUAL (DCPTime(2).floor(DCPTime::HZ / 2).get(), 2);
420 BOOST_CHECK_EQUAL (DCPTime(3).floor(DCPTime::HZ / 2).get(), 2);
422 BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 42).get(), 0);
423 BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 42).get(), 0);
424 BOOST_CHECK_EQUAL (DCPTime(42).floor(DCPTime::HZ / 42.0).get(), 42);
425 BOOST_CHECK_EQUAL (DCPTime(43).floor(DCPTime::HZ / 42.0).get(), 42);
427 /* Check that rounding down to non-integer frame rates works */
428 BOOST_CHECK_EQUAL (DCPTime(45312).floor(29.976).get(), 44836);