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/>.
21 /** @file test/dcpomatic_time_test.cc
22 * @brief Test Time and TimePeriod classes.
23 * @ingroup selfcontained
26 #include "lib/dcpomatic_time.h"
27 #include "lib/dcpomatic_time_coalesce.h"
28 #include <boost/test/unit_test.hpp>
35 BOOST_AUTO_TEST_CASE (dcpomatic_time_test)
37 FrameRateChange frc (24, 48);
40 for (int64_t i = 0; i < 62000; i += 2000) {
42 ContentTime c (d, frc);
43 BOOST_CHECK_EQUAL (c.frames_floor (24.0), j);
52 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_overlaps_test)
54 /* Taking times as the start of a sampling interval
56 |--|--|--|--|--|--|--|--|--|--|
58 |--|--|--|--|--|--|--|--|--|--|
60 <------a----><----b----->
62 and saying `from' is the start of the first sampling
63 interval and `to' is the start of the interval after
64 the period... a and b do not overlap.
67 TimePeriod<DCPTime> a (DCPTime (0), DCPTime (4));
68 TimePeriod<DCPTime> b (DCPTime (4), DCPTime (8));
69 BOOST_CHECK (!a.overlap (b));
71 /* Some more obvious non-overlaps */
72 a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
73 b = TimePeriod<DCPTime> (DCPTime (5), DCPTime (8));
74 BOOST_CHECK (!a.overlap (b));
77 a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
78 b = TimePeriod<DCPTime> (DCPTime (3), DCPTime (8));
79 BOOST_CHECK (a.overlap(b));
80 BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(3), DCPTime(4)));
81 a = TimePeriod<DCPTime> (DCPTime (1), DCPTime (9));
82 b = TimePeriod<DCPTime> (DCPTime (0), DCPTime (10));
83 BOOST_CHECK (a.overlap(b));
84 BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(1), DCPTime(9)));
87 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test1)
89 DCPTimePeriod A (DCPTime (0), DCPTime (106));
90 list<DCPTimePeriod> B;
91 B.push_back (DCPTimePeriod (DCPTime (0), DCPTime (42)));
92 B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
93 B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (106)));
94 list<DCPTimePeriod> r = subtract (A, B);
95 list<DCPTimePeriod>::const_iterator i = r.begin ();
96 BOOST_REQUIRE (i != r.end ());
97 BOOST_CHECK (i->from == DCPTime (42));
98 BOOST_CHECK (i->to == DCPTime (52));
100 BOOST_REQUIRE (i != r.end ());
101 BOOST_CHECK (i->from == DCPTime (91));
102 BOOST_CHECK (i->to == DCPTime (94));
104 BOOST_REQUIRE (i == r.end ());
107 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test2)
109 DCPTimePeriod A (DCPTime (0), DCPTime (106));
110 list<DCPTimePeriod> B;
111 B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
112 B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
113 B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (106)));
114 list<DCPTimePeriod> r = subtract (A, B);
115 list<DCPTimePeriod>::const_iterator i = r.begin ();
116 BOOST_REQUIRE (i != r.end ());
117 BOOST_CHECK (i->from == DCPTime (0));
118 BOOST_CHECK (i->to == DCPTime (14));
120 BOOST_REQUIRE (i != r.end ());
121 BOOST_CHECK (i->from == DCPTime (42));
122 BOOST_CHECK (i->to == DCPTime (52));
124 BOOST_REQUIRE (i != r.end ());
125 BOOST_CHECK (i->from == DCPTime (91));
126 BOOST_CHECK (i->to == DCPTime (94));
128 BOOST_REQUIRE (i == r.end ());
131 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test3)
133 DCPTimePeriod A (DCPTime (0), DCPTime (106));
134 list<DCPTimePeriod> B;
135 B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
136 B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
137 B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (99)));
138 list<DCPTimePeriod> r = subtract (A, B);
139 list<DCPTimePeriod>::const_iterator i = r.begin ();
140 BOOST_REQUIRE (i != r.end ());
141 BOOST_CHECK (i->from == DCPTime (0));
142 BOOST_CHECK (i->to == DCPTime (14));
144 BOOST_REQUIRE (i != r.end ());
145 BOOST_CHECK (i->from == DCPTime (42));
146 BOOST_CHECK (i->to == DCPTime (52));
148 BOOST_REQUIRE (i != r.end ());
149 BOOST_CHECK (i->from == DCPTime (91));
150 BOOST_CHECK (i->to == DCPTime (94));
152 BOOST_REQUIRE (i != r.end ());
153 BOOST_CHECK (i->from == DCPTime (99));
154 BOOST_CHECK (i->to == DCPTime (106));
156 BOOST_REQUIRE (i == r.end ());
159 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test4)
161 DCPTimePeriod A (DCPTime (0), DCPTime (106));
162 list<DCPTimePeriod> B;
163 list<DCPTimePeriod> r = subtract (A, B);
164 list<DCPTimePeriod>::const_iterator i = r.begin ();
165 BOOST_REQUIRE (i != r.end ());
166 BOOST_CHECK (i->from == DCPTime (0));
167 BOOST_CHECK (i->to == DCPTime (106));
169 BOOST_REQUIRE (i == r.end ());
172 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test5)
174 DCPTimePeriod A (DCPTime (0), DCPTime (106));
175 list<DCPTimePeriod> B;
176 B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
177 B.push_back (DCPTimePeriod (DCPTime (42), DCPTime (91)));
178 B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (99)));
179 list<DCPTimePeriod> r = subtract (A, B);
180 list<DCPTimePeriod>::const_iterator i = r.begin ();
181 BOOST_REQUIRE (i != r.end ());
182 BOOST_CHECK (i->from == DCPTime (0));
183 BOOST_CHECK (i->to == DCPTime (14));
185 BOOST_REQUIRE (i != r.end ());
186 BOOST_CHECK (i->from ==DCPTime (91));
187 BOOST_CHECK (i->to == DCPTime (94));
189 BOOST_REQUIRE (i != r.end ());
190 BOOST_CHECK (i->from == DCPTime (99));
191 BOOST_CHECK (i->to == DCPTime (106));
193 BOOST_REQUIRE (i == r.end ());
196 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test6)
198 DCPTimePeriod A (DCPTime (0), DCPTime (106));
199 list<DCPTimePeriod> B;
200 B.push_back (DCPTimePeriod (DCPTime (0), DCPTime (42)));
201 B.push_back (DCPTimePeriod (DCPTime (42), DCPTime (91)));
202 B.push_back (DCPTimePeriod (DCPTime (91), DCPTime (106)));
203 list<DCPTimePeriod> r = subtract (A, B);
204 BOOST_CHECK (r.empty());
207 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test7)
209 DCPTimePeriod A (DCPTime (228), DCPTime (356));
210 list<DCPTimePeriod> B;
211 B.push_back (DCPTimePeriod (DCPTime (34), DCPTime (162)));
212 list<DCPTimePeriod> r = subtract (A, B);
213 list<DCPTimePeriod>::const_iterator i = r.begin ();
214 BOOST_REQUIRE (i != r.end ());
215 BOOST_CHECK (i->from == DCPTime (228));
216 BOOST_CHECK (i->to == DCPTime (356));
218 BOOST_REQUIRE (i == r.end ());
221 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test8)
223 DCPTimePeriod A (DCPTime(0), DCPTime(32000));
224 list<DCPTimePeriod> B;
225 B.push_back (DCPTimePeriod (DCPTime(8000), DCPTime(20000)));
226 B.push_back (DCPTimePeriod (DCPTime(28000), DCPTime(32000)));
227 list<DCPTimePeriod> r = subtract (A, B);
228 list<DCPTimePeriod>::const_iterator i = r.begin ();
229 BOOST_REQUIRE (i != r.end ());
230 BOOST_CHECK (*i == DCPTimePeriod(DCPTime(0), DCPTime(8000)));
232 BOOST_REQUIRE (i != r.end ());
233 BOOST_CHECK (*i == DCPTimePeriod(DCPTime(20000), DCPTime(28000)));
235 BOOST_REQUIRE (i == r.end ());
238 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test1)
240 DCPTimePeriod A (DCPTime(14), DCPTime(29));
241 DCPTimePeriod B (DCPTime(45), DCPTime(91));
242 list<DCPTimePeriod> p;
245 list<DCPTimePeriod> q = coalesce (p);
246 BOOST_REQUIRE_EQUAL (q.size(), 2);
247 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(29)));
248 BOOST_CHECK (q.back () == DCPTimePeriod(DCPTime(45), DCPTime(91)));
251 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test2)
253 DCPTimePeriod A (DCPTime(14), DCPTime(29));
254 DCPTimePeriod B (DCPTime(26), DCPTime(91));
255 list<DCPTimePeriod> p;
258 list<DCPTimePeriod> q = coalesce (p);
259 BOOST_REQUIRE_EQUAL (q.size(), 1);
260 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
263 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test3)
265 DCPTimePeriod A (DCPTime(14), DCPTime(29));
266 DCPTimePeriod B (DCPTime(29), DCPTime(91));
267 list<DCPTimePeriod> p;
270 list<DCPTimePeriod> q = coalesce (p);
271 BOOST_REQUIRE_EQUAL (q.size(), 1);
272 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
275 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test4)
277 DCPTimePeriod A (DCPTime(14), DCPTime(29));
278 DCPTimePeriod B (DCPTime(20), DCPTime(91));
279 DCPTimePeriod C (DCPTime(35), DCPTime(106));
280 list<DCPTimePeriod> p;
284 list<DCPTimePeriod> q = coalesce (p);
285 BOOST_REQUIRE_EQUAL (q.size(), 1);
286 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(106)));
289 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test5)
291 DCPTimePeriod A (DCPTime(14), DCPTime(29));
292 DCPTimePeriod B (DCPTime(20), DCPTime(91));
293 DCPTimePeriod C (DCPTime(100), DCPTime(106));
294 list<DCPTimePeriod> p;
298 list<DCPTimePeriod> q = coalesce (p);
299 BOOST_REQUIRE_EQUAL (q.size(), 2);
300 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
301 BOOST_CHECK (q.back() == DCPTimePeriod(DCPTime(100), DCPTime(106)));
304 /* Straightforward test of DCPTime::ceil */
305 BOOST_AUTO_TEST_CASE (dcpomatic_time_ceil_test)
307 BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 2).get(), 0);
308 BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 2).get(), 2);
309 BOOST_CHECK_EQUAL (DCPTime(2).ceil(DCPTime::HZ / 2).get(), 2);
310 BOOST_CHECK_EQUAL (DCPTime(3).ceil(DCPTime::HZ / 2).get(), 4);
312 BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 42).get(), 0);
313 BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 42).get(), 42);
314 BOOST_CHECK_EQUAL (DCPTime(42).ceil(DCPTime::HZ / 42).get(), 42);
315 BOOST_CHECK_EQUAL (DCPTime(43).ceil(DCPTime::HZ / 42).get(), 84);
317 /* Check that rounding up to non-integer frame rates works */
318 BOOST_CHECK_EQUAL (DCPTime(45312).ceil(29.976).get(), 48038);
320 /* Check another tricky case that used to fail */
321 BOOST_CHECK_EQUAL (DCPTime(212256039).ceil(23.976).get(), 212256256);
324 /* Straightforward test of DCPTime::floor */
325 BOOST_AUTO_TEST_CASE (dcpomatic_time_floor_test)
327 BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 2).get(), 0);
328 BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 2).get(), 0);
329 BOOST_CHECK_EQUAL (DCPTime(2).floor(DCPTime::HZ / 2).get(), 2);
330 BOOST_CHECK_EQUAL (DCPTime(3).floor(DCPTime::HZ / 2).get(), 2);
332 BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 42).get(), 0);
333 BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 42).get(), 0);
334 BOOST_CHECK_EQUAL (DCPTime(42).floor(DCPTime::HZ / 42.0).get(), 42);
335 BOOST_CHECK_EQUAL (DCPTime(43).floor(DCPTime::HZ / 42.0).get(), 42);
337 /* Check that rounding down to non-integer frame rates works */
338 BOOST_CHECK_EQUAL (DCPTime(45312).floor(29.976).get(), 44836);