X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Ffilm.cc;h=56dce56e596bd9ac3e7ae9a516d47d06ecee7c46;hb=988ed4fac88965f2fc260f55a05e2db87bb1ecb8;hp=d331516dd1e9cac9c7b9b979975a1d4578927266;hpb=83efe84020dc0ba2801c4b305448790720fe133f;p=dcpomatic.git diff --git a/src/lib/film.cc b/src/lib/film.cc index d331516dd..56dce56e5 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2016 Carl Hetherington + Copyright (C) 2012-2017 Carl Hetherington This file is part of DCP-o-matic. @@ -57,6 +57,8 @@ #include #include #include +#include +#include #include #include #include @@ -83,6 +85,9 @@ using std::cout; using std::list; using std::set; using std::runtime_error; +using std::copy; +using std::back_inserter; +using std::map; using boost::shared_ptr; using boost::weak_ptr; using boost::dynamic_pointer_cast; @@ -288,6 +293,35 @@ Film::make_dcp () throw BadSettingError (_("name"), _("cannot contain slashes")); } + if (container() == 0) { + throw MissingSettingError (_("container")); + } + + if (content().empty()) { + throw runtime_error (_("you must add some content to the DCP before creating it")); + } + + if (dcp_content_type() == 0) { + throw MissingSettingError (_("content type")); + } + + if (name().empty()) { + throw MissingSettingError (_("name")); + } + + BOOST_FOREACH (shared_ptr i, content ()) { + if (!i->paths_valid()) { + throw runtime_error (_("some of your content is missing")); + } + shared_ptr dcp = dynamic_pointer_cast (i); + if (dcp && dcp->needs_kdm()) { + throw runtime_error (_("some of your content needs a KDM")); + } + if (dcp && dcp->needs_assets()) { + throw runtime_error (_("some of your content needs an OV")); + } + } + set_isdcf_date_today (); BOOST_FOREACH (string i, environment_info ()) { @@ -305,22 +339,6 @@ Film::make_dcp () } LOG_GENERAL ("J2K bandwidth %1", j2k_bandwidth()); - if (container() == 0) { - throw MissingSettingError (_("container")); - } - - if (content().empty()) { - throw runtime_error (_("You must add some content to the DCP before creating it")); - } - - if (dcp_content_type() == 0) { - throw MissingSettingError (_("content type")); - } - - if (name().empty()) { - throw MissingSettingError (_("name")); - } - JobManager::instance()->add (shared_ptr (new TranscodeJob (shared_from_this()))); } @@ -491,10 +509,11 @@ Film::read_metadata (optional path) } /** Given a directory name, return its full path within the Film's directory. - * The directory (and its parents) will be created if they do not exist. + * @param d directory name within the Filn's directory. + * @param create true to create the directory (and its parents) if they do not exist. */ boost::filesystem::path -Film::dir (boost::filesystem::path d) const +Film::dir (boost::filesystem::path d, bool create) const { DCPOMATIC_ASSERT (_directory); @@ -502,7 +521,9 @@ Film::dir (boost::filesystem::path d) const p /= _directory.get(); p /= d; - boost::filesystem::create_directories (p); + if (create) { + boost::filesystem::create_directories (p); + } return p; } @@ -773,24 +794,10 @@ Film::dcp_name (bool if_created_now) const { string unfiltered; if (use_isdcf_name()) { - unfiltered = isdcf_name (if_created_now); - } else { - unfiltered = name (); + return careful_string_filter (isdcf_name (if_created_now)); } - /* Filter out `bad' characters which cause problems with some systems. - There's no apparent list of what really is allowed, so this is a guess. - */ - - string filtered; - string const allowed = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"; - for (size_t i = 0; i < unfiltered.size(); ++i) { - if (allowed.find (unfiltered[i]) != string::npos) { - filtered += unfiltered[i]; - } - } - - return filtered; + return careful_string_filter (name ()); } void @@ -1219,8 +1226,44 @@ Film::make_kdm ( throw InvalidSignerError (); } + /* Find keys that have been added to imported, encrypted DCP content */ + list imported_keys; + BOOST_FOREACH (shared_ptr i, content()) { + shared_ptr d = dynamic_pointer_cast (i); + if (d && d->kdm()) { + dcp::DecryptedKDM kdm (d->kdm().get(), Config::instance()->decryption_chain()->key().get()); + list keys = kdm.keys (); + copy (keys.begin(), keys.end(), back_inserter (imported_keys)); + } + } + + map, dcp::Key> keys; + + BOOST_FOREACH(shared_ptr i, cpl->reel_assets ()) { + shared_ptr mxf = boost::dynamic_pointer_cast (i); + if (!mxf || !mxf->key_id()) { + continue; + } + + /* Get any imported key for this ID */ + bool done = false; + BOOST_FOREACH (dcp::DecryptedKDMKey j, imported_keys) { + if (j.id() == mxf->key_id().get()) { + LOG_GENERAL ("Using imported key for %1", mxf->key_id().get()); + keys[mxf] = j.key(); + done = true; + } + } + + if (!done) { + /* No imported key; it must be an asset that we encrypted */ + LOG_GENERAL ("Using our own key for %1", mxf->key_id().get()); + keys[mxf] = key(); + } + } + return dcp::DecryptedKDM ( - cpl, key(), from, until, cpl->content_title_text(), cpl->content_title_text(), dcp::LocalTime().as_string() + cpl->id(), keys, from, until, cpl->content_title_text(), cpl->content_title_text(), dcp::LocalTime().as_string() ).encrypt (signer, recipient, trusted_devices, formulation); } @@ -1416,7 +1459,7 @@ list Film::reels () const { list p; - DCPTime const len = length().round_up (video_frame_rate ()); + DCPTime const len = length().ceil (video_frame_rate ()); switch (reel_type ()) { case REELTYPE_SINGLE: