Some error message formatting tidy-ups.
[dcpomatic.git] / src / lib / film.cc
1 /*
2     Copyright (C) 2012-2016 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 /** @file  src/film.cc
22  *  @brief A representation of some audio and video content, and details of
23  *  how they should be presented in a DCP.
24  */
25
26 #include "film.h"
27 #include "job.h"
28 #include "util.h"
29 #include "job_manager.h"
30 #include "transcode_job.h"
31 #include "upload_job.h"
32 #include "null_log.h"
33 #include "file_log.h"
34 #include "exceptions.h"
35 #include "examine_content_job.h"
36 #include "config.h"
37 #include "playlist.h"
38 #include "dcp_content_type.h"
39 #include "ratio.h"
40 #include "cross.h"
41 #include "environment_info.h"
42 #include "audio_processor.h"
43 #include "digester.h"
44 #include "compose.hpp"
45 #include "screen.h"
46 #include "audio_content.h"
47 #include "video_content.h"
48 #include "subtitle_content.h"
49 #include "ffmpeg_content.h"
50 #include "dcp_content.h"
51 #include "screen_kdm.h"
52 #include "cinema.h"
53 #include <libcxml/cxml.h>
54 #include <dcp/cpl.h>
55 #include <dcp/certificate_chain.h>
56 #include <dcp/util.h>
57 #include <dcp/local_time.h>
58 #include <dcp/decrypted_kdm.h>
59 #include <dcp/raw_convert.h>
60 #include <libxml++/libxml++.h>
61 #include <boost/filesystem.hpp>
62 #include <boost/algorithm/string.hpp>
63 #include <boost/foreach.hpp>
64 #include <boost/regex.hpp>
65 #include <unistd.h>
66 #include <stdexcept>
67 #include <iostream>
68 #include <algorithm>
69 #include <cstdlib>
70 #include <iomanip>
71 #include <set>
72
73 #include "i18n.h"
74
75 using std::string;
76 using std::pair;
77 using std::vector;
78 using std::setfill;
79 using std::min;
80 using std::max;
81 using std::make_pair;
82 using std::cout;
83 using std::list;
84 using std::set;
85 using std::runtime_error;
86 using boost::shared_ptr;
87 using boost::weak_ptr;
88 using boost::dynamic_pointer_cast;
89 using boost::optional;
90 using boost::is_any_of;
91 using dcp::raw_convert;
92
93 #define LOG_GENERAL(...) log()->log (String::compose (__VA_ARGS__), LogEntry::TYPE_GENERAL);
94 #define LOG_GENERAL_NC(...) log()->log (__VA_ARGS__, LogEntry::TYPE_GENERAL);
95
96 /* 5 -> 6
97  * AudioMapping XML changed.
98  * 6 -> 7
99  * Subtitle offset changed to subtitle y offset, and subtitle x offset added.
100  * 7 -> 8
101  * Use <Scale> tag in <VideoContent> rather than <Ratio>.
102  * 8 -> 9
103  * DCI -> ISDCF
104  * 9 -> 10
105  * Subtitle X and Y scale.
106  *
107  * Bumped to 32 for 2.0 branch; some times are expressed in Times rather
108  * than frames now.
109  *
110  * 32 -> 33
111  * Changed <Period> to <Subtitle> in FFmpegSubtitleStream
112  * 33 -> 34
113  * Content only contains audio/subtitle-related tags if those things
114  * are present.
115  * 34 -> 35
116  * VideoFrameType in VideoContent is a string rather than an integer.
117  * 35 -> 36
118  * EffectColour rather than OutlineColour in Subtitle.
119  */
120 int const Film::current_state_version = 36;
121
122 /** Construct a Film object in a given directory.
123  *
124  *  @param dir Film directory.
125  */
126
127 Film::Film (optional<boost::filesystem::path> dir)
128         : _playlist (new Playlist)
129         , _use_isdcf_name (true)
130         , _dcp_content_type (Config::instance()->default_dcp_content_type ())
131         , _container (Config::instance()->default_container ())
132         , _resolution (RESOLUTION_2K)
133         , _signed (true)
134         , _encrypted (false)
135         , _context_id (dcp::make_uuid ())
136         , _j2k_bandwidth (Config::instance()->default_j2k_bandwidth ())
137         , _isdcf_metadata (Config::instance()->default_isdcf_metadata ())
138         , _video_frame_rate (24)
139         , _audio_channels (Config::instance()->default_dcp_audio_channels ())
140         , _three_d (false)
141         , _sequence (true)
142         , _interop (Config::instance()->default_interop ())
143         , _audio_processor (0)
144         , _reel_type (REELTYPE_SINGLE)
145         , _reel_length (2000000000)
146         , _upload_after_make_dcp (false)
147         , _state_version (current_state_version)
148         , _dirty (false)
149 {
150         set_isdcf_date_today ();
151
152         _playlist_changed_connection = _playlist->Changed.connect (bind (&Film::playlist_changed, this));
153         _playlist_order_changed_connection = _playlist->OrderChanged.connect (bind (&Film::playlist_order_changed, this));
154         _playlist_content_changed_connection = _playlist->ContentChanged.connect (bind (&Film::playlist_content_changed, this, _1, _2, _3));
155
156         if (dir) {
157                 /* Make state.directory a complete path without ..s (where possible)
158                    (Code swiped from Adam Bowen on stackoverflow)
159                    XXX: couldn't/shouldn't this just be boost::filesystem::canonical?
160                 */
161
162                 boost::filesystem::path p (boost::filesystem::system_complete (dir.get()));
163                 boost::filesystem::path result;
164                 for (boost::filesystem::path::iterator i = p.begin(); i != p.end(); ++i) {
165                         if (*i == "..") {
166                                 if (boost::filesystem::is_symlink (result) || result.filename() == "..") {
167                                         result /= *i;
168                                 } else {
169                                         result = result.parent_path ();
170                                 }
171                         } else if (*i != ".") {
172                                 result /= *i;
173                         }
174                 }
175
176                 set_directory (result.make_preferred ());
177         }
178
179         if (_directory) {
180                 _log.reset (new FileLog (file ("log")));
181         } else {
182                 _log.reset (new NullLog);
183         }
184
185         _playlist->set_sequence (_sequence);
186 }
187
188 Film::~Film ()
189 {
190         BOOST_FOREACH (boost::signals2::connection& i, _job_connections) {
191                 i.disconnect ();
192         }
193
194         BOOST_FOREACH (boost::signals2::connection& i, _audio_analysis_connections) {
195                 i.disconnect ();
196         }
197 }
198
199 string
200 Film::video_identifier () const
201 {
202         DCPOMATIC_ASSERT (container ());
203
204         string s = container()->id()
205                 + "_" + resolution_to_string (_resolution)
206                 + "_" + _playlist->video_identifier()
207                 + "_" + raw_convert<string>(_video_frame_rate)
208                 + "_" + raw_convert<string>(j2k_bandwidth());
209
210         if (encrypted ()) {
211                 s += "_E";
212         } else {
213                 s += "_P";
214         }
215
216         if (_interop) {
217                 s += "_I";
218         } else {
219                 s += "_S";
220         }
221
222         if (_three_d) {
223                 s += "_3D";
224         }
225
226         return s;
227 }
228
229 /** @return The file to write video frame info to */
230 boost::filesystem::path
231 Film::info_file (DCPTimePeriod period) const
232 {
233         boost::filesystem::path p;
234         p /= "info";
235         p /= video_identifier () + "_" + raw_convert<string> (period.from.get()) + "_" + raw_convert<string> (period.to.get());
236         return file (p);
237 }
238
239 boost::filesystem::path
240 Film::internal_video_asset_dir () const
241 {
242         return dir ("video");
243 }
244
245 boost::filesystem::path
246 Film::internal_video_asset_filename (DCPTimePeriod p) const
247 {
248         return video_identifier() + "_" + raw_convert<string> (p.from.get()) + "_" + raw_convert<string> (p.to.get()) + ".mxf";
249 }
250
251 boost::filesystem::path
252 Film::audio_analysis_path (shared_ptr<const Playlist> playlist) const
253 {
254         boost::filesystem::path p = dir ("analysis");
255
256         Digester digester;
257         BOOST_FOREACH (shared_ptr<Content> i, playlist->content ()) {
258                 if (!i->audio) {
259                         continue;
260                 }
261
262                 digester.add (i->digest ());
263                 digester.add (i->audio->mapping().digest ());
264                 if (playlist->content().size() != 1) {
265                         /* Analyses should be considered equal regardless of gain
266                            if they were made from just one piece of content.  This
267                            is because we can fake any gain change in a single-content
268                            analysis at the plotting stage rather than having to
269                            recompute it.
270                         */
271                         digester.add (i->audio->gain ());
272                 }
273         }
274
275         if (audio_processor ()) {
276                 digester.add (audio_processor()->id ());
277         }
278
279         p /= digester.get ();
280         return p;
281 }
282
283 /** Add suitable Jobs to the JobManager to create a DCP for this Film */
284 void
285 Film::make_dcp ()
286 {
287         if (dcp_name().find ("/") != string::npos) {
288                 throw BadSettingError (_("name"), _("cannot contain slashes"));
289         }
290
291         if (container() == 0) {
292                 throw MissingSettingError (_("container"));
293         }
294
295         if (content().empty()) {
296                 throw runtime_error (_("you must add some content to the DCP before creating it"));
297         }
298
299         if (dcp_content_type() == 0) {
300                 throw MissingSettingError (_("content type"));
301         }
302
303         if (name().empty()) {
304                 throw MissingSettingError (_("name"));
305         }
306
307         BOOST_FOREACH (shared_ptr<const Content> i, content ()) {
308                 if (!i->paths_valid()) {
309                         throw runtime_error (_("some of your content is missing"));
310                 }
311                 shared_ptr<const DCPContent> dcp = dynamic_pointer_cast<const DCPContent> (i);
312                 if (dcp && dcp->needs_kdm()) {
313                         throw runtime_error (_("some of your content needs a KDM"));
314                 }
315                 if (dcp && dcp->needs_assets()) {
316                         throw runtime_error (_("some of your content needs an OV"));
317                 }
318         }
319
320         set_isdcf_date_today ();
321
322         BOOST_FOREACH (string i, environment_info ()) {
323                 LOG_GENERAL_NC (i);
324         }
325
326         BOOST_FOREACH (shared_ptr<const Content> i, content ()) {
327                 LOG_GENERAL ("Content: %1", i->technical_summary());
328         }
329         LOG_GENERAL ("DCP video rate %1 fps", video_frame_rate());
330         if (Config::instance()->only_servers_encode ()) {
331                 LOG_GENERAL_NC ("0 threads: ONLY SERVERS SET TO ENCODE");
332         } else {
333                 LOG_GENERAL ("%1 threads", Config::instance()->num_local_encoding_threads());
334         }
335         LOG_GENERAL ("J2K bandwidth %1", j2k_bandwidth());
336
337         JobManager::instance()->add (shared_ptr<Job> (new TranscodeJob (shared_from_this())));
338 }
339
340 /** Start a job to send our DCP to the configured TMS */
341 void
342 Film::send_dcp_to_tms ()
343 {
344         shared_ptr<Job> j (new UploadJob (shared_from_this()));
345         JobManager::instance()->add (j);
346 }
347
348 shared_ptr<xmlpp::Document>
349 Film::metadata (bool with_content_paths) const
350 {
351         shared_ptr<xmlpp::Document> doc (new xmlpp::Document);
352         xmlpp::Element* root = doc->create_root_node ("Metadata");
353
354         root->add_child("Version")->add_child_text (raw_convert<string> (current_state_version));
355         root->add_child("Name")->add_child_text (_name);
356         root->add_child("UseISDCFName")->add_child_text (_use_isdcf_name ? "1" : "0");
357
358         if (_dcp_content_type) {
359                 root->add_child("DCPContentType")->add_child_text (_dcp_content_type->isdcf_name ());
360         }
361
362         if (_container) {
363                 root->add_child("Container")->add_child_text (_container->id ());
364         }
365
366         root->add_child("Resolution")->add_child_text (resolution_to_string (_resolution));
367         root->add_child("J2KBandwidth")->add_child_text (raw_convert<string> (_j2k_bandwidth));
368         _isdcf_metadata.as_xml (root->add_child ("ISDCFMetadata"));
369         root->add_child("VideoFrameRate")->add_child_text (raw_convert<string> (_video_frame_rate));
370         root->add_child("ISDCFDate")->add_child_text (boost::gregorian::to_iso_string (_isdcf_date));
371         root->add_child("AudioChannels")->add_child_text (raw_convert<string> (_audio_channels));
372         root->add_child("ThreeD")->add_child_text (_three_d ? "1" : "0");
373         root->add_child("Sequence")->add_child_text (_sequence ? "1" : "0");
374         root->add_child("Interop")->add_child_text (_interop ? "1" : "0");
375         root->add_child("Signed")->add_child_text (_signed ? "1" : "0");
376         root->add_child("Encrypted")->add_child_text (_encrypted ? "1" : "0");
377         root->add_child("Key")->add_child_text (_key.hex ());
378         root->add_child("ContextID")->add_child_text (_context_id);
379         if (_audio_processor) {
380                 root->add_child("AudioProcessor")->add_child_text (_audio_processor->id ());
381         }
382         root->add_child("ReelType")->add_child_text (raw_convert<string> (static_cast<int> (_reel_type)));
383         root->add_child("ReelLength")->add_child_text (raw_convert<string> (_reel_length));
384         root->add_child("UploadAfterMakeDCP")->add_child_text (_upload_after_make_dcp ? "1" : "0");
385         _playlist->as_xml (root->add_child ("Playlist"), with_content_paths);
386
387         return doc;
388 }
389
390 /** Write state to our `metadata' file */
391 void
392 Film::write_metadata () const
393 {
394         DCPOMATIC_ASSERT (directory());
395         boost::filesystem::create_directories (directory().get());
396         shared_ptr<xmlpp::Document> doc = metadata ();
397         doc->write_to_file_formatted (file("metadata.xml").string ());
398         _dirty = false;
399 }
400
401 /** Write a template from this film */
402 void
403 Film::write_template (boost::filesystem::path path) const
404 {
405         boost::filesystem::create_directories (path.parent_path());
406         shared_ptr<xmlpp::Document> doc = metadata (false);
407         doc->write_to_file_formatted (path.string ());
408 }
409
410 /** Read state from our metadata file.
411  *  @return Notes about things that the user should know about, or empty.
412  */
413 list<string>
414 Film::read_metadata (optional<boost::filesystem::path> path)
415 {
416         if (!path) {
417                 if (boost::filesystem::exists (file ("metadata")) && !boost::filesystem::exists (file ("metadata.xml"))) {
418                         throw runtime_error (_("This film was created with an older version of DCP-o-matic, and unfortunately it cannot be loaded into this version.  You will need to create a new Film, re-add your content and set it up again.  Sorry!"));
419                 }
420
421                 path = file ("metadata.xml");
422         }
423
424         cxml::Document f ("Metadata");
425         f.read_file (path.get ());
426
427         _state_version = f.number_child<int> ("Version");
428         if (_state_version > current_state_version) {
429                 throw runtime_error (_("This film was created with a newer version of DCP-o-matic, and it cannot be loaded into this version.  Sorry!"));
430         }
431
432         _name = f.string_child ("Name");
433         if (_state_version >= 9) {
434                 _use_isdcf_name = f.bool_child ("UseISDCFName");
435                 _isdcf_metadata = ISDCFMetadata (f.node_child ("ISDCFMetadata"));
436                 _isdcf_date = boost::gregorian::from_undelimited_string (f.string_child ("ISDCFDate"));
437         } else {
438                 _use_isdcf_name = f.bool_child ("UseDCIName");
439                 _isdcf_metadata = ISDCFMetadata (f.node_child ("DCIMetadata"));
440                 _isdcf_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate"));
441         }
442
443         {
444                 optional<string> c = f.optional_string_child ("DCPContentType");
445                 if (c) {
446                         _dcp_content_type = DCPContentType::from_isdcf_name (c.get ());
447                 }
448         }
449
450         {
451                 optional<string> c = f.optional_string_child ("Container");
452                 if (c) {
453                         _container = Ratio::from_id (c.get ());
454                 }
455         }
456
457         _resolution = string_to_resolution (f.string_child ("Resolution"));
458         _j2k_bandwidth = f.number_child<int> ("J2KBandwidth");
459         _video_frame_rate = f.number_child<int> ("VideoFrameRate");
460         _signed = f.optional_bool_child("Signed").get_value_or (true);
461         _encrypted = f.bool_child ("Encrypted");
462         _audio_channels = f.number_child<int> ("AudioChannels");
463         /* We used to allow odd numbers (and zero) channels, but it's just not worth
464            the pain.
465         */
466         if (_audio_channels == 0) {
467                 _audio_channels = 2;
468         } else if ((_audio_channels % 2) == 1) {
469                 _audio_channels++;
470         }
471
472         if (f.optional_bool_child("SequenceVideo")) {
473                 _sequence = f.bool_child("SequenceVideo");
474         } else {
475                 _sequence = f.bool_child("Sequence");
476         }
477
478         _three_d = f.bool_child ("ThreeD");
479         _interop = f.bool_child ("Interop");
480         _key = dcp::Key (f.string_child ("Key"));
481         _context_id = f.optional_string_child("ContextID").get_value_or (dcp::make_uuid ());
482
483         if (f.optional_string_child ("AudioProcessor")) {
484                 _audio_processor = AudioProcessor::from_id (f.string_child ("AudioProcessor"));
485         } else {
486                 _audio_processor = 0;
487         }
488
489         _reel_type = static_cast<ReelType> (f.optional_number_child<int>("ReelType").get_value_or (static_cast<int>(REELTYPE_SINGLE)));
490         _reel_length = f.optional_number_child<int64_t>("ReelLength").get_value_or (2000000000);
491         _upload_after_make_dcp = f.optional_bool_child("UploadAfterMakeDCP").get_value_or (false);
492
493         list<string> notes;
494         /* This method is the only one that can return notes (so far) */
495         _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version, notes);
496
497         /* Write backtraces to this film's directory, until another film is loaded */
498         if (_directory) {
499                 set_backtrace_file (file ("backtrace.txt"));
500         }
501
502         _dirty = false;
503         return notes;
504 }
505
506 /** Given a directory name, return its full path within the Film's directory.
507  *  The directory (and its parents) will be created if they do not exist.
508  */
509 boost::filesystem::path
510 Film::dir (boost::filesystem::path d) const
511 {
512         DCPOMATIC_ASSERT (_directory);
513
514         boost::filesystem::path p;
515         p /= _directory.get();
516         p /= d;
517
518         boost::filesystem::create_directories (p);
519
520         return p;
521 }
522
523 /** Given a file or directory name, return its full path within the Film's directory.
524  *  Any required parent directories will be created.
525  */
526 boost::filesystem::path
527 Film::file (boost::filesystem::path f) const
528 {
529         DCPOMATIC_ASSERT (_directory);
530
531         boost::filesystem::path p;
532         p /= _directory.get();
533         p /= f;
534
535         boost::filesystem::create_directories (p.parent_path ());
536
537         return p;
538 }
539
540 list<int>
541 Film::mapped_audio_channels () const
542 {
543         list<int> mapped;
544
545         if (audio_processor ()) {
546                 /* Processors are mapped 1:1 to DCP outputs so we can work out mappings from there */
547                 for (int i = 0; i < audio_processor()->out_channels(); ++i) {
548                         mapped.push_back (i);
549                 }
550         } else {
551                 BOOST_FOREACH (shared_ptr<Content> i, content ()) {
552                         if (i->audio) {
553                                 list<int> c = i->audio->mapping().mapped_output_channels ();
554                                 copy (c.begin(), c.end(), back_inserter (mapped));
555                         }
556                 }
557
558                 mapped.sort ();
559                 mapped.unique ();
560         }
561
562         return mapped;
563 }
564
565 /** @return a ISDCF-compliant name for a DCP of this film */
566 string
567 Film::isdcf_name (bool if_created_now) const
568 {
569         string d;
570
571         string raw_name = name ();
572
573         /* Split the raw name up into words */
574         vector<string> words;
575         split (words, raw_name, is_any_of (" _-"));
576
577         string fixed_name;
578
579         /* Add each word to fixed_name */
580         for (vector<string>::const_iterator i = words.begin(); i != words.end(); ++i) {
581                 string w = *i;
582
583                 /* First letter is always capitalised */
584                 w[0] = toupper (w[0]);
585
586                 /* Count caps in w */
587                 size_t caps = 0;
588                 for (size_t i = 0; i < w.size(); ++i) {
589                         if (isupper (w[i])) {
590                                 ++caps;
591                         }
592                 }
593
594                 /* If w is all caps make the rest of it lower case, otherwise
595                    leave it alone.
596                 */
597                 if (caps == w.size ()) {
598                         for (size_t i = 1; i < w.size(); ++i) {
599                                 w[i] = tolower (w[i]);
600                         }
601                 }
602
603                 for (size_t i = 0; i < w.size(); ++i) {
604                         fixed_name += w[i];
605                 }
606         }
607
608         if (fixed_name.length() > 14) {
609                 fixed_name = fixed_name.substr (0, 14);
610         }
611
612         d += fixed_name;
613
614         if (dcp_content_type()) {
615                 d += "_" + dcp_content_type()->isdcf_name();
616                 d += "-" + raw_convert<string>(isdcf_metadata().content_version);
617         }
618
619         ISDCFMetadata const dm = isdcf_metadata ();
620
621         if (dm.temp_version) {
622                 d += "-Temp";
623         }
624
625         if (dm.pre_release) {
626                 d += "-Pre";
627         }
628
629         if (dm.red_band) {
630                 d += "-RedBand";
631         }
632
633         if (!dm.chain.empty ()) {
634                 d += "-" + dm.chain;
635         }
636
637         if (three_d ()) {
638                 d += "-3D";
639         }
640
641         if (dm.two_d_version_of_three_d) {
642                 d += "-2D";
643         }
644
645         if (!dm.mastered_luminance.empty ()) {
646                 d += "-" + dm.mastered_luminance;
647         }
648
649         if (video_frame_rate() != 24) {
650                 d += "-" + raw_convert<string>(video_frame_rate());
651         }
652
653         if (container()) {
654                 d += "_" + container()->isdcf_name();
655         }
656
657         /* XXX: this uses the first bit of content only */
658
659         /* The standard says we don't do this for trailers, for some strange reason */
660         if (dcp_content_type() && dcp_content_type()->libdcp_kind() != dcp::TRAILER) {
661                 Ratio const * content_ratio = 0;
662                 BOOST_FOREACH (shared_ptr<Content> i, content ()) {
663                         if (i->video) {
664                                 /* Here's the first piece of video content */
665                                 if (i->video->scale().ratio ()) {
666                                         content_ratio = i->video->scale().ratio ();
667                                 } else {
668                                         content_ratio = Ratio::from_ratio (i->video->size().ratio ());
669                                 }
670                                 break;
671                         }
672                 }
673
674                 if (content_ratio && content_ratio != container()) {
675                         d += "-" + content_ratio->isdcf_name();
676                 }
677         }
678
679         if (!dm.audio_language.empty ()) {
680                 d += "_" + dm.audio_language;
681                 if (!dm.subtitle_language.empty()) {
682
683                         bool burnt_in = true;
684                         BOOST_FOREACH (shared_ptr<Content> i, content ()) {
685                                 if (!i->subtitle) {
686                                         continue;
687                                 }
688
689                                 if (i->subtitle->use() && !i->subtitle->burn()) {
690                                         burnt_in = false;
691                                 }
692                         }
693
694                         string language = dm.subtitle_language;
695                         if (burnt_in && language != "XX") {
696                                 transform (language.begin(), language.end(), language.begin(), ::tolower);
697                         } else {
698                                 transform (language.begin(), language.end(), language.begin(), ::toupper);
699                         }
700
701                         d += "-" + language;
702                 } else {
703                         d += "-XX";
704                 }
705         }
706
707         if (!dm.territory.empty ()) {
708                 d += "_" + dm.territory;
709                 if (dm.rating.empty ()) {
710                         d += "-NR";
711                 } else {
712                         d += "-" + dm.rating;
713                 }
714         }
715
716         /* Count mapped audio channels */
717
718         int non_lfe = 0;
719         int lfe = 0;
720
721         BOOST_FOREACH (int i, mapped_audio_channels ()) {
722                 if (i >= audio_channels()) {
723                         /* This channel is mapped but is not included in the DCP */
724                         continue;
725                 }
726
727                 if (static_cast<dcp::Channel> (i) == dcp::LFE) {
728                         ++lfe;
729                 } else {
730                         ++non_lfe;
731                 }
732         }
733
734         if (non_lfe) {
735                 d += String::compose("_%1%2", non_lfe, lfe);
736         }
737
738         /* XXX: HI/VI */
739
740         d += "_" + resolution_to_string (_resolution);
741
742         if (!dm.studio.empty ()) {
743                 d += "_" + dm.studio;
744         }
745
746         if (if_created_now) {
747                 d += "_" + boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ());
748         } else {
749                 d += "_" + boost::gregorian::to_iso_string (_isdcf_date);
750         }
751
752         if (!dm.facility.empty ()) {
753                 d += "_" + dm.facility;
754         }
755
756         if (_interop) {
757                 d += "_IOP";
758         } else {
759                 d += "_SMPTE";
760         }
761
762         if (three_d ()) {
763                 d += "-3D";
764         }
765
766         bool vf = false;
767         BOOST_FOREACH (shared_ptr<Content> i, content ()) {
768                 shared_ptr<const DCPContent> dc = dynamic_pointer_cast<const DCPContent> (i);
769                 if (dc && (dc->reference_video() || dc->reference_audio() || dc->reference_subtitle())) {
770                         vf = true;
771                 }
772         }
773
774         if (vf) {
775                 d += "_VF";
776         } else {
777                 d += "_OV";
778         }
779
780         return d;
781 }
782
783 /** @return name to give the DCP */
784 string
785 Film::dcp_name (bool if_created_now) const
786 {
787         string unfiltered;
788         if (use_isdcf_name()) {
789                 unfiltered = isdcf_name (if_created_now);
790         } else {
791                 unfiltered = name ();
792         }
793
794         /* Filter out `bad' characters which cause problems with some systems.
795            There's no apparent list of what really is allowed, so this is a guess.
796         */
797
798         string filtered;
799         string const allowed = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";
800         for (size_t i = 0; i < unfiltered.size(); ++i) {
801                 if (allowed.find (unfiltered[i]) != string::npos) {
802                         filtered += unfiltered[i];
803                 }
804         }
805
806         return filtered;
807 }
808
809 void
810 Film::set_directory (boost::filesystem::path d)
811 {
812         _directory = d;
813         _dirty = true;
814 }
815
816 void
817 Film::set_name (string n)
818 {
819         _name = n;
820         signal_changed (NAME);
821 }
822
823 void
824 Film::set_use_isdcf_name (bool u)
825 {
826         _use_isdcf_name = u;
827         signal_changed (USE_ISDCF_NAME);
828 }
829
830 void
831 Film::set_dcp_content_type (DCPContentType const * t)
832 {
833         _dcp_content_type = t;
834         signal_changed (DCP_CONTENT_TYPE);
835 }
836
837 void
838 Film::set_container (Ratio const * c)
839 {
840         _container = c;
841         signal_changed (CONTAINER);
842 }
843
844 void
845 Film::set_resolution (Resolution r)
846 {
847         _resolution = r;
848         signal_changed (RESOLUTION);
849 }
850
851 void
852 Film::set_j2k_bandwidth (int b)
853 {
854         _j2k_bandwidth = b;
855         signal_changed (J2K_BANDWIDTH);
856 }
857
858 void
859 Film::set_isdcf_metadata (ISDCFMetadata m)
860 {
861         _isdcf_metadata = m;
862         signal_changed (ISDCF_METADATA);
863 }
864
865 void
866 Film::set_video_frame_rate (int f)
867 {
868         _video_frame_rate = f;
869         signal_changed (VIDEO_FRAME_RATE);
870 }
871
872 void
873 Film::set_audio_channels (int c)
874 {
875         _audio_channels = c;
876         signal_changed (AUDIO_CHANNELS);
877 }
878
879 void
880 Film::set_three_d (bool t)
881 {
882         _three_d = t;
883         signal_changed (THREE_D);
884
885         if (_three_d && _isdcf_metadata.two_d_version_of_three_d) {
886                 _isdcf_metadata.two_d_version_of_three_d = false;
887                 signal_changed (ISDCF_METADATA);
888         }
889 }
890
891 void
892 Film::set_interop (bool i)
893 {
894         _interop = i;
895         signal_changed (INTEROP);
896 }
897
898 void
899 Film::set_audio_processor (AudioProcessor const * processor)
900 {
901         _audio_processor = processor;
902         signal_changed (AUDIO_PROCESSOR);
903         signal_changed (AUDIO_CHANNELS);
904 }
905
906 void
907 Film::set_reel_type (ReelType t)
908 {
909         _reel_type = t;
910         signal_changed (REEL_TYPE);
911 }
912
913 /** @param r Desired reel length in bytes */
914 void
915 Film::set_reel_length (int64_t r)
916 {
917         _reel_length = r;
918         signal_changed (REEL_LENGTH);
919 }
920
921 void
922 Film::set_upload_after_make_dcp (bool u)
923 {
924         _upload_after_make_dcp = u;
925         signal_changed (UPLOAD_AFTER_MAKE_DCP);
926 }
927
928 void
929 Film::signal_changed (Property p)
930 {
931         _dirty = true;
932
933         switch (p) {
934         case Film::CONTENT:
935                 set_video_frame_rate (_playlist->best_video_frame_rate ());
936                 break;
937         case Film::VIDEO_FRAME_RATE:
938         case Film::SEQUENCE:
939                 _playlist->maybe_sequence ();
940                 break;
941         default:
942                 break;
943         }
944
945         emit (boost::bind (boost::ref (Changed), p));
946 }
947
948 void
949 Film::set_isdcf_date_today ()
950 {
951         _isdcf_date = boost::gregorian::day_clock::local_day ();
952 }
953
954 boost::filesystem::path
955 Film::j2c_path (int reel, Frame frame, Eyes eyes, bool tmp) const
956 {
957         boost::filesystem::path p;
958         p /= "j2c";
959         p /= video_identifier ();
960
961         char buffer[256];
962         snprintf(buffer, sizeof(buffer), "%08d_%08" PRId64, reel, frame);
963         string s (buffer);
964
965         if (eyes == EYES_LEFT) {
966                 s += ".L";
967         } else if (eyes == EYES_RIGHT) {
968                 s += ".R";
969         }
970
971         s += ".j2c";
972
973         if (tmp) {
974                 s += ".tmp";
975         }
976
977         p /= s;
978         return file (p);
979 }
980
981 /** Find all the DCPs in our directory that can be dcp::DCP::read() and return details of their CPLs */
982 vector<CPLSummary>
983 Film::cpls () const
984 {
985         if (!directory ()) {
986                 return vector<CPLSummary> ();
987         }
988
989         vector<CPLSummary> out;
990
991         boost::filesystem::path const dir = directory().get();
992         for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator(dir); i != boost::filesystem::directory_iterator(); ++i) {
993                 if (
994                         boost::filesystem::is_directory (*i) &&
995                         i->path().leaf() != "j2c" && i->path().leaf() != "video" && i->path().leaf() != "info" && i->path().leaf() != "analysis"
996                         ) {
997
998                         try {
999                                 dcp::DCP dcp (*i);
1000                                 dcp.read ();
1001                                 DCPOMATIC_ASSERT (dcp.cpls().front()->file());
1002                                 out.push_back (
1003                                         CPLSummary (
1004                                                 i->path().leaf().string(),
1005                                                 dcp.cpls().front()->id(),
1006                                                 dcp.cpls().front()->annotation_text(),
1007                                                 dcp.cpls().front()->file().get()
1008                                                 )
1009                                         );
1010                         } catch (...) {
1011
1012                         }
1013                 }
1014         }
1015
1016         return out;
1017 }
1018
1019 void
1020 Film::set_signed (bool s)
1021 {
1022         _signed = s;
1023         signal_changed (SIGNED);
1024 }
1025
1026 void
1027 Film::set_encrypted (bool e)
1028 {
1029         _encrypted = e;
1030         signal_changed (ENCRYPTED);
1031 }
1032
1033 void
1034 Film::set_key (dcp::Key key)
1035 {
1036         _key = key;
1037         signal_changed (KEY);
1038 }
1039
1040 ContentList
1041 Film::content () const
1042 {
1043         return _playlist->content ();
1044 }
1045
1046 void
1047 Film::examine_and_add_content (shared_ptr<Content> c)
1048 {
1049         if (dynamic_pointer_cast<FFmpegContent> (c) && _directory) {
1050                 run_ffprobe (c->path(0), file ("ffprobe.log"), _log);
1051         }
1052
1053         shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), c));
1054
1055         _job_connections.push_back (
1056                 j->Finished.connect (bind (&Film::maybe_add_content, this, weak_ptr<Job> (j), weak_ptr<Content> (c)))
1057                 );
1058
1059         JobManager::instance()->add (j);
1060 }
1061
1062 void
1063 Film::maybe_add_content (weak_ptr<Job> j, weak_ptr<Content> c)
1064 {
1065         shared_ptr<Job> job = j.lock ();
1066         if (!job || !job->finished_ok ()) {
1067                 return;
1068         }
1069
1070         shared_ptr<Content> content = c.lock ();
1071         if (!content) {
1072                 return;
1073         }
1074
1075         add_content (content);
1076
1077         if (Config::instance()->automatic_audio_analysis() && content->audio) {
1078                 shared_ptr<Playlist> playlist (new Playlist);
1079                 playlist->add (content);
1080                 boost::signals2::connection c;
1081                 JobManager::instance()->analyse_audio (
1082                         shared_from_this (), playlist, c, bind (&Film::audio_analysis_finished, this)
1083                         );
1084                 _audio_analysis_connections.push_back (c);
1085         }
1086 }
1087
1088 void
1089 Film::add_content (shared_ptr<Content> c)
1090 {
1091         /* Add {video,subtitle} content after any existing {video,subtitle} content */
1092         if (c->video) {
1093                 c->set_position (_playlist->video_end ());
1094         } else if (c->subtitle) {
1095                 c->set_position (_playlist->subtitle_end ());
1096         }
1097
1098         if (_template_film) {
1099                 /* Take settings from the first piece of content of c's type in _template */
1100                 BOOST_FOREACH (shared_ptr<Content> i, _template_film->content()) {
1101                         if (typeid(i.get()) == typeid(c.get())) {
1102                                 c->use_template (i);
1103                         }
1104                 }
1105         }
1106
1107         _playlist->add (c);
1108 }
1109
1110 void
1111 Film::remove_content (shared_ptr<Content> c)
1112 {
1113         _playlist->remove (c);
1114 }
1115
1116 void
1117 Film::move_content_earlier (shared_ptr<Content> c)
1118 {
1119         _playlist->move_earlier (c);
1120 }
1121
1122 void
1123 Film::move_content_later (shared_ptr<Content> c)
1124 {
1125         _playlist->move_later (c);
1126 }
1127
1128 /** @return length of the film from time 0 to the last thing on the playlist */
1129 DCPTime
1130 Film::length () const
1131 {
1132         return _playlist->length ();
1133 }
1134
1135 int
1136 Film::best_video_frame_rate () const
1137 {
1138         return _playlist->best_video_frame_rate ();
1139 }
1140
1141 FrameRateChange
1142 Film::active_frame_rate_change (DCPTime t) const
1143 {
1144         return _playlist->active_frame_rate_change (t, video_frame_rate ());
1145 }
1146
1147 void
1148 Film::playlist_content_changed (weak_ptr<Content> c, int p, bool frequent)
1149 {
1150         _dirty = true;
1151
1152         if (p == ContentProperty::VIDEO_FRAME_RATE) {
1153                 set_video_frame_rate (_playlist->best_video_frame_rate ());
1154         } else if (p == AudioContentProperty::STREAMS) {
1155                 signal_changed (NAME);
1156         }
1157
1158         emit (boost::bind (boost::ref (ContentChanged), c, p, frequent));
1159 }
1160
1161 void
1162 Film::playlist_changed ()
1163 {
1164         signal_changed (CONTENT);
1165         signal_changed (NAME);
1166 }
1167
1168 void
1169 Film::playlist_order_changed ()
1170 {
1171         signal_changed (CONTENT_ORDER);
1172 }
1173
1174 int
1175 Film::audio_frame_rate () const
1176 {
1177         BOOST_FOREACH (shared_ptr<Content> i, content ()) {
1178                 if (i->audio && i->audio->has_rate_above_48k ()) {
1179                         return 96000;
1180                 }
1181         }
1182
1183         return 48000;
1184 }
1185
1186 void
1187 Film::set_sequence (bool s)
1188 {
1189         _sequence = s;
1190         _playlist->set_sequence (s);
1191         signal_changed (SEQUENCE);
1192 }
1193
1194 /** @return Size of the largest possible image in whatever resolution we are using */
1195 dcp::Size
1196 Film::full_frame () const
1197 {
1198         switch (_resolution) {
1199         case RESOLUTION_2K:
1200                 return dcp::Size (2048, 1080);
1201         case RESOLUTION_4K:
1202                 return dcp::Size (4096, 2160);
1203         }
1204
1205         DCPOMATIC_ASSERT (false);
1206         return dcp::Size ();
1207 }
1208
1209 /** @return Size of the frame */
1210 dcp::Size
1211 Film::frame_size () const
1212 {
1213         return fit_ratio_within (container()->ratio(), full_frame ());
1214 }
1215
1216 /** @param from KDM from time expressed as a local time with an offset from UTC
1217  *  @param to KDM to time expressed as a local time with an offset from UTC
1218  */
1219 dcp::EncryptedKDM
1220 Film::make_kdm (
1221         dcp::Certificate recipient,
1222         vector<dcp::Certificate> trusted_devices,
1223         boost::filesystem::path cpl_file,
1224         dcp::LocalTime from,
1225         dcp::LocalTime until,
1226         dcp::Formulation formulation
1227         ) const
1228 {
1229         shared_ptr<const dcp::CPL> cpl (new dcp::CPL (cpl_file));
1230         shared_ptr<const dcp::CertificateChain> signer = Config::instance()->signer_chain ();
1231         if (!signer->valid ()) {
1232                 throw InvalidSignerError ();
1233         }
1234
1235         return dcp::DecryptedKDM (
1236                 cpl, key(), from, until, cpl->content_title_text(), cpl->content_title_text(), dcp::LocalTime().as_string()
1237                 ).encrypt (signer, recipient, trusted_devices, formulation);
1238 }
1239
1240 /** @param from KDM from time expressed as a local time in the time zone of the Screen's Cinema.
1241  *  @param to KDM to time expressed as a local time in the time zone of the Screen's Cinema.
1242  */
1243 list<ScreenKDM>
1244 Film::make_kdms (
1245         list<shared_ptr<Screen> > screens,
1246         boost::filesystem::path dcp,
1247         boost::posix_time::ptime from,
1248         boost::posix_time::ptime until,
1249         dcp::Formulation formulation
1250         ) const
1251 {
1252         list<ScreenKDM> kdms;
1253
1254         BOOST_FOREACH (shared_ptr<Screen> i, screens) {
1255                 if (i->recipient) {
1256                         dcp::EncryptedKDM const kdm = make_kdm (
1257                                 i->recipient.get(),
1258                                 i->trusted_devices,
1259                                 dcp,
1260                                 dcp::LocalTime (from, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()),
1261                                 dcp::LocalTime (until, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()),
1262                                 formulation
1263                                 );
1264
1265                         kdms.push_back (ScreenKDM (i, kdm));
1266                 }
1267         }
1268
1269         return kdms;
1270 }
1271
1272 /** @return The approximate disk space required to encode a DCP of this film with the
1273  *  current settings, in bytes.
1274  */
1275 uint64_t
1276 Film::required_disk_space () const
1277 {
1278         return _playlist->required_disk_space (j2k_bandwidth(), audio_channels(), audio_frame_rate());
1279 }
1280
1281 /** This method checks the disk that the Film is on and tries to decide whether or not
1282  *  there will be enough space to make a DCP for it.  If so, true is returned; if not,
1283  *  false is returned and required and available are filled in with the amount of disk space
1284  *  required and available respectively (in Gb).
1285  *
1286  *  Note: the decision made by this method isn't, of course, 100% reliable.
1287  */
1288 bool
1289 Film::should_be_enough_disk_space (double& required, double& available, bool& can_hard_link) const
1290 {
1291         /* Create a test file and see if we can hard-link it */
1292         boost::filesystem::path test = internal_video_asset_dir() / "test";
1293         boost::filesystem::path test2 = internal_video_asset_dir() / "test2";
1294         can_hard_link = true;
1295         FILE* f = fopen_boost (test, "w");
1296         if (f) {
1297                 fclose (f);
1298                 boost::system::error_code ec;
1299                 boost::filesystem::create_hard_link (test, test2, ec);
1300                 if (ec) {
1301                         can_hard_link = false;
1302                 }
1303                 boost::filesystem::remove (test);
1304                 boost::filesystem::remove (test2);
1305         }
1306
1307         boost::filesystem::space_info s = boost::filesystem::space (internal_video_asset_dir ());
1308         required = double (required_disk_space ()) / 1073741824.0f;
1309         if (!can_hard_link) {
1310                 required *= 2;
1311         }
1312         available = double (s.available) / 1073741824.0f;
1313         return (available - required) > 1;
1314 }
1315
1316 string
1317 Film::subtitle_language () const
1318 {
1319         set<string> languages;
1320
1321         ContentList cl = content ();
1322         BOOST_FOREACH (shared_ptr<Content>& c, cl) {
1323                 if (c->subtitle) {
1324                         languages.insert (c->subtitle->language ());
1325                 }
1326         }
1327
1328         string all;
1329         BOOST_FOREACH (string s, languages) {
1330                 if (!all.empty ()) {
1331                         all += "/" + s;
1332                 } else {
1333                         all += s;
1334                 }
1335         }
1336
1337         return all;
1338 }
1339
1340 /** Change the gains of the supplied AudioMapping to make it a default
1341  *  for this film.  The defaults are guessed based on what processor (if any)
1342  *  is in use, the number of input channels and any filename supplied.
1343  */
1344 void
1345 Film::make_audio_mapping_default (AudioMapping& mapping, optional<boost::filesystem::path> filename) const
1346 {
1347         static string const regex[] = {
1348                 ".*[\\._-]L[\\._-].*",
1349                 ".*[\\._-]R[\\._-].*",
1350                 ".*[\\._-]C[\\._-].*",
1351                 ".*[\\._-]Lfe[\\._-].*",
1352                 ".*[\\._-]Ls[\\._-].*",
1353                 ".*[\\._-]Rs[\\._-].*"
1354         };
1355
1356         static int const regexes = sizeof(regex) / sizeof(*regex);
1357
1358         if (audio_processor ()) {
1359                 audio_processor()->make_audio_mapping_default (mapping);
1360         } else {
1361                 mapping.make_zero ();
1362                 if (mapping.input_channels() == 1) {
1363                         bool guessed = false;
1364
1365                         /* See if we can guess where this stream should go */
1366                         if (filename) {
1367                                 for (int i = 0; i < regexes; ++i) {
1368                                         boost::regex e (regex[i], boost::regex::icase);
1369                                         if (boost::regex_match (filename->string(), e) && i < mapping.output_channels()) {
1370                                                 mapping.set (0, i, 1);
1371                                                 guessed = true;
1372                                         }
1373                                 }
1374                         }
1375
1376                         if (!guessed) {
1377                                 /* If we have no idea, just put it on centre */
1378                                 mapping.set (0, static_cast<int> (dcp::CENTRE), 1);
1379                         }
1380                 } else {
1381                         /* 1:1 mapping */
1382                         for (int i = 0; i < min (mapping.input_channels(), mapping.output_channels()); ++i) {
1383                                 mapping.set (i, i, 1);
1384                         }
1385                 }
1386         }
1387 }
1388
1389 /** @return The names of the channels that audio contents' outputs are passed into;
1390  *  this is either the DCP or a AudioProcessor.
1391  */
1392 vector<string>
1393 Film::audio_output_names () const
1394 {
1395         if (audio_processor ()) {
1396                 return audio_processor()->input_names ();
1397         }
1398
1399         DCPOMATIC_ASSERT (MAX_DCP_AUDIO_CHANNELS == 16);
1400
1401         vector<string> n;
1402
1403         for (int i = 0; i < audio_channels(); ++i) {
1404                 n.push_back (short_audio_channel_name (i));
1405         }
1406
1407         return n;
1408 }
1409
1410 void
1411 Film::repeat_content (ContentList c, int n)
1412 {
1413         _playlist->repeat (c, n);
1414 }
1415
1416 void
1417 Film::remove_content (ContentList c)
1418 {
1419         _playlist->remove (c);
1420 }
1421
1422 void
1423 Film::audio_analysis_finished ()
1424 {
1425         /* XXX */
1426 }
1427
1428 list<DCPTimePeriod>
1429 Film::reels () const
1430 {
1431         list<DCPTimePeriod> p;
1432         DCPTime const len = length().ceil (video_frame_rate ());
1433
1434         switch (reel_type ()) {
1435         case REELTYPE_SINGLE:
1436                 p.push_back (DCPTimePeriod (DCPTime (), len));
1437                 break;
1438         case REELTYPE_BY_VIDEO_CONTENT:
1439         {
1440                 optional<DCPTime> last_split;
1441                 shared_ptr<Content> last_video;
1442                 BOOST_FOREACH (shared_ptr<Content> c, content ()) {
1443                         if (c->video) {
1444                                 BOOST_FOREACH (DCPTime t, c->reel_split_points()) {
1445                                         if (last_split) {
1446                                                 p.push_back (DCPTimePeriod (last_split.get(), t));
1447                                         }
1448                                         last_split = t;
1449                                 }
1450                                 last_video = c;
1451                         }
1452                 }
1453
1454                 DCPTime video_end = last_video ? last_video->end() : DCPTime(0);
1455                 if (last_split) {
1456                         /* Definitely go from the last split to the end of the video content */
1457                         p.push_back (DCPTimePeriod (last_split.get(), video_end));
1458                 }
1459
1460                 if (video_end < len) {
1461                         /* And maybe go after that as well if there is any non-video hanging over the end */
1462                         p.push_back (DCPTimePeriod (video_end, len));
1463                 }
1464                 break;
1465         }
1466         case REELTYPE_BY_LENGTH:
1467         {
1468                 DCPTime current;
1469                 /* Integer-divide reel length by the size of one frame to give the number of frames per reel */
1470                 Frame const reel_in_frames = _reel_length / ((j2k_bandwidth() / video_frame_rate()) / 8);
1471                 while (current < len) {
1472                         DCPTime end = min (len, current + DCPTime::from_frames (reel_in_frames, video_frame_rate ()));
1473                         p.push_back (DCPTimePeriod (current, end));
1474                         current = end;
1475                 }
1476                 break;
1477         }
1478         }
1479
1480         return p;
1481 }
1482
1483 string
1484 Film::content_summary (DCPTimePeriod period) const
1485 {
1486         return _playlist->content_summary (period);
1487 }
1488
1489 list<string>
1490 Film::fix_conflicting_settings ()
1491 {
1492         list<string> notes;
1493
1494         list<boost::filesystem::path> was_referencing;
1495         BOOST_FOREACH (shared_ptr<Content> i, content()) {
1496                 shared_ptr<DCPContent> d = dynamic_pointer_cast<DCPContent> (i);
1497                 if (d) {
1498                         list<string> reasons;
1499                         bool was = false;
1500                         if (!d->can_reference_video(reasons) && d->reference_video()) {
1501                                 d->set_reference_video (false);
1502                                 was = true;
1503                         }
1504                         if (!d->can_reference_audio(reasons) && d->reference_audio()) {
1505                                 d->set_reference_audio (false);
1506                                 was = true;
1507                         }
1508                         if (!d->can_reference_subtitle(reasons) && d->reference_subtitle()) {
1509                                 d->set_reference_subtitle (false);
1510                                 was = true;
1511                         }
1512                         if (was) {
1513                                 was_referencing.push_back (d->path(0).parent_path().filename());
1514                         }
1515                 }
1516         }
1517
1518         BOOST_FOREACH (boost::filesystem::path d, was_referencing) {
1519                 notes.push_back (String::compose (_("The DCP %1 was being referred to by this film.  This not now possible because the reel sizes in the film no longer agree with those in the imported DCP.\n\nSetting the 'Reel type' to 'split by video content' will probably help.\n\nAfter doing that you would need to re-tick the appropriate 'refer to existing DCP' checkboxes."), d.string()));
1520         }
1521
1522         return notes;
1523 }
1524
1525 void
1526 Film::use_template (string name)
1527 {
1528         _template_film.reset (new Film (optional<boost::filesystem::path>()));
1529         _template_film->read_metadata (Config::instance()->template_path (name));
1530         _use_isdcf_name = _template_film->_use_isdcf_name;
1531         _dcp_content_type = _template_film->_dcp_content_type;
1532         _container = _template_film->_container;
1533         _resolution = _template_film->_resolution;
1534         _j2k_bandwidth = _template_film->_j2k_bandwidth;
1535         _video_frame_rate = _template_film->_video_frame_rate;
1536         _signed = _template_film->_signed;
1537         _encrypted = _template_film->_encrypted;
1538         _audio_channels = _template_film->_audio_channels;
1539         _sequence = _template_film->_sequence;
1540         _three_d = _template_film->_three_d;
1541         _interop = _template_film->_interop;
1542         _audio_processor = _template_film->_audio_processor;
1543         _reel_type = _template_film->_reel_type;
1544         _reel_length = _template_film->_reel_length;
1545         _upload_after_make_dcp = _template_film->_upload_after_make_dcp;
1546 }