Reduce the disk space needed when running tests.
[dcpomatic.git] / test / ffmpeg_encoder_test.cc
1 /*
2     Copyright (C) 2017-2021 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
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.
10
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.
15
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/>.
18
19 */
20
21 #include "lib/ffmpeg_encoder.h"
22 #include "lib/film.h"
23 #include "lib/ffmpeg_content.h"
24 #include "lib/image_content.h"
25 #include "lib/video_content.h"
26 #include "lib/audio_content.h"
27 #include "lib/string_text_file_content.h"
28 #include "lib/ratio.h"
29 #include "lib/transcode_job.h"
30 #include "lib/dcp_content.h"
31 #include "lib/text_content.h"
32 #include "lib/compose.hpp"
33 #include "lib/content_factory.h"
34 #include "test.h"
35 #include <boost/test/unit_test.hpp>
36
37 using std::string;
38 using std::shared_ptr;
39 using std::make_shared;
40 using boost::optional;
41 using namespace dcpomatic;
42
43 static void
44 ffmpeg_content_test (int number, boost::filesystem::path content, ExportFormat format)
45 {
46         Cleanup cl;
47
48         string name = "ffmpeg_encoder_";
49         string extension;
50         switch (format) {
51         case ExportFormat::H264_AAC:
52                 name += "h264";
53                 extension = "mp4";
54                 break;
55         case ExportFormat::PRORES:
56                 name += "prores";
57                 extension = "mov";
58                 break;
59         case ExportFormat::H264_PCM:
60         case ExportFormat::SUBTITLES_DCP:
61                 BOOST_REQUIRE (false);
62         }
63
64         name = String::compose("%1_test%2", name, number);
65
66         shared_ptr<Film> film = new_test_film2 (name, &cl);
67         film->set_name (name);
68         auto c = make_shared<FFmpegContent>(content);
69         film->set_audio_channels (6);
70
71         film->examine_and_add_content (c);
72         BOOST_REQUIRE (!wait_for_jobs ());
73
74         film->write_metadata ();
75         auto job = make_shared<TranscodeJob>(film);
76         auto file = boost::filesystem::path("build") / "test" / String::compose("%1.%2", name, extension);
77         cl.add (file);
78         FFmpegEncoder encoder (film, job, file, format, false, false, false, 23);
79         encoder.go ();
80
81         cl.run ();
82 }
83
84 /** Red / green / blue MP4 -> Prores */
85 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test1)
86 {
87         ffmpeg_content_test (1, "test/data/test.mp4", ExportFormat::PRORES);
88 }
89
90 /** Dolby Aurora trailer VOB -> Prores */
91 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test2)
92 {
93         ffmpeg_content_test (2, TestPaths::private_data() / "dolby_aurora.vob", ExportFormat::PRORES);
94 }
95
96 /** Sintel trailer -> Prores */
97 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test3)
98 {
99         ffmpeg_content_test (3, TestPaths::private_data() / "Sintel_Trailer1.480p.DivX_Plus_HD.mkv", ExportFormat::PRORES);
100 }
101
102 /** Big Buck Bunny trailer -> Prores */
103 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test4)
104 {
105         ffmpeg_content_test (4, TestPaths::private_data() / "big_buck_bunny_trailer_480p.mov", ExportFormat::PRORES);
106 }
107
108 /** Still image -> Prores */
109 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test5)
110 {
111         auto film = new_test_film ("ffmpeg_encoder_prores_test5");
112         film->set_name ("ffmpeg_encoder_prores_test5");
113         shared_ptr<ImageContent> c (new ImageContent(TestPaths::private_data() / "bbc405.png"));
114         film->set_container (Ratio::from_id ("185"));
115         film->set_audio_channels (6);
116
117         film->examine_and_add_content (c);
118         BOOST_REQUIRE (!wait_for_jobs ());
119
120         c->video->set_length (240);
121
122         film->write_metadata ();
123         shared_ptr<Job> job (new TranscodeJob (film));
124         FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test5.mov", ExportFormat::PRORES, false, false, false, 23);
125         encoder.go ();
126 }
127
128 /** Subs -> Prores */
129 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test6)
130 {
131         shared_ptr<Film> film = new_test_film ("ffmpeg_encoder_prores_test6");
132         film->set_name ("ffmpeg_encoder_prores_test6");
133         film->set_container (Ratio::from_id ("185"));
134         film->set_audio_channels (6);
135
136         shared_ptr<StringTextFileContent> s (new StringTextFileContent("test/data/subrip2.srt"));
137         film->examine_and_add_content (s);
138         BOOST_REQUIRE (!wait_for_jobs ());
139         s->only_text()->set_colour (dcp::Colour (255, 255, 0));
140         s->only_text()->set_effect (dcp::Effect::SHADOW);
141         s->only_text()->set_effect_colour (dcp::Colour (0, 255, 255));
142         film->write_metadata();
143
144         shared_ptr<Job> job (new TranscodeJob (film));
145         FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test6.mov", ExportFormat::PRORES, false, false, false, 23);
146         encoder.go ();
147 }
148
149 /** Video + subs -> Prores */
150 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test7)
151 {
152         shared_ptr<Film> film = new_test_film ("ffmpeg_encoder_prores_test7");
153         film->set_name ("ffmpeg_encoder_prores_test7");
154         film->set_container (Ratio::from_id ("185"));
155         film->set_audio_channels (6);
156
157         shared_ptr<FFmpegContent> c (new FFmpegContent("test/data/test.mp4"));
158         film->examine_and_add_content (c);
159         BOOST_REQUIRE (!wait_for_jobs ());
160
161         shared_ptr<StringTextFileContent> s (new StringTextFileContent("test/data/subrip.srt"));
162         film->examine_and_add_content (s);
163         BOOST_REQUIRE (!wait_for_jobs ());
164         s->only_text()->set_colour (dcp::Colour (255, 255, 0));
165         s->only_text()->set_effect (dcp::Effect::SHADOW);
166         s->only_text()->set_effect_colour (dcp::Colour (0, 255, 255));
167
168         shared_ptr<Job> job (new TranscodeJob (film));
169         FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test7.mov", ExportFormat::PRORES, false, false, false, 23);
170         encoder.go ();
171 }
172
173 /** Red / green / blue MP4 -> H264 */
174 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test1)
175 {
176         ffmpeg_content_test(1, "test/data/test.mp4", ExportFormat::H264_AAC);
177 }
178
179 /** Just subtitles -> H264 */
180 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test2)
181 {
182         shared_ptr<Film> film = new_test_film ("ffmpeg_encoder_h264_test2");
183         film->set_name ("ffmpeg_encoder_h264_test2");
184         film->set_container (Ratio::from_id ("185"));
185         film->set_audio_channels (6);
186
187         shared_ptr<StringTextFileContent> s (new StringTextFileContent("test/data/subrip2.srt"));
188         film->examine_and_add_content (s);
189         BOOST_REQUIRE (!wait_for_jobs ());
190         s->only_text()->set_colour (dcp::Colour (255, 255, 0));
191         s->only_text()->set_effect (dcp::Effect::SHADOW);
192         s->only_text()->set_effect_colour (dcp::Colour (0, 255, 255));
193         film->write_metadata();
194
195         shared_ptr<Job> job (new TranscodeJob (film));
196         FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test2.mp4", ExportFormat::H264_AAC, false, false, false, 23);
197         encoder.go ();
198 }
199
200 /** Video + subs -> H264 */
201 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test3)
202 {
203         shared_ptr<Film> film = new_test_film ("ffmpeg_encoder_h264_test3");
204         film->set_name ("ffmpeg_encoder_h264_test3");
205         film->set_container (Ratio::from_id ("185"));
206         film->set_audio_channels (6);
207
208         shared_ptr<FFmpegContent> c (new FFmpegContent("test/data/test.mp4"));
209         film->examine_and_add_content (c);
210         BOOST_REQUIRE (!wait_for_jobs ());
211
212         shared_ptr<StringTextFileContent> s (new StringTextFileContent("test/data/subrip.srt"));
213         film->examine_and_add_content (s);
214         BOOST_REQUIRE (!wait_for_jobs ());
215         s->only_text()->set_colour (dcp::Colour (255, 255, 0));
216         s->only_text()->set_effect (dcp::Effect::SHADOW);
217         s->only_text()->set_effect_colour (dcp::Colour (0, 255, 255));
218         film->write_metadata();
219
220         shared_ptr<Job> job (new TranscodeJob (film));
221         FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test3.mp4", ExportFormat::H264_AAC, false, false, false, 23);
222         encoder.go ();
223 }
224
225 /** Scope-in-flat DCP -> H264 */
226 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test4)
227 {
228         shared_ptr<Film> film = new_test_film2("ffmpeg_encoder_h264_test4");
229         film->examine_and_add_content(shared_ptr<DCPContent>(new DCPContent("test/data/scope_dcp")));
230         BOOST_REQUIRE(!wait_for_jobs());
231
232         film->set_container(Ratio::from_id("185"));
233
234         shared_ptr<Job> job(new TranscodeJob(film));
235         FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test4.mp4", ExportFormat::H264_AAC, false, false, false, 23);
236         encoder.go();
237 }
238
239 /** Test mixdown from 5.1 to stereo */
240 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test5)
241 {
242         shared_ptr<Film> film = new_test_film ("ffmpeg_transcoder_h264_test5");
243         film->set_name ("ffmpeg_transcoder_h264_test5");
244         film->set_container (Ratio::from_id ("185"));
245         film->set_audio_channels (6);
246
247         shared_ptr<FFmpegContent> L (new FFmpegContent("test/data/L.wav"));
248         film->examine_and_add_content (L);
249         shared_ptr<FFmpegContent> R (new FFmpegContent("test/data/R.wav"));
250         film->examine_and_add_content (R);
251         shared_ptr<FFmpegContent> C (new FFmpegContent("test/data/C.wav"));
252         film->examine_and_add_content (C);
253         shared_ptr<FFmpegContent> Ls (new FFmpegContent("test/data/Ls.wav"));
254         film->examine_and_add_content (Ls);
255         shared_ptr<FFmpegContent> Rs (new FFmpegContent("test/data/Rs.wav"));
256         film->examine_and_add_content (Rs);
257         shared_ptr<FFmpegContent> Lfe (new FFmpegContent("test/data/Lfe.wav"));
258         film->examine_and_add_content (Lfe);
259         BOOST_REQUIRE (!wait_for_jobs ());
260
261         AudioMapping map (1, MAX_DCP_AUDIO_CHANNELS);
262
263         L->set_position (film, DCPTime::from_seconds(0));
264         map.make_zero ();
265         map.set (0, 0, 1);
266         L->audio->set_mapping (map);
267         R->set_position (film, DCPTime::from_seconds(1));
268         map.make_zero ();
269         map.set (0, 1, 1);
270         R->audio->set_mapping (map);
271         C->set_position (film, DCPTime::from_seconds(2));
272         map.make_zero ();
273         map.set (0, 2, 1);
274         C->audio->set_mapping (map);
275         Lfe->set_position (film, DCPTime::from_seconds(3));
276         map.make_zero ();
277         map.set (0, 3, 1);
278         Lfe->audio->set_mapping (map);
279         Ls->set_position (film, DCPTime::from_seconds(4));
280         map.make_zero ();
281         map.set (0, 4, 1);
282         Ls->audio->set_mapping (map);
283         Rs->set_position (film, DCPTime::from_seconds(5));
284         map.make_zero ();
285         map.set (0, 5, 1);
286         Rs->audio->set_mapping (map);
287
288         shared_ptr<Job> job (new TranscodeJob (film));
289         FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_h264_test5.mp4", ExportFormat::H264_AAC, true, false, false, 23);
290         encoder.go ();
291
292         check_ffmpeg ("build/test/ffmpeg_encoder_h264_test5.mp4", "test/data/ffmpeg_encoder_h264_test5.mp4", 1);
293 }
294
295 /** Test export of a VF */
296 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test6)
297 {
298         shared_ptr<Film> film = new_test_film2 ("ffmpeg_encoder_h264_test6_ov");
299         film->examine_and_add_content (shared_ptr<ImageContent>(new ImageContent(TestPaths::private_data() / "bbc405.png")));
300         BOOST_REQUIRE (!wait_for_jobs());
301         film->make_dcp ();
302         BOOST_REQUIRE (!wait_for_jobs());
303
304         shared_ptr<Film> film2 = new_test_film2 ("ffmpeg_encoder_h264_test6_vf");
305         shared_ptr<DCPContent> ov (new DCPContent("build/test/ffmpeg_encoder_h264_test6_ov/" + film->dcp_name(false)));
306         film2->examine_and_add_content (ov);
307         BOOST_REQUIRE (!wait_for_jobs());
308         ov->set_reference_video (true);
309         shared_ptr<Content> subs = content_factory("test/data/subrip.srt").front();
310         film2->examine_and_add_content (subs);
311         BOOST_REQUIRE (!wait_for_jobs());
312         for (auto i: subs->text) {
313                 i->set_use (true);
314         }
315
316         shared_ptr<Job> job (new TranscodeJob (film2));
317         FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test6_vf.mp4", ExportFormat::H264_AAC, true, false, false, 23);
318         encoder.go ();
319 }
320
321 /** Test export of a 3D DCP in a 2D project */
322 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test7)
323 {
324         shared_ptr<Film> film = new_test_film2 ("ffmpeg_encoder_h264_test7_data");
325         shared_ptr<Content> L (shared_ptr<ImageContent>(new ImageContent(TestPaths::private_data() / "bbc405.png")));
326         film->examine_and_add_content (L);
327         shared_ptr<Content> R (shared_ptr<ImageContent>(new ImageContent(TestPaths::private_data() / "bbc405.png")));
328         film->examine_and_add_content (R);
329         BOOST_REQUIRE (!wait_for_jobs());
330         L->video->set_frame_type (VideoFrameType::THREE_D_LEFT);
331         L->set_position (film, DCPTime());
332         R->video->set_frame_type (VideoFrameType::THREE_D_RIGHT);
333         R->set_position (film, DCPTime());
334         film->set_three_d (true);
335         film->make_dcp ();
336         BOOST_REQUIRE (!wait_for_jobs());
337
338         shared_ptr<Film> film2 = new_test_film2 ("ffmpeg_encoder_h264_test7_export");
339         shared_ptr<Content> dcp (new DCPContent(film->dir(film->dcp_name())));
340         film2->examine_and_add_content (dcp);
341         BOOST_REQUIRE (!wait_for_jobs());
342
343         shared_ptr<Job> job (new TranscodeJob (film2));
344         FFmpegEncoder encoder (film2, job, "build/test/ffmpeg_encoder_h264_test7.mp4", ExportFormat::H264_AAC, true, false, false, 23);
345         encoder.go ();
346 }
347
348
349 /** Stereo project with mixdown-to-stereo set */
350 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test8)
351 {
352         shared_ptr<Film> film = new_test_film2("ffmpeg_encoder_h264_test4");
353         film->examine_and_add_content(shared_ptr<DCPContent>(new DCPContent("test/data/scope_dcp")));
354         BOOST_REQUIRE(!wait_for_jobs());
355         film->set_audio_channels (2);
356
357         shared_ptr<Job> job(new TranscodeJob(film));
358         FFmpegEncoder encoder(film, job, "build/test/ffmpeg_encoder_h264_test8.mp4", ExportFormat::H264_AAC, true, false, false, 23);
359         encoder.go();
360 }
361
362
363 /** 7.1/HI/VI (i.e. 12-channel) project */
364 BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test9)
365 {
366         shared_ptr<Film> film = new_test_film ("ffmpeg_encoder_prores_test9");
367         film->set_name ("ffmpeg_encoder_prores_test9");
368         shared_ptr<ImageContent> c (new ImageContent(TestPaths::private_data() / "bbc405.png"));
369         film->set_container (Ratio::from_id ("185"));
370         film->set_audio_channels (12);
371
372         film->examine_and_add_content (c);
373         BOOST_REQUIRE (!wait_for_jobs ());
374
375         c->video->set_length (240);
376
377         film->write_metadata ();
378         shared_ptr<Job> job (new TranscodeJob (film));
379         FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test9.mov", ExportFormat::H264_AAC, false, false, false, 23);
380         encoder.go ();
381 }