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);
334 /* Position 0s, no trim, content rate 29.9978733, DCP rate 30 */
335 content->set_position (DCPTime::from_seconds (0));
336 content->set_trim_start (ContentTime::from_seconds (0));
337 content->set_video_frame_rate (29.9978733);
338 film->set_video_frame_rate (30);
339 player->setup_pieces ();
340 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
341 piece = player->_pieces.front ();
342 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
343 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (3200)), 1);
344 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (6400)), 2);
345 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (9600)), 3);
346 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (12800)), 4);
350 /** Test Player::content_video_to_dcp */
351 BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
353 shared_ptr<Film> film = new_test_film ("player_time_calculation_test2");
355 shared_ptr<cxml::Document> doc (new cxml::Document);
356 doc->read_string (xml);
359 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
360 film->set_sequence_video (false);
361 film->add_content (content);
363 shared_ptr<Player> player (new Player (film, film->playlist ()));
365 /* Position 0, no trim, content rate = DCP rate */
366 content->set_position (DCPTime ());
367 content->set_trim_start (ContentTime ());
368 content->set_video_frame_rate (24);
369 film->set_video_frame_rate (24);
370 player->setup_pieces ();
371 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
372 shared_ptr<Piece> piece = player->_pieces.front ();
373 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
374 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
375 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
377 /* Position 3s, no trim, content rate = DCP rate */
378 content->set_position (DCPTime::from_seconds (3));
379 content->set_trim_start (ContentTime ());
380 content->set_video_frame_rate (24);
381 film->set_video_frame_rate (24);
382 player->setup_pieces ();
383 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
384 piece = player->_pieces.front ();
385 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
386 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
387 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
389 /* Position 3s, 1.5s trim, content rate = DCP rate */
390 content->set_position (DCPTime::from_seconds (3));
391 content->set_trim_start (ContentTime::from_seconds (1.5));
392 content->set_video_frame_rate (24);
393 film->set_video_frame_rate (24);
394 player->setup_pieces ();
395 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
396 piece = player->_pieces.front ();
397 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
398 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
399 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
400 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
402 /* Position 0, no trim, content rate 24, DCP rate 25.
403 Now, for example, a DCPTime position of 3s means 3s at 25fps. Since we run the video
404 fast (at 25fps) in this case, this means 75 frames of content video will be used.
406 content->set_position (DCPTime ());
407 content->set_trim_start (ContentTime ());
408 content->set_video_frame_rate (24);
409 film->set_video_frame_rate (25);
410 player->setup_pieces ();
411 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
412 piece = player->_pieces.front ();
413 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
414 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 15), DCPTime::from_seconds (0.6));
415 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 75), DCPTime::from_seconds (3.0));
417 /* Position 3s, no trim, content rate 24, DCP rate 25 */
418 content->set_position (DCPTime::from_seconds (3));
419 content->set_trim_start (ContentTime ());
420 content->set_video_frame_rate (24);
421 film->set_video_frame_rate (25);
422 player->setup_pieces ();
423 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
424 piece = player->_pieces.front ();
425 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
426 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (4.60));
427 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 169), DCPTime::from_seconds (9.76));
429 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, so the 1.6s trim is at 24fps */
430 content->set_position (DCPTime::from_seconds (3));
431 content->set_trim_start (ContentTime::from_seconds (1.6));
432 content->set_video_frame_rate (24);
433 film->set_video_frame_rate (25);
434 player->setup_pieces ();
435 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
436 piece = player->_pieces.front ();
437 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.464));
438 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (3.064));
439 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 80), DCPTime::from_seconds (4.664));
440 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 209), DCPTime::from_seconds (9.824));
442 /* Position 0, no trim, content rate 24, DCP rate 48
443 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
444 with repeated frames in this case, 3 * 24 frames of content video will
445 be used to make 3 * 48 frames of DCP video. The results should be the same as the
446 content rate = DCP rate case.
448 content->set_position (DCPTime ());
449 content->set_trim_start (ContentTime ());
450 content->set_video_frame_rate (24);
451 film->set_video_frame_rate (48);
452 player->setup_pieces ();
453 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
454 piece = player->_pieces.front ();
455 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
456 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
457 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
459 /* Position 3s, no trim, content rate 24, DCP rate 48 */
460 content->set_position (DCPTime::from_seconds (3));
461 content->set_trim_start (ContentTime ());
462 content->set_video_frame_rate (24);
463 film->set_video_frame_rate (48);
464 player->setup_pieces ();
465 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
466 piece = player->_pieces.front ();
467 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
468 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
469 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
471 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
472 content->set_position (DCPTime::from_seconds (3));
473 content->set_trim_start (ContentTime::from_seconds (1.5));
474 content->set_video_frame_rate (24);
475 film->set_video_frame_rate (48);
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::from_seconds (1.50));
480 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
481 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
482 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
484 /* Position 0, no trim, content rate 48, DCP rate 24
485 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
486 with skipped frames in this case, 3 * 48 frames of content video will
487 be used to make 3 * 24 frames of DCP video.
489 content->set_position (DCPTime ());
490 content->set_trim_start (ContentTime ());
491 content->set_video_frame_rate (48);
492 film->set_video_frame_rate (24);
493 player->setup_pieces ();
494 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
495 piece = player->_pieces.front ();
496 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
497 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 24), DCPTime::from_seconds (0.5));
498 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (3.0));
500 /* Position 3s, no trim, content rate 24, DCP rate 48 */
501 content->set_position (DCPTime::from_seconds (3));
502 content->set_trim_start (ContentTime ());
503 content->set_video_frame_rate (48);
504 film->set_video_frame_rate (24);
505 player->setup_pieces ();
506 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
507 piece = player->_pieces.front ();
508 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
509 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
510 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 324), DCPTime::from_seconds (9.75));
512 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
513 content->set_position (DCPTime::from_seconds (3));
514 content->set_trim_start (ContentTime::from_seconds (1.5));
515 content->set_video_frame_rate (48);
516 film->set_video_frame_rate (24);
517 player->setup_pieces ();
518 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
519 piece = player->_pieces.front ();
520 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
521 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.00));
522 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (4.50));
523 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 396), DCPTime::from_seconds (9.75));
526 /** Test Player::dcp_to_content_audio */
527 BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
529 shared_ptr<Film> film = new_test_film ("player_time_calculation_test3");
531 shared_ptr<cxml::Document> doc (new cxml::Document);
532 doc->read_string (xml);
535 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
536 AudioStreamPtr stream = content->audio_streams().front();
537 film->set_sequence_video (false);
538 film->add_content (content);
540 shared_ptr<Player> player (new Player (film, film->playlist ()));
542 /* Position 0, no trim, video/audio content rate = video/audio DCP rate */
543 content->set_position (DCPTime ());
544 content->set_trim_start (ContentTime ());
545 content->set_video_frame_rate (24);
546 film->set_video_frame_rate (24);
547 stream->_frame_rate = 48000;
548 player->setup_pieces ();
549 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
550 shared_ptr<Piece> piece = player->_pieces.front ();
551 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
552 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
553 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
555 /* Position 3s, no trim, video/audio content rate = video/audio DCP rate */
556 content->set_position (DCPTime::from_seconds (3));
557 content->set_trim_start (ContentTime ());
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_resampled_audio (piece, DCPTime ()), 0);
565 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
566 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
567 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
568 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
570 /* Position 3s, 1.5s trim, video/audio content rate = video/audio DCP rate */
571 content->set_position (DCPTime::from_seconds (3));
572 content->set_trim_start (ContentTime::from_seconds (1.5));
573 content->set_video_frame_rate (24);
574 film->set_video_frame_rate (24);
575 stream->_frame_rate = 48000;
576 player->setup_pieces ();
577 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
578 piece = player->_pieces.front ();
579 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
580 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
581 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
582 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
583 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
585 /* Position 0, no trim, content video rate 24, DCP video rate 25, both audio rates still 48k */
586 content->set_position (DCPTime ());
587 content->set_trim_start (ContentTime ());
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_resampled_audio (piece, DCPTime ()), 0);
595 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.6)), 28800);
596 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
598 /* Position 3s, no trim, content video rate 24, DCP rate 25, both audio rates still 48k. */
599 content->set_position (DCPTime::from_seconds (3));
600 content->set_trim_start (ContentTime ());
601 content->set_video_frame_rate (24);
602 film->set_video_frame_rate (25);
603 stream->_frame_rate = 48000;
604 player->setup_pieces ();
605 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
606 piece = player->_pieces.front ();
607 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
608 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)), 0);
609 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
610 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 76800);
611 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
613 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, both audio rates still 48k.
614 1s of content is 46080 samples after resampling.
616 content->set_position (DCPTime::from_seconds (3));
617 content->set_trim_start (ContentTime::from_seconds (1.6));
618 content->set_video_frame_rate (24);
619 film->set_video_frame_rate (25);
620 stream->_frame_rate = 48000;
621 player->setup_pieces ();
622 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
623 piece = player->_pieces.front ();
624 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
625 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)), 0);
626 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 73728);
627 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 150528);
628 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 397728);
630 /* Position 0, no trim, content rate 24, DCP rate 48, both audio rates still 48k.
631 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
632 with repeated frames in this case, audio samples will map straight through.
633 The results should be the same as the content rate = DCP rate case.
635 content->set_position (DCPTime ());
636 content->set_trim_start (ContentTime ());
637 content->set_video_frame_rate (24);
638 film->set_video_frame_rate (48);
639 stream->_frame_rate = 48000;
640 player->setup_pieces ();
641 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
642 piece = player->_pieces.front ();
643 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
644 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
645 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
647 /* Position 3s, no trim, content rate 24, DCP rate 48 */
648 content->set_position (DCPTime::from_seconds (3));
649 content->set_trim_start (ContentTime ());
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_resampled_audio (piece, DCPTime ()), 0);
657 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
658 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
659 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
660 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
662 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
663 content->set_position (DCPTime::from_seconds (3));
664 content->set_trim_start (ContentTime::from_seconds (1.5));
665 content->set_video_frame_rate (24);
666 film->set_video_frame_rate (24);
667 stream->_frame_rate = 48000;
668 player->setup_pieces ();
669 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
670 piece = player->_pieces.front ();
671 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
672 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
673 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
674 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
675 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
677 /* Position 0, no trim, content rate 48, DCP rate 24
678 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
679 with skipped frames in this case, audio samples should map straight through.
681 content->set_position (DCPTime ());
682 content->set_trim_start (ContentTime ());
683 content->set_video_frame_rate (24);
684 film->set_video_frame_rate (48);
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_resampled_audio (piece, DCPTime ()), 0);
690 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
691 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
693 /* Position 3s, no trim, content rate 24, DCP rate 48 */
694 content->set_position (DCPTime::from_seconds (3));
695 content->set_trim_start (ContentTime ());
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_resampled_audio (piece, DCPTime ()), 0);
703 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
704 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
705 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
706 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
708 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
709 content->set_position (DCPTime::from_seconds (3));
710 content->set_trim_start (ContentTime::from_seconds (1.5));
711 content->set_video_frame_rate (24);
712 film->set_video_frame_rate (24);
713 stream->_frame_rate = 48000;
714 player->setup_pieces ();
715 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
716 piece = player->_pieces.front ();
717 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
718 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
719 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
720 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
721 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
723 /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
724 content->set_position (DCPTime ());
725 content->set_trim_start (ContentTime ());
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_resampled_audio (piece, DCPTime ()), 0);
733 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
734 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
736 /* Position 3s, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
737 content->set_position (DCPTime::from_seconds (3));
738 content->set_trim_start (ContentTime ());
739 content->set_video_frame_rate (24);
740 film->set_video_frame_rate (24);
741 stream->_frame_rate = 44100;
742 player->setup_pieces ();
743 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
744 piece = player->_pieces.front ();
745 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
746 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
747 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
748 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
749 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
751 /* Position 3s, 1.5s trim, video content rate = video DCP rate, content audio rate = 44.1k */
752 content->set_position (DCPTime::from_seconds (3));
753 content->set_trim_start (ContentTime::from_seconds (1.5));
754 content->set_video_frame_rate (24);
755 film->set_video_frame_rate (24);
756 stream->_frame_rate = 44100;
757 player->setup_pieces ();
758 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
759 piece = player->_pieces.front ();
760 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
761 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
762 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
763 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
764 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
766 /* Check with a large start trim */
767 content->set_position (DCPTime::from_seconds (0));
768 content->set_trim_start (ContentTime::from_seconds (54143));
769 content->set_video_frame_rate (24);
770 film->set_video_frame_rate (24);
771 stream->_frame_rate = 48000;
772 player->setup_pieces ();
773 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
774 piece = player->_pieces.front ();
775 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 54143L * 48000);