2 Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 /** @file test/frame_rate_test.cc
22 * @brief Tests for FrameRateChange and the computation of the best
23 * frame rate for the DCP.
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"
35 #include <boost/test/unit_test.hpp>
36 #include <boost/make_shared.hpp>
38 using boost::shared_ptr;
39 using boost::make_shared;
41 /* Test Playlist::best_dcp_frame_rate and FrameRateChange
42 with a single piece of content.
44 BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single)
46 shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_single");
47 /* Get any piece of content, it doesn't matter what */
48 shared_ptr<FFmpegContent> content = make_shared<FFmpegContent> (film, "test/data/test.mp4");
49 film->examine_and_add_content (content);
52 /* Run some tests with a limited range of allowed rates */
58 Config::instance()->set_allowed_dcp_frame_rates (afr);
60 content->_video_frame_rate = 60;
61 int best = film->best_video_frame_rate ();
62 FrameRateChange frc = FrameRateChange (60, best);
63 BOOST_CHECK_EQUAL (best, 30);
64 BOOST_CHECK_EQUAL (frc.skip, true);
65 BOOST_CHECK_EQUAL (frc.repeat, 1);
66 BOOST_CHECK_EQUAL (frc.change_speed, false);
67 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
69 content->_video_frame_rate = 50;
70 best = film->best_video_frame_rate ();
71 frc = FrameRateChange (50, best);
72 BOOST_CHECK_EQUAL (best, 25);
73 BOOST_CHECK_EQUAL (frc.skip, true);
74 BOOST_CHECK_EQUAL (frc.repeat, 1);
75 BOOST_CHECK_EQUAL (frc.change_speed, false);
76 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
78 content->_video_frame_rate = 48;
79 best = film->best_video_frame_rate ();
80 frc = FrameRateChange (48, best);
81 BOOST_CHECK_EQUAL (best, 24);
82 BOOST_CHECK_EQUAL (frc.skip, true);
83 BOOST_CHECK_EQUAL (frc.repeat, 1);
84 BOOST_CHECK_EQUAL (frc.change_speed, false);
85 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
87 content->_video_frame_rate = 30;
88 best = film->best_video_frame_rate ();
89 frc = FrameRateChange (30, best);
90 BOOST_CHECK_EQUAL (best, 30);
91 BOOST_CHECK_EQUAL (frc.skip, false);
92 BOOST_CHECK_EQUAL (frc.repeat, 1);
93 BOOST_CHECK_EQUAL (frc.change_speed, false);
94 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
96 content->_video_frame_rate = 29.97;
97 best = film->best_video_frame_rate ();
98 frc = FrameRateChange (29.97, best);
99 BOOST_CHECK_EQUAL (best, 30);
100 BOOST_CHECK_EQUAL (frc.skip, false);
101 BOOST_CHECK_EQUAL (frc.repeat, 1);
102 BOOST_CHECK_EQUAL (frc.change_speed, true);
103 BOOST_CHECK_CLOSE (frc.speed_up, 30 / 29.97, 0.1);
105 content->_video_frame_rate = 25;
106 best = film->best_video_frame_rate ();
107 frc = FrameRateChange (25, best);
108 BOOST_CHECK_EQUAL (best, 25);
109 BOOST_CHECK_EQUAL (frc.skip, false);
110 BOOST_CHECK_EQUAL (frc.repeat, 1);
111 BOOST_CHECK_EQUAL (frc.change_speed, false);
112 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
114 content->_video_frame_rate = 24;
115 best = film->best_video_frame_rate ();
116 frc = FrameRateChange (24, best);
117 BOOST_CHECK_EQUAL (best, 24);
118 BOOST_CHECK_EQUAL (frc.skip, false);
119 BOOST_CHECK_EQUAL (frc.repeat, 1);
120 BOOST_CHECK_EQUAL (frc.change_speed, false);
121 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
123 content->_video_frame_rate = 14.5;
124 best = film->best_video_frame_rate ();
125 frc = FrameRateChange (14.5, best);
126 BOOST_CHECK_EQUAL (best, 30);
127 BOOST_CHECK_EQUAL (frc.skip, false);
128 BOOST_CHECK_EQUAL (frc.repeat, 2);
129 BOOST_CHECK_EQUAL (frc.change_speed, true);
130 BOOST_CHECK_CLOSE (frc.speed_up, 15 / 14.5, 0.1);
132 content->_video_frame_rate = 12.6;
133 best = film->best_video_frame_rate ();
134 frc = FrameRateChange (12.6, best);
135 BOOST_CHECK_EQUAL (best, 25);
136 BOOST_CHECK_EQUAL (frc.skip, false);
137 BOOST_CHECK_EQUAL (frc.repeat, 2);
138 BOOST_CHECK_EQUAL (frc.change_speed, true);
139 BOOST_CHECK_CLOSE (frc.speed_up, 25 / 25.2, 0.1);
141 content->_video_frame_rate = 12.4;
142 best = film->best_video_frame_rate ();
143 frc = FrameRateChange (12.4, best);
144 BOOST_CHECK_EQUAL (best, 25);
145 BOOST_CHECK_EQUAL (frc.skip, false);
146 BOOST_CHECK_EQUAL (frc.repeat, 2);
147 BOOST_CHECK_EQUAL (frc.change_speed, true);
148 BOOST_CHECK_CLOSE (frc.speed_up, 25 / 24.8, 0.1);
150 content->_video_frame_rate = 12;
151 best = film->best_video_frame_rate ();
152 frc = FrameRateChange (12, best);
153 BOOST_CHECK_EQUAL (best, 24);
154 BOOST_CHECK_EQUAL (frc.skip, false);
155 BOOST_CHECK_EQUAL (frc.repeat, 2);
156 BOOST_CHECK_EQUAL (frc.change_speed, false);
157 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
159 /* Now add some more rates and see if it will use them
160 in preference to skip/repeat.
166 Config::instance()->set_allowed_dcp_frame_rates (afr);
168 content->_video_frame_rate = 60;
169 best = film->best_video_frame_rate ();
170 frc = FrameRateChange (60, best);
171 BOOST_CHECK_EQUAL (best, 60);
172 BOOST_CHECK_EQUAL (frc.skip, false);
173 BOOST_CHECK_EQUAL (frc.repeat, 1);
174 BOOST_CHECK_EQUAL (frc.change_speed, false);
175 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
177 content->_video_frame_rate = 50;
178 best = film->best_video_frame_rate ();
179 frc = FrameRateChange (50, best);
180 BOOST_CHECK_EQUAL (best, 50);
181 BOOST_CHECK_EQUAL (frc.skip, false);
182 BOOST_CHECK_EQUAL (frc.repeat, 1);
183 BOOST_CHECK_EQUAL (frc.change_speed, false);
184 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
186 content->_video_frame_rate = 48;
187 best = film->best_video_frame_rate ();
188 frc = FrameRateChange (48, best);
189 BOOST_CHECK_EQUAL (best, 48);
190 BOOST_CHECK_EQUAL (frc.skip, false);
191 BOOST_CHECK_EQUAL (frc.repeat, 1);
192 BOOST_CHECK_EQUAL (frc.change_speed, false);
193 BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
195 /* Check some out-there conversions (not the best) */
197 frc = FrameRateChange (14.99, 24);
198 BOOST_CHECK_EQUAL (frc.skip, false);
199 BOOST_CHECK_EQUAL (frc.repeat, 2);
200 BOOST_CHECK_EQUAL (frc.change_speed, true);
201 BOOST_CHECK_CLOSE (frc.speed_up, 24 / (2 * 14.99), 0.1);
203 /* Check some conversions with limited DCP targets */
207 Config::instance()->set_allowed_dcp_frame_rates (afr);
209 content->_video_frame_rate = 25;
210 best = film->best_video_frame_rate ();
211 frc = FrameRateChange (25, best);
212 BOOST_CHECK_EQUAL (best, 24);
213 BOOST_CHECK_EQUAL (frc.skip, false);
214 BOOST_CHECK_EQUAL (frc.repeat, 1);
215 BOOST_CHECK_EQUAL (frc.change_speed, true);
216 BOOST_CHECK_CLOSE (frc.speed_up, 24.0 / 25, 0.1);
219 /* Test Playlist::best_dcp_frame_rate and FrameRateChange
220 with two pieces of content.
222 BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_double)
224 shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_double");
225 /* Get any old content, it doesn't matter what */
226 shared_ptr<FFmpegContent> A = make_shared<FFmpegContent> (film, "test/data/test.mp4");
227 film->examine_and_add_content (A);
228 shared_ptr<FFmpegContent> B = make_shared<FFmpegContent> (film, "test/data/test.mp4");
229 film->examine_and_add_content (B);
232 /* Run some tests with a limited range of allowed rates */
238 Config::instance()->set_allowed_dcp_frame_rates (afr);
240 A->_video_frame_rate = 30;
241 B->_video_frame_rate = 24;
242 BOOST_CHECK_EQUAL (film->best_video_frame_rate(), 25);
244 A->_video_frame_rate = 24;
245 B->_video_frame_rate = 24;
246 BOOST_CHECK_EQUAL (film->best_video_frame_rate(), 24);
248 A->_video_frame_rate = 24;
249 B->_video_frame_rate = 48;
250 BOOST_CHECK_EQUAL (film->best_video_frame_rate(), 24);
253 BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
255 shared_ptr<Film> film = new_test_film ("audio_sampling_rate_test");
256 /* Get any piece of content, it doesn't matter what */
257 shared_ptr<FFmpegContent> content = make_shared<FFmpegContent> (film, "test/data/test.mp4");
258 film->examine_and_add_content (content);
265 Config::instance()->set_allowed_dcp_frame_rates (afr);
267 shared_ptr<FFmpegAudioStream> stream = make_shared<FFmpegAudioStream> ("foo", 0, 0, 0, 0);
268 content->audio.reset (new AudioContent (content.get()));
269 content->audio->add_stream (stream);
270 content->_video_frame_rate = 24;
271 film->set_video_frame_rate (24);
272 stream->_frame_rate = 48000;
273 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 48000);
275 stream->_frame_rate = 44100;
276 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 48000);
278 stream->_frame_rate = 80000;
279 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 96000);
281 content->_video_frame_rate = 23.976;
282 film->set_video_frame_rate (24);
283 stream->_frame_rate = 48000;
284 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 47952);
286 content->_video_frame_rate = 29.97;
287 film->set_video_frame_rate (30);
288 BOOST_CHECK_EQUAL (film->video_frame_rate (), 30);
289 stream->_frame_rate = 48000;
290 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 47952);
292 content->_video_frame_rate = 25;
293 film->set_video_frame_rate (24);
294 stream->_frame_rate = 48000;
295 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 50000);
297 content->_video_frame_rate = 25;
298 film->set_video_frame_rate (24);
299 stream->_frame_rate = 44100;
300 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), 50000);
302 /* Check some out-there conversions (not the best) */
304 content->_video_frame_rate = 14.99;
305 film->set_video_frame_rate (25);
306 stream->_frame_rate = 16000;
307 /* The FrameRateChange within resampled_frame_rate should choose to double-up
308 the 14.99 fps video to 30 and then run it slow at 25.
310 BOOST_CHECK_EQUAL (content->audio->resampled_frame_rate(), lrint (48000 * 2 * 14.99 / 25));