#include "text_content.h"
#include "ffmpeg_content.h"
#include "dcp_content.h"
-#include "screen_kdm.h"
+#include "kdm_with_metadata.h"
#include "cinema.h"
#include "change_signaller.h"
#include "check_content_change_job.h"
* 36 -> 37
* TextContent can be in a Caption tag, and some of the tag names
* have had Subtitle prefixes or suffixes removed.
+ * 37 -> 38
+ * VideoContent scale expressed just as "guess" or "custom"
*/
-int const Film::current_state_version = 37;
+int const Film::current_state_version = 38;
/** Construct a Film object in a given directory.
*
, _dcp_content_type (Config::instance()->default_dcp_content_type ())
, _container (Config::instance()->default_container ())
, _resolution (RESOLUTION_2K)
- , _signed (true)
, _encrypted (false)
, _context_id (dcp::make_uuid ())
, _j2k_bandwidth (Config::instance()->default_j2k_bandwidth ())
, _audio_processor (0)
, _reel_type (REELTYPE_SINGLE)
, _reel_length (2000000000)
- , _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)
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("Signed")->add_child_text (_signed ? "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);
}
root->add_child("ReelType")->add_child_text (raw_convert<string> (static_cast<int> (_reel_type)));
root->add_child("ReelLength")->add_child_text (raw_convert<string> (_reel_length));
- root->add_child("UploadAfterMakeDCP")->add_child_text (_upload_after_make_dcp ? "1" : "0");
root->add_child("ReencodeJ2K")->add_child_text (_reencode_j2k ? "1" : "0");
root->add_child("UserExplicitVideoFrameRate")->add_child_text(_user_explicit_video_frame_rate ? "1" : "0");
for (map<dcp::Marker, DCPTime>::const_iterator i = _markers.begin(); i != _markers.end(); ++i) {
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;
_resolution = string_to_resolution (f.string_child ("Resolution"));
_j2k_bandwidth = f.number_child<int> ("J2KBandwidth");
_video_frame_rate = f.number_child<int> ("VideoFrameRate");
- _signed = f.optional_bool_child("Signed").get_value_or (true);
_encrypted = f.bool_child ("Encrypted");
_audio_channels = f.number_child<int> ("AudioChannels");
/* We used to allow odd numbers (and zero) channels, but it's just not worth
_reel_type = static_cast<ReelType> (f.optional_number_child<int>("ReelType").get_value_or (static_cast<int>(REELTYPE_SINGLE)));
_reel_length = f.optional_number_child<int64_t>("ReelLength").get_value_or (2000000000);
- _upload_after_make_dcp = f.optional_bool_child("UploadAfterMakeDCP").get_value_or (false);
_reencode_j2k = f.optional_bool_child("ReencodeJ2K").get_value_or(false);
_user_explicit_video_frame_rate = f.optional_bool_child("UserExplicitVideoFrameRate").get_value_or(false);
_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);
BOOST_FOREACH (shared_ptr<Content> i, content ()) {
if (i->video) {
/* Here's the first piece of video content */
- if (i->video->scale().ratio ()) {
- content_ratio = i->video->scale().ratio ();
- } else {
- content_ratio = Ratio::from_ratio (i->video->size().ratio ());
- }
+ content_ratio = Ratio::nearest_from_ratio(i->video->scaled_size(frame_size()).ratio());
break;
}
}
_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)
{
_reel_length = r;
}
-void
-Film::set_upload_after_make_dcp (bool u)
-{
- ChangeSignaller<Film> ch (this, UPLOAD_AFTER_MAKE_DCP);
- _upload_after_make_dcp = u;
-}
-
void
Film::set_reencode_j2k (bool r)
{
return out;
}
-void
-Film::set_signed (bool s)
-{
- ChangeSignaller<Film> ch (this, SIGNED);
- _signed = s;
-}
-
void
Film::set_encrypted (bool e)
{
_encrypted = e;
}
-void
-Film::set_key (dcp::Key key)
-{
- ChangeSignaller<Film> ch (this, KEY);
- _key = key;
-}
-
ContentList
Film::content () const
{
}
_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
).encrypt (signer, recipient, trusted_devices, formulation, disable_forensic_marking_picture, disable_forensic_marking_audio);
}
-/** @param screens Screens to make KDMs for.
- * @param cpl_file Path to CPL to make KDMs for.
- * @param from KDM from time expressed as a local time in the time zone of the Screen's Cinema.
- * @param until KDM to time expressed as a local time in the time zone of the Screen's Cinema.
- * @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.
- */
-list<shared_ptr<ScreenKDM> >
-Film::make_kdms (
- list<shared_ptr<Screen> > screens,
- boost::filesystem::path cpl_file,
- boost::posix_time::ptime from,
- boost::posix_time::ptime until,
- dcp::Formulation formulation,
- bool disable_forensic_marking_picture,
- optional<int> disable_forensic_marking_audio
- ) const
-{
- list<shared_ptr<ScreenKDM> > kdms;
-
- BOOST_FOREACH (shared_ptr<Screen> i, screens) {
- if (i->recipient) {
- dcp::EncryptedKDM const kdm = make_kdm (
- i->recipient.get(),
- i->trusted_device_thumbprints(),
- cpl_file,
- dcp::LocalTime (from, i->cinema ? i->cinema->utc_offset_hour() : 0, i->cinema ? i->cinema->utc_offset_minute() : 0),
- dcp::LocalTime (until, i->cinema ? i->cinema->utc_offset_hour() : 0, i->cinema ? i->cinema->utc_offset_minute() : 0),
- formulation,
- disable_forensic_marking_picture,
- disable_forensic_marking_audio
- );
-
- kdms.push_back (shared_ptr<ScreenKDM>(new DCPScreenKDM(i, kdm)));
- }
- }
-
- return kdms;
-}
/** @return The approximate disk space required to encode a DCP of this film with the
* current settings, in bytes.
_resolution = _template_film->_resolution;
_j2k_bandwidth = _template_film->_j2k_bandwidth;
_video_frame_rate = _template_film->_video_frame_rate;
- _signed = _template_film->_signed;
_encrypted = _template_film->_encrypted;
_audio_channels = _template_film->_audio_channels;
_sequence = _template_film->_sequence;
_audio_processor = _template_film->_audio_processor;
_reel_type = _template_film->_reel_type;
_reel_length = _template_film->_reel_length;
- _upload_after_make_dcp = _template_film->_upload_after_make_dcp;
_isdcf_metadata = _template_film->_isdcf_metadata;
}