test/data updates.
[dcpomatic.git] / test / frame_rate_test.cc
1 /*
2     Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
3
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.
8
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.
13
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.
17
18 */
19
20 /** @file  test/frame_rate_test.cc
21  *  @brief Tests for FrameRateChange and the computation of the best
22  *  frame rate for the DCP.
23  */
24
25 #include <boost/test/unit_test.hpp>
26 #include "lib/film.h"
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 "test.h"
33
34 using boost::shared_ptr;
35
36 /* Test Playlist::best_dcp_frame_rate and FrameRateChange
37    with a single piece of content.
38 */
39 BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single)
40 {
41         shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_single");
42         /* Get any piece of content, it doesn't matter what */
43         shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
44         film->add_content (content);
45         wait_for_jobs ();
46         
47         /* Run some tests with a limited range of allowed rates */
48         
49         std::list<int> afr;
50         afr.push_back (24);
51         afr.push_back (25);
52         afr.push_back (30);
53         Config::instance()->set_allowed_dcp_frame_rates (afr);
54
55         content->_video_frame_rate = 60;
56         int best = film->playlist()->best_dcp_frame_rate ();
57         FrameRateChange frc = FrameRateChange (60, best);
58         BOOST_CHECK_EQUAL (best, 30);
59         BOOST_CHECK_EQUAL (frc.skip, true);
60         BOOST_CHECK_EQUAL (frc.repeat, 1);
61         BOOST_CHECK_EQUAL (frc.change_speed, false);
62         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
63         
64         content->_video_frame_rate = 50;
65         best = film->playlist()->best_dcp_frame_rate ();
66         frc = FrameRateChange (50, best);
67         BOOST_CHECK_EQUAL (best, 25);
68         BOOST_CHECK_EQUAL (frc.skip, true);
69         BOOST_CHECK_EQUAL (frc.repeat, 1);
70         BOOST_CHECK_EQUAL (frc.change_speed, false);
71         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
72
73         content->_video_frame_rate = 48;
74         best = film->playlist()->best_dcp_frame_rate ();
75         frc = FrameRateChange (48, best);
76         BOOST_CHECK_EQUAL (best, 24);
77         BOOST_CHECK_EQUAL (frc.skip, true);
78         BOOST_CHECK_EQUAL (frc.repeat, 1);
79         BOOST_CHECK_EQUAL (frc.change_speed, false);
80         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
81
82         content->_video_frame_rate = 30;
83         best = film->playlist()->best_dcp_frame_rate ();
84         frc = FrameRateChange (30, best);
85         BOOST_CHECK_EQUAL (best, 30);
86         BOOST_CHECK_EQUAL (frc.skip, false);
87         BOOST_CHECK_EQUAL (frc.repeat, 1);
88         BOOST_CHECK_EQUAL (frc.change_speed, false);
89         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
90
91         content->_video_frame_rate = 29.97;
92         best = film->playlist()->best_dcp_frame_rate ();
93         frc = FrameRateChange (29.97, best);
94         BOOST_CHECK_EQUAL (best, 30);
95         BOOST_CHECK_EQUAL (frc.skip, false);
96         BOOST_CHECK_EQUAL (frc.repeat, 1);
97         BOOST_CHECK_EQUAL (frc.change_speed, true);
98         BOOST_CHECK_CLOSE (frc.speed_up, 30 / 29.97, 0.1);
99         
100         content->_video_frame_rate = 25;
101         best = film->playlist()->best_dcp_frame_rate ();
102         frc = FrameRateChange (25, best);
103         BOOST_CHECK_EQUAL (best, 25);
104         BOOST_CHECK_EQUAL (frc.skip, false);
105         BOOST_CHECK_EQUAL (frc.repeat, 1);
106         BOOST_CHECK_EQUAL (frc.change_speed, false);
107         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
108
109         content->_video_frame_rate = 24;
110         best = film->playlist()->best_dcp_frame_rate ();
111         frc = FrameRateChange (24, best);
112         BOOST_CHECK_EQUAL (best, 24);
113         BOOST_CHECK_EQUAL (frc.skip, false);
114         BOOST_CHECK_EQUAL (frc.repeat, 1);
115         BOOST_CHECK_EQUAL (frc.change_speed, false);
116         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
117
118         content->_video_frame_rate = 14.5;
119         best = film->playlist()->best_dcp_frame_rate ();
120         frc = FrameRateChange (14.5, best);
121         BOOST_CHECK_EQUAL (best, 30);
122         BOOST_CHECK_EQUAL (frc.skip, false);
123         BOOST_CHECK_EQUAL (frc.repeat, 2);
124         BOOST_CHECK_EQUAL (frc.change_speed, true);
125         BOOST_CHECK_CLOSE (frc.speed_up, 15 / 14.5, 0.1);
126
127         content->_video_frame_rate = 12.6;
128         best = film->playlist()->best_dcp_frame_rate ();
129         frc = FrameRateChange (12.6, best);
130         BOOST_CHECK_EQUAL (best, 25);
131         BOOST_CHECK_EQUAL (frc.skip, false);
132         BOOST_CHECK_EQUAL (frc.repeat, 2);
133         BOOST_CHECK_EQUAL (frc.change_speed, true);
134         BOOST_CHECK_CLOSE (frc.speed_up, 25 / 25.2, 0.1);
135
136         content->_video_frame_rate = 12.4;
137         best = film->playlist()->best_dcp_frame_rate ();
138         frc = FrameRateChange (12.4, best);
139         BOOST_CHECK_EQUAL (best, 25);
140         BOOST_CHECK_EQUAL (frc.skip, false);
141         BOOST_CHECK_EQUAL (frc.repeat, 2);
142         BOOST_CHECK_EQUAL (frc.change_speed, true);
143         BOOST_CHECK_CLOSE (frc.speed_up, 25 / 24.8, 0.1);
144
145         content->_video_frame_rate = 12;
146         best = film->playlist()->best_dcp_frame_rate ();
147         frc = FrameRateChange (12, best);
148         BOOST_CHECK_EQUAL (best, 24);
149         BOOST_CHECK_EQUAL (frc.skip, false);
150         BOOST_CHECK_EQUAL (frc.repeat, 2);
151         BOOST_CHECK_EQUAL (frc.change_speed, false);
152         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
153
154         /* Now add some more rates and see if it will use them
155            in preference to skip/repeat.
156         */
157
158         afr.push_back (48);
159         afr.push_back (50);
160         afr.push_back (60);
161         Config::instance()->set_allowed_dcp_frame_rates (afr);
162
163         content->_video_frame_rate = 60;
164         best = film->playlist()->best_dcp_frame_rate ();
165         frc = FrameRateChange (60, best);
166         BOOST_CHECK_EQUAL (best, 60);
167         BOOST_CHECK_EQUAL (frc.skip, false);
168         BOOST_CHECK_EQUAL (frc.repeat, 1);
169         BOOST_CHECK_EQUAL (frc.change_speed, false);
170         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
171         
172         content->_video_frame_rate = 50;
173         best = film->playlist()->best_dcp_frame_rate ();
174         frc = FrameRateChange (50, best);
175         BOOST_CHECK_EQUAL (best, 50);
176         BOOST_CHECK_EQUAL (frc.skip, false);
177         BOOST_CHECK_EQUAL (frc.repeat, 1);
178         BOOST_CHECK_EQUAL (frc.change_speed, false);
179         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
180
181         content->_video_frame_rate = 48;
182         best = film->playlist()->best_dcp_frame_rate ();
183         frc = FrameRateChange (48, best);
184         BOOST_CHECK_EQUAL (best, 48);
185         BOOST_CHECK_EQUAL (frc.skip, false);
186         BOOST_CHECK_EQUAL (frc.repeat, 1);
187         BOOST_CHECK_EQUAL (frc.change_speed, false);
188         BOOST_CHECK_CLOSE (frc.speed_up, 1, 0.1);
189
190         /* Check some out-there conversions (not the best) */
191         
192         frc = FrameRateChange (14.99, 24);
193         BOOST_CHECK_EQUAL (frc.skip, false);
194         BOOST_CHECK_EQUAL (frc.repeat, 2);
195         BOOST_CHECK_EQUAL (frc.change_speed, true);
196         BOOST_CHECK_CLOSE (frc.speed_up, 24 / (2 * 14.99), 0.1);
197
198         /* Check some conversions with limited DCP targets */
199
200         afr.clear ();
201         afr.push_back (24);
202         Config::instance()->set_allowed_dcp_frame_rates (afr);
203
204         content->_video_frame_rate = 25;
205         best = film->playlist()->best_dcp_frame_rate ();
206         frc = FrameRateChange (25, best);
207         BOOST_CHECK_EQUAL (best, 24);
208         BOOST_CHECK_EQUAL (frc.skip, false);
209         BOOST_CHECK_EQUAL (frc.repeat, 1);
210         BOOST_CHECK_EQUAL (frc.change_speed, true);
211         BOOST_CHECK_CLOSE (frc.speed_up, 24.0 / 25, 0.1);
212 }
213
214 /* Test Playlist::best_dcp_frame_rate and FrameRateChange
215    with two pieces of content.
216 */
217 BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_double)
218 {
219         shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_double");
220         /* Get any old content, it doesn't matter what */
221         shared_ptr<FFmpegContent> A (new FFmpegContent (film, "test/data/test.mp4"));
222         film->add_content (A);
223         shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/test.mp4"));
224         film->add_content (B);
225         wait_for_jobs ();
226
227         /* Run some tests with a limited range of allowed rates */
228         
229         std::list<int> afr;
230         afr.push_back (24);
231         afr.push_back (25);
232         afr.push_back (30);
233         Config::instance()->set_allowed_dcp_frame_rates (afr);
234
235         A->_video_frame_rate = 30;
236         B->_video_frame_rate = 24;
237         BOOST_CHECK_EQUAL (film->playlist()->best_dcp_frame_rate(), 25);
238 }
239
240 BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
241 {
242         shared_ptr<Film> film = new_test_film ("audio_sampling_rate_test");
243         /* Get any piece of content, it doesn't matter what */
244         shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
245         film->examine_and_add_content (content);
246         wait_for_jobs ();
247         
248         std::list<int> afr;
249         afr.push_back (24);
250         afr.push_back (25);
251         afr.push_back (30);
252         Config::instance()->set_allowed_dcp_frame_rates (afr);
253
254         shared_ptr<FFmpegAudioStream> stream (new FFmpegAudioStream ("foo", 0, 0, 0));
255         content->_audio_streams.push_back (stream);
256         content->_video_frame_rate = 24;
257         film->set_video_frame_rate (24);
258         stream->_frame_rate = 48000;
259         BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 48000);
260
261         stream->_frame_rate = 44100;
262         BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 48000);
263
264         stream->_frame_rate = 80000;
265         BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 96000);
266
267         content->_video_frame_rate = 23.976;
268         film->set_video_frame_rate (24);
269         stream->_frame_rate = 48000;
270         BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 47952);
271
272         content->_video_frame_rate = 29.97;
273         film->set_video_frame_rate (30);
274         BOOST_CHECK_EQUAL (film->video_frame_rate (), 30);
275         stream->_frame_rate = 48000;
276         BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 47952);
277
278         content->_video_frame_rate = 25;
279         film->set_video_frame_rate (24);
280         stream->_frame_rate = 48000;
281         BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 50000);
282
283         content->_video_frame_rate = 25;
284         film->set_video_frame_rate (24);
285         stream->_frame_rate = 44100;
286         BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), 50000);
287
288         /* Check some out-there conversions (not the best) */
289         
290         content->_video_frame_rate = 14.99;
291         film->set_video_frame_rate (25);
292         stream->_frame_rate = 16000;
293         /* The FrameRateChange within resampled_audio_frame_rate should choose to double-up
294            the 14.99 fps video to 30 and then run it slow at 25.
295         */
296         BOOST_CHECK_EQUAL (content->resampled_audio_frame_rate(), rint (48000 * 2 * 14.99 / 25));
297 }