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>
34 using namespace dcpomatic;
36 BOOST_AUTO_TEST_CASE (dcpomatic_time_test)
38 FrameRateChange frc (24, 48);
41 for (int64_t i = 0; i < 62000; i += 2000) {
43 ContentTime c (d, frc);
44 BOOST_CHECK_EQUAL (c.frames_floor (24.0), j);
53 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_overlaps_test)
55 /* Taking times as the start of a sampling interval
57 |--|--|--|--|--|--|--|--|--|--|
59 |--|--|--|--|--|--|--|--|--|--|
61 <------a----><----b----->
63 and saying `from' is the start of the first sampling
64 interval and `to' is the start of the interval after
65 the period... a and b do not overlap.
68 TimePeriod<DCPTime> a (DCPTime (0), DCPTime (4));
69 TimePeriod<DCPTime> b (DCPTime (4), DCPTime (8));
70 BOOST_CHECK (!a.overlap (b));
72 /* Some more obvious non-overlaps */
73 a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
74 b = TimePeriod<DCPTime> (DCPTime (5), DCPTime (8));
75 BOOST_CHECK (!a.overlap (b));
78 a = TimePeriod<DCPTime> (DCPTime (0), DCPTime (4));
79 b = TimePeriod<DCPTime> (DCPTime (3), DCPTime (8));
80 BOOST_CHECK (a.overlap(b));
81 BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(3), DCPTime(4)));
82 a = TimePeriod<DCPTime> (DCPTime (1), DCPTime (9));
83 b = TimePeriod<DCPTime> (DCPTime (0), DCPTime (10));
84 BOOST_CHECK (a.overlap(b));
85 BOOST_CHECK (a.overlap(b).get() == DCPTimePeriod(DCPTime(1), DCPTime(9)));
88 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test1)
90 DCPTimePeriod A (DCPTime (0), DCPTime (106));
91 list<DCPTimePeriod> B;
92 B.push_back (DCPTimePeriod (DCPTime (0), DCPTime (42)));
93 B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
94 B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (106)));
95 list<DCPTimePeriod> r = subtract (A, B);
96 list<DCPTimePeriod>::const_iterator i = r.begin ();
97 BOOST_REQUIRE (i != r.end ());
98 BOOST_CHECK (i->from == DCPTime (42));
99 BOOST_CHECK (i->to == DCPTime (52));
101 BOOST_REQUIRE (i != r.end ());
102 BOOST_CHECK (i->from == DCPTime (91));
103 BOOST_CHECK (i->to == DCPTime (94));
105 BOOST_REQUIRE (i == r.end ());
108 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test2)
110 DCPTimePeriod A (DCPTime (0), DCPTime (106));
111 list<DCPTimePeriod> B;
112 B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
113 B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
114 B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (106)));
115 list<DCPTimePeriod> r = subtract (A, B);
116 list<DCPTimePeriod>::const_iterator i = r.begin ();
117 BOOST_REQUIRE (i != r.end ());
118 BOOST_CHECK (i->from == DCPTime (0));
119 BOOST_CHECK (i->to == DCPTime (14));
121 BOOST_REQUIRE (i != r.end ());
122 BOOST_CHECK (i->from == DCPTime (42));
123 BOOST_CHECK (i->to == DCPTime (52));
125 BOOST_REQUIRE (i != r.end ());
126 BOOST_CHECK (i->from == DCPTime (91));
127 BOOST_CHECK (i->to == DCPTime (94));
129 BOOST_REQUIRE (i == r.end ());
132 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test3)
134 DCPTimePeriod A (DCPTime (0), DCPTime (106));
135 list<DCPTimePeriod> B;
136 B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
137 B.push_back (DCPTimePeriod (DCPTime (52), DCPTime (91)));
138 B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (99)));
139 list<DCPTimePeriod> r = subtract (A, B);
140 list<DCPTimePeriod>::const_iterator i = r.begin ();
141 BOOST_REQUIRE (i != r.end ());
142 BOOST_CHECK (i->from == DCPTime (0));
143 BOOST_CHECK (i->to == DCPTime (14));
145 BOOST_REQUIRE (i != r.end ());
146 BOOST_CHECK (i->from == DCPTime (42));
147 BOOST_CHECK (i->to == DCPTime (52));
149 BOOST_REQUIRE (i != r.end ());
150 BOOST_CHECK (i->from == DCPTime (91));
151 BOOST_CHECK (i->to == DCPTime (94));
153 BOOST_REQUIRE (i != r.end ());
154 BOOST_CHECK (i->from == DCPTime (99));
155 BOOST_CHECK (i->to == DCPTime (106));
157 BOOST_REQUIRE (i == r.end ());
160 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test4)
162 DCPTimePeriod A (DCPTime (0), DCPTime (106));
163 list<DCPTimePeriod> B;
164 list<DCPTimePeriod> r = subtract (A, B);
165 list<DCPTimePeriod>::const_iterator i = r.begin ();
166 BOOST_REQUIRE (i != r.end ());
167 BOOST_CHECK (i->from == DCPTime (0));
168 BOOST_CHECK (i->to == DCPTime (106));
170 BOOST_REQUIRE (i == r.end ());
173 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test5)
175 DCPTimePeriod A (DCPTime (0), DCPTime (106));
176 list<DCPTimePeriod> B;
177 B.push_back (DCPTimePeriod (DCPTime (14), DCPTime (42)));
178 B.push_back (DCPTimePeriod (DCPTime (42), DCPTime (91)));
179 B.push_back (DCPTimePeriod (DCPTime (94), DCPTime (99)));
180 list<DCPTimePeriod> r = subtract (A, B);
181 list<DCPTimePeriod>::const_iterator i = r.begin ();
182 BOOST_REQUIRE (i != r.end ());
183 BOOST_CHECK (i->from == DCPTime (0));
184 BOOST_CHECK (i->to == DCPTime (14));
186 BOOST_REQUIRE (i != r.end ());
187 BOOST_CHECK (i->from ==DCPTime (91));
188 BOOST_CHECK (i->to == DCPTime (94));
190 BOOST_REQUIRE (i != r.end ());
191 BOOST_CHECK (i->from == DCPTime (99));
192 BOOST_CHECK (i->to == DCPTime (106));
194 BOOST_REQUIRE (i == r.end ());
197 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test6)
199 DCPTimePeriod A (DCPTime (0), DCPTime (106));
200 list<DCPTimePeriod> B;
201 B.push_back (DCPTimePeriod (DCPTime (0), DCPTime (42)));
202 B.push_back (DCPTimePeriod (DCPTime (42), DCPTime (91)));
203 B.push_back (DCPTimePeriod (DCPTime (91), DCPTime (106)));
204 list<DCPTimePeriod> r = subtract (A, B);
205 BOOST_CHECK (r.empty());
208 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test7)
210 DCPTimePeriod A (DCPTime (228), DCPTime (356));
211 list<DCPTimePeriod> B;
212 B.push_back (DCPTimePeriod (DCPTime (34), DCPTime (162)));
213 list<DCPTimePeriod> r = subtract (A, B);
214 list<DCPTimePeriod>::const_iterator i = r.begin ();
215 BOOST_REQUIRE (i != r.end ());
216 BOOST_CHECK (i->from == DCPTime (228));
217 BOOST_CHECK (i->to == DCPTime (356));
219 BOOST_REQUIRE (i == r.end ());
222 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_subtract_test8)
224 DCPTimePeriod A (DCPTime(0), DCPTime(32000));
225 list<DCPTimePeriod> B;
226 B.push_back (DCPTimePeriod (DCPTime(8000), DCPTime(20000)));
227 B.push_back (DCPTimePeriod (DCPTime(28000), DCPTime(32000)));
228 list<DCPTimePeriod> r = subtract (A, B);
229 list<DCPTimePeriod>::const_iterator i = r.begin ();
230 BOOST_REQUIRE (i != r.end ());
231 BOOST_CHECK (*i == DCPTimePeriod(DCPTime(0), DCPTime(8000)));
233 BOOST_REQUIRE (i != r.end ());
234 BOOST_CHECK (*i == DCPTimePeriod(DCPTime(20000), DCPTime(28000)));
236 BOOST_REQUIRE (i == r.end ());
239 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test1)
241 DCPTimePeriod A (DCPTime(14), DCPTime(29));
242 DCPTimePeriod B (DCPTime(45), DCPTime(91));
243 list<DCPTimePeriod> p;
246 list<DCPTimePeriod> q = coalesce (p);
247 BOOST_REQUIRE_EQUAL (q.size(), 2);
248 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(29)));
249 BOOST_CHECK (q.back () == DCPTimePeriod(DCPTime(45), DCPTime(91)));
252 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test2)
254 DCPTimePeriod A (DCPTime(14), DCPTime(29));
255 DCPTimePeriod B (DCPTime(26), DCPTime(91));
256 list<DCPTimePeriod> p;
259 list<DCPTimePeriod> q = coalesce (p);
260 BOOST_REQUIRE_EQUAL (q.size(), 1);
261 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
264 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test3)
266 DCPTimePeriod A (DCPTime(14), DCPTime(29));
267 DCPTimePeriod B (DCPTime(29), DCPTime(91));
268 list<DCPTimePeriod> p;
271 list<DCPTimePeriod> q = coalesce (p);
272 BOOST_REQUIRE_EQUAL (q.size(), 1);
273 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
276 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test4)
278 DCPTimePeriod A (DCPTime(14), DCPTime(29));
279 DCPTimePeriod B (DCPTime(20), DCPTime(91));
280 DCPTimePeriod C (DCPTime(35), DCPTime(106));
281 list<DCPTimePeriod> p;
285 list<DCPTimePeriod> q = coalesce (p);
286 BOOST_REQUIRE_EQUAL (q.size(), 1);
287 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(106)));
290 BOOST_AUTO_TEST_CASE (dcpomatic_time_period_coalesce_test5)
292 DCPTimePeriod A (DCPTime(14), DCPTime(29));
293 DCPTimePeriod B (DCPTime(20), DCPTime(91));
294 DCPTimePeriod C (DCPTime(100), DCPTime(106));
295 list<DCPTimePeriod> p;
299 list<DCPTimePeriod> q = coalesce (p);
300 BOOST_REQUIRE_EQUAL (q.size(), 2);
301 BOOST_CHECK (q.front() == DCPTimePeriod(DCPTime(14), DCPTime(91)));
302 BOOST_CHECK (q.back() == DCPTimePeriod(DCPTime(100), DCPTime(106)));
305 /* Straightforward test of DCPTime::ceil */
306 BOOST_AUTO_TEST_CASE (dcpomatic_time_ceil_test)
308 BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 2).get(), 0);
309 BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 2).get(), 2);
310 BOOST_CHECK_EQUAL (DCPTime(2).ceil(DCPTime::HZ / 2).get(), 2);
311 BOOST_CHECK_EQUAL (DCPTime(3).ceil(DCPTime::HZ / 2).get(), 4);
313 BOOST_CHECK_EQUAL (DCPTime(0).ceil(DCPTime::HZ / 42).get(), 0);
314 BOOST_CHECK_EQUAL (DCPTime(1).ceil(DCPTime::HZ / 42).get(), 42);
315 BOOST_CHECK_EQUAL (DCPTime(42).ceil(DCPTime::HZ / 42).get(), 42);
316 BOOST_CHECK_EQUAL (DCPTime(43).ceil(DCPTime::HZ / 42).get(), 84);
318 /* Check that rounding up to non-integer frame rates works */
319 BOOST_CHECK_EQUAL (DCPTime(45312).ceil(29.976).get(), 48038);
321 /* Check another tricky case that used to fail */
322 BOOST_CHECK_EQUAL (DCPTime(212256039).ceil(23.976).get(), 212256256);
325 /* Straightforward test of DCPTime::floor */
326 BOOST_AUTO_TEST_CASE (dcpomatic_time_floor_test)
328 BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 2).get(), 0);
329 BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 2).get(), 0);
330 BOOST_CHECK_EQUAL (DCPTime(2).floor(DCPTime::HZ / 2).get(), 2);
331 BOOST_CHECK_EQUAL (DCPTime(3).floor(DCPTime::HZ / 2).get(), 2);
333 BOOST_CHECK_EQUAL (DCPTime(0).floor(DCPTime::HZ / 42).get(), 0);
334 BOOST_CHECK_EQUAL (DCPTime(1).floor(DCPTime::HZ / 42).get(), 0);
335 BOOST_CHECK_EQUAL (DCPTime(42).floor(DCPTime::HZ / 42.0).get(), 42);
336 BOOST_CHECK_EQUAL (DCPTime(43).floor(DCPTime::HZ / 42.0).get(), 42);
338 /* Check that rounding down to non-integer frame rates works */
339 BOOST_CHECK_EQUAL (DCPTime(45312).floor(29.976).get(), 44836);