Suggest that DCP rates <= 30 are used unless the user explictly goes higher (#1441).
authorCarl Hetherington <cth@carlh.net>
Sat, 26 Jan 2019 22:44:08 +0000 (22:44 +0000)
committerCarl Hetherington <cth@carlh.net>
Sat, 26 Jan 2019 22:44:08 +0000 (22:44 +0000)
src/lib/film.cc
src/lib/film.h
src/lib/playlist.cc
src/wx/dcp_panel.cc

index 28734328be5b25874dd6fc83887a19a46c2ff434..f4745d0995597d2e17a91fee185a26d187d8f2bf 100644 (file)
@@ -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)
 {
@@ -400,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;
@@ -515,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) */
@@ -883,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
@@ -966,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));
@@ -1173,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
index 3fb24af934e5c999f84b4d49d55e1427b85c9808..7fdd4d269eaa8c679002a13bdb3f81c4a8cc743b 100644 (file)
@@ -316,7 +316,7 @@ public:
        void set_key (dcp::Key key);
        void set_j2k_bandwidth (int);
        void set_isdcf_metadata (ISDCFMetadata);
-       void set_video_frame_rate (int);
+       void set_video_frame_rate (int rate, bool user_explicit = false);
        void set_audio_channels (int);
        void set_three_d (bool);
        void set_isdcf_date_today ();
@@ -401,6 +401,8 @@ private:
        int64_t _reel_length;
        bool _upload_after_make_dcp;
        bool _reencode_j2k;
+       /** true if the user has ever explicitly set the video frame rate of this film */
+       bool _user_explicit_video_frame_rate;
 
        int _state_version;
 
@@ -409,6 +411,7 @@ private:
        /** film being used as a template, or 0 */
        boost::shared_ptr<Film> _template_film;
 
+
        boost::signals2::scoped_connection _playlist_change_connection;
        boost::signals2::scoped_connection _playlist_order_changed_connection;
        boost::signals2::scoped_connection _playlist_content_change_connection;
index f530d2ee3826d5eead2b4c1b061f96184b7118be..a6b633f2cfaaac64d06eba62730759574ac65ac7 100644 (file)
@@ -318,6 +318,7 @@ public:
        int dcp;
 };
 
+/** @return the best frame rate from Config::_allowed_dcp_frame_rates for the content in this list */
 int
 Playlist::best_video_frame_rate () const
 {
@@ -327,14 +328,14 @@ Playlist::best_video_frame_rate () const
        list<FrameRateCandidate> candidates;
 
        /* Start with the ones without skip / repeat so they will get matched in preference to skipped/repeated ones */
-       for (list<int>::const_iterator i = allowed_dcp_frame_rates.begin(); i != allowed_dcp_frame_rates.end(); ++i) {
-               candidates.push_back (FrameRateCandidate (*i, *i));
+       BOOST_FOREACH (int i, allowed_dcp_frame_rates) {
+               candidates.push_back (FrameRateCandidate(i, i));
        }
 
        /* Then the skip/repeat ones */
-       for (list<int>::const_iterator i = allowed_dcp_frame_rates.begin(); i != allowed_dcp_frame_rates.end(); ++i) {
-               candidates.push_back (FrameRateCandidate (float (*i) / 2, *i));
-               candidates.push_back (FrameRateCandidate (float (*i) * 2, *i));
+       BOOST_FOREACH (int i, allowed_dcp_frame_rates) {
+               candidates.push_back (FrameRateCandidate (float(i) / 2, i));
+               candidates.push_back (FrameRateCandidate (float(i) * 2, i));
        }
 
        /* Pick the best one */
index 5ebd0989d89801e4381011df6646955467060108..3defe75e4822b938f5dac5d6b40699fc54e2e937 100644 (file)
@@ -307,9 +307,10 @@ DCPPanel::frame_rate_choice_changed ()
        }
 
        _film->set_video_frame_rate (
-               boost::lexical_cast<int> (
-                       wx_to_std (_frame_rate_choice->GetString (_frame_rate_choice->GetSelection ()))
-                       )
+               boost::lexical_cast<int>(
+                       wx_to_std(_frame_rate_choice->GetString(_frame_rate_choice->GetSelection()))
+                       ),
+               true
                );
 }