2 Copyright (C) 2015-2016 Carl Hetherington <cth@carlh.net>
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.
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.
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.
21 #include "lib/ffmpeg_content.h"
22 #include "lib/video_content.h"
23 #include "lib/player.h"
24 #include "lib/audio_content.h"
26 #include <boost/test/unit_test.hpp>
30 using boost::shared_ptr;
32 static string const xml = "<Content>"
34 "<BurnSubtitles>0</BurnSubtitles>"
35 "<BitsPerPixel>8</BitsPerPixel>"
36 "<Path>test/data/red_24.mp4</Path>"
37 "<Digest>2760e03c7251480f7f02c01a907792673784335</Digest>"
38 "<Position>0</Position>"
39 "<TrimStart>0</TrimStart>"
40 "<TrimEnd>0</TrimEnd>"
41 "<VideoLength>1353600</VideoLength>"
42 "<VideoWidth>1280</VideoWidth>"
43 "<VideoHeight>720</VideoHeight>"
44 "<VideoFrameRate>25</VideoFrameRate>"
45 "<VideoFrameType>0</VideoFrameType>"
46 "<LeftCrop>0</LeftCrop>"
47 "<RightCrop>0</RightCrop>"
48 "<TopCrop>0</TopCrop>"
49 "<BottomCrop>0</BottomCrop>"
54 "<InputTransferFunction>"
55 "<Type>ModifiedGamma</Type>"
56 "<Power>2.222222222222222</Power>"
57 "<Threshold>0.081</Threshold>"
60 "</InputTransferFunction>"
63 "<GreenX>0.3</GreenX>"
64 "<GreenY>0.6</GreenY>"
67 "<WhiteX>0.3127</WhiteX>"
68 "<WhiteY>0.329</WhiteY>"
69 "<OutputGamma>2.6</OutputGamma>"
72 "<FadeOut>0</FadeOut>"
73 "<AudioGain>0</AudioGain>"
74 "<AudioDelay>0</AudioDelay>"
75 "<UseSubtitles>0</UseSubtitles>"
76 "<SubtitleXOffset>0</SubtitleXOffset>"
77 "<SubtitleYOffset>0</SubtitleYOffset>"
78 "<SubtitleXScale>1</SubtitleXScale>"
79 "<SubtitleYScale>1</SubtitleYScale>"
80 "<SubtitleLanguage></SubtitleLanguage>"
82 "<Selected>1</Selected>"
83 "<Name>und; 2 channels</Name>"
85 "<FrameRate>44100</FrameRate>"
86 "<Channels>2</Channels>"
87 "<FirstAudio>0</FirstAudio>"
89 "<InputChannels>2</InputChannels>"
90 "<OutputChannels>12</OutputChannels>"
91 "<Gain Input=\"0\" Output=\"0\">1</Gain>"
92 "<Gain Input=\"0\" Output=\"1\">0</Gain>"
93 "<Gain Input=\"0\" Output=\"2\">0</Gain>"
94 "<Gain Input=\"0\" Output=\"3\">0</Gain>"
95 "<Gain Input=\"0\" Output=\"4\">0</Gain>"
96 "<Gain Input=\"0\" Output=\"5\">0</Gain>"
97 "<Gain Input=\"0\" Output=\"6\">0</Gain>"
98 "<Gain Input=\"0\" Output=\"7\">0</Gain>"
99 "<Gain Input=\"0\" Output=\"8\">0</Gain>"
100 "<Gain Input=\"0\" Output=\"9\">0</Gain>"
101 "<Gain Input=\"0\" Output=\"10\">0</Gain>"
102 "<Gain Input=\"0\" Output=\"11\">0</Gain>"
103 "<Gain Input=\"1\" Output=\"0\">0</Gain>"
104 "<Gain Input=\"1\" Output=\"1\">1</Gain>"
105 "<Gain Input=\"1\" Output=\"2\">0</Gain>"
106 "<Gain Input=\"1\" Output=\"3\">0</Gain>"
107 "<Gain Input=\"1\" Output=\"4\">0</Gain>"
108 "<Gain Input=\"1\" Output=\"5\">0</Gain>"
109 "<Gain Input=\"1\" Output=\"6\">0</Gain>"
110 "<Gain Input=\"1\" Output=\"7\">0</Gain>"
111 "<Gain Input=\"1\" Output=\"8\">0</Gain>"
112 "<Gain Input=\"1\" Output=\"9\">0</Gain>"
113 "<Gain Input=\"1\" Output=\"10\">0</Gain>"
114 "<Gain Input=\"1\" Output=\"11\">0</Gain>"
117 "<FirstVideo>0</FirstVideo>"
120 BOOST_AUTO_TEST_CASE (ffmpeg_time_calculation_test)
122 shared_ptr<Film> film = new_test_film ("ffmpeg_time_calculation_test");
124 shared_ptr<cxml::Document> doc (new cxml::Document);
125 doc->read_string (xml);
128 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
130 /* 25fps content, 25fps DCP */
131 film->set_video_frame_rate (25);
132 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() / 25.0));
133 /* 25fps content, 24fps DCP; length should be increased */
134 film->set_video_frame_rate (24);
135 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() / 24.0));
136 /* 25fps content, 30fps DCP; length should be decreased */
137 film->set_video_frame_rate (30);
138 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() / 30.0));
139 /* 25fps content, 50fps DCP; length should be the same */
140 film->set_video_frame_rate (50);
141 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() / 25.0));
142 /* 25fps content, 60fps DCP; length should be decreased */
143 film->set_video_frame_rate (60);
144 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() * (50.0 / 60) / 25.0));
147 /** Test Player::dcp_to_content_video */
148 BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
150 shared_ptr<Film> film = new_test_film ("player_time_calculation_test1");
152 shared_ptr<cxml::Document> doc (new cxml::Document);
153 doc->read_string (xml);
156 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
157 film->set_sequence (false);
158 film->add_content (content);
160 shared_ptr<Player> player (new Player (film, film->playlist ()));
162 /* Position 0, no trim, content rate = DCP rate */
163 content->set_position (DCPTime ());
164 content->set_trim_start (ContentTime ());
165 content->set_video_frame_rate (24);
166 film->set_video_frame_rate (24);
167 player->setup_pieces ();
168 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
169 shared_ptr<Piece> piece = player->_pieces.front ();
170 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
171 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
172 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
174 /* Position 3s, no trim, content rate = DCP rate */
175 content->set_position (DCPTime::from_seconds (3));
176 content->set_trim_start (ContentTime ());
177 content->set_video_frame_rate (24);
178 film->set_video_frame_rate (24);
179 player->setup_pieces ();
180 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
181 piece = player->_pieces.front ();
182 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
183 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
184 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
185 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 36);
186 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
188 /* Position 3s, 1.5s trim, content rate = DCP rate */
189 content->set_position (DCPTime::from_seconds (3));
190 content->set_trim_start (ContentTime::from_seconds (1.5));
191 content->set_video_frame_rate (24);
192 film->set_video_frame_rate (24);
193 player->setup_pieces ();
194 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
195 piece = player->_pieces.front ();
196 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
197 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
198 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 36);
199 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
200 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
202 /* Position 0, no trim, content rate 24, DCP rate 25.
203 Now, for example, a DCPTime position of 3s means 3s at 25fps. Since we run the video
204 fast (at 25fps) in this case, this means 75 frames of content video will be used.
206 content->set_position (DCPTime ());
207 content->set_trim_start (ContentTime ());
208 content->set_video_frame_rate (24);
209 film->set_video_frame_rate (25);
210 player->setup_pieces ();
211 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
212 piece = player->_pieces.front ();
213 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
214 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.6)), 15);
215 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 75);
217 /* Position 3s, no trim, content rate 24, DCP rate 25 */
218 content->set_position (DCPTime::from_seconds (3));
219 content->set_trim_start (ContentTime ());
220 content->set_video_frame_rate (24);
221 film->set_video_frame_rate (25);
222 player->setup_pieces ();
223 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
224 piece = player->_pieces.front ();
225 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
226 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)), 0);
227 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
228 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)), 40);
229 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 168);
231 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25. Here the trim is in ContentTime,
232 so it's 1.6s at 24fps.
234 content->set_position (DCPTime::from_seconds (3));
235 content->set_trim_start (ContentTime::from_seconds (1.6));
236 content->set_video_frame_rate (24);
237 film->set_video_frame_rate (25);
238 player->setup_pieces ();
239 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
240 piece = player->_pieces.front ();
241 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
242 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)), 0);
243 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 38);
244 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)), 78);
245 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 207);
247 /* Position 0, no trim, content rate 24, DCP rate 48
248 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
249 with repeated frames in this case, 3 * 24 frames of content video will
250 be used to make 3 * 48 frames of DCP video. The results should be the same as the
251 content rate = DCP rate case.
253 content->set_position (DCPTime ());
254 content->set_trim_start (ContentTime ());
255 content->set_video_frame_rate (24);
256 film->set_video_frame_rate (48);
257 player->setup_pieces ();
258 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
259 piece = player->_pieces.front ();
260 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
261 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
262 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
264 /* Position 3s, no trim, content rate 24, DCP rate 48 */
265 content->set_position (DCPTime::from_seconds (3));
266 content->set_trim_start (ContentTime ());
267 content->set_video_frame_rate (24);
268 film->set_video_frame_rate (48);
269 player->setup_pieces ();
270 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
271 piece = player->_pieces.front ();
272 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
273 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
274 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
275 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 36);
276 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
278 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
279 content->set_position (DCPTime::from_seconds (3));
280 content->set_trim_start (ContentTime::from_seconds (1.5));
281 content->set_video_frame_rate (24);
282 film->set_video_frame_rate (48);
283 player->setup_pieces ();
284 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
285 piece = player->_pieces.front ();
286 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
287 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
288 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 36);
289 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
290 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
292 /* Position 0, no trim, content rate 48, DCP rate 24
293 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
294 with skipped frames in this case, 3 * 48 frames of content video will
295 be used to make 3 * 24 frames of DCP video.
297 content->set_position (DCPTime ());
298 content->set_trim_start (ContentTime ());
299 content->set_video_frame_rate (48);
300 film->set_video_frame_rate (24);
301 player->setup_pieces ();
302 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
303 piece = player->_pieces.front ();
304 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
305 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 24);
306 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 144);
308 /* Position 3s, no trim, content rate 24, DCP rate 48 */
309 content->set_position (DCPTime::from_seconds (3));
310 content->set_trim_start (ContentTime ());
311 content->set_video_frame_rate (48);
312 film->set_video_frame_rate (24);
313 player->setup_pieces ();
314 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
315 piece = player->_pieces.front ();
316 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
317 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
318 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
319 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
320 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 324);
322 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
323 content->set_position (DCPTime::from_seconds (3));
324 content->set_trim_start (ContentTime::from_seconds (1.5));
325 content->set_video_frame_rate (48);
326 film->set_video_frame_rate (24);
327 player->setup_pieces ();
328 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
329 piece = player->_pieces.front ();
330 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
331 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
332 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 72);
333 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 144);
334 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 396);
336 /* Position 0s, no trim, content rate 29.9978733, DCP rate 30 */
337 content->set_position (DCPTime::from_seconds (0));
338 content->set_trim_start (ContentTime::from_seconds (0));
339 content->set_video_frame_rate (29.9978733);
340 film->set_video_frame_rate (30);
341 player->setup_pieces ();
342 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
343 piece = player->_pieces.front ();
344 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
345 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (3200)), 1);
346 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (6400)), 2);
347 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (9600)), 3);
348 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (12800)), 4);
352 /** Test Player::content_video_to_dcp */
353 BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
355 shared_ptr<Film> film = new_test_film ("player_time_calculation_test2");
357 shared_ptr<cxml::Document> doc (new cxml::Document);
358 doc->read_string (xml);
361 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
362 film->set_sequence (false);
363 film->add_content (content);
365 shared_ptr<Player> player (new Player (film, film->playlist ()));
367 /* Position 0, no trim, content rate = DCP rate */
368 content->set_position (DCPTime ());
369 content->set_trim_start (ContentTime ());
370 content->set_video_frame_rate (24);
371 film->set_video_frame_rate (24);
372 player->setup_pieces ();
373 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
374 shared_ptr<Piece> piece = player->_pieces.front ();
375 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
376 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
377 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
379 /* Position 3s, no trim, content rate = DCP rate */
380 content->set_position (DCPTime::from_seconds (3));
381 content->set_trim_start (ContentTime ());
382 content->set_video_frame_rate (24);
383 film->set_video_frame_rate (24);
384 player->setup_pieces ();
385 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
386 piece = player->_pieces.front ();
387 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
388 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
389 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
391 /* Position 3s, 1.5s trim, content rate = DCP rate */
392 content->set_position (DCPTime::from_seconds (3));
393 content->set_trim_start (ContentTime::from_seconds (1.5));
394 content->set_video_frame_rate (24);
395 film->set_video_frame_rate (24);
396 player->setup_pieces ();
397 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
398 piece = player->_pieces.front ();
399 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
400 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
401 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
402 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
404 /* Position 0, no trim, content rate 24, DCP rate 25.
405 Now, for example, a DCPTime position of 3s means 3s at 25fps. Since we run the video
406 fast (at 25fps) in this case, this means 75 frames of content video will be used.
408 content->set_position (DCPTime ());
409 content->set_trim_start (ContentTime ());
410 content->set_video_frame_rate (24);
411 film->set_video_frame_rate (25);
412 player->setup_pieces ();
413 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
414 piece = player->_pieces.front ();
415 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
416 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 15), DCPTime::from_seconds (0.6));
417 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 75), DCPTime::from_seconds (3.0));
419 /* Position 3s, no trim, content rate 24, DCP rate 25 */
420 content->set_position (DCPTime::from_seconds (3));
421 content->set_trim_start (ContentTime ());
422 content->set_video_frame_rate (24);
423 film->set_video_frame_rate (25);
424 player->setup_pieces ();
425 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
426 piece = player->_pieces.front ();
427 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
428 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (4.60));
429 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 169), DCPTime::from_seconds (9.76));
431 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, so the 1.6s trim is at 24fps */
432 content->set_position (DCPTime::from_seconds (3));
433 content->set_trim_start (ContentTime::from_seconds (1.6));
434 content->set_video_frame_rate (24);
435 film->set_video_frame_rate (25);
436 player->setup_pieces ();
437 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
438 piece = player->_pieces.front ();
439 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.464));
440 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (3.064));
441 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 80), DCPTime::from_seconds (4.664));
442 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 209), DCPTime::from_seconds (9.824));
444 /* Position 0, no trim, content rate 24, DCP rate 48
445 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
446 with repeated frames in this case, 3 * 24 frames of content video will
447 be used to make 3 * 48 frames of DCP video. The results should be the same as the
448 content rate = DCP rate case.
450 content->set_position (DCPTime ());
451 content->set_trim_start (ContentTime ());
452 content->set_video_frame_rate (24);
453 film->set_video_frame_rate (48);
454 player->setup_pieces ();
455 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
456 piece = player->_pieces.front ();
457 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
458 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
459 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
461 /* Position 3s, no trim, content rate 24, DCP rate 48 */
462 content->set_position (DCPTime::from_seconds (3));
463 content->set_trim_start (ContentTime ());
464 content->set_video_frame_rate (24);
465 film->set_video_frame_rate (48);
466 player->setup_pieces ();
467 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
468 piece = player->_pieces.front ();
469 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
470 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
471 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
473 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
474 content->set_position (DCPTime::from_seconds (3));
475 content->set_trim_start (ContentTime::from_seconds (1.5));
476 content->set_video_frame_rate (24);
477 film->set_video_frame_rate (48);
478 player->setup_pieces ();
479 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
480 piece = player->_pieces.front ();
481 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
482 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
483 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
484 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
486 /* Position 0, no trim, content rate 48, DCP rate 24
487 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
488 with skipped frames in this case, 3 * 48 frames of content video will
489 be used to make 3 * 24 frames of DCP video.
491 content->set_position (DCPTime ());
492 content->set_trim_start (ContentTime ());
493 content->set_video_frame_rate (48);
494 film->set_video_frame_rate (24);
495 player->setup_pieces ();
496 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
497 piece = player->_pieces.front ();
498 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
499 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 24), DCPTime::from_seconds (0.5));
500 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (3.0));
502 /* Position 3s, no trim, content rate 24, DCP rate 48 */
503 content->set_position (DCPTime::from_seconds (3));
504 content->set_trim_start (ContentTime ());
505 content->set_video_frame_rate (48);
506 film->set_video_frame_rate (24);
507 player->setup_pieces ();
508 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
509 piece = player->_pieces.front ();
510 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
511 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
512 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 324), DCPTime::from_seconds (9.75));
514 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
515 content->set_position (DCPTime::from_seconds (3));
516 content->set_trim_start (ContentTime::from_seconds (1.5));
517 content->set_video_frame_rate (48);
518 film->set_video_frame_rate (24);
519 player->setup_pieces ();
520 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
521 piece = player->_pieces.front ();
522 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
523 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.00));
524 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (4.50));
525 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 396), DCPTime::from_seconds (9.75));
528 /** Test Player::dcp_to_content_audio */
529 BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
531 shared_ptr<Film> film = new_test_film ("player_time_calculation_test3");
533 shared_ptr<cxml::Document> doc (new cxml::Document);
534 doc->read_string (xml);
537 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
538 AudioStreamPtr stream = content->audio->streams().front();
539 film->set_sequence (false);
540 film->add_content (content);
542 shared_ptr<Player> player (new Player (film, film->playlist ()));
544 /* Position 0, no trim, video/audio content rate = video/audio DCP rate */
545 content->set_position (DCPTime ());
546 content->set_trim_start (ContentTime ());
547 content->set_video_frame_rate (24);
548 film->set_video_frame_rate (24);
549 stream->_frame_rate = 48000;
550 player->setup_pieces ();
551 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
552 shared_ptr<Piece> piece = player->_pieces.front ();
553 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
554 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
555 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
557 /* Position 3s, no trim, video/audio content rate = video/audio DCP rate */
558 content->set_position (DCPTime::from_seconds (3));
559 content->set_trim_start (ContentTime ());
560 content->set_video_frame_rate (24);
561 film->set_video_frame_rate (24);
562 stream->_frame_rate = 48000;
563 player->setup_pieces ();
564 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
565 piece = player->_pieces.front ();
566 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
567 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
568 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
569 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
570 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
572 /* Position 3s, 1.5s trim, video/audio content rate = video/audio DCP rate */
573 content->set_position (DCPTime::from_seconds (3));
574 content->set_trim_start (ContentTime::from_seconds (1.5));
575 content->set_video_frame_rate (24);
576 film->set_video_frame_rate (24);
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_resampled_audio (piece, DCPTime ()), 0);
582 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
583 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
584 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
585 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
587 /* Position 0, no trim, content video rate 24, DCP video rate 25, both audio rates still 48k */
588 content->set_position (DCPTime ());
589 content->set_trim_start (ContentTime ());
590 content->set_video_frame_rate (24);
591 film->set_video_frame_rate (25);
592 stream->_frame_rate = 48000;
593 player->setup_pieces ();
594 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
595 piece = player->_pieces.front ();
596 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
597 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.6)), 28800);
598 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
600 /* Position 3s, no trim, content video rate 24, DCP rate 25, both audio rates still 48k. */
601 content->set_position (DCPTime::from_seconds (3));
602 content->set_trim_start (ContentTime ());
603 content->set_video_frame_rate (24);
604 film->set_video_frame_rate (25);
605 stream->_frame_rate = 48000;
606 player->setup_pieces ();
607 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
608 piece = player->_pieces.front ();
609 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
610 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)), 0);
611 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
612 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 76800);
613 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
615 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, both audio rates still 48k.
616 1s of content is 46080 samples after resampling.
618 content->set_position (DCPTime::from_seconds (3));
619 content->set_trim_start (ContentTime::from_seconds (1.6));
620 content->set_video_frame_rate (24);
621 film->set_video_frame_rate (25);
622 stream->_frame_rate = 48000;
623 player->setup_pieces ();
624 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
625 piece = player->_pieces.front ();
626 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
627 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)), 0);
628 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 73728);
629 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 150528);
630 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 397728);
632 /* Position 0, no trim, content rate 24, DCP rate 48, both audio rates still 48k.
633 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
634 with repeated frames in this case, audio samples will map straight through.
635 The results should be the same as the content rate = DCP rate case.
637 content->set_position (DCPTime ());
638 content->set_trim_start (ContentTime ());
639 content->set_video_frame_rate (24);
640 film->set_video_frame_rate (48);
641 stream->_frame_rate = 48000;
642 player->setup_pieces ();
643 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
644 piece = player->_pieces.front ();
645 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
646 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
647 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
649 /* Position 3s, no trim, content rate 24, DCP rate 48 */
650 content->set_position (DCPTime::from_seconds (3));
651 content->set_trim_start (ContentTime ());
652 content->set_video_frame_rate (24);
653 film->set_video_frame_rate (24);
654 stream->_frame_rate = 48000;
655 player->setup_pieces ();
656 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
657 piece = player->_pieces.front ();
658 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
659 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
660 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
661 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
662 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
664 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
665 content->set_position (DCPTime::from_seconds (3));
666 content->set_trim_start (ContentTime::from_seconds (1.5));
667 content->set_video_frame_rate (24);
668 film->set_video_frame_rate (24);
669 stream->_frame_rate = 48000;
670 player->setup_pieces ();
671 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
672 piece = player->_pieces.front ();
673 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
674 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
675 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
676 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
677 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
679 /* Position 0, no trim, content rate 48, DCP rate 24
680 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
681 with skipped frames in this case, audio samples should map straight through.
683 content->set_position (DCPTime ());
684 content->set_trim_start (ContentTime ());
685 content->set_video_frame_rate (24);
686 film->set_video_frame_rate (48);
687 stream->_frame_rate = 48000;
688 player->setup_pieces ();
689 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
690 piece = player->_pieces.front ();
691 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
692 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
693 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
695 /* Position 3s, no trim, content rate 24, DCP rate 48 */
696 content->set_position (DCPTime::from_seconds (3));
697 content->set_trim_start (ContentTime ());
698 content->set_video_frame_rate (24);
699 film->set_video_frame_rate (24);
700 stream->_frame_rate = 48000;
701 player->setup_pieces ();
702 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
703 piece = player->_pieces.front ();
704 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
705 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
706 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
707 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
708 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
710 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
711 content->set_position (DCPTime::from_seconds (3));
712 content->set_trim_start (ContentTime::from_seconds (1.5));
713 content->set_video_frame_rate (24);
714 film->set_video_frame_rate (24);
715 stream->_frame_rate = 48000;
716 player->setup_pieces ();
717 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
718 piece = player->_pieces.front ();
719 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
720 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
721 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
722 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
723 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
725 /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
726 content->set_position (DCPTime ());
727 content->set_trim_start (ContentTime ());
728 content->set_video_frame_rate (24);
729 film->set_video_frame_rate (24);
730 stream->_frame_rate = 44100;
731 player->setup_pieces ();
732 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
733 piece = player->_pieces.front ();
734 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
735 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
736 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
738 /* Position 3s, no 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 (ContentTime ());
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_resampled_audio (piece, DCPTime ()), 0);
748 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
749 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
750 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
751 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
753 /* Position 3s, 1.5s trim, video content rate = video DCP rate, content audio rate = 44.1k */
754 content->set_position (DCPTime::from_seconds (3));
755 content->set_trim_start (ContentTime::from_seconds (1.5));
756 content->set_video_frame_rate (24);
757 film->set_video_frame_rate (24);
758 stream->_frame_rate = 44100;
759 player->setup_pieces ();
760 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
761 piece = player->_pieces.front ();
762 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
763 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
764 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
765 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
766 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
768 /* Check with a large start trim */
769 content->set_position (DCPTime::from_seconds (0));
770 content->set_trim_start (ContentTime::from_seconds (54143));
771 content->set_video_frame_rate (24);
772 film->set_video_frame_rate (24);
773 stream->_frame_rate = 48000;
774 player->setup_pieces ();
775 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
776 piece = player->_pieces.front ();
777 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 54143L * 48000);