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>test/data/red_24.mp4</Path>"
35 "<Digest>2760e03c7251480f7f02c01a907792673784335</Digest>"
36 "<Position>0</Position>"
37 "<TrimStart>0</TrimStart>"
38 "<TrimEnd>0</TrimEnd>"
39 "<VideoLength>1353600</VideoLength>"
40 "<VideoWidth>1280</VideoWidth>"
41 "<VideoHeight>720</VideoHeight>"
42 "<VideoFrameRate>25</VideoFrameRate>"
43 "<VideoFrameType>0</VideoFrameType>"
44 "<LeftCrop>0</LeftCrop>"
45 "<RightCrop>0</RightCrop>"
46 "<TopCrop>0</TopCrop>"
47 "<BottomCrop>0</BottomCrop>"
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 (ContentTime ());
163 content->set_video_frame_rate (24);
164 film->set_video_frame_rate (24);
165 player->setup_pieces ();
166 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
167 shared_ptr<Piece> piece = player->_pieces.front ();
168 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
169 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
170 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
172 /* Position 3s, no trim, content rate = DCP rate */
173 content->set_position (DCPTime::from_seconds (3));
174 content->set_trim_start (ContentTime ());
175 content->set_video_frame_rate (24);
176 film->set_video_frame_rate (24);
177 player->setup_pieces ();
178 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
179 piece = player->_pieces.front ();
180 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
181 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
182 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
183 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 36);
184 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
186 /* Position 3s, 1.5s trim, content rate = DCP rate */
187 content->set_position (DCPTime::from_seconds (3));
188 content->set_trim_start (ContentTime::from_seconds (1.5));
189 content->set_video_frame_rate (24);
190 film->set_video_frame_rate (24);
191 player->setup_pieces ();
192 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
193 piece = player->_pieces.front ();
194 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
195 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
196 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 36);
197 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
198 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
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 (ContentTime ());
206 content->set_video_frame_rate (24);
207 film->set_video_frame_rate (25);
208 player->setup_pieces ();
209 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
210 piece = player->_pieces.front ();
211 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
212 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.6)), 15);
213 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 75);
215 /* Position 3s, no trim, content rate 24, DCP rate 25 */
216 content->set_position (DCPTime::from_seconds (3));
217 content->set_trim_start (ContentTime ());
218 content->set_video_frame_rate (24);
219 film->set_video_frame_rate (25);
220 player->setup_pieces ();
221 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
222 piece = player->_pieces.front ();
223 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
224 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)), 0);
225 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
226 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)), 40);
227 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 168);
229 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25. Here the trim is in ContentTime,
230 so it's 1.6s at 24fps.
232 content->set_position (DCPTime::from_seconds (3));
233 content->set_trim_start (ContentTime::from_seconds (1.6));
234 content->set_video_frame_rate (24);
235 film->set_video_frame_rate (25);
236 player->setup_pieces ();
237 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
238 piece = player->_pieces.front ();
239 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
240 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)), 0);
241 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 38);
242 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)), 78);
243 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 207);
245 /* Position 0, no trim, content rate 24, DCP rate 48
246 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
247 with repeated frames in this case, 3 * 24 frames of content video will
248 be used to make 3 * 48 frames of DCP video. The results should be the same as the
249 content rate = DCP rate case.
251 content->set_position (DCPTime ());
252 content->set_trim_start (ContentTime ());
253 content->set_video_frame_rate (24);
254 film->set_video_frame_rate (48);
255 player->setup_pieces ();
256 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
257 piece = player->_pieces.front ();
258 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
259 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
260 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
262 /* Position 3s, no trim, content rate 24, DCP rate 48 */
263 content->set_position (DCPTime::from_seconds (3));
264 content->set_trim_start (ContentTime ());
265 content->set_video_frame_rate (24);
266 film->set_video_frame_rate (48);
267 player->setup_pieces ();
268 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
269 piece = player->_pieces.front ();
270 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
271 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
272 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
273 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 36);
274 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
276 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
277 content->set_position (DCPTime::from_seconds (3));
278 content->set_trim_start (ContentTime::from_seconds (1.5));
279 content->set_video_frame_rate (24);
280 film->set_video_frame_rate (48);
281 player->setup_pieces ();
282 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
283 piece = player->_pieces.front ();
284 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
285 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
286 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 36);
287 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
288 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
290 /* Position 0, no trim, content rate 48, DCP rate 24
291 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
292 with skipped frames in this case, 3 * 48 frames of content video will
293 be used to make 3 * 24 frames of DCP video.
295 content->set_position (DCPTime ());
296 content->set_trim_start (ContentTime ());
297 content->set_video_frame_rate (48);
298 film->set_video_frame_rate (24);
299 player->setup_pieces ();
300 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
301 piece = player->_pieces.front ();
302 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
303 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 24);
304 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 144);
306 /* Position 3s, no trim, content rate 24, DCP rate 48 */
307 content->set_position (DCPTime::from_seconds (3));
308 content->set_trim_start (ContentTime ());
309 content->set_video_frame_rate (48);
310 film->set_video_frame_rate (24);
311 player->setup_pieces ();
312 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
313 piece = player->_pieces.front ();
314 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
315 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
316 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
317 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
318 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 324);
320 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
321 content->set_position (DCPTime::from_seconds (3));
322 content->set_trim_start (ContentTime::from_seconds (1.5));
323 content->set_video_frame_rate (48);
324 film->set_video_frame_rate (24);
325 player->setup_pieces ();
326 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
327 piece = player->_pieces.front ();
328 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
329 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
330 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 72);
331 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 144);
332 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 396);
335 /** Test Player::content_video_to_dcp */
336 BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
338 shared_ptr<Film> film = new_test_film ("player_time_calculation_test2");
340 shared_ptr<cxml::Document> doc (new cxml::Document);
341 doc->read_string (xml);
344 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
345 film->set_sequence_video (false);
346 film->add_content (content);
348 shared_ptr<Player> player (new Player (film, film->playlist ()));
350 /* Position 0, no trim, content rate = DCP rate */
351 content->set_position (DCPTime ());
352 content->set_trim_start (ContentTime ());
353 content->set_video_frame_rate (24);
354 film->set_video_frame_rate (24);
355 player->setup_pieces ();
356 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
357 shared_ptr<Piece> piece = player->_pieces.front ();
358 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
359 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
360 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
362 /* Position 3s, no trim, content rate = DCP rate */
363 content->set_position (DCPTime::from_seconds (3));
364 content->set_trim_start (ContentTime ());
365 content->set_video_frame_rate (24);
366 film->set_video_frame_rate (24);
367 player->setup_pieces ();
368 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
369 piece = player->_pieces.front ();
370 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
371 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
372 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
374 /* Position 3s, 1.5s trim, content rate = DCP rate */
375 content->set_position (DCPTime::from_seconds (3));
376 content->set_trim_start (ContentTime::from_seconds (1.5));
377 content->set_video_frame_rate (24);
378 film->set_video_frame_rate (24);
379 player->setup_pieces ();
380 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
381 piece = player->_pieces.front ();
382 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
383 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
384 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
385 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
387 /* Position 0, no trim, content rate 24, DCP rate 25.
388 Now, for example, a DCPTime position of 3s means 3s at 25fps. Since we run the video
389 fast (at 25fps) in this case, this means 75 frames of content video will be used.
391 content->set_position (DCPTime ());
392 content->set_trim_start (ContentTime ());
393 content->set_video_frame_rate (24);
394 film->set_video_frame_rate (25);
395 player->setup_pieces ();
396 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
397 piece = player->_pieces.front ();
398 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
399 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 15), DCPTime::from_seconds (0.6));
400 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 75), DCPTime::from_seconds (3.0));
402 /* Position 3s, no trim, content rate 24, DCP rate 25 */
403 content->set_position (DCPTime::from_seconds (3));
404 content->set_trim_start (ContentTime ());
405 content->set_video_frame_rate (24);
406 film->set_video_frame_rate (25);
407 player->setup_pieces ();
408 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
409 piece = player->_pieces.front ();
410 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
411 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (4.60));
412 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 169), DCPTime::from_seconds (9.76));
414 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, so the 1.6s trim is at 24fps */
415 content->set_position (DCPTime::from_seconds (3));
416 content->set_trim_start (ContentTime::from_seconds (1.6));
417 content->set_video_frame_rate (24);
418 film->set_video_frame_rate (25);
419 player->setup_pieces ();
420 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
421 piece = player->_pieces.front ();
422 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.464));
423 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (3.064));
424 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 80), DCPTime::from_seconds (4.664));
425 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 209), DCPTime::from_seconds (9.824));
427 /* Position 0, no trim, content rate 24, DCP rate 48
428 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
429 with repeated frames in this case, 3 * 24 frames of content video will
430 be used to make 3 * 48 frames of DCP video. The results should be the same as the
431 content rate = DCP rate case.
433 content->set_position (DCPTime ());
434 content->set_trim_start (ContentTime ());
435 content->set_video_frame_rate (24);
436 film->set_video_frame_rate (48);
437 player->setup_pieces ();
438 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
439 piece = player->_pieces.front ();
440 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
441 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
442 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
444 /* Position 3s, no trim, content rate 24, DCP rate 48 */
445 content->set_position (DCPTime::from_seconds (3));
446 content->set_trim_start (ContentTime ());
447 content->set_video_frame_rate (24);
448 film->set_video_frame_rate (48);
449 player->setup_pieces ();
450 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
451 piece = player->_pieces.front ();
452 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
453 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
454 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
456 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
457 content->set_position (DCPTime::from_seconds (3));
458 content->set_trim_start (ContentTime::from_seconds (1.5));
459 content->set_video_frame_rate (24);
460 film->set_video_frame_rate (48);
461 player->setup_pieces ();
462 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
463 piece = player->_pieces.front ();
464 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
465 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
466 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
467 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
469 /* Position 0, no trim, content rate 48, DCP rate 24
470 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
471 with skipped frames in this case, 3 * 48 frames of content video will
472 be used to make 3 * 24 frames of DCP video.
474 content->set_position (DCPTime ());
475 content->set_trim_start (ContentTime ());
476 content->set_video_frame_rate (48);
477 film->set_video_frame_rate (24);
478 player->setup_pieces ();
479 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
480 piece = player->_pieces.front ();
481 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
482 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 24), DCPTime::from_seconds (0.5));
483 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (3.0));
485 /* Position 3s, no trim, content rate 24, DCP rate 48 */
486 content->set_position (DCPTime::from_seconds (3));
487 content->set_trim_start (ContentTime ());
488 content->set_video_frame_rate (48);
489 film->set_video_frame_rate (24);
490 player->setup_pieces ();
491 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
492 piece = player->_pieces.front ();
493 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
494 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
495 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 324), DCPTime::from_seconds (9.75));
497 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
498 content->set_position (DCPTime::from_seconds (3));
499 content->set_trim_start (ContentTime::from_seconds (1.5));
500 content->set_video_frame_rate (48);
501 film->set_video_frame_rate (24);
502 player->setup_pieces ();
503 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
504 piece = player->_pieces.front ();
505 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
506 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.00));
507 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (4.50));
508 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 396), DCPTime::from_seconds (9.75));
511 /** Test Player::dcp_to_content_audio */
512 BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
514 shared_ptr<Film> film = new_test_film ("player_time_calculation_test3");
516 shared_ptr<cxml::Document> doc (new cxml::Document);
517 doc->read_string (xml);
520 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
521 AudioStreamPtr stream = content->audio_streams().front();
522 film->set_sequence_video (false);
523 film->add_content (content);
525 shared_ptr<Player> player (new Player (film, film->playlist ()));
527 /* Position 0, no trim, video/audio content rate = video/audio DCP rate */
528 content->set_position (DCPTime ());
529 content->set_trim_start (ContentTime ());
530 content->set_video_frame_rate (24);
531 film->set_video_frame_rate (24);
532 stream->_frame_rate = 48000;
533 player->setup_pieces ();
534 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
535 shared_ptr<Piece> piece = player->_pieces.front ();
536 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
537 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.5)), 24000);
538 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.0)), 144000);
540 /* Position 3s, no trim, video/audio content rate = video/audio DCP rate */
541 content->set_position (DCPTime::from_seconds (3));
542 content->set_trim_start (ContentTime ());
543 content->set_video_frame_rate (24);
544 film->set_video_frame_rate (24);
545 stream->_frame_rate = 48000;
546 player->setup_pieces ();
547 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
548 piece = player->_pieces.front ();
549 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
550 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)), 0);
551 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 0);
552 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 72000);
553 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 324000);
555 /* Position 3s, 1.5s trim, video/audio content rate = video/audio DCP rate */
556 content->set_position (DCPTime::from_seconds (3));
557 content->set_trim_start (ContentTime::from_seconds (1.5));
558 content->set_video_frame_rate (24);
559 film->set_video_frame_rate (24);
560 stream->_frame_rate = 48000;
561 player->setup_pieces ();
562 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
563 piece = player->_pieces.front ();
564 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
565 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)), 0);
566 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 72000);
567 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 144000);
568 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 396000);
570 /* Position 0, no trim, content video rate 24, DCP video rate 25, both audio rates still 48k.
571 Now we are resampling the audio so that 48000 content samples become 46080 DCP samples
572 (sounding the same and still corresponding to 1 second) which are then played over 24/25s
573 so that they run fast. Hence 1 second in the DCP uses (25/24) * 48000 content samples.
575 content->set_position (DCPTime ());
576 content->set_trim_start (ContentTime ());
577 content->set_video_frame_rate (24);
578 film->set_video_frame_rate (25);
579 stream->_frame_rate = 48000;
580 player->setup_pieces ();
581 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
582 piece = player->_pieces.front ();
583 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
584 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.6)), 30000);
585 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.0)), 150000);
587 /* Position 3s, no trim, content video rate 24, DCP rate 25, both audio rates still 48k. */
588 content->set_position (DCPTime::from_seconds (3));
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_content_audio (piece, stream, DCPTime ()), 0);
597 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.60)), 0);
598 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 0);
599 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.60)), 80000);
600 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 337500);
602 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, both audio rates still 48k */
603 content->set_position (DCPTime::from_seconds (3));
604 content->set_trim_start (ContentTime::from_seconds (1.6));
605 content->set_video_frame_rate (24);
606 film->set_video_frame_rate (25);
607 stream->_frame_rate = 48000;
608 player->setup_pieces ();
609 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
610 piece = player->_pieces.front ();
611 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
612 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.60)), 0);
613 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 76800);
614 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.60)), 156800);
615 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 414300);
617 /* Position 0, no trim, content rate 24, DCP rate 48, both audio rates still 48k.
618 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
619 with repeated frames in this case, audio samples will map straight through.
620 The results should be the same as the content rate = DCP rate case.
622 content->set_position (DCPTime ());
623 content->set_trim_start (ContentTime ());
624 content->set_video_frame_rate (24);
625 film->set_video_frame_rate (48);
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_content_audio (piece, stream, DCPTime ()), 0);
631 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.5)), 24000);
632 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.0)), 144000);
634 /* Position 3s, no trim, content rate 24, DCP rate 48 */
635 content->set_position (DCPTime::from_seconds (3));
636 content->set_trim_start (ContentTime ());
637 content->set_video_frame_rate (24);
638 film->set_video_frame_rate (24);
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_content_audio (piece, stream, DCPTime ()), 0);
644 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)), 0);
645 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 0);
646 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 72000);
647 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 324000);
649 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
650 content->set_position (DCPTime::from_seconds (3));
651 content->set_trim_start (ContentTime::from_seconds (1.5));
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_content_audio (piece, stream, DCPTime ()), 0);
659 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)), 0);
660 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 72000);
661 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 144000);
662 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 396000);
664 /* Position 0, no trim, content rate 48, DCP rate 24
665 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
666 with skipped frames in this case, audio samples should map straight through.
668 content->set_position (DCPTime ());
669 content->set_trim_start (ContentTime ());
670 content->set_video_frame_rate (24);
671 film->set_video_frame_rate (48);
672 stream->_frame_rate = 48000;
673 player->setup_pieces ();
674 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
675 piece = player->_pieces.front ();
676 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
677 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.5)), 24000);
678 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.0)), 144000);
680 /* Position 3s, no trim, content rate 24, DCP rate 48 */
681 content->set_position (DCPTime::from_seconds (3));
682 content->set_trim_start (ContentTime ());
683 content->set_video_frame_rate (24);
684 film->set_video_frame_rate (24);
685 stream->_frame_rate = 48000;
686 player->setup_pieces ();
687 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
688 piece = player->_pieces.front ();
689 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
690 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)), 0);
691 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 0);
692 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 72000);
693 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 324000);
695 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
696 content->set_position (DCPTime::from_seconds (3));
697 content->set_trim_start (ContentTime::from_seconds (1.5));
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_content_audio (piece, stream, DCPTime ()), 0);
705 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)), 0);
706 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 72000);
707 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 144000);
708 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 396000);
710 /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k
711 Now 44100 content samples correspond to 1s.
713 content->set_position (DCPTime ());
714 content->set_trim_start (ContentTime ());
715 content->set_video_frame_rate (24);
716 film->set_video_frame_rate (24);
717 stream->_frame_rate = 44100;
718 player->setup_pieces ();
719 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
720 piece = player->_pieces.front ();
721 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
722 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.5)), 22050);
723 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.0)), 132300);
725 /* Position 3s, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
726 content->set_position (DCPTime::from_seconds (3));
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_content_audio (piece, stream, DCPTime ()), 0);
735 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)), 0);
736 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 0);
737 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 66150);
738 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 297675);
740 /* Position 3s, 1.5s trim, video content rate = video DCP rate, content audio rate = 44.1k */
741 content->set_position (DCPTime::from_seconds (3));
742 content->set_trim_start (ContentTime::from_seconds (1.5));
743 content->set_video_frame_rate (24);
744 film->set_video_frame_rate (24);
745 stream->_frame_rate = 44100;
746 player->setup_pieces ();
747 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
748 piece = player->_pieces.front ();
749 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime ()), 0);
750 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (0.50)), 0);
751 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (3.00)), 66150);
752 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (4.50)), 132300);
753 BOOST_CHECK_EQUAL (player->dcp_to_content_audio (piece, stream, DCPTime::from_seconds (9.75)), 363825);