2 Copyright (C) 2012-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.
20 /** @file test/frame_rate_test.cc
21 * @brief Tests for FrameRateChange and the computation of the best
22 * frame rate for the DCP.
25 #include <boost/test/unit_test.hpp>
27 #include "lib/config.h"
28 #include "lib/ffmpeg_content.h"
29 #include "lib/playlist.h"
30 #include "lib/ffmpeg_audio_stream.h"
31 #include "lib/frame_rate_change.h"
32 #include "lib/video_content.h"
33 #include "lib/audio_content.h"
36 using boost::shared_ptr;
38 /* Test Playlist::best_dcp_frame_rate and FrameRateChange
39 with a single piece of content.
41 BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single)
43 shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_single");
44 /* Get any piece of content, it doesn't matter what */
45 shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
46 film->examine_and_add_content (content);
49 /* Run some tests with a limited range of allowed rates */
55 Config::instance()->set_allowed_dcp_frame_rates (afr);
57 content->_video_frame_rate = 60;
58 int best = film->best_video_frame_rate ();
59 FrameRateChange frc = FrameRateChange (60, best);
60 BOOST_CHECK_EQUAL (best, 30);
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 = 50;
67 best = film->best_video_frame_rate ();
68 frc = FrameRateChange (50, best);
69 BOOST_CHECK_EQUAL (best, 25);
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 = 48;
76 best = film->best_video_frame_rate ();
77 frc = FrameRateChange (48, best);
78 BOOST_CHECK_EQUAL (best, 24);
79 BOOST_CHECK_EQUAL (frc.skip, true);
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 = 30;
85 best = film->best_video_frame_rate ();
86 frc = FrameRateChange (30, 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, false);
91 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
93 content->_video_frame_rate = 29.97;
94 best = film->best_video_frame_rate ();
95 frc = FrameRateChange (29.97, best);
96 BOOST_CHECK_EQUAL (best, 30);
97 BOOST_CHECK_EQUAL (frc.skip, false);
98 BOOST_CHECK_EQUAL (frc.repeat, 1);
99 BOOST_CHECK_EQUAL (frc.change_speed, true);
100 BOOST_CHECK_CLOSE (frc.speed_up, 30 / 29.97, 0.1);
102 content->_video_frame_rate = 25;
103 best = film->best_video_frame_rate ();
104 frc = FrameRateChange (25, best);
105 BOOST_CHECK_EQUAL (best, 25);
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 = 24;
112 best = film->best_video_frame_rate ();
113 frc = FrameRateChange (24, best);
114 BOOST_CHECK_EQUAL (best, 24);
115 BOOST_CHECK_EQUAL (frc.skip, false);
116 BOOST_CHECK_EQUAL (frc.repeat, 1);
117 BOOST_CHECK_EQUAL (frc.change_speed, false);
118 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
120 content->_video_frame_rate = 14.5;
121 best = film->best_video_frame_rate ();
122 frc = FrameRateChange (14.5, best);
123 BOOST_CHECK_EQUAL (best, 30);
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, 15 / 14.5, 0.1);
129 content->_video_frame_rate = 12.6;
130 best = film->best_video_frame_rate ();
131 frc = FrameRateChange (12.6, 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 / 25.2, 0.1);
138 content->_video_frame_rate = 12.4;
139 best = film->best_video_frame_rate ();
140 frc = FrameRateChange (12.4, best);
141 BOOST_CHECK_EQUAL (best, 25);
142 BOOST_CHECK_EQUAL (frc.skip, false);
143 BOOST_CHECK_EQUAL (frc.repeat, 2);
144 BOOST_CHECK_EQUAL (frc.change_speed, true);
145 BOOST_CHECK_CLOSE (frc.speed_up, 25 / 24.8, 0.1);
147 content->_video_frame_rate = 12;
148 best = film->best_video_frame_rate ();
149 frc = FrameRateChange (12, best);
150 BOOST_CHECK_EQUAL (best, 24);
151 BOOST_CHECK_EQUAL (frc.skip, false);
152 BOOST_CHECK_EQUAL (frc.repeat, 2);
153 BOOST_CHECK_EQUAL (frc.change_speed, false);
154 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
156 /* Now add some more rates and see if it will use them
157 in preference to skip/repeat.
163 Config::instance()->set_allowed_dcp_frame_rates (afr);
165 content->_video_frame_rate = 60;
166 best = film->best_video_frame_rate ();
167 frc = FrameRateChange (60, best);
168 BOOST_CHECK_EQUAL (best, 60);
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 = 50;
175 best = film->best_video_frame_rate ();
176 frc = FrameRateChange (50, best);
177 BOOST_CHECK_EQUAL (best, 50);
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 content->_video_frame_rate = 48;
184 best = film->best_video_frame_rate ();
185 frc = FrameRateChange (48, best);
186 BOOST_CHECK_EQUAL (best, 48);
187 BOOST_CHECK_EQUAL (frc.skip, false);
188 BOOST_CHECK_EQUAL (frc.repeat, 1);
189 BOOST_CHECK_EQUAL (frc.change_speed, false);
190 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
192 /* Check some out-there conversions (not the best) */
194 frc = FrameRateChange (14.99, 24);
195 BOOST_CHECK_EQUAL (frc.skip, false);
196 BOOST_CHECK_EQUAL (frc.repeat, 2);
197 BOOST_CHECK_EQUAL (frc.change_speed, true);
198 BOOST_CHECK_CLOSE (frc.speed_up, 24 / (2 * 14.99), 0.1);
200 /* Check some conversions with limited DCP targets */
204 Config::instance()->set_allowed_dcp_frame_rates (afr);
206 content->_video_frame_rate = 25;
207 best = film->best_video_frame_rate ();
208 frc = FrameRateChange (25, best);
209 BOOST_CHECK_EQUAL (best, 24);
210 BOOST_CHECK_EQUAL (frc.skip, false);
211 BOOST_CHECK_EQUAL (frc.repeat, 1);
212 BOOST_CHECK_EQUAL (frc.change_speed, true);
213 BOOST_CHECK_CLOSE (frc.speed_up, 24.0 / 25, 0.1);
216 /* Test Playlist::best_dcp_frame_rate and FrameRateChange
217 with two pieces of content.
219 BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_double)
221 shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_double");
222 /* Get any old content, it doesn't matter what */
223 shared_ptr<FFmpegContent> A (new FFmpegContent (film, "test/data/test.mp4"));
224 film->examine_and_add_content (A);
225 shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/test.mp4"));
226 film->examine_and_add_content (B);
229 /* Run some tests with a limited range of allowed rates */
235 Config::instance()->set_allowed_dcp_frame_rates (afr);
237 A->_video_frame_rate = 30;
238 B->_video_frame_rate = 24;
239 BOOST_CHECK_EQUAL (film->best_video_frame_rate(), 25);
241 A->_video_frame_rate = 24;
242 B->_video_frame_rate = 24;
243 BOOST_CHECK_EQUAL (film->best_video_frame_rate(), 24);
245 A->_video_frame_rate = 24;
246 B->_video_frame_rate = 48;
247 BOOST_CHECK_EQUAL (film->best_video_frame_rate(), 24);
250 BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
252 shared_ptr<Film> film = new_test_film ("audio_sampling_rate_test");
253 /* Get any piece of content, it doesn't matter what */
254 shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
255 film->examine_and_add_content (content);
262 Config::instance()->set_allowed_dcp_frame_rates (afr);
264 shared_ptr<FFmpegAudioStream> stream (new FFmpegAudioStream ("foo", 0, 0, 0, 0));
265 content->audio.reset (new AudioContent (content.get()));
266 content->audio->add_stream (stream);
267 content->_video_frame_rate = 24;
268 film->set_video_frame_rate (24);
269 stream->_frame_rate = 48000;
270 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 48000);
272 stream->_frame_rate = 44100;
273 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 48000);
275 stream->_frame_rate = 80000;
276 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 96000);
278 content->_video_frame_rate = 23.976;
279 film->set_video_frame_rate (24);
280 stream->_frame_rate = 48000;
281 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 47952);
283 content->_video_frame_rate = 29.97;
284 film->set_video_frame_rate (30);
285 BOOST_CHECK_EQUAL (film->video_frame_rate (), 30);
286 stream->_frame_rate = 48000;
287 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 47952);
289 content->_video_frame_rate = 25;
290 film->set_video_frame_rate (24);
291 stream->_frame_rate = 48000;
292 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 50000);
294 content->_video_frame_rate = 25;
295 film->set_video_frame_rate (24);
296 stream->_frame_rate = 44100;
297 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 50000);
299 /* Check some out-there conversions (not the best) */
301 content->_video_frame_rate = 14.99;
302 film->set_video_frame_rate (25);
303 stream->_frame_rate = 16000;
304 /* The FrameRateChange within resampled_frame_rate should choose to double-up
305 the 14.99 fps video to 30 and then run it slow at 25.
307 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), lrint (48000 * 2 * 14.99 / 25));