summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-05-11 22:42:32 +0200
committerCarl Hetherington <cth@carlh.net>2020-05-12 13:13:36 +0200
commit2b870d03ce118f9d9146f53658d3a9a2e2626600 (patch)
tree8766a84cb75e7c7e954bfa9b7a4b5c5123cdd6d6
parent186654cc20ef302abed1a2ddfa01fc1fa3af81fa (diff)
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.
-rw-r--r--src/lib/film.cc73
-rw-r--r--src/lib/film.h7
-rw-r--r--src/tools/dcpomatic_create.cc8
m---------test/data0
4 files changed, 82 insertions, 6 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<boost::filesystem::path> 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<boost::filesystem::path> 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<string> 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<Film> 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<Film> 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<Content> 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<VideoContent> video;
+ BOOST_FOREACH (shared_ptr<const Content> 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<Content> 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<Content>);
void move_content_later (boost::shared_ptr<Content>);
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<Job>, boost::weak_ptr<Content>, 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<dcp::Marker, dcpomatic::DCPTime> _markers;
std::vector<dcp::Rating> _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
-Subproject 9ec245b7f59b65ad6dd6d0f717686931ff66d74
+Subproject 3b21196b894bfbc096a5e90ee11dcf5f50bd4bf