2 Copyright (C) 2015 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/player.h"
24 #include <boost/test/unit_test.hpp>
28 using boost::shared_ptr;
30 static string const xml = "<Content>"
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>"
52 "<InputTransferFunction>"
53 "<Type>ModifiedGamma</Type>"
54 "<Power>2.222222222222222</Power>"
55 "<Threshold>0.081</Threshold>"
58 "</InputTransferFunction>"
61 "<GreenX>0.3</GreenX>"
62 "<GreenY>0.6</GreenY>"
65 "<WhiteX>0.3127</WhiteX>"
66 "<WhiteY>0.329</WhiteY>"
67 "<OutputGamma>2.6</OutputGamma>"
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>"
80 "<Selected>1</Selected>"
81 "<Name>und; 2 channels</Name>"
83 "<FrameRate>44100</FrameRate>"
84 "<Channels>2</Channels>"
85 "<FirstAudio>0</FirstAudio>"
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>"
115 "<FirstVideo>0</FirstVideo>"
118 BOOST_AUTO_TEST_CASE (ffmpeg_time_calculation_test)
120 shared_ptr<Film> film = new_test_film ("ffmpeg_time_calculation_test");
122 shared_ptr<cxml::Document> doc (new cxml::Document);
123 doc->read_string (xml);
126 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
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));
145 /** Test Player::dcp_to_content_video */
146 BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
148 shared_ptr<Film> film = new_test_film ("player_time_calculation_test1");
150 shared_ptr<cxml::Document> doc (new cxml::Document);
151 doc->read_string (xml);
154 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
155 film->set_sequence_video (false);
156 film->add_content (content);
158 shared_ptr<Player> player (new Player (film, film->playlist ()));
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);
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);
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);
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.
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);
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);
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);
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.
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);
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);
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);
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.
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);
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);
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);
333 /** Test Player::content_video_to_dcp */
334 BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
336 shared_ptr<Film> film = new_test_film ("player_time_calculation_test2");
338 shared_ptr<cxml::Document> doc (new cxml::Document);
339 doc->read_string (xml);
342 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
343 film->set_sequence_video (false);
344 film->add_content (content);
346 shared_ptr<Player> player (new Player (film, film->playlist ()));
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));
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));
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));
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.
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));
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));
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));
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.
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));
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));
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));
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.
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));
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));
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));
509 /** Test Player::dcp_to_content_audio */
510 BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
512 shared_ptr<Film> film = new_test_film ("player_time_calculation_test3");
514 shared_ptr<cxml::Document> doc (new cxml::Document);
515 doc->read_string (xml);
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);
523 shared_ptr<Player> player (new Player (film, film->playlist ()));
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);
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);
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);
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.
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);
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);
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);
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.
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);
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);
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);
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.
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);
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);
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);
708 /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k
709 Now 44100 content samples correspond to 1s.
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);
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);
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);