2 Copyright (C) 2012 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.
20 #include <boost/test/unit_test.hpp>
22 #include "lib/config.h"
23 #include "lib/ffmpeg_content.h"
24 #include "lib/playlist.h"
27 using boost::shared_ptr;
29 /* Test Playlist::best_dcp_frame_rate and FrameRateConversion
30 with a single piece of content.
32 BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single)
34 shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_single");
35 /* Get any piece of content, it doesn't matter what */
36 shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
37 film->add_content (content);
40 /* Run some tests with a limited range of allowed rates */
46 Config::instance()->set_allowed_dcp_frame_rates (afr);
48 content->_video_frame_rate = 60;
49 int best = film->playlist()->best_dcp_frame_rate ();
50 FrameRateChange frc = FrameRateChange (60, best);
51 BOOST_CHECK_EQUAL (best, 30);
52 BOOST_CHECK_EQUAL (frc.skip, true);
53 BOOST_CHECK_EQUAL (frc.repeat, 1);
54 BOOST_CHECK_EQUAL (frc.change_speed, false);
55 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
57 content->_video_frame_rate = 50;
58 best = film->playlist()->best_dcp_frame_rate ();
59 frc = FrameRateChange (50, best);
60 BOOST_CHECK_EQUAL (best, 25);
61 BOOST_CHECK_EQUAL (frc.skip, true);
62 BOOST_CHECK_EQUAL (frc.repeat, 1);
63 BOOST_CHECK_EQUAL (frc.change_speed, false);
64 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
66 content->_video_frame_rate = 48;
67 best = film->playlist()->best_dcp_frame_rate ();
68 frc = FrameRateChange (48, best);
69 BOOST_CHECK_EQUAL (best, 24);
70 BOOST_CHECK_EQUAL (frc.skip, true);
71 BOOST_CHECK_EQUAL (frc.repeat, 1);
72 BOOST_CHECK_EQUAL (frc.change_speed, false);
73 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
75 content->_video_frame_rate = 30;
76 best = film->playlist()->best_dcp_frame_rate ();
77 frc = FrameRateChange (30, best);
78 BOOST_CHECK_EQUAL (best, 30);
79 BOOST_CHECK_EQUAL (frc.skip, false);
80 BOOST_CHECK_EQUAL (frc.repeat, 1);
81 BOOST_CHECK_EQUAL (frc.change_speed, false);
82 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
84 content->_video_frame_rate = 29.97;
85 best = film->playlist()->best_dcp_frame_rate ();
86 frc = FrameRateChange (29.97, best);
87 BOOST_CHECK_EQUAL (best, 30);
88 BOOST_CHECK_EQUAL (frc.skip, false);
89 BOOST_CHECK_EQUAL (frc.repeat, 1);
90 BOOST_CHECK_EQUAL (frc.change_speed, true);
91 BOOST_CHECK_CLOSE (frc.speed_up, 30 / 29.97, 0.1);
93 content->_video_frame_rate = 25;
94 best = film->playlist()->best_dcp_frame_rate ();
95 frc = FrameRateChange (25, best);
96 BOOST_CHECK_EQUAL (best, 25);
97 BOOST_CHECK_EQUAL (frc.skip, false);
98 BOOST_CHECK_EQUAL (frc.repeat, 1);
99 BOOST_CHECK_EQUAL (frc.change_speed, false);
100 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
102 content->_video_frame_rate = 24;
103 best = film->playlist()->best_dcp_frame_rate ();
104 frc = FrameRateChange (24, best);
105 BOOST_CHECK_EQUAL (best, 24);
106 BOOST_CHECK_EQUAL (frc.skip, false);
107 BOOST_CHECK_EQUAL (frc.repeat, 1);
108 BOOST_CHECK_EQUAL (frc.change_speed, false);
109 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
111 content->_video_frame_rate = 14.5;
112 best = film->playlist()->best_dcp_frame_rate ();
113 frc = FrameRateChange (14.5, best);
114 BOOST_CHECK_EQUAL (best, 30);
115 BOOST_CHECK_EQUAL (frc.skip, false);
116 BOOST_CHECK_EQUAL (frc.repeat, 2);
117 BOOST_CHECK_EQUAL (frc.change_speed, true);
118 BOOST_CHECK_CLOSE (frc.speed_up, 15 / 14.5, 0.1);
120 content->_video_frame_rate = 12.6;
121 best = film->playlist()->best_dcp_frame_rate ();
122 frc = FrameRateChange (12.6, best);
123 BOOST_CHECK_EQUAL (best, 25);
124 BOOST_CHECK_EQUAL (frc.skip, false);
125 BOOST_CHECK_EQUAL (frc.repeat, 2);
126 BOOST_CHECK_EQUAL (frc.change_speed, true);
127 BOOST_CHECK_CLOSE (frc.speed_up, 25 / 25.2, 0.1);
129 content->_video_frame_rate = 12.4;
130 best = film->playlist()->best_dcp_frame_rate ();
131 frc = FrameRateChange (12.4, best);
132 BOOST_CHECK_EQUAL (best, 25);
133 BOOST_CHECK_EQUAL (frc.skip, false);
134 BOOST_CHECK_EQUAL (frc.repeat, 2);
135 BOOST_CHECK_EQUAL (frc.change_speed, true);
136 BOOST_CHECK_CLOSE (frc.speed_up, 25 / 24.8, 0.1);
138 content->_video_frame_rate = 12;
139 best = film->playlist()->best_dcp_frame_rate ();
140 frc = FrameRateChange (12, best);
141 BOOST_CHECK_EQUAL (best, 24);
142 BOOST_CHECK_EQUAL (frc.skip, false);
143 BOOST_CHECK_EQUAL (frc.repeat, 2);
144 BOOST_CHECK_EQUAL (frc.change_speed, false);
145 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
147 /* Now add some more rates and see if it will use them
148 in preference to skip/repeat.
154 Config::instance()->set_allowed_dcp_frame_rates (afr);
156 content->_video_frame_rate = 60;
157 best = film->playlist()->best_dcp_frame_rate ();
158 frc = FrameRateChange (60, best);
159 BOOST_CHECK_EQUAL (best, 60);
160 BOOST_CHECK_EQUAL (frc.skip, false);
161 BOOST_CHECK_EQUAL (frc.repeat, 1);
162 BOOST_CHECK_EQUAL (frc.change_speed, false);
163 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
165 content->_video_frame_rate = 50;
166 best = film->playlist()->best_dcp_frame_rate ();
167 frc = FrameRateChange (50, best);
168 BOOST_CHECK_EQUAL (best, 50);
169 BOOST_CHECK_EQUAL (frc.skip, false);
170 BOOST_CHECK_EQUAL (frc.repeat, 1);
171 BOOST_CHECK_EQUAL (frc.change_speed, false);
172 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
174 content->_video_frame_rate = 48;
175 best = film->playlist()->best_dcp_frame_rate ();
176 frc = FrameRateChange (48, best);
177 BOOST_CHECK_EQUAL (best, 48);
178 BOOST_CHECK_EQUAL (frc.skip, false);
179 BOOST_CHECK_EQUAL (frc.repeat, 1);
180 BOOST_CHECK_EQUAL (frc.change_speed, false);
181 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
183 /* Check some out-there conversions (not the best) */
185 frc = FrameRateChange (14.99, 24);
186 BOOST_CHECK_EQUAL (frc.skip, false);
187 BOOST_CHECK_EQUAL (frc.repeat, 2);
188 BOOST_CHECK_EQUAL (frc.change_speed, true);
189 BOOST_CHECK_CLOSE (frc.speed_up, 24 / (2 * 14.99), 0.1);
191 /* Check some conversions with limited DCP targets */
195 Config::instance()->set_allowed_dcp_frame_rates (afr);
197 content->_video_frame_rate = 25;
198 best = film->playlist()->best_dcp_frame_rate ();
199 frc = FrameRateChange (25, best);
200 BOOST_CHECK_EQUAL (best, 24);
201 BOOST_CHECK_EQUAL (frc.skip, false);
202 BOOST_CHECK_EQUAL (frc.repeat, 1);
203 BOOST_CHECK_EQUAL (frc.change_speed, true);
204 BOOST_CHECK_CLOSE (frc.speed_up, 24.0 / 25, 0.1);
207 /* Test Playlist::best_dcp_frame_rate and FrameRateChange
208 with two pieces of content.
210 BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_double)
212 shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_double");
213 /* Get any old content, it doesn't matter what */
214 shared_ptr<FFmpegContent> A (new FFmpegContent (film, "test/data/test.mp4"));
215 film->add_content (A);
216 shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/test.mp4"));
217 film->add_content (B);
220 /* Run some tests with a limited range of allowed rates */
226 Config::instance()->set_allowed_dcp_frame_rates (afr);
228 A->_video_frame_rate = 30;
229 B->_video_frame_rate = 24;
230 BOOST_CHECK_EQUAL (film->playlist()->best_dcp_frame_rate(), 25);
234 BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
236 shared_ptr<Film> film = new_test_film ("audio_sampling_rate_test");
237 /* Get any piece of content, it doesn't matter what */
238 shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
239 film->add_content (content);
246 Config::instance()->set_allowed_dcp_frame_rates (afr);
248 content->_video_frame_rate = 24;
249 film->set_video_frame_rate (24);
250 content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
251 BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 48000);
253 content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
254 BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 48000);
256 content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 80000, 0)));
257 BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 96000);
259 content->_video_frame_rate = 23.976;
260 film->set_video_frame_rate (24);
261 content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
262 BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 47952);
264 content->_video_frame_rate = 29.97;
265 film->set_video_frame_rate (30);
266 BOOST_CHECK_EQUAL (film->video_frame_rate (), 30);
267 content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
268 BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 47952);
270 content->_video_frame_rate = 25;
271 film->set_video_frame_rate (24);
272 content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
273 BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 50000);
275 content->_video_frame_rate = 25;
276 film->set_video_frame_rate (24);
277 content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
278 BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 50000);
280 /* Check some out-there conversions (not the best) */
282 content->_video_frame_rate = 14.99;
283 film->set_video_frame_rate (25);
284 content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 16000, 0)));
285 /* The FrameRateChange within output_audio_frame_rate should choose to double-up
286 the 14.99 fps video to 30 and then run it slow at 25.
288 BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), rint (48000 * 2 * 14.99 / 25));