From 2b870d03ce118f9d9146f53658d3a9a2e2626600 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 11 May 2020 22:42:32 +0200 Subject: [PATCH 1/1] Guess DCP container size and resolution when content is added or removed such that there is one piece of video content left in the project. Container size and resolution are never again guessed once the user has set them to something. --- src/lib/film.cc | 73 ++++++++++++++++++++++++++++++++++- src/lib/film.h | 7 +++- src/tools/dcpomatic_create.cc | 8 +++- test/data | 2 +- 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/src/lib/film.cc b/src/lib/film.cc index b1dcb46d7..2f631bd89 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -164,6 +164,8 @@ Film::Film (optional dir) , _upload_after_make_dcp (Config::instance()->default_upload_after_make_dcp()) , _reencode_j2k (false) , _user_explicit_video_frame_rate (false) + , _user_explicit_container (false) + , _user_explicit_resolution (false) , _state_version (current_state_version) , _dirty (false) , _tolerant (false) @@ -466,6 +468,8 @@ Film::metadata (bool with_content_paths) const i.as_xml (root->add_child("Rating")); } root->add_child("ContentVersion")->add_child_text(_content_version); + root->add_child("UserExplicitContainer")->add_child_text(_user_explicit_container ? "1" : "0"); + root->add_child("UserExplicitResolution")->add_child_text(_user_explicit_resolution ? "1" : "0"); _playlist->as_xml (root->add_child ("Playlist"), with_content_paths); return doc; @@ -615,6 +619,10 @@ Film::read_metadata (optional path) _content_version = f.optional_string_child("ContentVersion").get_value_or(""); + /* Disable guessing for files made in previous DCP-o-matic versions */ + _user_explicit_container = f.optional_bool_child("UserExplicitContainer").get_value_or(true); + _user_explicit_resolution = f.optional_bool_child("UserExplicitResolution").get_value_or(true); + list notes; _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version, notes); @@ -969,20 +977,39 @@ Film::set_dcp_content_type (DCPContentType const * t) _dcp_content_type = t; } + +/** @param explicit_user true if this is being set because of + * a direct user request, false if it is being done because + * DCP-o-matic is guessing the best container to use. + */ void -Film::set_container (Ratio const * c) +Film::set_container (Ratio const * c, bool explicit_user) { ChangeSignaller ch (this, CONTAINER); _container = c; + + if (explicit_user) { + _user_explicit_container = true; + } } + +/** @param explicit_user true if this is being set because of + * a direct user request, false if it is being done because + * DCP-o-matic is guessing the best resolution to use. + */ void -Film::set_resolution (Resolution r) +Film::set_resolution (Resolution r, bool explicit_user) { ChangeSignaller ch (this, RESOLUTION); _resolution = r; + + if (explicit_user) { + _user_explicit_resolution = true; + } } + void Film::set_j2k_bandwidth (int b) { @@ -1267,12 +1294,54 @@ Film::add_content (shared_ptr c) } _playlist->add (shared_from_this(), c); + + maybe_set_container_and_resolution (); +} + + +void +Film::maybe_set_container_and_resolution () +{ + /* Get the only piece of video content, if there is only one */ + shared_ptr video; + BOOST_FOREACH (shared_ptr i, _playlist->content()) { + if (i->video) { + if (!video) { + video = i->video; + } else { + video.reset (); + } + } + } + + if (video) { + /* This is the only piece of video content in this Film. Use it to make a guess for + * DCP container size and resolution, unless the user has already explicitly set these + * things. + */ + if (!_user_explicit_container) { + if (video->size().ratio() > 2.3) { + set_container (Ratio::from_id("239"), false); + } else { + set_container (Ratio::from_id("185"), false); + } + } + + if (!_user_explicit_resolution) { + if (video->size_after_crop().width > 2048 || video->size_after_crop().height > 1080) { + set_resolution (RESOLUTION_4K, false); + } else { + set_resolution (RESOLUTION_2K, false); + } + } + } } void Film::remove_content (shared_ptr c) { _playlist->remove (c); + maybe_set_container_and_resolution (); } void diff --git a/src/lib/film.h b/src/lib/film.h index 40d366f8f..b03b0258e 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -351,8 +351,8 @@ public: void move_content_earlier (boost::shared_ptr); void move_content_later (boost::shared_ptr); void set_dcp_content_type (DCPContentType const *); - void set_container (Ratio const *); - void set_resolution (Resolution); + void set_container (Ratio const *, bool user_explicit = true); + void set_resolution (Resolution, bool user_explicit = true); void set_signed (bool); void set_encrypted (bool); void set_key (dcp::Key key); @@ -409,6 +409,7 @@ private: void maybe_add_content (boost::weak_ptr, boost::weak_ptr, bool disable_audio_analysis); void audio_analysis_finished (); void check_settings_consistency (); + void maybe_set_container_and_resolution (); static std::string const metadata_file; @@ -462,6 +463,8 @@ private: bool _reencode_j2k; /** true if the user has ever explicitly set the video frame rate of this film */ bool _user_explicit_video_frame_rate; + bool _user_explicit_container; + bool _user_explicit_resolution; std::map _markers; std::vector _ratings; std::string _content_version; diff --git a/src/tools/dcpomatic_create.cc b/src/tools/dcpomatic_create.cc index bcfc2f68b..857359117 100644 --- a/src/tools/dcpomatic_create.cc +++ b/src/tools/dcpomatic_create.cc @@ -96,14 +96,18 @@ main (int argc, char* argv[]) } film->set_name (cc.name); - film->set_container (cc.container_ratio); + if (cc.container_ratio) { + film->set_container (cc.container_ratio); + } film->set_dcp_content_type (cc.dcp_content_type); film->set_interop (cc.standard == dcp::INTEROP); film->set_use_isdcf_name (!cc.no_use_isdcf_name); film->set_signed (!cc.no_sign); film->set_encrypted (cc.encrypt); film->set_three_d (cc.threed); - film->set_resolution (cc.fourk ? RESOLUTION_4K : RESOLUTION_2K); + if (cc.fourk) { + film->set_resolution (RESOLUTION_4K); + } if (cc.j2k_bandwidth) { film->set_j2k_bandwidth (*cc.j2k_bandwidth); } diff --git a/test/data b/test/data index 9ec245b7f..3b21196b8 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 9ec245b7f59b65ad6dd6d0f717686931ff66d748 +Subproject commit 3b21196b894bfbc096a5e90ee11dcf5f50bd4bf9 -- 2.30.2