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