Use IAB rather than ATMOS in ISDCF names (#2482).
[dcpomatic.git] / src / lib / film.cc
index 29952d0f2e8f57fe6e10a7920af1fbce42940338..ace371ba7923de6988ba89e9f5fcb891e4503660 100644 (file)
@@ -32,6 +32,7 @@
 #include "cinema.h"
 #include "compose.hpp"
 #include "config.h"
+#include "constants.h"
 #include "cross.h"
 #include "dcp_content.h"
 #include "dcp_content_type.h"
@@ -56,7 +57,6 @@
 #include "text_content.h"
 #include "transcode_job.h"
 #include "upload_job.h"
-#include "util.h"
 #include "video_content.h"
 #include "version.h"
 #include <libcxml/cxml.h>
@@ -166,6 +166,7 @@ Film::Film (optional<boost::filesystem::path> dir)
        , _three_d (false)
        , _sequence (true)
        , _interop (Config::instance()->default_interop ())
+       , _limit_to_smpte_bv20(false)
        , _audio_processor (0)
        , _reel_type (ReelType::SINGLE)
        , _reel_length (2000000000)
@@ -269,6 +270,11 @@ Film::video_identifier () const
                s += "_I";
        } else {
                s += "_S";
+               if (_limit_to_smpte_bv20) {
+                       s += "_L20";
+               } else {
+                       s += "_L21";
+               }
        }
 
        if (_three_d) {
@@ -353,6 +359,7 @@ Film::subtitle_analysis_path (shared_ptr<const Content> content) const
 
        Digester digester;
        digester.add (content->digest());
+       digester.add(_interop ? "1" : "0");
 
        if (!content->text.empty()) {
                auto tc = content->text.front();
@@ -415,6 +422,7 @@ Film::metadata (bool with_content_paths) const
        root->add_child("ThreeD")->add_child_text (_three_d ? "1" : "0");
        root->add_child("Sequence")->add_child_text (_sequence ? "1" : "0");
        root->add_child("Interop")->add_child_text (_interop ? "1" : "0");
+       root->add_child("LimitToSMPTEBv20")->add_child_text(_limit_to_smpte_bv20 ? "1" : "0");
        root->add_child("Encrypted")->add_child_text (_encrypted ? "1" : "0");
        root->add_child("Key")->add_child_text (_key.hex ());
        root->add_child("ContextID")->add_child_text (_context_id);
@@ -585,6 +593,7 @@ Film::read_metadata (optional<boost::filesystem::path> path)
 
        _three_d = f.bool_child ("ThreeD");
        _interop = f.bool_child ("Interop");
+       _limit_to_smpte_bv20 = f.optional_bool_child("LimitToSMPTEBv20").get_value_or(false);
        _key = dcp::Key (f.string_child ("Key"));
        _context_id = f.optional_string_child("ContextID").get_value_or (dcp::make_uuid ());
 
@@ -632,7 +641,7 @@ Film::read_metadata (optional<boost::filesystem::path> path)
                _sign_language_video_language = dcp::LanguageTag(*sign_language_video_language);
        }
 
-       _version_number = f.optional_number_child<int>("VersionNumber").get_value_or(0);
+       _version_number = f.optional_number_child<int>("VersionNumber").get_value_or(1);
 
        auto status = f.optional_string_child("Status");
        if (status) {
@@ -809,6 +818,11 @@ Film::isdcf_name (bool if_created_now) const
 
        auto raw_name = name ();
 
+       auto to_upper = [](string s) {
+               transform(s.begin(), s.end(), s.begin(), ::toupper);
+               return s;
+       };
+
        /* Split the raw name up into words */
        vector<string> words;
        split (words, raw_name, is_any_of (" _-"));
@@ -903,13 +917,14 @@ Film::isdcf_name (bool if_created_now) const
                isdcf_name += "_" + container()->isdcf_name();
        }
 
+       auto content_list = content();
+
        /* XXX: this uses the first bit of content only */
 
        /* Interior aspect ratio.  The standard says we don't do this for trailers, for some strange reason */
        if (dcp_content_type() && dcp_content_type()->libdcp_kind() != dcp::ContentKind::TRAILER) {
-               auto cl = content();
-               auto first_video = std::find_if(cl.begin(), cl.end(), [](shared_ptr<Content> c) { return static_cast<bool>(c->video); });
-               if (first_video != cl.end()) {
+               auto first_video = std::find_if(content_list.begin(), content_list.end(), [](shared_ptr<Content> c) { return static_cast<bool>(c->video); });
+               if (first_video != content_list.end()) {
                        auto first_ratio = lrintf((*first_video)->video->scaled_size(frame_size()).ratio() * 100);
                        auto container_ratio = lrintf(container()->ratio() * 100);
                        if (first_ratio != container_ratio) {
@@ -939,7 +954,7 @@ Film::isdcf_name (bool if_created_now) const
 
        auto burnt_in = true;
        auto ccap = false;
-       for (auto i: content()) {
+       for (auto i: content_list) {
                for (auto j: i->text) {
                        if (j->type() == TextType::OPEN_SUBTITLE && j->use() && !j->burn()) {
                                burnt_in = false;
@@ -996,6 +1011,10 @@ Film::isdcf_name (bool if_created_now) const
                isdcf_name += "-VI";
        }
 
+       if (find_if(content_list.begin(), content_list.end(), [](shared_ptr<Content> c) { return static_cast<bool>(c->atmos); }) != content_list.end()) {
+               isdcf_name += "-IAB";
+       }
+
        isdcf_name += "_" + resolution_to_string (_resolution);
 
        if (_studio && _studio->length() >= 2) {
@@ -1023,7 +1042,7 @@ Film::isdcf_name (bool if_created_now) const
        }
 
        auto vf = false;
-       for (auto i: content()) {
+       for (auto i: content_list) {
                auto dc = dynamic_pointer_cast<const DCPContent>(i);
                if (!dc) {
                        continue;
@@ -1168,6 +1187,15 @@ Film::set_interop (bool i)
        _interop = i;
 }
 
+
+void
+Film::set_limit_to_smpte_bv20(bool limit)
+{
+       FilmChangeSignaller ch(this, Property::LIMIT_TO_SMPTE_BV20);
+       _limit_to_smpte_bv20 = limit;
+}
+
+
 void
 Film::set_audio_processor (AudioProcessor const * processor)
 {
@@ -1624,37 +1652,18 @@ Film::active_area () const
 }
 
 
-/** @param recipient KDM recipient certificate.
- *  @param trusted_devices Certificate thumbprints of other trusted devices (can be empty).
- *  @param cpl_file CPL filename.
+/*  @param cpl_file CPL filename.
  *  @param from KDM from time expressed as a local time with an offset from UTC.
  *  @param until KDM to time expressed as a local time with an offset from UTC.
- *  @param formulation KDM formulation to use.
- *  @param disable_forensic_marking_picture true to disable forensic marking of picture.
- *  @param disable_forensic_marking_audio if not set, don't disable forensic marking of audio.  If set to 0,
- *  disable all forensic marking; if set above 0, disable forensic marking above that channel.
  */
-dcp::EncryptedKDM
-Film::make_kdm (
-       dcp::Certificate recipient,
-       vector<string> trusted_devices,
-       boost::filesystem::path cpl_file,
-       dcp::LocalTime from,
-       dcp::LocalTime until,
-       dcp::Formulation formulation,
-       bool disable_forensic_marking_picture,
-       optional<int> disable_forensic_marking_audio
-       ) const
+dcp::DecryptedKDM
+Film::make_kdm(boost::filesystem::path cpl_file, dcp::LocalTime from, dcp::LocalTime until) const
 {
        if (!_encrypted) {
                throw runtime_error (_("Cannot make a KDM as this project is not encrypted."));
        }
 
        auto cpl = make_shared<dcp::CPL>(cpl_file);
-       auto signer = Config::instance()->signer_chain();
-       if (!signer->valid ()) {
-               throw InvalidSignerError ();
-       }
 
        /* Find keys that have been added to imported, encrypted DCP content */
        list<dcp::DecryptedKDMKey> imported_keys;
@@ -1693,7 +1702,7 @@ Film::make_kdm (
 
        return dcp::DecryptedKDM (
                cpl->id(), keys, from, until, cpl->content_title_text(), cpl->content_title_text(), dcp::LocalTime().as_string()
-               ).encrypt (signer, recipient, trusted_devices, formulation, disable_forensic_marking_picture, disable_forensic_marking_audio);
+               );
 }