2 Copyright (C) 2015-2016 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "lib/ffmpeg_content.h"
22 #include "lib/video_content.h"
23 #include "lib/player.h"
25 #include <boost/test/unit_test.hpp>
29 using boost::shared_ptr;
31 static string const xml = "<Content>"
33 "<BurnSubtitles>0</BurnSubtitles>"
34 "<BitsPerPixel>8</BitsPerPixel>"
35 "<Path>test/data/red_24.mp4</Path>"
36 "<Digest>2760e03c7251480f7f02c01a907792673784335</Digest>"
37 "<Position>0</Position>"
38 "<TrimStart>0</TrimStart>"
39 "<TrimEnd>0</TrimEnd>"
40 "<VideoLength>1353600</VideoLength>"
41 "<VideoWidth>1280</VideoWidth>"
42 "<VideoHeight>720</VideoHeight>"
43 "<VideoFrameRate>25</VideoFrameRate>"
44 "<VideoFrameType>0</VideoFrameType>"
45 "<LeftCrop>0</LeftCrop>"
46 "<RightCrop>0</RightCrop>"
47 "<TopCrop>0</TopCrop>"
48 "<BottomCrop>0</BottomCrop>"
53 "<InputTransferFunction>"
54 "<Type>ModifiedGamma</Type>"
55 "<Power>2.222222222222222</Power>"
56 "<Threshold>0.081</Threshold>"
59 "</InputTransferFunction>"
62 "<GreenX>0.3</GreenX>"
63 "<GreenY>0.6</GreenY>"
66 "<WhiteX>0.3127</WhiteX>"
67 "<WhiteY>0.329</WhiteY>"
68 "<OutputGamma>2.6</OutputGamma>"
71 "<FadeOut>0</FadeOut>"
72 "<AudioGain>0</AudioGain>"
73 "<AudioDelay>0</AudioDelay>"
74 "<UseSubtitles>0</UseSubtitles>"
75 "<SubtitleXOffset>0</SubtitleXOffset>"
76 "<SubtitleYOffset>0</SubtitleYOffset>"
77 "<SubtitleXScale>1</SubtitleXScale>"
78 "<SubtitleYScale>1</SubtitleYScale>"
79 "<SubtitleLanguage></SubtitleLanguage>"
81 "<Selected>1</Selected>"
82 "<Name>und; 2 channels</Name>"
84 "<FrameRate>44100</FrameRate>"
85 "<Channels>2</Channels>"
86 "<FirstAudio>0</FirstAudio>"
88 "<InputChannels>2</InputChannels>"
89 "<OutputChannels>12</OutputChannels>"
90 "<Gain Input=\"0\" Output=\"0\">1</Gain>"
91 "<Gain Input=\"0\" Output=\"1\">0</Gain>"
92 "<Gain Input=\"0\" Output=\"2\">0</Gain>"
93 "<Gain Input=\"0\" Output=\"3\">0</Gain>"
94 "<Gain Input=\"0\" Output=\"4\">0</Gain>"
95 "<Gain Input=\"0\" Output=\"5\">0</Gain>"
96 "<Gain Input=\"0\" Output=\"6\">0</Gain>"
97 "<Gain Input=\"0\" Output=\"7\">0</Gain>"
98 "<Gain Input=\"0\" Output=\"8\">0</Gain>"
99 "<Gain Input=\"0\" Output=\"9\">0</Gain>"
100 "<Gain Input=\"0\" Output=\"10\">0</Gain>"
101 "<Gain Input=\"0\" Output=\"11\">0</Gain>"
102 "<Gain Input=\"1\" Output=\"0\">0</Gain>"
103 "<Gain Input=\"1\" Output=\"1\">1</Gain>"
104 "<Gain Input=\"1\" Output=\"2\">0</Gain>"
105 "<Gain Input=\"1\" Output=\"3\">0</Gain>"
106 "<Gain Input=\"1\" Output=\"4\">0</Gain>"
107 "<Gain Input=\"1\" Output=\"5\">0</Gain>"
108 "<Gain Input=\"1\" Output=\"6\">0</Gain>"
109 "<Gain Input=\"1\" Output=\"7\">0</Gain>"
110 "<Gain Input=\"1\" Output=\"8\">0</Gain>"
111 "<Gain Input=\"1\" Output=\"9\">0</Gain>"
112 "<Gain Input=\"1\" Output=\"10\">0</Gain>"
113 "<Gain Input=\"1\" Output=\"11\">0</Gain>"
116 "<FirstVideo>0</FirstVideo>"
119 BOOST_AUTO_TEST_CASE (ffmpeg_time_calculation_test)
121 shared_ptr<Film> film = new_test_film ("ffmpeg_time_calculation_test");
123 shared_ptr<cxml::Document> doc (new cxml::Document);
124 doc->read_string (xml);
127 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
129 /* 25fps content, 25fps DCP */
130 film->set_video_frame_rate (25);
131 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() / 25.0));
132 /* 25fps content, 24fps DCP; length should be increased */
133 film->set_video_frame_rate (24);
134 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() / 24.0));
135 /* 25fps content, 30fps DCP; length should be decreased */
136 film->set_video_frame_rate (30);
137 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() / 30.0));
138 /* 25fps content, 50fps DCP; length should be the same */
139 film->set_video_frame_rate (50);
140 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() / 25.0));
141 /* 25fps content, 60fps DCP; length should be decreased */
142 film->set_video_frame_rate (60);
143 BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds (content->video->length() * (50.0 / 60) / 25.0));
146 /** Test Player::dcp_to_content_video */
147 BOOST_AUTO_TEST_CASE (player_time_calculation_test1)
149 shared_ptr<Film> film = new_test_film ("player_time_calculation_test1");
151 shared_ptr<cxml::Document> doc (new cxml::Document);
152 doc->read_string (xml);
155 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
156 film->set_sequence (false);
157 film->add_content (content);
159 shared_ptr<Player> player (new Player (film, film->playlist ()));
161 /* Position 0, no trim, content rate = DCP rate */
162 content->set_position (DCPTime ());
163 content->set_trim_start (ContentTime ());
164 content->video->set_frame_rate (24);
165 film->set_video_frame_rate (24);
166 player->setup_pieces ();
167 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
168 shared_ptr<Piece> piece = player->_pieces.front ();
169 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
170 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
171 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
173 /* Position 3s, no trim, content rate = DCP rate */
174 content->set_position (DCPTime::from_seconds (3));
175 content->set_trim_start (ContentTime ());
176 content->video->set_frame_rate (24);
177 film->set_video_frame_rate (24);
178 player->setup_pieces ();
179 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
180 piece = player->_pieces.front ();
181 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
182 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
183 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
184 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 36);
185 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
187 /* Position 3s, 1.5s trim, content rate = DCP rate */
188 content->set_position (DCPTime::from_seconds (3));
189 content->set_trim_start (ContentTime::from_seconds (1.5));
190 content->video->set_frame_rate (24);
191 film->set_video_frame_rate (24);
192 player->setup_pieces ();
193 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
194 piece = player->_pieces.front ();
195 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
196 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
197 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 36);
198 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
199 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
201 /* Position 0, no trim, content rate 24, DCP rate 25.
202 Now, for example, a DCPTime position of 3s means 3s at 25fps. Since we run the video
203 fast (at 25fps) in this case, this means 75 frames of content video will be used.
205 content->set_position (DCPTime ());
206 content->set_trim_start (ContentTime ());
207 content->video->set_frame_rate (24);
208 film->set_video_frame_rate (25);
209 player->setup_pieces ();
210 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
211 piece = player->_pieces.front ();
212 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
213 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.6)), 15);
214 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 75);
216 /* Position 3s, no trim, content rate 24, DCP rate 25 */
217 content->set_position (DCPTime::from_seconds (3));
218 content->set_trim_start (ContentTime ());
219 content->video->set_frame_rate (24);
220 film->set_video_frame_rate (25);
221 player->setup_pieces ();
222 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
223 piece = player->_pieces.front ();
224 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
225 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)), 0);
226 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
227 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)), 40);
228 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 168);
230 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25. Here the trim is in ContentTime,
231 so it's 1.6s at 24fps.
233 content->set_position (DCPTime::from_seconds (3));
234 content->set_trim_start (ContentTime::from_seconds (1.6));
235 content->video->set_frame_rate (24);
236 film->set_video_frame_rate (25);
237 player->setup_pieces ();
238 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
239 piece = player->_pieces.front ();
240 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
241 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.60)), 0);
242 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 38);
243 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.60)), 78);
244 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 207);
246 /* Position 0, no trim, content rate 24, DCP rate 48
247 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
248 with repeated frames in this case, 3 * 24 frames of content video will
249 be used to make 3 * 48 frames of DCP video. The results should be the same as the
250 content rate = DCP rate case.
252 content->set_position (DCPTime ());
253 content->set_trim_start (ContentTime ());
254 content->video->set_frame_rate (24);
255 film->set_video_frame_rate (48);
256 player->setup_pieces ();
257 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
258 piece = player->_pieces.front ();
259 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
260 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 12);
261 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 72);
263 /* Position 3s, no trim, content rate 24, DCP rate 48 */
264 content->set_position (DCPTime::from_seconds (3));
265 content->set_trim_start (ContentTime ());
266 content->video->set_frame_rate (24);
267 film->set_video_frame_rate (48);
268 player->setup_pieces ();
269 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
270 piece = player->_pieces.front ();
271 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
272 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
273 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
274 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 36);
275 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 162);
277 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
278 content->set_position (DCPTime::from_seconds (3));
279 content->set_trim_start (ContentTime::from_seconds (1.5));
280 content->video->set_frame_rate (24);
281 film->set_video_frame_rate (48);
282 player->setup_pieces ();
283 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
284 piece = player->_pieces.front ();
285 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
286 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
287 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 36);
288 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
289 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 198);
291 /* Position 0, no trim, content rate 48, DCP rate 24
292 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
293 with skipped frames in this case, 3 * 48 frames of content video will
294 be used to make 3 * 24 frames of DCP video.
296 content->set_position (DCPTime ());
297 content->set_trim_start (ContentTime ());
298 content->video->set_frame_rate (48);
299 film->set_video_frame_rate (24);
300 player->setup_pieces ();
301 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
302 piece = player->_pieces.front ();
303 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
304 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.5)), 24);
305 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.0)), 144);
307 /* Position 3s, no trim, content rate 24, DCP rate 48 */
308 content->set_position (DCPTime::from_seconds (3));
309 content->set_trim_start (ContentTime ());
310 content->video->set_frame_rate (48);
311 film->set_video_frame_rate (24);
312 player->setup_pieces ();
313 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
314 piece = player->_pieces.front ();
315 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
316 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
317 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 0);
318 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 72);
319 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 324);
321 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
322 content->set_position (DCPTime::from_seconds (3));
323 content->set_trim_start (ContentTime::from_seconds (1.5));
324 content->video->set_frame_rate (48);
325 film->set_video_frame_rate (24);
326 player->setup_pieces ();
327 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
328 piece = player->_pieces.front ();
329 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
330 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (0.50)), 0);
331 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (3.00)), 72);
332 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (4.50)), 144);
333 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime::from_seconds (9.75)), 396);
335 /* Position 0s, no trim, content rate 29.9978733, DCP rate 30 */
336 content->set_position (DCPTime::from_seconds (0));
337 content->set_trim_start (ContentTime::from_seconds (0));
338 content->video->set_frame_rate (29.9978733);
339 film->set_video_frame_rate (30);
340 player->setup_pieces ();
341 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
342 piece = player->_pieces.front ();
343 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime ()), 0);
344 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (3200)), 1);
345 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (6400)), 2);
346 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (9600)), 3);
347 BOOST_CHECK_EQUAL (player->dcp_to_content_video (piece, DCPTime (12800)), 4);
351 /** Test Player::content_video_to_dcp */
352 BOOST_AUTO_TEST_CASE (player_time_calculation_test2)
354 shared_ptr<Film> film = new_test_film ("player_time_calculation_test2");
356 shared_ptr<cxml::Document> doc (new cxml::Document);
357 doc->read_string (xml);
360 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
361 film->set_sequence (false);
362 film->add_content (content);
364 shared_ptr<Player> player (new Player (film, film->playlist ()));
366 /* Position 0, no trim, content rate = DCP rate */
367 content->set_position (DCPTime ());
368 content->set_trim_start (ContentTime ());
369 content->video->set_frame_rate (24);
370 film->set_video_frame_rate (24);
371 player->setup_pieces ();
372 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
373 shared_ptr<Piece> piece = player->_pieces.front ();
374 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
375 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
376 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
378 /* Position 3s, no trim, content rate = DCP rate */
379 content->set_position (DCPTime::from_seconds (3));
380 content->set_trim_start (ContentTime ());
381 content->video->set_frame_rate (24);
382 film->set_video_frame_rate (24);
383 player->setup_pieces ();
384 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
385 piece = player->_pieces.front ();
386 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
387 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
388 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
390 /* Position 3s, 1.5s trim, content rate = DCP rate */
391 content->set_position (DCPTime::from_seconds (3));
392 content->set_trim_start (ContentTime::from_seconds (1.5));
393 content->video->set_frame_rate (24);
394 film->set_video_frame_rate (24);
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::from_seconds (1.50));
399 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
400 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
401 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
403 /* Position 0, no trim, content rate 24, DCP rate 25.
404 Now, for example, a DCPTime position of 3s means 3s at 25fps. Since we run the video
405 fast (at 25fps) in this case, this means 75 frames of content video will be used.
407 content->set_position (DCPTime ());
408 content->set_trim_start (ContentTime ());
409 content->video->set_frame_rate (24);
410 film->set_video_frame_rate (25);
411 player->setup_pieces ();
412 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
413 piece = player->_pieces.front ();
414 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
415 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 15), DCPTime::from_seconds (0.6));
416 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 75), DCPTime::from_seconds (3.0));
418 /* Position 3s, no trim, content rate 24, DCP rate 25 */
419 content->set_position (DCPTime::from_seconds (3));
420 content->set_trim_start (ContentTime ());
421 content->video->set_frame_rate (24);
422 film->set_video_frame_rate (25);
423 player->setup_pieces ();
424 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
425 piece = player->_pieces.front ();
426 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
427 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (4.60));
428 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 169), DCPTime::from_seconds (9.76));
430 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, so the 1.6s trim is at 24fps */
431 content->set_position (DCPTime::from_seconds (3));
432 content->set_trim_start (ContentTime::from_seconds (1.6));
433 content->video->set_frame_rate (24);
434 film->set_video_frame_rate (25);
435 player->setup_pieces ();
436 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
437 piece = player->_pieces.front ();
438 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.464));
439 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 40), DCPTime::from_seconds (3.064));
440 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 80), DCPTime::from_seconds (4.664));
441 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 209), DCPTime::from_seconds (9.824));
443 /* Position 0, no trim, content rate 24, DCP rate 48
444 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
445 with repeated frames in this case, 3 * 24 frames of content video will
446 be used to make 3 * 48 frames of DCP video. The results should be the same as the
447 content rate = DCP rate case.
449 content->set_position (DCPTime ());
450 content->set_trim_start (ContentTime ());
451 content->video->set_frame_rate (24);
452 film->set_video_frame_rate (48);
453 player->setup_pieces ();
454 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
455 piece = player->_pieces.front ();
456 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
457 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 12), DCPTime::from_seconds (0.5));
458 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.0));
460 /* Position 3s, no trim, content rate 24, DCP rate 48 */
461 content->set_position (DCPTime::from_seconds (3));
462 content->set_trim_start (ContentTime ());
463 content->video->set_frame_rate (24);
464 film->set_video_frame_rate (48);
465 player->setup_pieces ();
466 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
467 piece = player->_pieces.front ();
468 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
469 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (4.50));
470 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 162), DCPTime::from_seconds (9.75));
472 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
473 content->set_position (DCPTime::from_seconds (3));
474 content->set_trim_start (ContentTime::from_seconds (1.5));
475 content->video->set_frame_rate (24);
476 film->set_video_frame_rate (48);
477 player->setup_pieces ();
478 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
479 piece = player->_pieces.front ();
480 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
481 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 36), DCPTime::from_seconds (3.00));
482 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
483 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 198), DCPTime::from_seconds (9.75));
485 /* Position 0, no trim, content rate 48, DCP rate 24
486 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
487 with skipped frames in this case, 3 * 48 frames of content video will
488 be used to make 3 * 24 frames of DCP video.
490 content->set_position (DCPTime ());
491 content->set_trim_start (ContentTime ());
492 content->video->set_frame_rate (48);
493 film->set_video_frame_rate (24);
494 player->setup_pieces ();
495 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
496 piece = player->_pieces.front ();
497 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime ());
498 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 24), DCPTime::from_seconds (0.5));
499 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (3.0));
501 /* Position 3s, no trim, content rate 24, DCP rate 48 */
502 content->set_position (DCPTime::from_seconds (3));
503 content->set_trim_start (ContentTime ());
504 content->video->set_frame_rate (48);
505 film->set_video_frame_rate (24);
506 player->setup_pieces ();
507 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
508 piece = player->_pieces.front ();
509 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (3.00));
510 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (4.50));
511 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 324), DCPTime::from_seconds (9.75));
513 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
514 content->set_position (DCPTime::from_seconds (3));
515 content->set_trim_start (ContentTime::from_seconds (1.5));
516 content->video->set_frame_rate (48);
517 film->set_video_frame_rate (24);
518 player->setup_pieces ();
519 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
520 piece = player->_pieces.front ();
521 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 0), DCPTime::from_seconds (1.50));
522 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 72), DCPTime::from_seconds (3.00));
523 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 144), DCPTime::from_seconds (4.50));
524 BOOST_CHECK_EQUAL (player->content_video_to_dcp (piece, 396), DCPTime::from_seconds (9.75));
527 /** Test Player::dcp_to_content_audio */
528 BOOST_AUTO_TEST_CASE (player_time_calculation_test3)
530 shared_ptr<Film> film = new_test_film ("player_time_calculation_test3");
532 shared_ptr<cxml::Document> doc (new cxml::Document);
533 doc->read_string (xml);
536 shared_ptr<FFmpegContent> content (new FFmpegContent (film, doc, film->state_version(), notes));
537 AudioStreamPtr stream = content->audio_streams().front();
538 film->set_sequence (false);
539 film->add_content (content);
541 shared_ptr<Player> player (new Player (film, film->playlist ()));
543 /* Position 0, no trim, video/audio content rate = video/audio DCP rate */
544 content->set_position (DCPTime ());
545 content->set_trim_start (ContentTime ());
546 content->video->set_frame_rate (24);
547 film->set_video_frame_rate (24);
548 stream->_frame_rate = 48000;
549 player->setup_pieces ();
550 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
551 shared_ptr<Piece> piece = player->_pieces.front ();
552 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
553 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
554 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
556 /* Position 3s, no trim, video/audio content rate = video/audio DCP rate */
557 content->set_position (DCPTime::from_seconds (3));
558 content->set_trim_start (ContentTime ());
559 content->video->set_frame_rate (24);
560 film->set_video_frame_rate (24);
561 stream->_frame_rate = 48000;
562 player->setup_pieces ();
563 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
564 piece = player->_pieces.front ();
565 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
566 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
567 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
568 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
569 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
571 /* Position 3s, 1.5s trim, video/audio content rate = video/audio DCP rate */
572 content->set_position (DCPTime::from_seconds (3));
573 content->set_trim_start (ContentTime::from_seconds (1.5));
574 content->video->set_frame_rate (24);
575 film->set_video_frame_rate (24);
576 stream->_frame_rate = 48000;
577 player->setup_pieces ();
578 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
579 piece = player->_pieces.front ();
580 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
581 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
582 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
583 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
584 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
586 /* Position 0, no trim, content video rate 24, DCP video rate 25, both audio rates still 48k */
587 content->set_position (DCPTime ());
588 content->set_trim_start (ContentTime ());
589 content->video->set_frame_rate (24);
590 film->set_video_frame_rate (25);
591 stream->_frame_rate = 48000;
592 player->setup_pieces ();
593 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
594 piece = player->_pieces.front ();
595 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
596 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.6)), 28800);
597 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
599 /* Position 3s, no trim, content video rate 24, DCP rate 25, both audio rates still 48k. */
600 content->set_position (DCPTime::from_seconds (3));
601 content->set_trim_start (ContentTime ());
602 content->video->set_frame_rate (24);
603 film->set_video_frame_rate (25);
604 stream->_frame_rate = 48000;
605 player->setup_pieces ();
606 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
607 piece = player->_pieces.front ();
608 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
609 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)), 0);
610 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 0);
611 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 76800);
612 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
614 /* Position 3s, 1.6s trim, content rate 24, DCP rate 25, both audio rates still 48k.
615 1s of content is 46080 samples after resampling.
617 content->set_position (DCPTime::from_seconds (3));
618 content->set_trim_start (ContentTime::from_seconds (1.6));
619 content->video->set_frame_rate (24);
620 film->set_video_frame_rate (25);
621 stream->_frame_rate = 48000;
622 player->setup_pieces ();
623 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
624 piece = player->_pieces.front ();
625 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
626 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.60)), 0);
627 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 73728);
628 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.60)), 150528);
629 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 397728);
631 /* Position 0, no trim, content rate 24, DCP rate 48, both audio rates still 48k.
632 Now, for example, a DCPTime position of 3s means 3s at 48fps. Since we run the video
633 with repeated frames in this case, audio samples will map straight through.
634 The results should be the same as the content rate = DCP rate case.
636 content->set_position (DCPTime ());
637 content->set_trim_start (ContentTime ());
638 content->video->set_frame_rate (24);
639 film->set_video_frame_rate (48);
640 stream->_frame_rate = 48000;
641 player->setup_pieces ();
642 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
643 piece = player->_pieces.front ();
644 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
645 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
646 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
648 /* Position 3s, no trim, content rate 24, DCP rate 48 */
649 content->set_position (DCPTime::from_seconds (3));
650 content->set_trim_start (ContentTime ());
651 content->video->set_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)), 0);
660 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
661 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
663 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
664 content->set_position (DCPTime::from_seconds (3));
665 content->set_trim_start (ContentTime::from_seconds (1.5));
666 content->video->set_frame_rate (24);
667 film->set_video_frame_rate (24);
668 stream->_frame_rate = 48000;
669 player->setup_pieces ();
670 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
671 piece = player->_pieces.front ();
672 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
673 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
674 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
675 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
676 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
678 /* Position 0, no trim, content rate 48, DCP rate 24
679 Now, for example, a DCPTime position of 3s means 3s at 24fps. Since we run the video
680 with skipped frames in this case, audio samples should map straight through.
682 content->set_position (DCPTime ());
683 content->set_trim_start (ContentTime ());
684 content->video->set_frame_rate (24);
685 film->set_video_frame_rate (48);
686 stream->_frame_rate = 48000;
687 player->setup_pieces ();
688 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
689 piece = player->_pieces.front ();
690 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
691 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
692 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
694 /* Position 3s, no trim, content rate 24, DCP rate 48 */
695 content->set_position (DCPTime::from_seconds (3));
696 content->set_trim_start (ContentTime ());
697 content->video->set_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)), 0);
706 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
707 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
709 /* Position 3s, 1.5s trim, content rate 24, DCP rate 48 */
710 content->set_position (DCPTime::from_seconds (3));
711 content->set_trim_start (ContentTime::from_seconds (1.5));
712 content->video->set_frame_rate (24);
713 film->set_video_frame_rate (24);
714 stream->_frame_rate = 48000;
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.50)), 0);
720 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
721 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
722 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
724 /* Position 0, no trim, video content rate = video DCP rate, content audio rate = 44.1k */
725 content->set_position (DCPTime ());
726 content->set_trim_start (ContentTime ());
727 content->video->set_frame_rate (24);
728 film->set_video_frame_rate (24);
729 stream->_frame_rate = 44100;
730 player->setup_pieces ();
731 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
732 piece = player->_pieces.front ();
733 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
734 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.5)), 24000);
735 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.0)), 144000);
737 /* Position 3s, no 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 ());
740 content->video->set_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)), 0);
749 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 72000);
750 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 324000);
752 /* Position 3s, 1.5s trim, video content rate = video DCP rate, content audio rate = 44.1k */
753 content->set_position (DCPTime::from_seconds (3));
754 content->set_trim_start (ContentTime::from_seconds (1.5));
755 content->video->set_frame_rate (24);
756 film->set_video_frame_rate (24);
757 stream->_frame_rate = 44100;
758 player->setup_pieces ();
759 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
760 piece = player->_pieces.front ();
761 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 0);
762 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (0.50)), 0);
763 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (3.00)), 72000);
764 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (4.50)), 144000);
765 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime::from_seconds (9.75)), 396000);
767 /* Check with a large start trim */
768 content->set_position (DCPTime::from_seconds (0));
769 content->set_trim_start (ContentTime::from_seconds (54143));
770 content->video->set_frame_rate (24);
771 film->set_video_frame_rate (24);
772 stream->_frame_rate = 48000;
773 player->setup_pieces ();
774 BOOST_REQUIRE_EQUAL (player->_pieces.size(), 1);
775 piece = player->_pieces.front ();
776 BOOST_CHECK_EQUAL (player->dcp_to_resampled_audio (piece, DCPTime ()), 54143L * 48000);