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