Fix non-translated days of the week (#1455).
[dcpomatic.git] / src / lib / film.cc
index 60b80d052689de056619a2dc8b967fba4f46f66b..f4745d0995597d2e17a91fee185a26d187d8f2bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -156,6 +156,7 @@ Film::Film (optional<boost::filesystem::path> dir)
        , _reel_length (2000000000)
        , _upload_after_make_dcp (Config::instance()->default_upload_after_make_dcp())
        , _reencode_j2k (false)
+       , _user_explicit_video_frame_rate (false)
        , _state_version (current_state_version)
        , _dirty (false)
 {
@@ -288,6 +289,8 @@ Film::audio_analysis_path (shared_ptr<const Playlist> playlist) const
                digester.add (audio_processor()->id ());
        }
 
+       digester.add (audio_channels());
+
        p /= digester.get ();
        return p;
 }
@@ -398,6 +401,7 @@ Film::metadata (bool with_content_paths) const
        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");
        _playlist->as_xml (root->add_child ("Playlist"), with_content_paths);
 
        return doc;
@@ -513,6 +517,7 @@ Film::read_metadata (optional<boost::filesystem::path> path)
        _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);
 
        list<string> notes;
        /* This method is the only one that can return notes (so far) */
@@ -881,11 +886,18 @@ Film::set_isdcf_metadata (ISDCFMetadata m)
        _isdcf_metadata = m;
 }
 
+/** @param f New frame rate.
+ *  @param user_explicit true if this comes from a direct user instruction, false if it is from
+ *  DCP-o-matic being helpful.
+ */
 void
-Film::set_video_frame_rate (int f)
+Film::set_video_frame_rate (int f, bool user_explicit)
 {
        ChangeSignaller<Film> ch (this, VIDEO_FRAME_RATE);
        _video_frame_rate = f;
+       if (user_explicit) {
+               _user_explicit_video_frame_rate = true;
+       }
 }
 
 void
@@ -964,7 +976,9 @@ Film::signal_change (ChangeType type, Property p)
                _dirty = true;
 
                if (p == Film::CONTENT) {
-                       set_video_frame_rate (_playlist->best_video_frame_rate ());
+                       if (!_user_explicit_video_frame_rate) {
+                               set_video_frame_rate (best_video_frame_rate());
+                       }
                }
 
                emit (boost::bind (boost::ref (Change), type, p));
@@ -1171,7 +1185,12 @@ Film::length () const
 int
 Film::best_video_frame_rate () const
 {
-       return _playlist->best_video_frame_rate ();
+       /* Don't default to anything above 30fps (make the user select that explicitly) */
+       int best = _playlist->best_video_frame_rate ();
+       if (best > 30) {
+               best /= 2;
+       }
+       return best;
 }
 
 FrameRateChange
@@ -1213,12 +1232,9 @@ Film::playlist_order_changed ()
 int
 Film::audio_frame_rate () const
 {
-       BOOST_FOREACH (shared_ptr<Content> i, content ()) {
-               if (i->audio && i->audio->has_rate_above_48k ()) {
-                       return 96000;
-               }
-       }
-
+       /* It seems that nobody makes 96kHz DCPs at the moment, so let's avoid them.
+          See #1436.
+       */
        return 48000;
 }
 
@@ -1357,8 +1373,8 @@ Film::make_kdms (
                                i->recipient.get(),
                                i->trusted_device_thumbprints(),
                                cpl_file,
-                               dcp::LocalTime (from, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()),
-                               dcp::LocalTime (until, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()),
+                               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
@@ -1383,7 +1399,7 @@ Film::required_disk_space () const
 /** This method checks the disk that the Film is on and tries to decide whether or not
  *  there will be enough space to make a DCP for it.  If so, true is returned; if not,
  *  false is returned and required and available are filled in with the amount of disk space
- *  required and available respectively (in Gb).
+ *  required and available respectively (in GB).
  *
  *  Note: the decision made by this method isn't, of course, 100% reliable.
  */
@@ -1438,55 +1454,6 @@ Film::subtitle_language () const
        return all;
 }
 
-/** Change the gains of the supplied AudioMapping to make it a default
- *  for this film.  The defaults are guessed based on what processor (if any)
- *  is in use, the number of input channels and any filename supplied.
- */
-void
-Film::make_audio_mapping_default (AudioMapping& mapping, optional<boost::filesystem::path> filename) const
-{
-       static string const regex[] = {
-               ".*[\\._-]L[\\._-].*",
-               ".*[\\._-]R[\\._-].*",
-               ".*[\\._-]C[\\._-].*",
-               ".*[\\._-]Lfe[\\._-].*",
-               ".*[\\._-]Ls[\\._-].*",
-               ".*[\\._-]Rs[\\._-].*"
-       };
-
-       static int const regexes = sizeof(regex) / sizeof(*regex);
-
-       if (audio_processor ()) {
-               audio_processor()->make_audio_mapping_default (mapping);
-       } else {
-               mapping.make_zero ();
-               if (mapping.input_channels() == 1) {
-                       bool guessed = false;
-
-                       /* See if we can guess where this stream should go */
-                       if (filename) {
-                               for (int i = 0; i < regexes; ++i) {
-                                       boost::regex e (regex[i], boost::regex::icase);
-                                       if (boost::regex_match (filename->string(), e) && i < mapping.output_channels()) {
-                                               mapping.set (0, i, 1);
-                                               guessed = true;
-                                       }
-                               }
-                       }
-
-                       if (!guessed) {
-                               /* If we have no idea, just put it on centre */
-                               mapping.set (0, static_cast<int> (dcp::CENTRE), 1);
-                       }
-               } else {
-                       /* 1:1 mapping */
-                       for (int i = 0; i < min (mapping.input_channels(), mapping.output_channels()); ++i) {
-                               mapping.set (i, i, 1);
-                       }
-               }
-       }
-}
-
 /** @return The names of the channels that audio contents' outputs are passed into;
  *  this is either the DCP or a AudioProcessor.
  */
@@ -1542,7 +1509,7 @@ Film::reels () const
                shared_ptr<Content> last_video;
                BOOST_FOREACH (shared_ptr<Content> c, content ()) {
                        if (c->video) {
-                               BOOST_FOREACH (DCPTime t, c->reel_split_points()) {
+                               BOOST_FOREACH (DCPTime t, c->reel_split_points(shared_from_this())) {
                                        if (last_split) {
                                                p.push_back (DCPTimePeriod (last_split.get(), t));
                                        }