8d15aba5291b28e30a5e661fd9c87d87dee244f4
[dcpomatic.git] / test / reels_test.cc
1 /*
2     Copyright (C) 2015-2020 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
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.
10
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.
15
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/>.
18
19 */
20
21 /** @file  test/reels_test.cc
22  *  @brief Check manipulation of reels in various ways.
23  *  @ingroup specific
24  */
25
26 #include "lib/film.h"
27 #include "lib/ratio.h"
28 #include "lib/ffmpeg_content.h"
29 #include "lib/image_content.h"
30 #include "lib/dcp_content_type.h"
31 #include "lib/dcp_content.h"
32 #include "lib/video_content.h"
33 #include "lib/string_text_file_content.h"
34 #include "lib/content_factory.h"
35 #include "test.h"
36 #include <boost/test/unit_test.hpp>
37 #include <boost/foreach.hpp>
38 #include <iostream>
39
40 using std::list;
41 using std::cout;
42 using std::vector;
43 using std::string;
44 using boost::shared_ptr;
45 using boost::function;
46 using namespace dcpomatic;
47
48 /** Test Film::reels() */
49 BOOST_AUTO_TEST_CASE (reels_test1)
50 {
51         shared_ptr<Film> film = new_test_film ("reels_test1");
52         film->set_container (Ratio::from_id ("185"));
53         shared_ptr<FFmpegContent> A (new FFmpegContent("test/data/test.mp4"));
54         film->examine_and_add_content (A);
55         shared_ptr<FFmpegContent> B (new FFmpegContent("test/data/test.mp4"));
56         film->examine_and_add_content (B);
57         BOOST_REQUIRE (!wait_for_jobs());
58         BOOST_CHECK_EQUAL (A->full_length(film).get(), 288000);
59
60         film->set_reel_type (REELTYPE_SINGLE);
61         list<DCPTimePeriod> r = film->reels ();
62         BOOST_CHECK_EQUAL (r.size(), 1);
63         BOOST_CHECK_EQUAL (r.front().from.get(), 0);
64         BOOST_CHECK_EQUAL (r.front().to.get(), 288000 * 2);
65
66         film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
67         r = film->reels ();
68         BOOST_CHECK_EQUAL (r.size(), 2);
69         BOOST_CHECK_EQUAL (r.front().from.get(), 0);
70         BOOST_CHECK_EQUAL (r.front().to.get(), 288000);
71         BOOST_CHECK_EQUAL (r.back().from.get(), 288000);
72         BOOST_CHECK_EQUAL (r.back().to.get(), 288000 * 2);
73
74         film->set_j2k_bandwidth (100000000);
75         film->set_reel_type (REELTYPE_BY_LENGTH);
76         /* This is just over 2.5s at 100Mbit/s; should correspond to 60 frames */
77         film->set_reel_length (31253154);
78         r = film->reels ();
79         BOOST_CHECK_EQUAL (r.size(), 3);
80         list<DCPTimePeriod>::const_iterator i = r.begin ();
81         BOOST_CHECK_EQUAL (i->from.get(), 0);
82         BOOST_CHECK_EQUAL (i->to.get(), DCPTime::from_frames(60, 24).get());
83         ++i;
84         BOOST_CHECK_EQUAL (i->from.get(), DCPTime::from_frames(60, 24).get());
85         BOOST_CHECK_EQUAL (i->to.get(), DCPTime::from_frames(120, 24).get());
86         ++i;
87         BOOST_CHECK_EQUAL (i->from.get(), DCPTime::from_frames(120, 24).get());
88         BOOST_CHECK_EQUAL (i->to.get(), DCPTime::from_frames(144, 24).get());
89 }
90
91 /** Make a short DCP with multi reels split by video content, then import
92  *  this into a new project and make a new DCP referencing it.
93  */
94 BOOST_AUTO_TEST_CASE (reels_test2)
95 {
96         shared_ptr<Film> film = new_test_film ("reels_test2");
97         film->set_name ("reels_test2");
98         film->set_container (Ratio::from_id ("185"));
99         film->set_interop (false);
100         film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
101
102         {
103                 shared_ptr<ImageContent> c (new ImageContent("test/data/flat_red.png"));
104                 film->examine_and_add_content (c);
105                 BOOST_REQUIRE (!wait_for_jobs());
106                 c->video->set_length (24);
107         }
108
109         {
110                 shared_ptr<ImageContent> c (new ImageContent("test/data/flat_green.png"));
111                 film->examine_and_add_content (c);
112                 BOOST_REQUIRE (!wait_for_jobs());
113                 c->video->set_length (24);
114         }
115
116         {
117                 shared_ptr<ImageContent> c (new ImageContent("test/data/flat_blue.png"));
118                 film->examine_and_add_content (c);
119                 BOOST_REQUIRE (!wait_for_jobs());
120                 c->video->set_length (24);
121         }
122
123         film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
124         BOOST_REQUIRE (!wait_for_jobs());
125
126         film->make_dcp ();
127         BOOST_REQUIRE (!wait_for_jobs());
128
129         check_dcp ("test/data/reels_test2", film->dir (film->dcp_name()));
130
131         shared_ptr<Film> film2 = new_test_film ("reels_test2b");
132         film2->set_name ("reels_test2b");
133         film2->set_container (Ratio::from_id ("185"));
134         film2->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
135         film2->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
136
137         shared_ptr<DCPContent> c (new DCPContent(film->dir(film->dcp_name())));
138         film2->examine_and_add_content (c);
139         BOOST_REQUIRE (!wait_for_jobs ());
140
141         list<DCPTimePeriod> r = film2->reels ();
142         BOOST_CHECK_EQUAL (r.size(), 3);
143         list<DCPTimePeriod>::const_iterator i = r.begin ();
144         BOOST_CHECK_EQUAL (i->from.get(), 0);
145         BOOST_CHECK_EQUAL (i->to.get(), 96000);
146         ++i;
147         BOOST_CHECK_EQUAL (i->from.get(), 96000);
148         BOOST_CHECK_EQUAL (i->to.get(), 96000 * 2);
149         ++i;
150         BOOST_CHECK_EQUAL (i->from.get(), 96000 * 2);
151         BOOST_CHECK_EQUAL (i->to.get(), 96000 * 3);
152
153         c->set_reference_video (true);
154         c->set_reference_audio (true);
155
156         film2->make_dcp ();
157         BOOST_REQUIRE (!wait_for_jobs());
158 }
159
160 /** Check that REELTYPE_BY_VIDEO_CONTENT adds an extra reel, if necessary, at the end
161  *  of all the video content to mop up anything afterward.
162  */
163 BOOST_AUTO_TEST_CASE (reels_test3)
164 {
165         shared_ptr<Film> film = new_test_film ("reels_test3");
166         film->set_name ("reels_test3");
167         film->set_container (Ratio::from_id ("185"));
168         film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
169         film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
170
171         shared_ptr<Content> dcp (new DCPContent("test/data/reels_test2"));
172         film->examine_and_add_content (dcp);
173         shared_ptr<Content> sub (new StringTextFileContent("test/data/subrip.srt"));
174         film->examine_and_add_content (sub);
175         BOOST_REQUIRE (!wait_for_jobs());
176
177         list<DCPTimePeriod> reels = film->reels();
178         BOOST_REQUIRE_EQUAL (reels.size(), 4);
179         list<DCPTimePeriod>::const_iterator i = reels.begin ();
180         BOOST_CHECK_EQUAL (i->from.get(), 0);
181         BOOST_CHECK_EQUAL (i->to.get(), 96000);
182         ++i;
183         BOOST_CHECK_EQUAL (i->from.get(), 96000);
184         BOOST_CHECK_EQUAL (i->to.get(), 96000 * 2);
185         ++i;
186         BOOST_CHECK_EQUAL (i->from.get(), 96000 * 2);
187         BOOST_CHECK_EQUAL (i->to.get(), 96000 * 3);
188         ++i;
189         BOOST_CHECK_EQUAL (i->from.get(), 96000 * 3);
190         BOOST_CHECK_EQUAL (i->to.get(), sub->full_length(film).ceil(film->video_frame_rate()).get());
191 }
192
193 /** Check creation of a multi-reel DCP with a single .srt subtitle file;
194  *  make sure that the reel subtitle timing is done right.
195  */
196 BOOST_AUTO_TEST_CASE (reels_test4)
197 {
198         shared_ptr<Film> film = new_test_film ("reels_test4");
199         film->set_name ("reels_test4");
200         film->set_container (Ratio::from_id ("185"));
201         film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
202         film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
203         film->set_interop (false);
204
205         /* 4 piece of 1s-long content */
206         shared_ptr<ImageContent> content[4];
207         for (int i = 0; i < 4; ++i) {
208                 content[i].reset (new ImageContent("test/data/flat_green.png"));
209                 film->examine_and_add_content (content[i]);
210                 BOOST_REQUIRE (!wait_for_jobs());
211                 content[i]->video->set_length (24);
212         }
213
214         shared_ptr<StringTextFileContent> subs (new StringTextFileContent("test/data/subrip3.srt"));
215         film->examine_and_add_content (subs);
216         BOOST_REQUIRE (!wait_for_jobs());
217
218         list<DCPTimePeriod> reels = film->reels();
219         BOOST_REQUIRE_EQUAL (reels.size(), 4);
220         list<DCPTimePeriod>::const_iterator i = reels.begin ();
221         BOOST_CHECK_EQUAL (i->from.get(), 0);
222         BOOST_CHECK_EQUAL (i->to.get(), 96000);
223         ++i;
224         BOOST_CHECK_EQUAL (i->from.get(), 96000);
225         BOOST_CHECK_EQUAL (i->to.get(), 96000 * 2);
226         ++i;
227         BOOST_CHECK_EQUAL (i->from.get(), 96000 * 2);
228         BOOST_CHECK_EQUAL (i->to.get(), 96000 * 3);
229         ++i;
230         BOOST_CHECK_EQUAL (i->from.get(), 96000 * 3);
231         BOOST_CHECK_EQUAL (i->to.get(), 96000 * 4);
232
233         film->make_dcp ();
234         BOOST_REQUIRE (!wait_for_jobs());
235
236         check_dcp ("test/data/reels_test4", film->dir (film->dcp_name()));
237 }
238
239 BOOST_AUTO_TEST_CASE (reels_test5)
240 {
241         shared_ptr<Film> film = new_test_film ("reels_test5");
242         film->set_sequence (false);
243         shared_ptr<DCPContent> dcp (new DCPContent("test/data/reels_test4"));
244         film->examine_and_add_content (dcp);
245         BOOST_REQUIRE (!wait_for_jobs ());
246
247         /* Set to 2123 but it will be rounded up to the next frame (4000) */
248         dcp->set_position(film, DCPTime(2123));
249
250         {
251                 list<DCPTimePeriod> p = dcp->reels (film);
252                 BOOST_REQUIRE_EQUAL (p.size(), 4);
253                 list<DCPTimePeriod>::const_iterator i = p.begin();
254                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 0), DCPTime(4000 + 96000)));
255                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 96000), DCPTime(4000 + 192000)));
256                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 192000), DCPTime(4000 + 288000)));
257                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 288000), DCPTime(4000 + 384000)));
258         }
259
260         {
261                 dcp->set_trim_start (ContentTime::from_seconds (0.5));
262                 list<DCPTimePeriod> p = dcp->reels (film);
263                 BOOST_REQUIRE_EQUAL (p.size(), 4);
264                 list<DCPTimePeriod>::const_iterator i = p.begin();
265                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 0), DCPTime(4000 + 48000)));
266                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 48000), DCPTime(4000 + 144000)));
267                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 144000), DCPTime(4000 + 240000)));
268                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 240000), DCPTime(4000 + 336000)));
269         }
270
271         {
272                 dcp->set_trim_end (ContentTime::from_seconds (0.5));
273                 list<DCPTimePeriod> p = dcp->reels (film);
274                 BOOST_REQUIRE_EQUAL (p.size(), 4);
275                 list<DCPTimePeriod>::const_iterator i = p.begin();
276                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 0), DCPTime(4000 + 48000)));
277                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 48000), DCPTime(4000 + 144000)));
278                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 144000), DCPTime(4000 + 240000)));
279                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 240000), DCPTime(4000 + 288000)));
280         }
281
282         {
283                 dcp->set_trim_start (ContentTime::from_seconds (1.5));
284                 list<DCPTimePeriod> p = dcp->reels (film);
285                 BOOST_REQUIRE_EQUAL (p.size(), 3);
286                 list<DCPTimePeriod>::const_iterator i = p.begin();
287                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 0), DCPTime(4000 + 48000)));
288                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 48000), DCPTime(4000 + 144000)));
289                 BOOST_CHECK (*i++ == DCPTimePeriod (DCPTime(4000 + 144000), DCPTime(4000 + 192000)));
290         }
291 }
292
293 /** Check reel split with a muxed video/audio source */
294 BOOST_AUTO_TEST_CASE (reels_test6)
295 {
296         shared_ptr<Film> film = new_test_film ("reels_test6");
297         film->set_name ("reels_test6");
298         film->set_container (Ratio::from_id ("185"));
299         film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
300         shared_ptr<FFmpegContent> A (new FFmpegContent("test/data/test2.mp4"));
301         film->examine_and_add_content (A);
302         BOOST_REQUIRE (!wait_for_jobs ());
303
304         film->set_j2k_bandwidth (100000000);
305         film->set_reel_type (REELTYPE_BY_LENGTH);
306         /* This is just over 2.5s at 100Mbit/s; should correspond to 60 frames */
307         film->set_reel_length (31253154);
308         film->make_dcp ();
309         BOOST_REQUIRE (!wait_for_jobs ());
310 }
311
312 /** Check the case where the last bit of audio hangs over the end of the video
313  *  and we are using REELTYPE_BY_VIDEO_CONTENT.
314  */
315 BOOST_AUTO_TEST_CASE (reels_test7)
316 {
317         shared_ptr<Film> film = new_test_film ("reels_test7");
318         film->set_name ("reels_test7");
319         film->set_container (Ratio::from_id ("185"));
320         film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
321         shared_ptr<Content> A = content_factory("test/data/flat_red.png").front();
322         film->examine_and_add_content (A);
323         BOOST_REQUIRE (!wait_for_jobs ());
324         shared_ptr<Content> B = content_factory("test/data/awkward_length.wav").front();
325         film->examine_and_add_content (B);
326         BOOST_REQUIRE (!wait_for_jobs ());
327         film->set_video_frame_rate (24);
328         A->video->set_length (3 * 24);
329
330         film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
331         BOOST_REQUIRE_EQUAL (film->reels().size(), 2);
332         BOOST_CHECK (film->reels().front() == DCPTimePeriod(DCPTime(0), DCPTime::from_frames(3 * 24, 24)));
333         BOOST_CHECK (film->reels().back() == DCPTimePeriod(DCPTime::from_frames(3 * 24, 24), DCPTime::from_frames(3 * 24 + 1, 24)));
334
335         film->make_dcp ();
336         BOOST_REQUIRE (!wait_for_jobs ());
337 }
338
339 /** Check a reels-related error; make_dcp() would raise a ProgrammingError */
340 BOOST_AUTO_TEST_CASE (reels_test8)
341 {
342         shared_ptr<Film> film = new_test_film ("reels_test8");
343         film->set_name ("reels_test8");
344         film->set_container (Ratio::from_id ("185"));
345         film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
346         shared_ptr<FFmpegContent> A (new FFmpegContent("test/data/test2.mp4"));
347         film->examine_and_add_content (A);
348         BOOST_REQUIRE (!wait_for_jobs ());
349
350         A->set_trim_end (ContentTime::from_seconds (1));
351         film->make_dcp ();
352         BOOST_REQUIRE (!wait_for_jobs ());
353 }
354
355 /** Check another reels-related error; make_dcp() would raise a ProgrammingError */
356 BOOST_AUTO_TEST_CASE (reels_test9)
357 {
358         shared_ptr<Film> film = new_test_film2("reels_test9a");
359         shared_ptr<FFmpegContent> A(new FFmpegContent("test/data/flat_red.png"));
360         film->examine_and_add_content(A);
361         BOOST_REQUIRE(!wait_for_jobs());
362         A->video->set_length(5 * 24);
363         film->set_video_frame_rate(24);
364         film->make_dcp();
365         BOOST_REQUIRE(!wait_for_jobs());
366
367         shared_ptr<Film> film2 = new_test_film2("reels_test9b");
368         shared_ptr<DCPContent> B(new DCPContent(film->dir(film->dcp_name())));
369         film2->examine_and_add_content(B);
370         film2->examine_and_add_content(content_factory("test/data/dcp_sub4.xml").front());
371         B->set_reference_video(true);
372         B->set_reference_audio(true);
373         BOOST_REQUIRE(!wait_for_jobs());
374         film2->set_reel_type(REELTYPE_BY_VIDEO_CONTENT);
375         film2->write_metadata();
376         film2->make_dcp();
377         BOOST_REQUIRE(!wait_for_jobs());
378 }
379
380 /** Another reels-related error; make_dcp() would raise a ProgrammingError
381  *  in AudioBuffers::allocate due to an attempt to allocate a negatively-sized buffer.
382  *  This was triggered by a VF where there are referenced audio reels followed by
383  *  VF audio.  When the VF audio arrives the Writer did not correctly skip over the
384  *  referenced reels.
385  */
386 BOOST_AUTO_TEST_CASE (reels_test10)
387 {
388         /* Make the OV */
389         shared_ptr<Film> ov = new_test_film2("reels_test10_ov");
390         shared_ptr<FFmpegContent> A(new FFmpegContent("test/data/flat_red.png"));
391         ov->examine_and_add_content (A);
392         BOOST_REQUIRE (!wait_for_jobs());
393         A->video->set_length (5 * 24);
394
395         shared_ptr<FFmpegContent> B(new FFmpegContent("test/data/flat_red.png"));
396         ov->examine_and_add_content (B);
397         BOOST_REQUIRE (!wait_for_jobs());
398         B->video->set_length (5 * 24);
399
400         ov->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
401         ov->make_dcp ();
402         BOOST_REQUIRE (!wait_for_jobs());
403         ov->write_metadata ();
404
405         /* Now try to make the VF; this used to fail */
406         shared_ptr<Film> vf = new_test_film2("reels_test10_vf");
407         shared_ptr<DCPContent> ov_dcp(new DCPContent(ov->dir(ov->dcp_name())));
408         vf->examine_and_add_content (ov_dcp);
409         BOOST_REQUIRE (!wait_for_jobs());
410         vf->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
411         ov_dcp->set_reference_video (true);
412         ov_dcp->set_reference_audio (true);
413         vf->examine_and_add_content (content_factory("test/data/15s.srt").front());
414         BOOST_REQUIRE (!wait_for_jobs());
415
416         vf->make_dcp ();
417         BOOST_REQUIRE (!wait_for_jobs());
418         vf->write_metadata ();
419 }
420
421 /** Another reels error; REELTYPE_BY_VIDEO_CONTENT when the first content is not
422  *  at time 0.
423  */
424 BOOST_AUTO_TEST_CASE (reels_test11)
425 {
426         shared_ptr<Film> film = new_test_film2 ("reels_test11");
427         film->set_video_frame_rate (24);
428         shared_ptr<FFmpegContent> A(new FFmpegContent("test/data/flat_red.png"));
429         film->examine_and_add_content (A);
430         BOOST_REQUIRE (!wait_for_jobs());
431         A->video->set_length (240);
432         A->set_video_frame_rate (24);
433         A->set_position (film, DCPTime::from_seconds(1));
434         film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
435         film->make_dcp ();
436         BOOST_REQUIRE (!wait_for_jobs());
437         BOOST_CHECK_EQUAL (A->position().get(), DCPTime::from_seconds(1).get());
438         BOOST_CHECK_EQUAL (A->end(film).get(), DCPTime::from_seconds(1 + 10).get());
439
440         list<DCPTimePeriod> r = film->reels ();
441         BOOST_CHECK_EQUAL (r.size(), 2);
442         BOOST_CHECK_EQUAL (r.front().from.get(), 0);
443         BOOST_CHECK_EQUAL (r.front().to.get(), DCPTime::from_seconds(1).get());
444         BOOST_CHECK_EQUAL (r.back().from.get(), DCPTime::from_seconds(1).get());
445         BOOST_CHECK_EQUAL (r.back().to.get(), DCPTime::from_seconds(1 + 10).get());
446 }
447
448 /** For VFs to work right we have to make separate reels for empty bits between
449  *  video content.
450  */
451 BOOST_AUTO_TEST_CASE (reels_test12)
452 {
453         shared_ptr<Film> film = new_test_film2 ("reels_test12");
454         film->set_video_frame_rate (24);
455         film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
456         film->set_sequence (false);
457
458         shared_ptr<FFmpegContent> A(new FFmpegContent("test/data/flat_red.png"));
459         film->examine_and_add_content (A);
460         BOOST_REQUIRE (!wait_for_jobs());
461         A->video->set_length (240);
462         A->set_video_frame_rate (24);
463         A->set_position (film, DCPTime::from_seconds(1));
464
465         shared_ptr<FFmpegContent> B(new FFmpegContent("test/data/flat_red.png"));
466         film->examine_and_add_content (B);
467         BOOST_REQUIRE (!wait_for_jobs());
468         B->video->set_length (120);
469         B->set_video_frame_rate (24);
470         B->set_position (film, DCPTime::from_seconds(14));
471
472         list<DCPTimePeriod> r = film->reels ();
473         BOOST_REQUIRE_EQUAL (r.size(), 4);
474         list<DCPTimePeriod>::const_iterator i = r.begin ();
475
476         BOOST_CHECK_EQUAL (i->from.get(), 0);
477         BOOST_CHECK_EQUAL (i->to.get(),   DCPTime::from_seconds(1).get());
478         ++i;
479         BOOST_CHECK_EQUAL (i->from.get(), DCPTime::from_seconds(1).get());
480         BOOST_CHECK_EQUAL (i->to.get(),   DCPTime::from_seconds(11).get());
481         ++i;
482         BOOST_CHECK_EQUAL (i->from.get(), DCPTime::from_seconds(11).get());
483         BOOST_CHECK_EQUAL (i->to.get(),   DCPTime::from_seconds(14).get());
484         ++i;
485         BOOST_CHECK_EQUAL (i->from.get(), DCPTime::from_seconds(14).get());
486         BOOST_CHECK_EQUAL (i->to.get(),   DCPTime::from_seconds(19).get());
487 }
488
489 static void
490 no_op ()
491 {
492
493 }
494
495
496 /** Using less than 1 second's worth of content should not result in a reel
497  *  of less than 1 second's duration.
498  */
499 BOOST_AUTO_TEST_CASE (reels_should_not_be_short1)
500 {
501         shared_ptr<Film> film = new_test_film2 ("reels_should_not_be_short1");
502         film->set_video_frame_rate (24);
503
504         shared_ptr<FFmpegContent> A(new FFmpegContent("test/data/flat_red.png"));
505         film->examine_and_add_content (A);
506         BOOST_REQUIRE (!wait_for_jobs());
507         A->video->set_length (23);
508
509         film->make_dcp ();
510         BOOST_REQUIRE (!wait_for_jobs());
511
512         vector<boost::filesystem::path> dirs;
513         dirs.push_back (film->dir(film->dcp_name(false)));
514         BOOST_REQUIRE (dcp::verify(dirs, boost::bind(&no_op), boost::bind(&no_op), TestPaths::xsd).empty());
515 }
516