From 54ca5a01f0648d2a5101fab0f50b41d8c90612e4 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 17 Jun 2020 01:08:48 +0200 Subject: [PATCH] Allow more complete control over the libdcp/DCP-o-matic metadata written to various places. --- cscript | 4 +-- src/lib/config.cc | 12 ++++++++ src/lib/config.h | 36 ++++++++++++++++++++++++ src/lib/dcp_video.cc | 5 +++- src/lib/reel_writer.cc | 24 +++++++++++++++- src/wx/full_config_dialog.cc | 54 ++++++++++++++++++++++++++++++++++++ 6 files changed, 131 insertions(+), 4 deletions(-) diff --git a/cscript b/cscript index 2e7820e53..6966864a6 100644 --- a/cscript +++ b/cscript @@ -375,8 +375,8 @@ def dependencies(target, options): (target.platform == 'osx' and target.bits == 64) or (target.platform == 'windows')) else {} - deps.append(('libdcp', 'a8d652b', cpp_lib_options)) - deps.append(('libsub', 'bb87e0e', cpp_lib_options)) + deps.append(('libdcp', 'cdb664d', cpp_lib_options)) + deps.append(('libsub', 'dec1726', cpp_lib_options)) deps.append(('leqm-nrt', 'carl')) deps.append(('rtaudio', 'carl')) # We get our OpenSSL libraries from the environment, but we diff --git a/src/lib/config.cc b/src/lib/config.cc index b1f2a4f18..7b381e33b 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -323,6 +323,10 @@ try } _upload_after_make_dcp = up.get_value_or (false); _dcp_creator = f.optional_string_child ("DCPCreator").get_value_or (""); + _dcp_company_name = f.optional_string_child("DCPCompanyName").get_value_or(""); + _dcp_product_name = f.optional_string_child("DCPProductName").get_value_or(""); + _dcp_product_version = f.optional_string_child("DCPProductVersion").get_value_or(""); + _dcp_j2k_comment = f.optional_string_child("DCPJ2KComment").get_value_or(""); if (version && version.get() >= 2) { _default_isdcf_metadata = ISDCFMetadata (f.node_child ("ISDCFMetadata")); @@ -729,6 +733,14 @@ Config::write_config () const root->add_child("DCPIssuer")->add_child_text (_dcp_issuer); /* [XML] DCPIssuer Creator text to write into CPL files. */ root->add_child("DCPCreator")->add_child_text (_dcp_creator); + /* [XML] Company name to write into MXF files. */ + root->add_child("DCPCompanyName")->add_child_text (_dcp_company_name); + /* [XML] Product name to write into MXF files. */ + root->add_child("DCPProductName")->add_child_text (_dcp_product_name); + /* [XML] Product version to write into MXF files. */ + root->add_child("DCPProductVersion")->add_child_text (_dcp_product_version); + /* [XML] Comment to write into JPEG2000 data. */ + root->add_child("DCPJ2KComment")->add_child_text (_dcp_j2k_comment); /* [XML] UploadAfterMakeDCP 1 to upload to a TMS after making a DCP, 0 for no upload. */ root->add_child("UploadAfterMakeDCP")->add_child_text (_upload_after_make_dcp ? "1" : "0"); diff --git a/src/lib/config.h b/src/lib/config.h index 4b7488d15..74a44bc2f 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -202,6 +202,22 @@ public: return _dcp_creator; } + std::string dcp_company_name () const { + return _dcp_company_name; + } + + std::string dcp_product_name () const { + return _dcp_product_name; + } + + std::string dcp_product_version () const { + return _dcp_product_version; + } + + std::string dcp_j2k_comment () const { + return _dcp_j2k_comment; + } + int default_j2k_bandwidth () const { return _default_j2k_bandwidth; } @@ -698,6 +714,22 @@ public: maybe_set (_dcp_creator, c); } + void set_dcp_company_name (std::string c) { + maybe_set (_dcp_company_name, c); + } + + void set_dcp_product_name (std::string c) { + maybe_set (_dcp_product_name, c); + } + + void set_dcp_product_version (std::string c) { + maybe_set (_dcp_product_version, c); + } + + void set_dcp_j2k_comment (std::string c) { + maybe_set (_dcp_j2k_comment, c); + } + void set_default_j2k_bandwidth (int b) { maybe_set (_default_j2k_bandwidth, b); } @@ -1229,6 +1261,10 @@ private: int _default_dcp_audio_channels; std::string _dcp_issuer; std::string _dcp_creator; + std::string _dcp_company_name; + std::string _dcp_product_name; + std::string _dcp_product_version; + std::string _dcp_j2k_comment; int _default_j2k_bandwidth; int _default_audio_delay; bool _default_interop; diff --git a/src/lib/dcp_video.cc b/src/lib/dcp_video.cc index 5416f2ae7..7b06f8cfc 100644 --- a/src/lib/dcp_video.cc +++ b/src/lib/dcp_video.cc @@ -115,12 +115,15 @@ DCPVideo::convert_to_xyz (shared_ptr frame, dcp::NoteHandler Data DCPVideo::encode_locally () { + string const comment = Config::instance()->dcp_j2k_comment(); + Data enc = compress_j2k ( convert_to_xyz (_frame, boost::bind(&Log::dcp_log, dcpomatic_log.get(), _1, _2)), _j2k_bandwidth, _frames_per_second, _frame->eyes() == EYES_LEFT || _frame->eyes() == EYES_RIGHT, - _resolution == RESOLUTION_4K + _resolution == RESOLUTION_4K, + comment.empty() ? "libdcp" : comment ); switch (_frame->eyes()) { diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index 06d20e7c8..3697fc7b1 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2019 Carl Hetherington + Copyright (C) 2012-2020 Carl Hetherington This file is part of DCP-o-matic. @@ -27,6 +27,7 @@ #include "digester.h" #include "font.h" #include "compose.hpp" +#include "config.h" #include "audio_buffers.h" #include "image.h" #include @@ -65,6 +66,23 @@ using namespace dcpomatic; int const ReelWriter::_info_size = 48; +static dcp::MXFMetadata +mxf_metadata () +{ + dcp::MXFMetadata meta; + Config* config = Config::instance(); + if (!config->dcp_company_name().empty()) { + meta.company_name = config->dcp_company_name (); + } + if (!config->dcp_product_name().empty()) { + meta.product_name = config->dcp_product_name (); + } + if (!config->dcp_product_version().empty()) { + meta.product_version = config->dcp_product_version (); + } + return meta; +} + /** @param job Related job, or 0 */ ReelWriter::ReelWriter ( shared_ptr film, DCPTimePeriod period, shared_ptr job, int reel_index, int reel_count, optional content_summary @@ -113,6 +131,7 @@ ReelWriter::ReelWriter ( } _picture_asset->set_size (_film->frame_size()); + _picture_asset->set_metadata (mxf_metadata()); if (_film->encrypted ()) { _picture_asset->set_key (_film->key()); @@ -136,6 +155,8 @@ ReelWriter::ReelWriter ( new dcp::SoundAsset (dcp::Fraction (_film->video_frame_rate(), 1), _film->audio_frame_rate (), _film->audio_channels (), standard) ); + _sound_asset->set_metadata (mxf_metadata()); + if (_film->encrypted ()) { _sound_asset->set_key (_film->key ()); } @@ -634,6 +655,7 @@ ReelWriter::write (PlayerText subs, TextType type, optional track, } else { shared_ptr s (new dcp::SMPTESubtitleAsset ()); s->set_content_title_text (_film->name ()); + s->set_metadata (mxf_metadata()); if (type == TEXT_OPEN_SUBTITLE && !lang.empty()) { s->set_language (lang); } else { diff --git a/src/wx/full_config_dialog.cc b/src/wx/full_config_dialog.cc index ab3dc0800..342657e29 100644 --- a/src/wx/full_config_dialog.cc +++ b/src/wx/full_config_dialog.cc @@ -133,12 +133,34 @@ private: add_label_to_sizer (bottom_table, _panel, _("Issuer"), true); _issuer = new wxTextCtrl (_panel, wxID_ANY); + _issuer->SetToolTip (_("This will be written to the DCP's XML files as the . If it is blank, a default value mentioning DCP-o-matic will be used.")); bottom_table->Add (_issuer, 1, wxALL | wxEXPAND); add_label_to_sizer (bottom_table, _panel, _("Creator"), true); _creator = new wxTextCtrl (_panel, wxID_ANY); + _creator->SetToolTip (_("This will be written to the DCP's XML files as the . If it is blank, a default value mentioning DCP-o-matic will be used.")); bottom_table->Add (_creator, 1, wxALL | wxEXPAND); + add_label_to_sizer (bottom_table, _panel, _("Company name"), true); + _company_name = new wxTextCtrl (_panel, wxID_ANY); + _company_name->SetToolTip (_("This will be written to the DCP's MXF files as the 'company name'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used.")); + bottom_table->Add (_company_name, 1, wxALL | wxEXPAND); + + add_label_to_sizer (bottom_table, _panel, _("Product name"), true); + _product_name = new wxTextCtrl (_panel, wxID_ANY); + _product_name->SetToolTip (_("This will be written to the DCP's MXF files as the 'product name'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used.")); + bottom_table->Add (_product_name, 1, wxALL | wxEXPAND); + + add_label_to_sizer (bottom_table, _panel, _("Product version"), true); + _product_version = new wxTextCtrl (_panel, wxID_ANY); + _product_version->SetToolTip (_("This will be written to the DCP's MXF files as the 'product version'. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used.")); + bottom_table->Add (_product_version, 1, wxALL | wxEXPAND); + + add_label_to_sizer (bottom_table, _panel, _("JPEG2000 comment"), true); + _j2k_comment = new wxTextCtrl (_panel, wxID_ANY); + _j2k_comment->SetToolTip (_("This will be written to the DCP's JPEG2000 data as a comment. If it is blank, a default value mentioning libdcp (an internal DCP-o-matic library) will be used.")); + bottom_table->Add (_j2k_comment, 1, wxALL | wxEXPAND); + table->Add (bottom_table, wxGBPosition (r, 0), wxGBSpan (2, 2), wxEXPAND); ++r; @@ -162,6 +184,10 @@ private: _issuer->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::issuer_changed, this)); _creator->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::creator_changed, this)); + _company_name->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::company_name_changed, this)); + _product_name->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::product_name_changed, this)); + _product_version->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::product_version_changed, this)); + _j2k_comment->Bind (wxEVT_TEXT, boost::bind (&FullGeneralPage::j2k_comment_changed, this)); } void config_changed () @@ -184,6 +210,10 @@ private: checked_set (_automatic_audio_analysis, config->automatic_audio_analysis ()); checked_set (_issuer, config->dcp_issuer ()); checked_set (_creator, config->dcp_creator ()); + checked_set (_company_name, config->dcp_company_name ()); + checked_set (_product_name, config->dcp_product_name ()); + checked_set (_product_version, config->dcp_product_version ()); + checked_set (_j2k_comment, config->dcp_j2k_comment ()); checked_set (_config_file, config->config_file()); checked_set (_cinemas_file, config->cinemas_file()); @@ -245,6 +275,26 @@ private: Config::instance()->set_dcp_creator (wx_to_std (_creator->GetValue ())); } + void company_name_changed () + { + Config::instance()->set_dcp_company_name (wx_to_std(_company_name->GetValue())); + } + + void product_name_changed () + { + Config::instance()->set_dcp_product_name (wx_to_std(_product_name->GetValue())); + } + + void product_version_changed () + { + Config::instance()->set_dcp_product_version (wx_to_std(_product_version->GetValue())); + } + + void j2k_comment_changed () + { + Config::instance()->set_dcp_j2k_comment (wx_to_std(_j2k_comment->GetValue())); + } + void config_file_changed () { Config* config = Config::instance(); @@ -287,6 +337,10 @@ private: wxCheckBox* _automatic_audio_analysis; wxTextCtrl* _issuer; wxTextCtrl* _creator; + wxTextCtrl* _company_name; + wxTextCtrl* _product_name; + wxTextCtrl* _product_version; + wxTextCtrl* _j2k_comment; }; class DefaultsPage : public StandardPage -- 2.30.2