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