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->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->_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->_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->_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->_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->_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->_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->_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->_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->_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->_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->_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->_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->_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->_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->_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->add_content (A);
225 shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/test.mp4"));
226 film->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->_video_frame_rate = 30;
238 B->video->_video_frame_rate = 24;
239 BOOST_CHECK_EQUAL (film->best_video_frame_rate(), 25);
241 A->video->_video_frame_rate = 24;
242 B->video->_video_frame_rate = 24;
243 BOOST_CHECK_EQUAL (film->best_video_frame_rate(), 24);
245 A->video->_video_frame_rate = 24;
246 B->video->_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));
265 content->_audio_streams.push_back (stream);
266 content->video->_video_frame_rate = 24;
267 film->set_video_frame_rate (24);
268 stream->_frame_rate = 48000;
269 BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 48000);
271 stream->_frame_rate = 44100;
272 BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 48000);
274 stream->_frame_rate = 80000;
275 BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 96000);
277 content->video->_video_frame_rate = 23.976;
278 film->set_video_frame_rate (24);
279 stream->_frame_rate = 48000;
280 BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 47952);
282 content->video->_video_frame_rate = 29.97;
283 film->set_video_frame_rate (30);
284 BOOST_CHECK_EQUAL (film->video_frame_rate (), 30);
285 stream->_frame_rate = 48000;
286 BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 47952);
288 content->video->_video_frame_rate = 25;
289 film->set_video_frame_rate (24);
290 stream->_frame_rate = 48000;
291 BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 50000);
293 content->video->_video_frame_rate = 25;
294 film->set_video_frame_rate (24);
295 stream->_frame_rate = 44100;
296 BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), 50000);
298 /* Check some out-there conversions (not the best) */
300 content->video->_video_frame_rate = 14.99;
301 film->set_video_frame_rate (25);
302 stream->_frame_rate = 16000;
303 /* The FrameRateChange within resampled_audio_frame_rate should choose to double-up
304 the 14.99 fps video to 30 and then run it slow at 25.
306 BOOST_CHECK_EQUAL (content->audio->resampled_audio_frame_rate(), lrint (48000 * 2 * 14.99 / 25));