diff options
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/cinema.cc | 75 | ||||
| -rw-r--r-- | src/lib/cinema.h | 69 | ||||
| -rw-r--r-- | src/lib/config.cc | 34 | ||||
| -rw-r--r-- | src/lib/config.h | 27 | ||||
| -rw-r--r-- | src/lib/exceptions.h | 8 | ||||
| -rw-r--r-- | src/lib/film.cc | 92 | ||||
| -rw-r--r-- | src/lib/film.h | 21 | ||||
| -rw-r--r-- | src/lib/make_dcp_job.cc | 188 | ||||
| -rw-r--r-- | src/lib/util.cc | 18 | ||||
| -rw-r--r-- | src/lib/util.h | 1 | ||||
| -rw-r--r-- | src/lib/writer.cc | 10 | ||||
| -rw-r--r-- | src/lib/wscript | 1 |
12 files changed, 531 insertions, 13 deletions
diff --git a/src/lib/cinema.cc b/src/lib/cinema.cc new file mode 100644 index 000000000..7af4372f5 --- /dev/null +++ b/src/lib/cinema.cc @@ -0,0 +1,75 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <libxml++/libxml++.h> +#include <libcxml/cxml.h> +#include "cinema.h" + +using std::list; +using boost::shared_ptr; + +Cinema::Cinema (shared_ptr<const cxml::Node> node) +{ + name = node->string_child ("Name"); + email = node->string_child ("Email"); + + list<shared_ptr<cxml::Node> > s = node->node_children ("Screen"); + for (list<shared_ptr<cxml::Node> >::iterator i = s.begin(); i != s.end(); ++i) { + add_screen (shared_ptr<Screen> (new Screen (*i))); + } +} + +void +Cinema::as_xml (xmlpp::Element* parent) const +{ + parent->add_child("Name")->add_child_text (name); + parent->add_child("Email")->add_child_text (email); + + for (list<shared_ptr<Screen> >::const_iterator i = _screens.begin(); i != _screens.end(); ++i) { + (*i)->as_xml (parent->add_child ("Screen")); + } +} + +void +Cinema::add_screen (shared_ptr<Screen> s) +{ + s->cinema = shared_from_this (); + _screens.push_back (s); +} + +void +Cinema::remove_screen (shared_ptr<Screen> s) +{ + _screens.remove (s); +} + +Screen::Screen (shared_ptr<const cxml::Node> node) +{ + name = node->string_child ("Name"); + certificate = shared_ptr<libdcp::Certificate> (new libdcp::Certificate (node->string_child ("Certificate"))); +} + +void +Screen::as_xml (xmlpp::Element* parent) const +{ + parent->add_child("Name")->add_child_text (name); + parent->add_child("Certificate")->add_child_text (certificate->certificate (true)); +} + + diff --git a/src/lib/cinema.h b/src/lib/cinema.h new file mode 100644 index 000000000..251bb5d61 --- /dev/null +++ b/src/lib/cinema.h @@ -0,0 +1,69 @@ +/* + Copyright (C) 2013 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <boost/enable_shared_from_this.hpp> +#include <libdcp/certificates.h> + +class Cinema; + +namespace cxml { + class Node; +} + +class Screen +{ +public: + Screen (std::string const & n, boost::shared_ptr<libdcp::Certificate> cert) + : name (n) + , certificate (cert) + {} + + Screen (boost::shared_ptr<const cxml::Node>); + + void as_xml (xmlpp::Element *) const; + + boost::shared_ptr<Cinema> cinema; + std::string name; + boost::shared_ptr<libdcp::Certificate> certificate; +}; + +class Cinema : public boost::enable_shared_from_this<Cinema> +{ +public: + Cinema (std::string const & n, std::string const & e) + : name (n) + , email (e) + {} + + Cinema (boost::shared_ptr<const cxml::Node>); + + void as_xml (xmlpp::Element *) const; + + void add_screen (boost::shared_ptr<Screen>); + void remove_screen (boost::shared_ptr<Screen>); + + std::string name; + std::string email; + std::list<boost::shared_ptr<Screen> > screens () const { + return _screens; + } + +private: + std::list<boost::shared_ptr<Screen> > _screens; +}; diff --git a/src/lib/config.cc b/src/lib/config.cc index 9f981c619..a72e1a9e4 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -32,6 +32,7 @@ #include "dcp_content_type.h" #include "sound_processor.h" #include "colour_conversion.h" +#include "cinema.h" #include "i18n.h" @@ -128,6 +129,11 @@ Config::read () for (list<shared_ptr<cxml::Node> >::iterator i = cc.begin(); i != cc.end(); ++i) { _colour_conversions.push_back (PresetColourConversion (*i)); } + + list<shared_ptr<cxml::Node> > cin = f.node_children ("Cinema"); + for (list<shared_ptr<cxml::Node> >::iterator i = cin.begin(); i != cin.end(); ++i) { + _cinemas.push_back (shared_ptr<Cinema> (new Cinema (*i))); + } } void @@ -135,6 +141,7 @@ Config::read_old_metadata () { ifstream f (file(true).c_str ()); string line; + while (getline (f, line)) { if (line.empty ()) { continue; @@ -192,7 +199,7 @@ Config::read_old_metadata () } /** @return Filename to write configuration to */ -string +boost::filesystem::path Config::file (bool old) const { boost::filesystem::path p; @@ -204,7 +211,18 @@ Config::file (bool old) const } else { p /= "dcpomatic.xml"; } - return p.string (); + return p; +} + +boost::filesystem::path +Config::signer_chain_directory () const +{ + boost::filesystem::path p; + p /= g_get_user_config_dir (); + p /= "dvdomatic"; + p /= "crypt"; + boost::filesystem::create_directories (p); + return p; } /** @return Singleton instance */ @@ -233,7 +251,7 @@ Config::write () const xmlpp::Element* root = doc.create_root_node ("Config"); root->add_child("NumLocalEncodingThreads")->add_child_text (lexical_cast<string> (_num_local_encoding_threads)); - root->add_child("DefaultDirectory")->add_child_text (_default_directory); + root->add_child("DefaultDirectory")->add_child_text (_default_directory.string ()); root->add_child("ServerPort")->add_child_text (lexical_cast<string> (_server_port)); for (vector<ServerDescription>::const_iterator i = _servers.begin(); i != _servers.end(); ++i) { @@ -268,11 +286,15 @@ Config::write () const i->as_xml (root->add_child ("ColourConversion")); } - doc.write_to_file_formatted (file (false)); + for (list<shared_ptr<Cinema> >::const_iterator i = _cinemas.begin(); i != _cinemas.end(); ++i) { + (*i)->as_xml (root->add_child ("Cinema")); + } + + doc.write_to_file_formatted (file(false).string ()); } -string -Config::default_directory_or (string a) const +boost::filesystem::path +Config::default_directory_or (boost::filesystem::path a) const { if (_default_directory.empty() || !boost::filesystem::exists (_default_directory)) { return a; diff --git a/src/lib/config.h b/src/lib/config.h index bce6bfd7e..3e8a975d6 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -27,6 +27,7 @@ #include <vector> #include <boost/shared_ptr.hpp> #include <boost/signals2.hpp> +#include <boost/filesystem.hpp> #include <libdcp/metadata.h> #include "dci_metadata.h" #include "colour_conversion.h" @@ -38,6 +39,7 @@ class Filter; class SoundProcessor; class DCPContentType; class Ratio; +class Cinema; /** @class Config * @brief A singleton class holding configuration. @@ -51,11 +53,11 @@ public: return _num_local_encoding_threads; } - std::string default_directory () const { + boost::filesystem::path default_directory () const { return _default_directory; } - std::string default_directory_or (std::string a) const; + boost::filesystem::path default_directory_or (boost::filesystem::path a) const; /** @return port to use for J2K encoding servers */ int server_port () const { @@ -92,6 +94,10 @@ public: return _sound_processor; } + std::list<boost::shared_ptr<Cinema> > cinemas () const { + return _cinemas; + } + std::list<int> allowed_dcp_frame_rates () const { return _allowed_dcp_frame_rates; } @@ -133,7 +139,7 @@ public: _num_local_encoding_threads = n; } - void set_default_directory (std::string d) { + void set_default_directory (boost::filesystem::path d) { _default_directory = d; } @@ -175,6 +181,14 @@ public: _tms_password = p; } + void add_cinema (boost::shared_ptr<Cinema> c) { + _cinemas.push_back (c); + } + + void remove_cinema (boost::shared_ptr<Cinema> c) { + _cinemas.remove (c); + } + void set_allowed_dcp_frame_rates (std::list<int> const & r) { _allowed_dcp_frame_rates = r; } @@ -217,19 +231,21 @@ public: void write () const; + boost::filesystem::path signer_chain_directory () const; + static Config* instance (); static void drop (); private: Config (); - std::string file (bool) const; + boost::filesystem::path file (bool) const; void read (); void read_old_metadata (); /** number of threads to use for J2K encoding on the local machine */ int _num_local_encoding_threads; /** default directory to put new films in */ - std::string _default_directory; + boost::filesystem::path _default_directory; /** port to use for J2K encoding servers */ int _server_port; @@ -259,6 +275,7 @@ private: libdcp::XMLMetadata _dcp_metadata; int _default_j2k_bandwidth; std::vector<PresetColourConversion> _colour_conversions; + std::list<boost::shared_ptr<Cinema> > _cinemas; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h index f587f055f..b04d973dc 100644 --- a/src/lib/exceptions.h +++ b/src/lib/exceptions.h @@ -209,6 +209,14 @@ public: {} }; +class KDMError : public StringError +{ +public: + KDMError (std::string s) + : StringError (s) + {} +}; + class PixelFormatError : public StringError { public: diff --git a/src/lib/film.cc b/src/lib/film.cc index 940e94fa7..07af46d97 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -31,6 +31,9 @@ #include <boost/date_time.hpp> #include <libxml++/libxml++.h> #include <libcxml/cxml.h> +#include <libdcp/signer_chain.h> +#include <libdcp/cpl.h> +#include <libdcp/signer.h> #include "film.h" #include "job.h" #include "util.h" @@ -49,6 +52,7 @@ #include "dcp_content_type.h" #include "ratio.h" #include "cross.h" +#include "cinema.h" #include "i18n.h" @@ -75,6 +79,7 @@ using boost::ends_with; using boost::starts_with; using boost::optional; using libdcp::Size; +using libdcp::Signer; int const Film::state_version = 4; @@ -91,6 +96,7 @@ Film::Film (boost::filesystem::path dir) , _resolution (RESOLUTION_2K) , _scaler (Scaler::from_id ("bicubic")) , _with_subtitles (false) + , _encrypted (false) , _j2k_bandwidth (Config::instance()->default_j2k_bandwidth ()) , _dci_metadata (Config::instance()->default_dci_metadata ()) , _video_frame_rate (24) @@ -339,6 +345,8 @@ Film::write_metadata () const root->add_child("ThreeD")->add_child_text (_three_d ? "1" : "0"); root->add_child("SequenceVideo")->add_child_text (_sequence_video ? "1" : "0"); root->add_child("Interop")->add_child_text (_interop ? "1" : "0"); + root->add_child("Encrypted")->add_child_text (_encrypted ? "1" : "0"); + root->add_child("Key")->add_child_text (_key.hex ()); _playlist->as_xml (root->add_child ("Playlist")); doc.write_to_file_formatted (file ("metadata.xml")); @@ -383,11 +391,12 @@ Film::read_metadata () _dci_metadata = DCIMetadata (f.node_child ("DCIMetadata")); _video_frame_rate = f.number_child<int> ("VideoFrameRate"); _dci_date = boost::gregorian::from_undelimited_string (f.string_child ("DCIDate")); + _encrypted = f.bool_child ("Encrypted"); _audio_channels = f.number_child<int> ("AudioChannels"); _sequence_video = f.bool_child ("SequenceVideo"); _three_d = f.bool_child ("ThreeD"); _interop = f.bool_child ("Interop"); - + _key = libdcp::Key (f.string_child ("Key")); _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist")); _dirty = false; @@ -737,6 +746,13 @@ Film::make_player () const return shared_ptr<Player> (new Player (shared_from_this (), _playlist)); } +void +Film::set_encrypted (bool e) +{ + _encrypted = e; + signal_changed (ENCRYPTED); +} + shared_ptr<Playlist> Film::playlist () const { @@ -876,3 +892,77 @@ Film::full_frame () const assert (false); return libdcp::Size (); } + +void +Film::make_kdms ( + list<shared_ptr<Screen> > screens, + boost::posix_time::ptime from, + boost::posix_time::ptime until, + string directory + ) const +{ + boost::filesystem::path const sd = Config::instance()->signer_chain_directory (); + if (boost::filesystem::is_empty (sd)) { + libdcp::make_signer_chain (sd); + } + + libdcp::CertificateChain chain; + + { + boost::filesystem::path p (sd); + p /= "ca.self-signed.pem"; + chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p))); + } + + { + boost::filesystem::path p (sd); + p /= "intermediate.signed.pem"; + chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p))); + } + + { + boost::filesystem::path p (sd); + p /= "leaf.signed.pem"; + chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p))); + } + + boost::filesystem::path signer_key (sd); + signer_key /= "leaf.key"; + + shared_ptr<const Signer> signer (new Signer (chain, signer_key)); + + /* Find the DCP to make the KDM for */ + string const dir = this->directory (); + list<boost::filesystem::path> dcps; + for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator(dir); i != boost::filesystem::directory_iterator(); ++i) { + if (boost::filesystem::is_directory (*i) && i->path().leaf() != "j2c" && i->path().leaf() != "video" && i->path().leaf() != "info") { + dcps.push_back (i->path()); + } + } + + if (dcps.empty()) { + throw KDMError (_("Could not find DCP to make KDM for")); + } else if (dcps.size() > 1) { + throw KDMError (_("More than one possible DCP to make KDM for")); + } + + for (list<shared_ptr<Screen> >::iterator i = screens.begin(); i != screens.end(); ++i) { + + libdcp::DCP dcp (dcps.front ()); + + try { + dcp.read (); + } catch (...) { + throw KDMError (_("Could not read DCP to make KDM for")); + } + + shared_ptr<xmlpp::Document> kdm = dcp.cpls().front()->make_kdm ( + signer, (*i)->certificate, key (), from, until, _interop, libdcp::MXFMetadata (), Config::instance()->dcp_metadata () + ); + + boost::filesystem::path out = directory; + out /= tidy_for_filename ((*i)->cinema->name) + "_" + tidy_for_filename ((*i)->name) + ".kdm.xml"; + kdm->write_to_file_formatted (out.string()); + } +} + diff --git a/src/lib/film.h b/src/lib/film.h index f5b29466a..26623e69e 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -31,6 +31,7 @@ #include <boost/signals2.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/filesystem.hpp> +#include <libdcp/key.h> #include "util.h" #include "types.h" #include "dci_metadata.h" @@ -42,6 +43,7 @@ class Player; class Playlist; class AudioContent; class Scaler; +class Screen; /** @class Film * @@ -113,6 +115,17 @@ public: bool has_subtitles () const; OutputVideoFrame best_video_frame_rate () const; + void make_kdms ( + std::list<boost::shared_ptr<Screen> >, + boost::posix_time::ptime from, + boost::posix_time::ptime until, + std::string directory + ) const; + + libdcp::Key key () const { + return _key; + } + /** Identifiers for the parts of our state; used for signalling changes. */ @@ -127,6 +140,7 @@ public: RESOLUTION, SCALER, WITH_SUBTITLES, + ENCRYPTED, J2K_BANDWIDTH, DCI_METADATA, VIDEO_FRAME_RATE, @@ -172,6 +186,10 @@ public: return _with_subtitles; } + bool encrypted () const { + return _encrypted; + } + int j2k_bandwidth () const { return _j2k_bandwidth; } @@ -215,6 +233,7 @@ public: void set_resolution (Resolution); void set_scaler (Scaler const *); void set_with_subtitles (bool); + void set_encrypted (bool); void set_j2k_bandwidth (int); void set_dci_metadata (DCIMetadata); void set_video_frame_rate (int); @@ -265,6 +284,7 @@ private: Scaler const * _scaler; /** True if subtitles should be shown for this film */ bool _with_subtitles; + bool _encrypted; /** bandwidth for J2K files in bits per second */ int _j2k_bandwidth; /** DCI naming stuff */ @@ -281,6 +301,7 @@ private: bool _three_d; bool _sequence_video; bool _interop; + libdcp::Key _key; /** true if our state has changed since we last saved it */ mutable bool _dirty; diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc new file mode 100644 index 000000000..37c9ca620 --- /dev/null +++ b/src/lib/make_dcp_job.cc @@ -0,0 +1,188 @@ +/* + Copyright (C) 2012 Carl Hetherington <cth@carlh.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/** @file src/make_dcp_job.cc + * @brief A job to create DCPs. + */ + +#include <iostream> +#include <boost/filesystem.hpp> +#include <libdcp/dcp.h> +#include <libdcp/picture_asset.h> +#include <libdcp/sound_asset.h> +#include <libdcp/reel.h> +extern "C" { +#include <libavutil/pixdesc.h> +} +#include "make_dcp_job.h" +#include "dcp_content_type.h" +#include "exceptions.h" +#include "options.h" +#include "imagemagick_decoder.h" +#include "film.h" + +using std::string; +using std::cout; +using boost::shared_ptr; + +/** @param f Film we are making the DCP for. + * @param o Options. + */ +MakeDCPJob::MakeDCPJob (shared_ptr<Film> f, shared_ptr<const EncodeOptions> o, shared_ptr<Job> req) + : Job (f, req) + , _opt (o) +{ + +} + +string +MakeDCPJob::name () const +{ + return String::compose ("Make DCP for %1", _film->name()); +} + +/** @param f DCP frame index */ +string +MakeDCPJob::j2c_path (int f, int offset) const +{ + SourceFrame const s = ((f + offset) * dcp_frame_rate(_film->frames_per_second()).skip) + _film->dcp_trim_start(); + return _opt->frame_out_path (s, false); +} + +string +MakeDCPJob::wav_path (libdcp::Channel c) const +{ + return _opt->multichannel_audio_out_path (int (c), false); +} + +void +MakeDCPJob::run () +{ + if (!_film->dcp_length()) { + throw EncodeError ("cannot make a DCP when the source length is not known"); + } + + descend (0.9); + + string const dcp_path = _film->dir (_film->dcp_name()); + + /* Remove any old DCP */ + boost::filesystem::remove_all (dcp_path); + + DCPFrameRate const dfr = dcp_frame_rate (_film->frames_per_second ()); + + int frames = 0; + switch (_film->content_type ()) { + case VIDEO: + /* Source frames -> DCP frames */ + frames = _film->dcp_length().get() / dfr.skip; + break; + case STILL: + frames = _film->still_duration() * 24; + break; + } + + libdcp::DCP dcp (_film->dir (_film->dcp_name())); + dcp.Progress.connect (boost::bind (&MakeDCPJob::dcp_progress, this, _1)); + + shared_ptr<libdcp::CPL> cpl ( + new libdcp::CPL (_film->dir (_film->dcp_name()), _film->dcp_name(), _film->dcp_content_type()->libdcp_kind (), frames, dfr.frames_per_second) + ); + + dcp.add_cpl (cpl); + + int frames_per_reel = 0; + if (_film->reel_size()) { + frames_per_reel = (_film->reel_size().get() / (_film->j2k_bandwidth() / 8)) * dfr.frames_per_second; + } else { + frames_per_reel = frames; + } + + int frames_done = 0; + int reel = 0; + + while (frames_done < frames) { + + descend (float (frames_per_reel) / frames); + + int this_time = std::min (frames_per_reel, (frames - frames_done)); + + descend (0.8); + + shared_ptr<libdcp::MonoPictureAsset> pa ( + new libdcp::MonoPictureAsset ( + boost::bind (&MakeDCPJob::j2c_path, this, _1, frames_done), + _film->dir (_film->dcp_name()), + String::compose ("video_%1.mxf", reel), + &dcp.Progress, + dfr.frames_per_second, + this_time, + _opt->out_size.width, + _opt->out_size.height, + _film->encrypted() + ) + ); + + ascend (); + + shared_ptr<libdcp::SoundAsset> sa; + + if (_film->audio_channels() > 0) { + descend (0.1); + sa.reset ( + new libdcp::SoundAsset ( + boost::bind (&MakeDCPJob::wav_path, this, _1), + _film->dir (_film->dcp_name()), + String::compose ("audio_%1.mxf", reel), + &dcp.Progress, + dfr.frames_per_second, + this_time, + frames_done, + dcp_audio_channels (_film->audio_channels()), + _film->encrypted() + ) + ); + ascend (); + } + + descend (0.1); + cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (pa, sa, shared_ptr<libdcp::SubtitleAsset> ()))); + ascend (); + + frames_done += frames_per_reel; + ++reel; + + ascend (); + } + + ascend (); + + descend (0.1); + dcp.write_xml (); + ascend (); + + set_progress (1); + set_state (FINISHED_OK); +} + +void +MakeDCPJob::dcp_progress (float p) +{ + set_progress (p); +} diff --git a/src/lib/util.cc b/src/lib/util.cc index 4180bbfd7..667ee8ce9 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -45,6 +45,7 @@ #include <magick/MagickCore.h> #include <magick/version.h> #include <libdcp/version.h> +#include <libdcp/util.h> extern "C" { #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> @@ -274,6 +275,8 @@ dcpomatic_setup () #endif avfilter_register_all (); + + libdcp::init (); Ratio::setup_ratios (); DCPContentType::setup_dcp_content_types (); @@ -799,3 +802,18 @@ valid_image_file (boost::filesystem::path f) return (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".bmp" || ext == ".tga"); } +string +tidy_for_filename (string f) +{ + string t; + for (size_t i = 0; i < f.length(); ++i) { + if (isalpha (f[i]) || f[i] == '_' || f[i] == '-') { + t += f[i]; + } else { + t += '_'; + } + } + + return t; +} + diff --git a/src/lib/util.h b/src/lib/util.h index a83426206..b5c94d994 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -70,6 +70,7 @@ extern bool valid_image_file (boost::filesystem::path); #ifdef DCPOMATIC_WINDOWS extern boost::filesystem::path mo_path (); #endif +extern std::string tidy_for_filename (std::string); struct FrameRateConversion { diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 5f94d5d6b..37376ca23 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -73,7 +73,7 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j) it into the DCP later. */ - if (f->three_d ()) { + if (_film->three_d ()) { _picture_asset.reset ( new libdcp::StereoPictureAsset ( _film->internal_video_mxf_dir (), @@ -95,6 +95,10 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j) } + if (_film->encrypted ()) { + _picture_asset->set_key (_film->key ()); + } + _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0, _film->interop ()); _sound_asset.reset ( @@ -106,6 +110,10 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j) _film->audio_frame_rate () ) ); + + if (_film->encrypted ()) { + _sound_asset->set_key (_film->key ()); + } _sound_asset_writer = _sound_asset->start_write (_film->interop ()); diff --git a/src/lib/wscript b/src/lib/wscript index 6c45d8b1e..e91666f7f 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -8,6 +8,7 @@ sources = """ audio_content.cc audio_decoder.cc audio_mapping.cc + cinema.cc colour_conversion.cc config.cc content.cc |
