Revert "Fix test to take into account changes to rounding."
[dcpomatic.git] / test / time_calculation_test.cc
1 /*
2     Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "lib/film.h"
21 #include "lib/ffmpeg_content.h"
22 #include "lib/player.h"
23 #include "test.h"
24 #include <boost/test/unit_test.hpp>
25
26 using std::string;
27 using std::list;
28 using boost::shared_ptr;
29
30 static string const xml = "<Content>"
31         "<Type>FFmpeg</Type>"
32         "<BurnSubtitles>0</BurnSubtitles>"
33         "<BitsPerPixel>8</BitsPerPixel>"
34         "<Path>test/data/red_24.mp4</Path>"
35         "<Digest>2760e03c7251480f7f02c01a907792673784335</Digest>"
36         "<Position>0</Position>"
37         "<TrimStart>0</TrimStart>"
38         "<TrimEnd>0</TrimEnd>"
39         "<VideoLength>1353600</VideoLength>"
40         "<VideoWidth>1280</VideoWidth>"
41         "<VideoHeight>720</VideoHeight>"
42         "<VideoFrameRate>25</VideoFrameRate>"
43         "<VideoFrameType>0</VideoFrameType>"
44         "<LeftCrop>0</LeftCrop>"
45         "<RightCrop>0</RightCrop>"
46         "<TopCrop>0</TopCrop>"
47         "<BottomCrop>0</BottomCrop>"
48         "<Scale>"
49         "<Ratio>178</Ratio>"
50         "</Scale>"
51         "<ColourConversion>"
52         "<InputTransferFunction>"
53         "<Type>ModifiedGamma</Type>"
54         "<Power>2.222222222222222</Power>"
55         "<Threshold>0.081</Threshold>"
56         "<A>0.099</A>"
57         "<B>4.5</B>"
58         "</InputTransferFunction>"
59         "<RedX>0.64</RedX>"
60         "<RedY>0.33</RedY>"
61         "<GreenX>0.3</GreenX>"
62         "<GreenY>0.6</GreenY>"
63         "<BlueX>0.15</BlueX>"
64         "<BlueY>0.06</BlueY>"
65         "<WhiteX>0.3127</WhiteX>"
66         "<WhiteY>0.329</WhiteY>"
67         "<OutputGamma>2.6</OutputGamma>"
68         "</ColourConversion>"
69         "<FadeIn>0</FadeIn>"
70         "<FadeOut>0</FadeOut>"
71         "<AudioGain>0</AudioGain>"
72         "<AudioDelay>0</AudioDelay>"
73         "<UseSubtitles>0</UseSubtitles>"
74         "<SubtitleXOffset>0</SubtitleXOffset>"
75         "<SubtitleYOffset>0</SubtitleYOffset>"
76         "<SubtitleXScale>1</SubtitleXScale>"
77         "<SubtitleYScale>1</SubtitleYScale>"
78         "<SubtitleLanguage></SubtitleLanguage>"
79         "<AudioStream>"
80         "<Selected>1</Selected>"
81         "<Name>und; 2 channels</Name>"
82         "<Id>2</Id>"
83         "<FrameRate>44100</FrameRate>"
84         "<Channels>2</Channels>"
85         "<FirstAudio>0</FirstAudio>"
86         "<Mapping>"
87         "<InputChannels>2</InputChannels>"
88         "<OutputChannels>12</OutputChannels>"
89         "<Gain Input=\"0\" Output=\"0\">1</Gain>"
90         "<Gain Input=\"0\" Output=\"1\">0</Gain>"
91         "<Gain Input=\"0\" Output=\"2\">0</Gain>"
92         "<Gain Input=\"0\" Output=\"3\">0</Gain>"
93         "<Gain Input=\"0\" Output=\"4\">0</Gain>"
94         "<Gain Input=\"0\" Output=\"5\">0</Gain>"
95         "<Gain Input=\"0\" Output=\"6\">0</Gain>"
96         "<Gain Input=\"0\" Output=\"7\">0</Gain>"
97         "<Gain Input=\"0\" Output=\"8\">0</Gain>"
98         "<Gain Input=\"0\" Output=\"9\">0</Gain>"
99         "<Gain Input=\"0\" Output=\"10\">0</Gain>"
100         "<Gain Input=\"0\" Output=\"11\">0</Gain>"
101         "<Gain Input=\"1\" Output=\"0\">0</Gain>"
102         "<Gain Input=\"1\" Output=\"1\">1</Gain>"
103         "<Gain Input=\"1\" Output=\"2\">0</Gain>"
104         "<Gain Input=\"1\" Output=\"3\">0</Gain>"
105         "<Gain Input=\"1\" Output=\"4\">0</Gain>"
106         "<Gain Input=\"1\" Output=\"5\">0</Gain>"
107         "<Gain Input=\"1\" Output=\"6\">0</Gain>"
108         "<Gain Input=\"1\" Output=\"7\">0</Gain>"
109         "<Gain Input=\"1\" Output=\"8\">0</Gain>"
110         "<Gain Input=\"1\" Output=\"9\">0</Gain>"
111         "<Gain Input=\"1\" Output=\"10\">0</Gain>"
112         "<Gain Input=\"1\" Output=\"11\">0</Gain>"
113         "</Mapping>"
114         "</AudioStream>"
115         "<FirstVideo>0</FirstVideo>"
116         "</Content>";
117
118 BOOST_AUTO_TEST_CASE (ffmpeg_time_calculation_test)
119 {
120         shared_ptr<Film> film = new_test_film ("ffmpeg_time_calculation_test");
121
122         shared_ptr<cxml::Document> doc (new cxml::Document);
123         doc->read_string (xml);
124
125         list<string> notes;
126         shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
127
128         /* 25fps content, 25fps DCP */
129         film->set_video_frame_rate (25);
130         BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() / 25.0));
131         /* 25fps content, 24fps DCP; length should be increased */
132         film->set_video_frame_rate (24);
133         BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() / 24.0));
134         /* 25fps content, 30fps DCP; length should be decreased */
135         film->set_video_frame_rate (30);
136         BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() / 30.0));
137         /* 25fps content, 50fps DCP; length should be the same */
138         film->set_video_frame_rate (50);
139         BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() / 25.0));
140         /* 25fps content, 60fps DCP; length should be decreased */
141         film->set_video_frame_rate (60);
142         BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video_length() * (50.0 / 60) / 25.0));
143 }
144
145 /** Test Player::dcp_to_content_video */
146 BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
147 {
148         shared_ptr<Film> film = new_test_film ("player_time_calculation_test1");
149
150         shared_ptr<cxml::Document> doc (new cxml::Document);
151         doc->read_string (xml);
152
153         list<string> notes;
154         shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
155         film->set_sequence_video (false);
156         film->add_content (content);
157
158         shared_ptr<Player> player (new Player (film, film->playlist ()));
159
160         /* Position 0, no trim, content rate = DCP rate */
161         content->set_position (DCPTime ());
162         content->set_trim_start (ContentTime ());
163         content->set_video_frame_rate (24);
164         film->set_video_frame_rate (24);
165         player->setup_pieces ();
166         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
167         shared_ptr<Piece> piece = player->_pieces.front ();
168         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
169         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
170         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
171
172         /* Position 3s, no trim, content rate = DCP rate */
173         content->set_position (DCPTime::from_seconds (3));
174         content->set_trim_start (ContentTime ());
175         content->set_video_frame_rate (24);
176         film->set_video_frame_rate (24);
177         player->setup_pieces ();
178         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
179         piece = player->_pieces.front ();
180         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
181         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
182         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),   0);
183         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)),  36);
184         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
185
186         /* Position 3s, 1.5s trim, content rate = DCP rate */
187         content->set_position (DCPTime::from_seconds (3));
188         content->set_trim_start (ContentTime::from_seconds (1.5));
189         content->set_video_frame_rate (24);
190         film->set_video_frame_rate (24);
191         player->setup_pieces ();
192         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
193         piece = player->_pieces.front ();
194         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
195         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
196         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),  36);
197         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)),  72);
198         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
199
200         /* Position 0, no trim, content rate 24, DCP rate 25.
201            Now, for example, a DCPTime position of 3s means 3s at 25fps.  Since we run the video
202            fast (at 25fps) in this case, this means 75 frames of content video will be used.
203         */
204         content->set_position (DCPTime ());
205         content->set_trim_start (ContentTime ());
206         content->set_video_frame_rate (24);
207         film->set_video_frame_rate (25);
208         player->setup_pieces ();
209         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
210         piece = player->_pieces.front ();
211         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
212         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.6)), 15);
213         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 75);
214
215         /* Position 3s, no trim, content rate 24, DCP rate 25 */
216         content->set_position (DCPTime::from_seconds (3));
217         content->set_trim_start (ContentTime ());
218         content->set_video_frame_rate (24);
219         film->set_video_frame_rate (25);
220         player->setup_pieces ();
221         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
222         piece = player->_pieces.front ();
223         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
224         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)),   0);
225         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),   0);
226         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)),  40);
227         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 168);
228
229         /* Position 3s, 1.6s trim, content rate 24, DCP rate 25.  Here the trim is in ContentTime,
230            so it's 1.6s at 24fps.
231          */
232         content->set_position (DCPTime::from_seconds (3));
233         content->set_trim_start (ContentTime::from_seconds (1.6));
234         content->set_video_frame_rate (24);
235         film->set_video_frame_rate (25);
236         player->setup_pieces ();
237         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
238         piece = player->_pieces.front ();
239         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
240         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)),   0);
241         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),  38);
242         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)),  78);
243         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 207);
244
245         /* Position 0, no trim, content rate 24, DCP rate 48
246            Now, for example, a DCPTime position of 3s means 3s at 48fps.  Since we run the video
247            with repeated frames in this case, 3 * 24 frames of content video will
248            be used to make 3 * 48 frames of DCP video.  The results should be the same as the
249            content rate = DCP rate case.
250         */
251         content->set_position (DCPTime ());
252         content->set_trim_start (ContentTime ());
253         content->set_video_frame_rate (24);
254         film->set_video_frame_rate (48);
255         player->setup_pieces ();
256         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
257         piece = player->_pieces.front ();
258         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
259         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
260         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
261
262         /* Position 3s, no trim, content rate 24, DCP rate 48 */
263         content->set_position (DCPTime::from_seconds (3));
264         content->set_trim_start (ContentTime ());
265         content->set_video_frame_rate (24);
266         film->set_video_frame_rate (48);
267         player->setup_pieces ();
268         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
269         piece = player->_pieces.front ();
270         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
271         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
272         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),   0);
273         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)),  36);
274         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
275
276         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
277         content->set_position (DCPTime::from_seconds (3));
278         content->set_trim_start (ContentTime::from_seconds (1.5));
279         content->set_video_frame_rate (24);
280         film->set_video_frame_rate (48);
281         player->setup_pieces ();
282         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
283         piece = player->_pieces.front ();
284         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
285         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
286         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),  36);
287         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)),  72);
288         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
289
290         /* Position 0, no trim, content rate 48, DCP rate 24
291            Now, for example, a DCPTime position of 3s means 3s at 24fps.  Since we run the video
292            with skipped frames in this case, 3 * 48 frames of content video will
293            be used to make 3 * 24 frames of DCP video.
294         */
295         content->set_position (DCPTime ());
296         content->set_trim_start (ContentTime ());
297         content->set_video_frame_rate (48);
298         film->set_video_frame_rate (24);
299         player->setup_pieces ();
300         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
301         piece = player->_pieces.front ();
302         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
303         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 24);
304         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 144);
305
306         /* Position 3s, no trim, content rate 24, DCP rate 48 */
307         content->set_position (DCPTime::from_seconds (3));
308         content->set_trim_start (ContentTime ());
309         content->set_video_frame_rate (48);
310         film->set_video_frame_rate (24);
311         player->setup_pieces ();
312         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
313         piece = player->_pieces.front ();
314         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
315         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
316         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),   0);
317         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)),  72);
318         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 324);
319
320         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
321         content->set_position (DCPTime::from_seconds (3));
322         content->set_trim_start (ContentTime::from_seconds (1.5));
323         content->set_video_frame_rate (48);
324         film->set_video_frame_rate (24);
325         player->setup_pieces ();
326         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
327         piece = player->_pieces.front ();
328         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
329         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
330         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),  72);
331         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 144);
332         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 396);
333 }
334
335 /** Test Player::content_video_to_dcp */
336 BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
337 {
338         shared_ptr<Film> film = new_test_film ("player_time_calculation_test2");
339
340         shared_ptr<cxml::Document> doc (new cxml::Document);
341         doc->read_string (xml);
342
343         list<string> notes;
344         shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
345         film->set_sequence_video (false);
346         film->add_content (content);
347
348         shared_ptr<Player> player (new Player (film, film->playlist ()));
349
350         /* Position 0, no trim, content rate = DCP rate */
351         content->set_position (DCPTime ());
352         content->set_trim_start (ContentTime ());
353         content->set_video_frame_rate (24);
354         film->set_video_frame_rate (24);
355         player->setup_pieces ();
356         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
357         shared_ptr<Piece> piece = player->_pieces.front ();
358         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
359         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
360         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
361
362         /* Position 3s, no trim, content rate = DCP rate */
363         content->set_position (DCPTime::from_seconds (3));
364         content->set_trim_start (ContentTime ());
365         content->set_video_frame_rate (24);
366         film->set_video_frame_rate (24);
367         player->setup_pieces ();
368         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
369         piece = player->_pieces.front ();
370         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
371         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
372         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
373
374         /* Position 3s, 1.5s trim, content rate = DCP rate */
375         content->set_position (DCPTime::from_seconds (3));
376         content->set_trim_start (ContentTime::from_seconds (1.5));
377         content->set_video_frame_rate (24);
378         film->set_video_frame_rate (24);
379         player->setup_pieces ();
380         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
381         piece = player->_pieces.front ();
382         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
383         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
384         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
385         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
386
387         /* Position 0, no trim, content rate 24, DCP rate 25.
388            Now, for example, a DCPTime position of 3s means 3s at 25fps.  Since we run the video
389            fast (at 25fps) in this case, this means 75 frames of content video will be used.
390         */
391         content->set_position (DCPTime ());
392         content->set_trim_start (ContentTime ());
393         content->set_video_frame_rate (24);
394         film->set_video_frame_rate (25);
395         player->setup_pieces ();
396         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
397         piece = player->_pieces.front ();
398         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
399         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 15), DCPTime::from_seconds (0.6));
400         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 75), DCPTime::from_seconds (3.0));
401
402         /* Position 3s, no trim, content rate 24, DCP rate 25 */
403         content->set_position (DCPTime::from_seconds (3));
404         content->set_trim_start (ContentTime ());
405         content->set_video_frame_rate (24);
406         film->set_video_frame_rate (25);
407         player->setup_pieces ();
408         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
409         piece = player->_pieces.front ();
410         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
411         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (4.60));
412         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 169), DCPTime::from_seconds (9.76));
413
414         /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, so the 1.6s trim is at 24fps */
415         content->set_position (DCPTime::from_seconds (3));
416         content->set_trim_start (ContentTime::from_seconds (1.6));
417         content->set_video_frame_rate (24);
418         film->set_video_frame_rate (25);
419         player->setup_pieces ();
420         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
421         piece = player->_pieces.front ();
422         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.464));
423         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (3.064));
424         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 80), DCPTime::from_seconds (4.664));
425         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 209), DCPTime::from_seconds (9.824));
426
427         /* Position 0, no trim, content rate 24, DCP rate 48
428            Now, for example, a DCPTime position of 3s means 3s at 48fps.  Since we run the video
429            with repeated frames in this case, 3 * 24 frames of content video will
430            be used to make 3 * 48 frames of DCP video.  The results should be the same as the
431            content rate = DCP rate case.
432         */
433         content->set_position (DCPTime ());
434         content->set_trim_start (ContentTime ());
435         content->set_video_frame_rate (24);
436         film->set_video_frame_rate (48);
437         player->setup_pieces ();
438         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
439         piece = player->_pieces.front ();
440         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
441         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
442         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
443
444         /* Position 3s, no trim, content rate 24, DCP rate 48 */
445         content->set_position (DCPTime::from_seconds (3));
446         content->set_trim_start (ContentTime ());
447         content->set_video_frame_rate (24);
448         film->set_video_frame_rate (48);
449         player->setup_pieces ();
450         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
451         piece = player->_pieces.front ();
452         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
453         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
454         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
455
456         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
457         content->set_position (DCPTime::from_seconds (3));
458         content->set_trim_start (ContentTime::from_seconds (1.5));
459         content->set_video_frame_rate (24);
460         film->set_video_frame_rate (48);
461         player->setup_pieces ();
462         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
463         piece = player->_pieces.front ();
464         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
465         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
466         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
467         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
468
469         /* Position 0, no trim, content rate 48, DCP rate 24
470            Now, for example, a DCPTime position of 3s means 3s at 24fps.  Since we run the video
471            with skipped frames in this case, 3 * 48 frames of content video will
472            be used to make 3 * 24 frames of DCP video.
473         */
474         content->set_position (DCPTime ());
475         content->set_trim_start (ContentTime ());
476         content->set_video_frame_rate (48);
477         film->set_video_frame_rate (24);
478         player->setup_pieces ();
479         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
480         piece = player->_pieces.front ();
481         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
482         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 24), DCPTime::from_seconds (0.5));
483         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (3.0));
484
485         /* Position 3s, no trim, content rate 24, DCP rate 48 */
486         content->set_position (DCPTime::from_seconds (3));
487         content->set_trim_start (ContentTime ());
488         content->set_video_frame_rate (48);
489         film->set_video_frame_rate (24);
490         player->setup_pieces ();
491         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
492         piece = player->_pieces.front ();
493         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
494         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
495         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 324), DCPTime::from_seconds (9.75));
496
497         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
498         content->set_position (DCPTime::from_seconds (3));
499         content->set_trim_start (ContentTime::from_seconds (1.5));
500         content->set_video_frame_rate (48);
501         film->set_video_frame_rate (24);
502         player->setup_pieces ();
503         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
504         piece = player->_pieces.front ();
505         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
506         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.00));
507         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (4.50));
508         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 396), DCPTime::from_seconds (9.75));
509 }
510
511 /** Test Player::dcp_to_content_audio */
512 BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
513 {
514         shared_ptr<Film> film = new_test_film ("player_time_calculation_test3");
515
516         shared_ptr<cxml::Document> doc (new cxml::Document);
517         doc->read_string (xml);
518
519         list<string> notes;
520         shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
521         AudioStreamPtr stream = content->audio_streams().front();
522         film->set_sequence_video (false);
523         film->add_content (content);
524
525         shared_ptr<Player> player (new Player (film, film->playlist ()));
526
527         /* Position 0, no trim, video/audio content rate = video/audio DCP rate */
528         content->set_position (DCPTime ());
529         content->set_trim_start (ContentTime ());
530         content->set_video_frame_rate (24);
531         film->set_video_frame_rate (24);
532         stream->_frame_rate = 48000;
533         player->setup_pieces ();
534         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
535         shared_ptr<Piece> piece = player->_pieces.front ();
536         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
537         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)),  24000);
538         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
539
540         /* Position 3s, no trim, video/audio content rate = video/audio DCP rate */
541         content->set_position (DCPTime::from_seconds (3));
542         content->set_trim_start (ContentTime ());
543         content->set_video_frame_rate (24);
544         film->set_video_frame_rate (24);
545         stream->_frame_rate = 48000;
546         player->setup_pieces ();
547         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
548         piece = player->_pieces.front ();
549         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
550         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)),      0);
551         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),      0);
552         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)),  72000);
553         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
554
555         /* Position 3s, 1.5s trim, video/audio content rate = video/audio DCP rate */
556         content->set_position (DCPTime::from_seconds (3));
557         content->set_trim_start (ContentTime::from_seconds (1.5));
558         content->set_video_frame_rate (24);
559         film->set_video_frame_rate (24);
560         stream->_frame_rate = 48000;
561         player->setup_pieces ();
562         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
563         piece = player->_pieces.front ();
564         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
565         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)),      0);
566         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),  72000);
567         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
568         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
569
570         /* Position 0, no trim, content video rate 24, DCP video rate 25, both audio rates still 48k */
571         content->set_position (DCPTime ());
572         content->set_trim_start (ContentTime ());
573         content->set_video_frame_rate (24);
574         film->set_video_frame_rate (25);
575         stream->_frame_rate = 48000;
576         player->setup_pieces ();
577         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
578         piece = player->_pieces.front ();
579         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
580         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.6)),  28800);
581         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
582
583         /* Position 3s, no trim, content video rate 24, DCP rate 25, both audio rates still 48k. */
584         content->set_position (DCPTime::from_seconds (3));
585         content->set_trim_start (ContentTime ());
586         content->set_video_frame_rate (24);
587         film->set_video_frame_rate (25);
588         stream->_frame_rate = 48000;
589         player->setup_pieces ();
590         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
591         piece = player->_pieces.front ();
592         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
593         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)),      0);
594         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),      0);
595         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)),  76800);
596         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
597
598         /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, both audio rates still 48k.
599            1s of content is 46080 samples after resampling.
600         */
601         content->set_position (DCPTime::from_seconds (3));
602         content->set_trim_start (ContentTime::from_seconds (1.6));
603         content->set_video_frame_rate (24);
604         film->set_video_frame_rate (25);
605         stream->_frame_rate = 48000;
606         player->setup_pieces ();
607         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
608         piece = player->_pieces.front ();
609         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
610         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)),      0);
611         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),  73728);
612         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 150528);
613         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 397728);
614
615         /* Position 0, no trim, content rate 24, DCP rate 48, both audio rates still 48k.
616            Now, for example, a DCPTime position of 3s means 3s at 48fps.  Since we run the video
617            with repeated frames in this case, audio samples will map straight through.
618            The results should be the same as the content rate = DCP rate case.
619         */
620         content->set_position (DCPTime ());
621         content->set_trim_start (ContentTime ());
622         content->set_video_frame_rate (24);
623         film->set_video_frame_rate (48);
624         stream->_frame_rate = 48000;
625         player->setup_pieces ();
626         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
627         piece = player->_pieces.front ();
628         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
629         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)),  24000);
630         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
631
632         /* Position 3s, no trim, content rate 24, DCP rate 48 */
633         content->set_position (DCPTime::from_seconds (3));
634         content->set_trim_start (ContentTime ());
635         content->set_video_frame_rate (24);
636         film->set_video_frame_rate (24);
637         stream->_frame_rate = 48000;
638         player->setup_pieces ();
639         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
640         piece = player->_pieces.front ();
641         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
642         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)),      0);
643         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),      0);
644         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)),  72000);
645         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
646
647         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
648         content->set_position (DCPTime::from_seconds (3));
649         content->set_trim_start (ContentTime::from_seconds (1.5));
650         content->set_video_frame_rate (24);
651         film->set_video_frame_rate (24);
652         stream->_frame_rate = 48000;
653         player->setup_pieces ();
654         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
655         piece = player->_pieces.front ();
656         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
657         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)),   0);
658         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),  72000);
659         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
660         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
661
662         /* Position 0, no trim, content rate 48, DCP rate 24
663            Now, for example, a DCPTime position of 3s means 3s at 24fps.  Since we run the video
664            with skipped frames in this case, audio samples should map straight through.
665         */
666         content->set_position (DCPTime ());
667         content->set_trim_start (ContentTime ());
668         content->set_video_frame_rate (24);
669         film->set_video_frame_rate (48);
670         stream->_frame_rate = 48000;
671         player->setup_pieces ();
672         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
673         piece = player->_pieces.front ();
674         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
675         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)),  24000);
676         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
677
678         /* Position 3s, no trim, content rate 24, DCP rate 48 */
679         content->set_position (DCPTime::from_seconds (3));
680         content->set_trim_start (ContentTime ());
681         content->set_video_frame_rate (24);
682         film->set_video_frame_rate (24);
683         stream->_frame_rate = 48000;
684         player->setup_pieces ();
685         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
686         piece = player->_pieces.front ();
687         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
688         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)),      0);
689         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),      0);
690         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)),  72000);
691         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
692
693         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
694         content->set_position (DCPTime::from_seconds (3));
695         content->set_trim_start (ContentTime::from_seconds (1.5));
696         content->set_video_frame_rate (24);
697         film->set_video_frame_rate (24);
698         stream->_frame_rate = 48000;
699         player->setup_pieces ();
700         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
701         piece = player->_pieces.front ();
702         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
703         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)),   0);
704         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),  72000);
705         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
706         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
707
708         /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
709         content->set_position (DCPTime ());
710         content->set_trim_start (ContentTime ());
711         content->set_video_frame_rate (24);
712         film->set_video_frame_rate (24);
713         stream->_frame_rate = 44100;
714         player->setup_pieces ();
715         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
716         piece = player->_pieces.front ();
717         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
718         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)),  24000);
719         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
720
721         /* Position 3s, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
722         content->set_position (DCPTime::from_seconds (3));
723         content->set_trim_start (ContentTime ());
724         content->set_video_frame_rate (24);
725         film->set_video_frame_rate (24);
726         stream->_frame_rate = 44100;
727         player->setup_pieces ();
728         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
729         piece = player->_pieces.front ();
730         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
731         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)),      0);
732         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),      0);
733         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)),  72000);
734         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
735
736         /* Position 3s, 1.5s trim, video content rate = video DCP rate, content audio rate = 44.1k */
737         content->set_position (DCPTime::from_seconds (3));
738         content->set_trim_start (ContentTime::from_seconds (1.5));
739         content->set_video_frame_rate (24);
740         film->set_video_frame_rate (24);
741         stream->_frame_rate = 44100;
742         player->setup_pieces ();
743         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
744         piece = player->_pieces.front ();
745         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
746         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)),      0);
747         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)),  72000);
748         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
749         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
750
751         /* Check with a large start trim */
752         content->set_position (DCPTime::from_seconds (0));
753         content->set_trim_start (ContentTime::from_seconds (54143));
754         content->set_video_frame_rate (24);
755         film->set_video_frame_rate (24);
756         stream->_frame_rate = 48000;
757         player->setup_pieces ();
758         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
759         piece = player->_pieces.front ();
760         BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 54143L * 48000);
761 }