Basic and rather clumsy option to respect KDM validity windows.
authorCarl Hetherington <cth@carlh.net>
Fri, 14 Sep 2018 20:22:33 +0000 (21:22 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 14 Sep 2018 20:22:33 +0000 (21:22 +0100)
cscript
src/lib/config.cc
src/lib/config.h
src/lib/dcp_content.cc
src/lib/dcp_content.h
src/tools/dcpomatic_player.cc
src/wx/film_viewer.cc
src/wx/film_viewer.h
src/wx/player_config_dialog.cc

diff --git a/cscript b/cscript
index 0cfc31edbf5801a46d1177b95e193cff674d4f6b..04c27781eb065b3386d63ec70426006605f6cd9d 100644 (file)
--- a/cscript
+++ b/cscript
@@ -331,8 +331,8 @@ def dependencies(target):
         # Use distro-provided FFmpeg on Arch
         deps = []
 
-    deps.append(('libdcp', '6fef005'))
-    deps.append(('libsub', '32b8463'))
+    deps.append(('libdcp', 'ee05b1c'))
+    deps.append(('libsub', '1cf5cdf'))
     deps.append(('rtaudio-cdist', '739969e'))
 
     return deps
index 30271283b27e1b2bdec84b50eba9054648b17dfc..373b71df6b447685d8e96dab628b020d7ec2fb37 100644 (file)
@@ -164,6 +164,7 @@ Config::set_defaults ()
        _gdc_password = optional<string>();
        _interface_complexity = INTERFACE_SIMPLE;
        _player_mode = PLAYER_MODE_WINDOW;
+       _respect_kdm_validity_periods = false;
 
        _allowed_dcp_frame_rates.clear ();
        _allowed_dcp_frame_rates.push_back (24);
@@ -491,6 +492,8 @@ try
                _player_mode = PLAYER_MODE_DUAL;
        }
 
+       _respect_kdm_validity_periods = f.optional_bool_child("RespectKDMValidityPeriods").get_value_or(false);
+
        /* Replace any cinemas from config.xml with those from the configured file */
        if (boost::filesystem::exists (_cinemas_file)) {
                cxml::Document f ("Cinemas");
@@ -876,6 +879,8 @@ Config::write_config () const
                break;
        }
 
+       root->add_child("RespectKDMValidityPeriods")->add_child_text(_respect_kdm_validity_periods ? "1" : "0");
+
        try {
                doc.write_to_file_formatted(config_file().string());
        } catch (xmlpp::exception& e) {
index d2829af0884bdf374b6c2c6847fd2c78862041c5..c8ae32efd7bf02de3c66c252a971044b4722df49 100644 (file)
@@ -469,6 +469,10 @@ public:
                return _player_mode;
        }
 
+       bool respect_kdm_validity_periods () const {
+               return _respect_kdm_validity_periods;
+       }
+
        /* SET (mostly) */
 
        void set_master_encoding_threads (int n) {
@@ -871,6 +875,10 @@ public:
                maybe_set (_player_mode, m);
        }
 
+       void set_respect_kdm_validity_periods (bool r) {
+               maybe_set (_respect_kdm_validity_periods, r);
+       }
+
        void changed (Property p = OTHER);
        boost::signals2::signal<void (Property)> Changed;
        /** Emitted if read() failed on an existing Config file.  There is nothing
@@ -1054,6 +1062,7 @@ private:
        boost::optional<std::string> _gdc_password;
        Interface _interface_complexity;
        PlayerMode _player_mode;
+       bool _respect_kdm_validity_periods;
 
        static int const _current_version;
 
index a2874a6044811a0524e3f8adf6fd080420443ca1..3498cc96119940bbd2a25a4546c0c1fc0bc56662 100644 (file)
@@ -657,3 +657,14 @@ DCPContent::set_cpl (string id)
                _cpl = id;
        }
 }
+
+bool
+DCPContent::kdm_timing_window_valid () const
+{
+       if (!_kdm) {
+               return true;
+       }
+
+       dcp::LocalTime now;
+       return _kdm->not_valid_before() < now && now < _kdm->not_valid_after();
+}
index 43476e729c7f8ca3495bb26dcde21988b96dc4e5..db617afa2c52f8d8e53faf9cbeb6308a46f47fd9 100644 (file)
@@ -138,6 +138,8 @@ public:
                return _three_d;
        }
 
+       bool kdm_timing_window_valid () const;
+
 private:
        friend class reels_test5;
 
index 10b75b03dae170f85527fd511a9b632df94f0160..53947527f8dd0cd14dc7e6ed0581b07f47633b16 100644 (file)
@@ -162,6 +162,7 @@ public:
                _viewer.reset (new FilmViewer (_overall_panel));
                _controls = new Controls (_overall_panel, _viewer);
                _viewer->set_dcp_decode_reduction (Config::instance()->decode_reduction ());
+               _viewer->PlaybackPermitted.connect (bind(&DOMFrame::playback_permitted, this));
                _info = new PlayerInformation (_overall_panel, _viewer);
                wxSizer* main_sizer = new wxBoxSizer (wxVERTICAL);
                main_sizer->Add (_viewer->panel(), 1, wxEXPAND);
@@ -197,6 +198,27 @@ public:
                setup_screen ();
        }
 
+       bool playback_permitted ()
+       {
+               if (!_film || !Config::instance()->respect_kdm_validity_periods()) {
+                       return true;
+               }
+
+               bool ok = true;
+               BOOST_FOREACH (shared_ptr<Content> i, _film->content()) {
+                       shared_ptr<DCPContent> d = dynamic_pointer_cast<DCPContent>(i);
+                       if (d && !d->kdm_timing_window_valid()) {
+                               ok = false;
+                       }
+               }
+
+               if (!ok) {
+                       error_dialog (this, _("The KDM does not allow playback of this content at this time."));
+               }
+
+               return ok;
+       }
+
        void set_decode_reduction (optional<int> reduction)
        {
                _viewer->set_dcp_decode_reduction (reduction);
index c062524e93fce32db1d51a4a1de90a66d4e1fa4f..d45da20213c3da6197a6adff0bf0df2f129ea51b 100644 (file)
@@ -406,6 +406,12 @@ FilmViewer::start ()
                return;
        }
 
+       optional<bool> v = PlaybackPermitted ();
+       if (v && !*v) {
+               /* Computer says no */
+               return;
+       }
+
        if (_audio.isStreamOpen()) {
                _audio.setStreamTime (_video_position.seconds());
                _audio.startStream ();
index 029ec0323eb75846a52cf7c764fcf8c2814fb42f..0e44994de565092c9aec2b155762b242aef683b3 100644 (file)
@@ -93,6 +93,8 @@ public:
        boost::signals2::signal<void ()> Stopped;
        boost::signals2::signal<void ()> FilmChanged;
 
+       boost::signals2::signal<bool ()> PlaybackPermitted;
+
 private:
        void paint_panel ();
        void panel_sized (wxSizeEvent &);
index 258db9a5734b61ed0fa87016673cf0103569320f..c84c8b2129c60d6d461b1566e1a0f744a5b0e679 100644 (file)
@@ -94,7 +94,12 @@ private:
                table->Add (_player_mode, wxGBPosition(r, 1));
                ++r;
 
+               _respect_kdm = new wxCheckBox (_panel, wxID_ANY, _("Respect KDM validity periods"));
+               table->Add (_respect_kdm, wxGBPosition(r, 0), wxGBSpan(1, 2));
+               ++r;
+
                _player_mode->Bind (wxEVT_CHOICE, bind(&PlayerGeneralPage::player_mode_changed, this));
+               _respect_kdm->Bind (wxEVT_CHECKBOX, bind(&PlayerGeneralPage::respect_kdm_changed, this));
        }
 
        void config_changed ()
@@ -112,6 +117,8 @@ private:
                        checked_set (_player_mode, 2);
                        break;
                }
+
+               checked_set (_respect_kdm, Config::instance()->respect_kdm_validity_periods());
        }
 
 private:
@@ -130,7 +137,13 @@ private:
                }
        }
 
+       void respect_kdm_changed ()
+       {
+               Config::instance()->set_respect_kdm_validity_periods(_respect_kdm->GetValue());
+       }
+
        wxChoice* _player_mode;
+       wxCheckBox* _respect_kdm;
 };
 
 wxPreferencesEditor*