From: Carl Hetherington Date: Tue, 10 Jun 2014 16:14:17 +0000 (+0100) Subject: Support ISDCF naming convention version 9. X-Git-Tag: v2.0.48~551^2~106 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=f0cc79a6c34b8198155f6e519d4464385ea30049;hp=e7bc3bd16456c17bc6fe1d7981040b14e820505e Support ISDCF naming convention version 9. Reported-by: Elia Orselli --- diff --git a/ChangeLog b/ChangeLog index d9aeec1fb..26bd287dc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2014-06-10 Carl Hetherington + * Support ISDCF naming convention version 9 (#257). + * Rename DCI to ISDCF when talking about the digital cinema naming convention (#362). diff --git a/src/lib/film.cc b/src/lib/film.cc index fb3026039..fd3e78c35 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -490,14 +490,20 @@ Film::isdcf_name (bool if_created_now) const { stringstream d; - string fixed_name = to_upper_copy (name()); - for (size_t i = 0; i < fixed_name.length(); ++i) { - if (fixed_name[i] == ' ') { - fixed_name[i] = '-'; + string raw_name = name (); + string fixed_name; + bool cap_next = true; + for (size_t i = 0; i < raw_name.length(); ++i) { + if (raw_name[i] == ' ') { + cap_next = true; + } else if (cap_next) { + fixed_name += toupper (raw_name[i]); + cap_next = false; + } else { + fixed_name += tolower (raw_name[i]); } } - /* Spec is that the name part should be maximum 14 characters, as I understand it */ if (fixed_name.length() > 14) { fixed_name = fixed_name.substr (0, 14); } @@ -509,19 +515,60 @@ Film::isdcf_name (bool if_created_now) const d << "-" << isdcf_metadata().content_version; } + ISDCFMetadata const dm = isdcf_metadata (); + + if (dm.temp_version) { + d << "-Temp"; + } + + if (dm.pre_release) { + d << "-Pre"; + } + + if (dm.red_band) { + d << "-RedBand"; + } + + if (!dm.chain.empty ()) { + d << "-" << dm.chain; + } + if (three_d ()) { d << "-3D"; } + if (dm.two_d_version_of_three_d) { + d << "-2D"; + } + + if (!dm.mastered_luminance.empty ()) { + d << "-" << dm.mastered_luminance; + } + if (video_frame_rate() != 24) { d << "-" << video_frame_rate(); } - + if (container()) { d << "_" << container()->isdcf_name(); } - ISDCFMetadata const dm = isdcf_metadata (); + /* XXX: this only works for content which has been scaled to a given ratio, + and uses the first bit of content only. + */ + + ContentList cl = content (); + Ratio const * content_ratio = 0; + for (ContentList::const_iterator i = cl.begin(); i != cl.end(); ++i) { + shared_ptr vc = dynamic_pointer_cast (*i); + if (vc && (content_ratio == 0 || vc->scale().ratio() != content_ratio)) { + content_ratio = vc->scale().ratio(); + } + } + + if (content_ratio && content_ratio != container()) { + d << "-" << content_ratio->isdcf_name(); + } if (!dm.audio_language.empty ()) { d << "_" << dm.audio_language; @@ -560,8 +607,10 @@ Film::isdcf_name (bool if_created_now) const break; } - d << "_" << resolution_to_string (_resolution); + /* XXX: HI/VI */ + d << "_" << resolution_to_string (_resolution); + if (!dm.studio.empty ()) { d << "_" << dm.studio; } @@ -576,6 +625,16 @@ Film::isdcf_name (bool if_created_now) const d << "_" << dm.facility; } + if (_interop) { + d << "_IOP"; + } else { + d << "_SMPTE"; + } + + if (three_d ()) { + d << "-3D"; + } + if (!dm.package_type.empty ()) { d << "_" << dm.package_type; } diff --git a/src/lib/film.h b/src/lib/film.h index f77309862..96ea930cc 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -46,6 +46,7 @@ class Playlist; class AudioContent; class Scaler; class Screen; +class isdcf_name_test; /** @class Film * @@ -282,6 +283,8 @@ public: private: + friend class ::isdcf_name_test; + void signal_changed (Property); std::string video_identifier () const; void playlist_changed (); diff --git a/src/lib/isdcf_metadata.cc b/src/lib/isdcf_metadata.cc index ae99280ca..dfba50a9a 100644 --- a/src/lib/isdcf_metadata.cc +++ b/src/lib/isdcf_metadata.cc @@ -38,6 +38,14 @@ ISDCFMetadata::ISDCFMetadata (shared_ptr node) studio = node->string_child ("Studio"); facility = node->string_child ("Facility"); package_type = node->string_child ("PackageType"); + + /* This stuff was added later */ + temp_version = node->optional_bool_child ("TempVersion").get_value_or (false); + pre_release = node->optional_bool_child ("PreRelease").get_value_or (false); + red_band = node->optional_bool_child ("RedBand").get_value_or (false); + chain = node->optional_string_child ("Chain").get_value_or (""); + two_d_version_of_three_d = node->optional_bool_child ("TwoDVersionOfThreeD").get_value_or (false); + mastered_luminance = node->optional_string_child ("MasteredLuminance").get_value_or (""); } void @@ -51,6 +59,12 @@ ISDCFMetadata::as_xml (xmlpp::Node* root) const root->add_child("Studio")->add_child_text (studio); root->add_child("Facility")->add_child_text (facility); root->add_child("PackageType")->add_child_text (package_type); + root->add_child("TempVersion")->add_child_text (temp_version ? "1" : "0"); + root->add_child("PreRelease")->add_child_text (pre_release ? "1" : "0"); + root->add_child("RedBand")->add_child_text (red_band ? "1" : "0"); + root->add_child("Chain")->add_child_text (chain); + root->add_child("TwoDVersionOfThreeD")->add_child_text (two_d_version_of_three_d ? "1" : "0"); + root->add_child("MasteredLuminance")->add_child_text (mastered_luminance); } void diff --git a/src/lib/isdcf_metadata.h b/src/lib/isdcf_metadata.h index cd63ba2ee..0fb7e7baa 100644 --- a/src/lib/isdcf_metadata.h +++ b/src/lib/isdcf_metadata.h @@ -32,6 +32,10 @@ class ISDCFMetadata public: ISDCFMetadata () : content_version (1) + , temp_version (false) + , pre_release (false) + , red_band (false) + , two_d_version_of_three_d (false) {} ISDCFMetadata (boost::shared_ptr); @@ -47,6 +51,18 @@ public: std::string studio; std::string facility; std::string package_type; + /** true if this is a temporary version (without final picture or sound) */ + bool temp_version; + /** true if this is a pre-release version (final picture and sound, but without accessibility features) */ + bool pre_release; + /** true if this has adult content */ + bool red_band; + /** specific theatre chain or event */ + std::string chain; + /** true if this is a 2D version of content that also exists in 3D */ + bool two_d_version_of_three_d; + /** mastered luminance if there are multiple versions distributed (e.g. 35, 4fl, 6fl etc.) */ + std::string mastered_luminance; }; #endif diff --git a/src/lib/ratio.cc b/src/lib/ratio.cc index a47b2101e..52577d3bb 100644 --- a/src/lib/ratio.cc +++ b/src/lib/ratio.cc @@ -32,12 +32,12 @@ vector Ratio::_ratios; void Ratio::setup_ratios () { - _ratios.push_back (new Ratio (float(1290) / 1080, "119", _("1.19"), "F")); - _ratios.push_back (new Ratio (float(1440) / 1080, "133", _("4:3"), "F")); - _ratios.push_back (new Ratio (float(1480) / 1080, "137", _("Academy"), "F")); - _ratios.push_back (new Ratio (float(1485) / 1080, "138", _("1.375"), "F")); - _ratios.push_back (new Ratio (float(1800) / 1080, "166", _("1.66"), "F")); - _ratios.push_back (new Ratio (float(1920) / 1080, "178", _("16:9"), "F")); + _ratios.push_back (new Ratio (float(1290) / 1080, "119", _("1.19"), "119")); + _ratios.push_back (new Ratio (float(1440) / 1080, "133", _("4:3"), "133")); + _ratios.push_back (new Ratio (float(1480) / 1080, "137", _("Academy"), "137")); + _ratios.push_back (new Ratio (float(1485) / 1080, "138", _("1.375"), "137")); + _ratios.push_back (new Ratio (float(1800) / 1080, "166", _("1.66"), "166")); + _ratios.push_back (new Ratio (float(1920) / 1080, "178", _("16:9"), "178")); _ratios.push_back (new Ratio (float(1998) / 1080, "185", _("Flat"), "F")); _ratios.push_back (new Ratio (float(2048) / 858, "239", _("Scope"), "S")); _ratios.push_back (new Ratio (float(2048) / 1080, "full-frame", _("Full frame"), "C")); diff --git a/src/wx/isdcf_metadata_dialog.cc b/src/wx/isdcf_metadata_dialog.cc index 0fd00ff7a..e47c944d0 100644 --- a/src/wx/isdcf_metadata_dialog.cc +++ b/src/wx/isdcf_metadata_dialog.cc @@ -53,6 +53,24 @@ ISDCFMetadataDialog::ISDCFMetadataDialog (wxWindow* parent, ISDCFMetadata dm) add (_("Package Type (e.g. OV)"), true); _package_type = add (new wxTextCtrl (this, wxID_ANY)); + _temp_version = add (new wxCheckBox (this, wxID_ANY, _("Temp version"))); + add_spacer (); + + _pre_release = add (new wxCheckBox (this, wxID_ANY, _("Pre-release"))); + add_spacer (); + + _red_band = add (new wxCheckBox (this, wxID_ANY, _("Red band"))); + add_spacer (); + + add (_("Chain"), true); + _chain = add (new wxTextCtrl (this, wxID_ANY)); + + _two_d_version_of_three_d = add (new wxCheckBox (this, wxID_ANY, _("2D version of content available in 3D"))); + add_spacer (); + + add (_("Mastered luminance (e.g. 4fl)"), true); + _mastered_luminance = add (new wxTextCtrl (this, wxID_ANY)); + _content_version->SetRange (1, 1024); _content_version->SetValue (dm.content_version); @@ -63,6 +81,12 @@ ISDCFMetadataDialog::ISDCFMetadataDialog (wxWindow* parent, ISDCFMetadata dm) _studio->SetValue (std_to_wx (dm.studio)); _facility->SetValue (std_to_wx (dm.facility)); _package_type->SetValue (std_to_wx (dm.package_type)); + _temp_version->SetValue (dm.temp_version); + _pre_release->SetValue (dm.pre_release); + _red_band->SetValue (dm.red_band); + _chain->SetValue (std_to_wx (dm.chain)); + _two_d_version_of_three_d->SetValue (dm.two_d_version_of_three_d); + _mastered_luminance->SetValue (std_to_wx (dm.mastered_luminance)); layout (); } @@ -80,6 +104,12 @@ ISDCFMetadataDialog::isdcf_metadata () const dm.studio = wx_to_std (_studio->GetValue ()); dm.facility = wx_to_std (_facility->GetValue ()); dm.package_type = wx_to_std (_package_type->GetValue ()); + dm.temp_version = _temp_version->GetValue (); + dm.pre_release = _pre_release->GetValue (); + dm.red_band = _red_band->GetValue (); + dm.chain = wx_to_std (_chain->GetValue ()); + dm.two_d_version_of_three_d = _two_d_version_of_three_d->GetValue (); + dm.mastered_luminance = wx_to_std (_mastered_luminance->GetValue ()); return dm; } diff --git a/src/wx/isdcf_metadata_dialog.h b/src/wx/isdcf_metadata_dialog.h index e20dbf5e3..516f83231 100644 --- a/src/wx/isdcf_metadata_dialog.h +++ b/src/wx/isdcf_metadata_dialog.h @@ -41,4 +41,10 @@ private: wxTextCtrl* _studio; wxTextCtrl* _facility; wxTextCtrl* _package_type; + wxCheckBox* _temp_version; + wxCheckBox* _pre_release; + wxCheckBox* _red_band; + wxTextCtrl* _chain; + wxCheckBox* _two_d_version_of_three_d; + wxTextCtrl* _mastered_luminance; }; diff --git a/test/isdcf_name_test.cc b/test/isdcf_name_test.cc new file mode 100644 index 000000000..65f89c0f4 --- /dev/null +++ b/test/isdcf_name_test.cc @@ -0,0 +1,100 @@ +/* + Copyright (C) 2014 Carl Hetherington + + 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 +#include "lib/film.h" +#include "lib/ratio.h" +#include "lib/dcp_content_type.h" +#include "lib/image_content.h" +#include "test.h" + +using std::cout; +using boost::shared_ptr; + +BOOST_AUTO_TEST_CASE (isdcf_name_test) +{ + shared_ptr film = new_test_film ("isdcf_name_test"); + + /* A basic test */ + + film->set_name ("My Nice Film"); + film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR")); + film->set_container (Ratio::from_id ("185")); + film->_isdcf_date = boost::gregorian::date (2014, boost::gregorian::Jul, 4); + ISDCFMetadata m; + m.content_version = 1; + m.audio_language = "EN"; + m.subtitle_language = "XX"; + m.territory = "UK"; + m.rating = "PG"; + m.studio = "ST"; + m.facility = "FA"; + m.package_type = "OV"; + film->set_isdcf_metadata (m); + film->set_interop (true); + BOOST_CHECK_EQUAL (film->isdcf_name(false), "MyNiceFilm_FTR-1_F_EN-XX_UK-PG_51_2K_ST_20140704_FA_IOP_OV"); + + /* Test a long name and some different data */ + + film->set_name ("My Nice Film With A Very Long Name"); + film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR")); + film->set_container (Ratio::from_id ("239")); + film->_isdcf_date = boost::gregorian::date (2014, boost::gregorian::Jul, 4); + film->set_audio_channels (1); + film->set_resolution (RESOLUTION_4K); + m.content_version = 2; + m.audio_language = "DE"; + m.subtitle_language = "FR"; + m.territory = "US"; + m.rating = "R"; + m.studio = "DI"; + m.facility = "PP"; + m.package_type = "VF"; + film->set_isdcf_metadata (m); + film->set_interop (false); + BOOST_CHECK_EQUAL (film->isdcf_name(false), "MyNiceFilmWith_TLR-2_S_DE-FR_US-R_10_4K_DI_20140704_PP_SMPTE_VF"); + + /* Test interior aspect ratio */ + + shared_ptr content (new ImageContent (film, "test/data/simple_testcard_640x480.png")); + film->examine_and_add_content (content); + wait_for_jobs (); + content->set_scale (VideoContentScale (Ratio::from_id ("133"))); + film->set_container (Ratio::from_id ("185")); + BOOST_CHECK_EQUAL (film->isdcf_name(false), "MyNiceFilmWith_TLR-2_F-133_DE-FR_US-R_10_4K_DI_20140704_PP_SMPTE_VF"); + + /* Test 3D */ + + film->set_three_d (true); + BOOST_CHECK_EQUAL (film->isdcf_name(false), "MyNiceFilmWith_TLR-2-3D_F-133_DE-FR_US-R_10_4K_DI_20140704_PP_SMPTE-3D_VF"); + + /* Test content type modifiers */ + + film->set_three_d (false); + m.temp_version = true; + m.pre_release = true; + m.red_band = true; + m.chain = "MyChain"; + m.two_d_version_of_three_d = true; + m.mastered_luminance = "4fl"; + film->set_isdcf_metadata (m); + film->set_video_frame_rate (48); + BOOST_CHECK_EQUAL (film->isdcf_name(false), "MyNiceFilmWith_TLR-2-Temp-Pre-RedBand-MyChain-2D-4fl-48_F-133_DE-FR_US-R_10_4K_DI_20140704_PP_SMPTE_VF"); +} + diff --git a/test/wscript b/test/wscript index 676f47104..09df14673 100644 --- a/test/wscript +++ b/test/wscript @@ -31,6 +31,7 @@ def build(bld): film_metadata_test.cc frame_rate_test.cc image_test.cc + isdcf_name_test.cc job_test.cc make_black_test.cc pixel_formats_test.cc