Tests of Player::dcp_to_content_video, content_video_to_dcp and
[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>/home/c.hetherington/DCP/clapperboard.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 (DCPTime ());
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 (DCPTime ());
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 (DCPTime::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 (DCPTime ());
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 (DCPTime ());
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)), 169);
228
229         /* Position 3s, 1.6s trim, content rate 24, DCP rate 25 */
230         content->set_position (DCPTime::from_seconds (3));
231         content->set_trim_start (DCPTime::from_seconds (1.6));
232         content->set_video_frame_rate (24);
233         film->set_video_frame_rate (25);
234         player->setup_pieces ();
235         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
236         piece = player->_pieces.front ();
237         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
238         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)),   0);
239         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),  40);
240         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)),  80);
241         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 209);
242
243         /* Position 0, no trim, content rate 24, DCP rate 48
244            Now, for example, a DCPTime position of 3s means 3s at 48fps.  Since we run the video
245            with repeated frames in this case, 3 * 24 frames of content video will
246            be used to make 3 * 48 frames of DCP video.  The results should be the same as the
247            content rate = DCP rate case.
248         */
249         content->set_position (DCPTime ());
250         content->set_trim_start (DCPTime ());
251         content->set_video_frame_rate (24);
252         film->set_video_frame_rate (48);
253         player->setup_pieces ();
254         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
255         piece = player->_pieces.front ();
256         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
257         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
258         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
259
260         /* Position 3s, no trim, content rate 24, DCP rate 48 */
261         content->set_position (DCPTime::from_seconds (3));
262         content->set_trim_start (DCPTime ());
263         content->set_video_frame_rate (24);
264         film->set_video_frame_rate (48);
265         player->setup_pieces ();
266         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
267         piece = player->_pieces.front ();
268         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
269         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
270         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),   0);
271         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)),  36);
272         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
273
274         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
275         content->set_position (DCPTime::from_seconds (3));
276         content->set_trim_start (DCPTime::from_seconds (1.5));
277         content->set_video_frame_rate (24);
278         film->set_video_frame_rate (48);
279         player->setup_pieces ();
280         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
281         piece = player->_pieces.front ();
282         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
283         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
284         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),  36);
285         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)),  72);
286         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
287
288         /* Position 0, no trim, content rate 48, DCP rate 24
289            Now, for example, a DCPTime position of 3s means 3s at 24fps.  Since we run the video
290            with skipped frames in this case, 3 * 48 frames of content video will
291            be used to make 3 * 24 frames of DCP video.
292         */
293         content->set_position (DCPTime ());
294         content->set_trim_start (DCPTime ());
295         content->set_video_frame_rate (48);
296         film->set_video_frame_rate (24);
297         player->setup_pieces ();
298         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
299         piece = player->_pieces.front ();
300         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
301         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 24);
302         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 144);
303
304         /* Position 3s, no trim, content rate 24, DCP rate 48 */
305         content->set_position (DCPTime::from_seconds (3));
306         content->set_trim_start (DCPTime ());
307         content->set_video_frame_rate (48);
308         film->set_video_frame_rate (24);
309         player->setup_pieces ();
310         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
311         piece = player->_pieces.front ();
312         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
313         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
314         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),   0);
315         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)),  72);
316         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 324);
317
318         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
319         content->set_position (DCPTime::from_seconds (3));
320         content->set_trim_start (DCPTime::from_seconds (1.5));
321         content->set_video_frame_rate (48);
322         film->set_video_frame_rate (24);
323         player->setup_pieces ();
324         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
325         piece = player->_pieces.front ();
326         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
327         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)),   0);
328         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)),  72);
329         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 144);
330         BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 396);
331 }
332
333 /** Test Player::content_video_to_dcp */
334 BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
335 {
336         shared_ptr<Film> film = new_test_film ("player_time_calculation_test2");
337
338         shared_ptr<cxml::Document> doc (new cxml::Document);
339         doc->read_string (xml);
340
341         list<string> notes;
342         shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
343         film->set_sequence_video (false);
344         film->add_content (content);
345
346         shared_ptr<Player> player (new Player (film, film->playlist ()));
347
348         /* Position 0, no trim, content rate = DCP rate */
349         content->set_position (DCPTime ());
350         content->set_trim_start (DCPTime ());
351         content->set_video_frame_rate (24);
352         film->set_video_frame_rate (24);
353         player->setup_pieces ();
354         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
355         shared_ptr<Piece> piece = player->_pieces.front ();
356         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
357         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
358         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
359
360         /* Position 3s, no trim, content rate = DCP rate */
361         content->set_position (DCPTime::from_seconds (3));
362         content->set_trim_start (DCPTime ());
363         content->set_video_frame_rate (24);
364         film->set_video_frame_rate (24);
365         player->setup_pieces ();
366         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
367         piece = player->_pieces.front ();
368         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
369         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
370         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
371
372         /* Position 3s, 1.5s trim, content rate = DCP rate */
373         content->set_position (DCPTime::from_seconds (3));
374         content->set_trim_start (DCPTime::from_seconds (1.5));
375         content->set_video_frame_rate (24);
376         film->set_video_frame_rate (24);
377         player->setup_pieces ();
378         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
379         piece = player->_pieces.front ();
380         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
381         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
382         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
383         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
384
385         /* Position 0, no trim, content rate 24, DCP rate 25.
386            Now, for example, a DCPTime position of 3s means 3s at 25fps.  Since we run the video
387            fast (at 25fps) in this case, this means 75 frames of content video will be used.
388         */
389         content->set_position (DCPTime ());
390         content->set_trim_start (DCPTime ());
391         content->set_video_frame_rate (24);
392         film->set_video_frame_rate (25);
393         player->setup_pieces ();
394         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
395         piece = player->_pieces.front ();
396         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
397         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 15), DCPTime::from_seconds (0.6));
398         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 75), DCPTime::from_seconds (3.0));
399
400         /* Position 3s, no trim, content rate 24, DCP rate 25 */
401         content->set_position (DCPTime::from_seconds (3));
402         content->set_trim_start (DCPTime ());
403         content->set_video_frame_rate (24);
404         film->set_video_frame_rate (25);
405         player->setup_pieces ();
406         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
407         piece = player->_pieces.front ();
408         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
409         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (4.60));
410         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 169), DCPTime::from_seconds (9.76));
411
412         /* Position 3s, 1.6s trim, content rate 24, DCP rate 25 */
413         content->set_position (DCPTime::from_seconds (3));
414         content->set_trim_start (DCPTime::from_seconds (1.6));
415         content->set_video_frame_rate (24);
416         film->set_video_frame_rate (25);
417         player->setup_pieces ();
418         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
419         piece = player->_pieces.front ();
420         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.4));
421         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (3.00));
422         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 80), DCPTime::from_seconds (4.60));
423         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 209), DCPTime::from_seconds (9.76));
424
425         /* Position 0, no trim, content rate 24, DCP rate 48
426            Now, for example, a DCPTime position of 3s means 3s at 48fps.  Since we run the video
427            with repeated frames in this case, 3 * 24 frames of content video will
428            be used to make 3 * 48 frames of DCP video.  The results should be the same as the
429            content rate = DCP rate case.
430         */
431         content->set_position (DCPTime ());
432         content->set_trim_start (DCPTime ());
433         content->set_video_frame_rate (24);
434         film->set_video_frame_rate (48);
435         player->setup_pieces ();
436         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
437         piece = player->_pieces.front ();
438         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
439         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
440         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
441
442         /* Position 3s, no trim, content rate 24, DCP rate 48 */
443         content->set_position (DCPTime::from_seconds (3));
444         content->set_trim_start (DCPTime ());
445         content->set_video_frame_rate (24);
446         film->set_video_frame_rate (48);
447         player->setup_pieces ();
448         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
449         piece = player->_pieces.front ();
450         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
451         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
452         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
453
454         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
455         content->set_position (DCPTime::from_seconds (3));
456         content->set_trim_start (DCPTime::from_seconds (1.5));
457         content->set_video_frame_rate (24);
458         film->set_video_frame_rate (48);
459         player->setup_pieces ();
460         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
461         piece = player->_pieces.front ();
462         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
463         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
464         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
465         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
466
467         /* Position 0, no trim, content rate 48, DCP rate 24
468            Now, for example, a DCPTime position of 3s means 3s at 24fps.  Since we run the video
469            with skipped frames in this case, 3 * 48 frames of content video will
470            be used to make 3 * 24 frames of DCP video.
471         */
472         content->set_position (DCPTime ());
473         content->set_trim_start (DCPTime ());
474         content->set_video_frame_rate (48);
475         film->set_video_frame_rate (24);
476         player->setup_pieces ();
477         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
478         piece = player->_pieces.front ();
479         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
480         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 24), DCPTime::from_seconds (0.5));
481         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (3.0));
482
483         /* Position 3s, no trim, content rate 24, DCP rate 48 */
484         content->set_position (DCPTime::from_seconds (3));
485         content->set_trim_start (DCPTime ());
486         content->set_video_frame_rate (48);
487         film->set_video_frame_rate (24);
488         player->setup_pieces ();
489         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
490         piece = player->_pieces.front ();
491         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
492         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
493         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 324), DCPTime::from_seconds (9.75));
494
495         /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
496         content->set_position (DCPTime::from_seconds (3));
497         content->set_trim_start (DCPTime::from_seconds (1.5));
498         content->set_video_frame_rate (48);
499         film->set_video_frame_rate (24);
500         player->setup_pieces ();
501         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
502         piece = player->_pieces.front ();
503         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
504         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.00));
505         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (4.50));
506         BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 396), DCPTime::from_seconds (9.75));
507 }
508
509 /** Test Player::dcp_to_content_audio */
510 BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
511 {
512         shared_ptr<Film> film = new_test_film ("player_time_calculation_test3");
513
514         shared_ptr<cxml::Document> doc (new cxml::Document);
515         doc->read_string (xml);
516
517         list<string> notes;
518         shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
519         AudioStreamPtr stream = content->audio_streams().front();
520         film->set_sequence_video (false);
521         film->add_content (content);
522
523         shared_ptr<Player> player (new Player (film, film->playlist ()));
524
525         /* Position 0, no trim, video/audio content rate = video/audio DCP rate */
526         content->set_position (DCPTime ());
527         content->set_trim_start (DCPTime ());
528         content->set_video_frame_rate (24);
529         film->set_video_frame_rate (24);
530         stream->_frame_rate = 48000;
531         player->setup_pieces ();
532         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
533         shared_ptr<Piece> piece = player->_pieces.front ();
534         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
535         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.5)),  24000);
536         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.0)), 144000);
537
538         /* Position 3s, no trim, video/audio content rate = video/audio DCP rate */
539         content->set_position (DCPTime::from_seconds (3));
540         content->set_trim_start (DCPTime ());
541         content->set_video_frame_rate (24);
542         film->set_video_frame_rate (24);
543         stream->_frame_rate = 48000;
544         player->setup_pieces ();
545         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
546         piece = player->_pieces.front ();
547         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
548         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)),      0);
549         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),      0);
550         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)),  72000);
551         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 324000);
552
553         /* Position 3s, 1.5s trim, video/audio content rate = video/audio DCP rate */
554         content->set_position (DCPTime::from_seconds (3));
555         content->set_trim_start (DCPTime::from_seconds (1.5));
556         content->set_video_frame_rate (24);
557         film->set_video_frame_rate (24);
558         stream->_frame_rate = 48000;
559         player->setup_pieces ();
560         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
561         piece = player->_pieces.front ();
562         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
563         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)),   0);
564         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),  72000);
565         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 144000);
566         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 396000);
567
568         /* Position 0, no trim, content video rate 24, DCP video rate 25, both audio rates still 48k.
569            Now we are resampling the audio so that 48000 content samples become 46080 DCP samples
570            (sounding the same and still corresponding to 1 second) which are then played over 24/25s
571            so that they run fast.  Hence 1 second in the DCP uses (25/24) * 48000 content samples.
572         */
573         content->set_position (DCPTime ());
574         content->set_trim_start (DCPTime ());
575         content->set_video_frame_rate (24);
576         film->set_video_frame_rate (25);
577         stream->_frame_rate = 48000;
578         player->setup_pieces ();
579         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
580         piece = player->_pieces.front ();
581         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
582         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.6)),  30000);
583         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.0)), 150000);
584
585         /* Position 3s, no trim, content video rate 24, DCP rate 25, both audio rates still 48k. */
586         content->set_position (DCPTime::from_seconds (3));
587         content->set_trim_start (DCPTime ());
588         content->set_video_frame_rate (24);
589         film->set_video_frame_rate (25);
590         stream->_frame_rate = 48000;
591         player->setup_pieces ();
592         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
593         piece = player->_pieces.front ();
594         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
595         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.60)),      0);
596         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),      0);
597         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.60)),  80000);
598         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 337500);
599
600         /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, both audio rates still 48k. */
601         content->set_position (DCPTime::from_seconds (3));
602         content->set_trim_start (DCPTime::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_content_audio (piece, stream, DCPTime ()), 0);
610         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.60)),   0);
611         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),  80000);
612         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.60)), 160000);
613         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 417500);
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 (DCPTime ());
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_content_audio (piece, stream, DCPTime ()), 0);
629         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.5)),  24000);
630         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, 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 (DCPTime ());
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_content_audio (piece, stream, DCPTime ()), 0);
642         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)),      0);
643         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),      0);
644         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)),  72000);
645         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, 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 (DCPTime::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_content_audio (piece, stream, DCPTime ()), 0);
657         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)),   0);
658         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),  72000);
659         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 144000);
660         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, 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 (DCPTime ());
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_content_audio (piece, stream, DCPTime ()), 0);
675         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.5)),  24000);
676         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, 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 (DCPTime ());
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_content_audio (piece, stream, DCPTime ()), 0);
688         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)),      0);
689         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),      0);
690         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)),  72000);
691         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, 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 (DCPTime::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_content_audio (piece, stream, DCPTime ()), 0);
703         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)),   0);
704         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),  72000);
705         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 144000);
706         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 396000);
707
708         /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k
709            Now 44100 content samples correspond to 1s.
710         */
711         content->set_position (DCPTime ());
712         content->set_trim_start (DCPTime ());
713         content->set_video_frame_rate (24);
714         film->set_video_frame_rate (24);
715         stream->_frame_rate = 44100;
716         player->setup_pieces ();
717         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
718         piece = player->_pieces.front ();
719         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
720         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.5)),  22050);
721         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.0)), 132300);
722
723         /* Position 3s, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
724         content->set_position (DCPTime::from_seconds (3));
725         content->set_trim_start (DCPTime ());
726         content->set_video_frame_rate (24);
727         film->set_video_frame_rate (24);
728         stream->_frame_rate = 44100;
729         player->setup_pieces ();
730         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
731         piece = player->_pieces.front ();
732         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
733         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)),      0);
734         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),      0);
735         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)),  66150);
736         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 297675);
737
738         /* Position 3s, 1.5s trim, video content rate = video DCP rate, content audio rate = 44.1k */
739         content->set_position (DCPTime::from_seconds (3));
740         content->set_trim_start (DCPTime::from_seconds (1.5));
741         content->set_video_frame_rate (24);
742         film->set_video_frame_rate (24);
743         stream->_frame_rate = 44100;
744         player->setup_pieces ();
745         BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
746         piece = player->_pieces.front ();
747         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
748         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)),      0);
749         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)),  66150);
750         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 132300);
751         BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 363825);
752 }