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_resampled_audio (piece, DCPTime ()), 0);
537 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
538 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, 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_resampled_audio (piece, DCPTime ()), 0);
550 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
551 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
552 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
553 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, 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_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)), 72000);
567 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
568 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, 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 content->set_position (DCPTime ());
572 content->set_trim_start (ContentTime ());
573 content->set_video_frame_rate (24);
574 film->set_video_frame_rate (25);
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.6)), 28800);
581 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
583 /* Position 3s, no trim, content video rate 24, DCP rate 25, both audio rates still 48k. */
584 content->set_position (DCPTime::from_seconds (3));
585 content->set_trim_start (ContentTime ());
586 content->set_video_frame_rate (24);
587 film->set_video_frame_rate (25);
588 stream->_frame_rate = 48000;
589 player->setup_pieces ();
590 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
591 piece = player->_pieces.front ();
592 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
593 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)), 0);
594 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
595 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 76800);
596 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
598 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, both audio rates still 48k.
599 Since the DCP is faster, and resampled audio is at the DCP rate, our 1.6s trim in
600 content time corresponds to 1.6 * 24 * 48000 / 25 audio samples.
602 content->set_position (DCPTime::from_seconds (3));
603 content->set_trim_start (ContentTime::from_seconds (1.6));
604 content->set_video_frame_rate (24);
605 film->set_video_frame_rate (25);
606 stream->_frame_rate = 48000;
607 player->setup_pieces ();
608 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
609 piece = player->_pieces.front ();
610 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
611 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)), 0);
612 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 73728);
613 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 150528);
614 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 397728);
616 /* Position 0, no trim, content rate 24, DCP rate 48, both audio rates still 48k.
617 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
618 with repeated frames in this case, audio samples will map straight through.
619 The results should be the same as the content rate = DCP rate case.
621 content->set_position (DCPTime ());
622 content->set_trim_start (ContentTime ());
623 content->set_video_frame_rate (24);
624 film->set_video_frame_rate (48);
625 stream->_frame_rate = 48000;
626 player->setup_pieces ();
627 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
628 piece = player->_pieces.front ();
629 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
630 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
631 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
633 /* Position 3s, no trim, content rate 24, DCP rate 48 */
634 content->set_position (DCPTime::from_seconds (3));
635 content->set_trim_start (ContentTime ());
636 content->set_video_frame_rate (24);
637 film->set_video_frame_rate (24);
638 stream->_frame_rate = 48000;
639 player->setup_pieces ();
640 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
641 piece = player->_pieces.front ();
642 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
643 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
644 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
645 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
646 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
648 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
649 content->set_position (DCPTime::from_seconds (3));
650 content->set_trim_start (ContentTime::from_seconds (1.5));
651 content->set_video_frame_rate (24);
652 film->set_video_frame_rate (24);
653 stream->_frame_rate = 48000;
654 player->setup_pieces ();
655 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
656 piece = player->_pieces.front ();
657 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
658 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
659 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
660 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
661 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
663 /* Position 0, no trim, content rate 48, DCP rate 24
664 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
665 with skipped frames in this case, audio samples should map straight through.
667 content->set_position (DCPTime ());
668 content->set_trim_start (ContentTime ());
669 content->set_video_frame_rate (24);
670 film->set_video_frame_rate (48);
671 stream->_frame_rate = 48000;
672 player->setup_pieces ();
673 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
674 piece = player->_pieces.front ();
675 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
676 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
677 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
679 /* Position 3s, no trim, content rate 24, DCP rate 48 */
680 content->set_position (DCPTime::from_seconds (3));
681 content->set_trim_start (ContentTime ());
682 content->set_video_frame_rate (24);
683 film->set_video_frame_rate (24);
684 stream->_frame_rate = 48000;
685 player->setup_pieces ();
686 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
687 piece = player->_pieces.front ();
688 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
689 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
690 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
691 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
692 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
694 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
695 content->set_position (DCPTime::from_seconds (3));
696 content->set_trim_start (ContentTime::from_seconds (1.5));
697 content->set_video_frame_rate (24);
698 film->set_video_frame_rate (24);
699 stream->_frame_rate = 48000;
700 player->setup_pieces ();
701 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
702 piece = player->_pieces.front ();
703 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
704 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
705 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
706 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
707 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
709 /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
710 content->set_position (DCPTime ());
711 content->set_trim_start (ContentTime ());
712 content->set_video_frame_rate (24);
713 film->set_video_frame_rate (24);
714 stream->_frame_rate = 44100;
715 player->setup_pieces ();
716 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
717 piece = player->_pieces.front ();
718 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
719 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
720 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
722 /* Position 3s, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
723 content->set_position (DCPTime::from_seconds (3));
724 content->set_trim_start (ContentTime ());
725 content->set_video_frame_rate (24);
726 film->set_video_frame_rate (24);
727 stream->_frame_rate = 44100;
728 player->setup_pieces ();
729 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
730 piece = player->_pieces.front ();
731 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
732 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
733 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
734 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
735 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
737 /* Position 3s, 1.5s trim, video content rate = video DCP rate, content audio rate = 44.1k */
738 content->set_position (DCPTime::from_seconds (3));
739 content->set_trim_start (ContentTime::from_seconds (1.5));
740 content->set_video_frame_rate (24);
741 film->set_video_frame_rate (24);
742 stream->_frame_rate = 44100;
743 player->setup_pieces ();
744 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
745 piece = player->_pieces.front ();
746 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
747 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
748 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
749 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
750 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);