Move stress testing code into a separate class and always build it.
authorCarl Hetherington <cth@carlh.net>
Sun, 15 Mar 2020 23:44:31 +0000 (00:44 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 15 Mar 2020 23:46:34 +0000 (00:46 +0100)
Fix stress script generation to always reload a DCP rather than
expecting it to be available after it has finished playback.

12 files changed:
hacks/stress.py
src/tools/dcpomatic_player.cc
src/wx/controls.cc
src/wx/controls.h
src/wx/player_stress_tester.cc [new file with mode: 0644]
src/wx/player_stress_tester.h [new file with mode: 0644]
src/wx/playlist_controls.cc
src/wx/playlist_controls.h
src/wx/standard_controls.cc
src/wx/standard_controls.h
src/wx/wscript
wscript

index 4e20fa2..34fe17b 100644 (file)
@@ -22,12 +22,11 @@ def make_repeated_play(dcp, output, plays):
     # Hackily ignore frames here
     length = int(length_parts[0]) * 3600 + int(length_parts[1]) * 60 + int(length_parts[2])
     with open(output, 'w') as f:
-        print("O %s" % dcp, file=f)
         for i in range(0, plays):
+            print("O %s" % dcp, file=f)
             print("P", file=f)
             print("W %d" % (length * 1000), file=f)
             print("S", file=f)
-            print("K 0", file=f)
 
 make_seeks("/home/carl/DCP/Examples/BohemianRhapsody_TLR-7_S_DE-XX_DE_51_2K_TCFG_20180514_TM_IOP_OV/", "boho_seek", 64)
 make_repeated_play("/home/carl/DCP/Examples/BohemianRhapsody_TLR-7_S_DE-XX_DE_51_2K_TCFG_20180514_TM_IOP_OV/", "boho_long", 1000)
index bbbbe3a..8ee6572 100644 (file)
@@ -34,6 +34,7 @@
 #endif
 #include "wx/timer_display.h"
 #include "wx/system_information_dialog.h"
+#include "wx/player_stress_tester.h"
 #include "lib/cross.h"
 #include "lib/config.h"
 #include "lib/util.h"
@@ -100,59 +101,6 @@ using boost::bind;
 using dcp::raw_convert;
 using namespace dcpomatic;
 
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
-/* Interval to check what to do next with the stress checker, in milliseconds */
-#define STRESS_TEST_CHECK_INTERVAL 20
-
-class Command
-{
-public:
-       enum Type {
-               NONE,
-               OPEN,
-               PLAY,
-               WAIT,
-               STOP,
-               SEEK,
-       };
-
-       Command(string line)
-               : type (NONE)
-               , int_param (0)
-       {
-               vector<string> bits;
-               boost::split (bits, line, boost::is_any_of(" "));
-               if (bits[0] == "O") {
-                       if (bits.size() != 2) {
-                               return;
-                       }
-                       type = OPEN;
-                       string_param = bits[1];
-               } else if (bits[0] == "P") {
-                       type = PLAY;
-               } else if (bits[0] == "W") {
-                       if (bits.size() != 2) {
-                               return;
-                       }
-                       type = WAIT;
-                       int_param = raw_convert<int>(bits[1]);
-               } else if (bits[0] == "S") {
-                       type = STOP;
-               } else if (bits[0] == "K") {
-                       if (bits.size() != 2) {
-                               return;
-                       }
-                       type = SEEK;
-                       int_param = raw_convert<int>(bits[1]);
-               }
-       }
-
-       Type type;
-       string string_param;
-       int int_param;
-};
-#endif
-
 enum {
        ID_file_open = 1,
        ID_file_add_ov,
@@ -197,10 +145,6 @@ public:
                , _system_information_dialog (0)
                , _view_full_screen (0)
                , _view_dual_screen (0)
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
-               , _timer (this)
-               , _stress_suspended (false)
-#endif
 {
                dcpomatic_log.reset (new NullLog());
 
@@ -273,6 +217,8 @@ public:
                int accelerators = 3;
 #endif
 
+               _stress.setup (this, _controls);
+
                wxAcceleratorEntry* accel = new wxAcceleratorEntry[accelerators];
                accel[0].Set(wxACCEL_NORMAL, WXK_SPACE, ID_start_stop);
                accel[1].Set(wxACCEL_NORMAL, WXK_LEFT, ID_back_frame);
@@ -299,79 +245,13 @@ public:
 #endif
                setup_screen ();
 
+               _stress.LoadDCP.connect (boost::bind(&DOMFrame::load_dcp, this, _1));
+
 #ifdef DCPOMATIC_VARIANT_SWAROOP
                sc->check_restart ();
 #endif
        }
 
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
-       void stress (boost::filesystem::path script_file)
-       {
-               Bind (wxEVT_TIMER, boost::bind(&DOMFrame::check_commands, this));
-               _timer.Start(STRESS_TEST_CHECK_INTERVAL);
-               vector<string> lines;
-               string const script = dcp::file_to_string(script_file);
-               boost::split (lines, script, boost::is_any_of("\n"));
-               BOOST_FOREACH (string i, lines) {
-                       _commands.push_back (Command(i));
-               }
-               _current_command = _commands.begin();
-       }
-
-       void check_commands ()
-       {
-               if (_stress_suspended) {
-                       return;
-               }
-
-               if (_current_command == _commands.end()) {
-                       _timer.Stop ();
-                       cout << "ST: finished.\n";
-                       return;
-               }
-
-               switch (_current_command->type) {
-                       case Command::OPEN:
-                               load_dcp (_current_command->string_param);
-                               ++_current_command;
-                               break;
-                       case Command::PLAY:
-                               cout << "ST: play\n";
-                               _controls->play ();
-                               ++_current_command;
-                               break;
-                       case Command::WAIT:
-                               /* int_param here is the number of milliseconds to wait */
-                               if (_wait_remaining) {
-                                       _wait_remaining = *_wait_remaining - STRESS_TEST_CHECK_INTERVAL;
-                                       if (_wait_remaining < 0) {
-                                               cout << "ST: wait done.\n";
-                                               _wait_remaining = optional<int>();
-                                               ++_current_command;
-                                       }
-                               } else {
-                                       _wait_remaining = _current_command->int_param;
-                                       cout << "ST: waiting for " << *_wait_remaining << ".\n";
-                               }
-                               break;
-                       case Command::STOP:
-                               cout << "ST: stop\n";
-                               _controls->stop ();
-                               ++_current_command;
-                               break;
-                       case Command::NONE:
-                               ++_current_command;
-                               break;
-                       case Command::SEEK:
-                               /* int_param here is a number between 0 and 4095, corresponding to the possible slider positions */
-                               cout << "ST: seek to " << _current_command->int_param << "\n";
-                               _controls->seek (_current_command->int_param);
-                               ++_current_command;
-                               break;
-               }
-       }
-#endif
-
 #ifdef DCPOMATIC_VARIANT_SWAROOP
        void monitor_checker_state_changed ()
        {
@@ -508,7 +388,7 @@ public:
 
                reset_film ();
                try {
-                       _stress_suspended = true;
+                       _stress.set_suspended (true);
                        shared_ptr<DCPContent> dcp (new DCPContent(dir));
                        shared_ptr<Job> job (new ExamineContentJob(_film, dcp));
                        _examine_job_connection = job->Finished.connect(bind(&DOMFrame::add_dcp_to_film, this, weak_ptr<Job>(job), weak_ptr<Content>(dcp)));
@@ -538,7 +418,7 @@ public:
                }
 
                _film->add_content (content);
-               _stress_suspended = false;
+               _stress.set_suspended (false);
        }
 
        void reset_film_weak (weak_ptr<Film> weak_film)
@@ -622,6 +502,11 @@ public:
                }
        }
 
+       void load_stress_script (boost::filesystem::path path)
+       {
+               _stress.load_script (path);
+       }
+
 private:
 
        bool report_errors_from_last_job (wxWindow* parent) const
@@ -1135,8 +1020,6 @@ private:
                _viewer->seek_by (_viewer->one_video_frame(), true);
        }
 
-private:
-
        wxFrame* _dual_screen;
        bool _update_news_requested;
        PlayerInformation* _info;
@@ -1160,22 +1043,13 @@ private:
        wxMenuItem* _tools_verify;
        wxMenuItem* _view_full_screen;
        wxMenuItem* _view_dual_screen;
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
-       wxTimer _timer;
-       list<Command> _commands;
-       list<Command>::const_iterator _current_command;
-       /** Remaining time that the script must wait, in milliseconds */
-       optional<int> _wait_remaining;
-       bool _stress_suspended;
-#endif
+       PlayerStressTester _stress;
 };
 
 static const wxCmdLineEntryDesc command_line_description[] = {
        { wxCMD_LINE_PARAM, 0, 0, "DCP to load or create", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
        { wxCMD_LINE_OPTION, "c", "config", "Directory containing config.xml", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
        { wxCMD_LINE_OPTION, "s", "stress", "File containing description of stress test", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
-#endif
        { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 }
 };
 
@@ -1291,15 +1165,13 @@ private:
                                }
                        }
 
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
                        if (_stress) {
                                try {
-                                       _frame->stress (_stress.get());
+                                       _frame->load_stress_script (*_stress);
                                } catch (exception& e) {
                                        error_dialog (0, wxString::Format("Could not load stress test file %s", std_to_wx(*_stress)));
                                }
                        }
-#endif
 
                        Bind (wxEVT_IDLE, boost::bind (&App::idle, this));
 
@@ -1334,12 +1206,10 @@ private:
                if (parser.Found("c", &config)) {
                        Config::override_path = wx_to_std (config);
                }
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
                wxString stress;
                if (parser.Found("s", &stress)) {
                        _stress = wx_to_std (stress);
                }
-#endif
 
                return true;
        }
@@ -1400,9 +1270,7 @@ private:
 
        DOMFrame* _frame;
        string _dcp_to_load;
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
        boost::optional<string> _stress;
-#endif
 };
 
 IMPLEMENT_APP (App)
index 27139f1..9210363 100644 (file)
@@ -407,7 +407,6 @@ Controls::film_change (ChangeType type, Film::Property p)
        }
 }
 
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
 void
 Controls::seek (int slider)
 {
@@ -415,4 +414,3 @@ Controls::seek (int slider)
        slider_moved (false);
        slider_released ();
 }
-#endif
index c11d6e8..b9c4604 100644 (file)
@@ -52,11 +52,11 @@ public:
 
        virtual void log (wxString) {}
        virtual void set_film (boost::shared_ptr<Film> film);
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
+
        virtual void play () {};
        virtual void stop () {};
        void seek (int slider);
-#endif
+
        boost::shared_ptr<Film> film () const;
        void back_frame ();
        void forward_frame ();
diff --git a/src/wx/player_stress_tester.cc b/src/wx/player_stress_tester.cc
new file mode 100644 (file)
index 0000000..c0e6e84
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+    Copyright (C) 2017-2020 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "player_stress_tester.h"
+#include "controls.h"
+#include <dcp/raw_convert.h>
+#include <dcp/util.h>
+#include <wx/wx.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <string>
+#include <vector>
+#include <iostream>
+
+using std::string;
+using std::vector;
+using std::cout;
+using dcp::raw_convert;
+using boost::optional;
+
+/* Interval to check for things to do with the stress script (in milliseconds) */
+#define CHECK_INTERVAL 20
+
+Command::Command (string line)
+       : type (NONE)
+       , int_param (0)
+{
+       vector<string> bits;
+       boost::split (bits, line, boost::is_any_of(" "));
+       if (bits[0] == "O") {
+               if (bits.size() != 2) {
+                       return;
+               }
+               type = OPEN;
+               string_param = bits[1];
+       } else if (bits[0] == "P") {
+               type = PLAY;
+       } else if (bits[0] == "W") {
+               if (bits.size() != 2) {
+                       return;
+               }
+               type = WAIT;
+               int_param = raw_convert<int>(bits[1]);
+       } else if (bits[0] == "S") {
+               type = STOP;
+       } else if (bits[0] == "K") {
+               if (bits.size() != 2) {
+                       return;
+               }
+               type = SEEK;
+               int_param = raw_convert<int>(bits[1]);
+       }
+}
+
+PlayerStressTester::PlayerStressTester ()
+       : _parent (0)
+       , _controls (0)
+       , _suspended (false)
+{
+
+}
+
+
+void
+PlayerStressTester::setup (wxWindow* parent, Controls* controls)
+{
+       _parent = parent;
+       _controls = controls;
+}
+
+
+void
+PlayerStressTester::load_script (boost::filesystem::path file)
+{
+       DCPOMATIC_ASSERT (_parent);
+
+       _timer.Bind (wxEVT_TIMER, boost::bind(&PlayerStressTester::check_commands, this));
+       _timer.Start (CHECK_INTERVAL);
+       vector<string> lines;
+       string const script = dcp::file_to_string(file);
+       boost::split (lines, script, boost::is_any_of("\n"));
+       BOOST_FOREACH (string i, lines) {
+               _commands.push_back (Command(i));
+       }
+       _current_command = _commands.begin();
+}
+
+void
+PlayerStressTester::check_commands ()
+{
+       DCPOMATIC_ASSERT (_controls);
+
+       if (_suspended) {
+               return;
+       }
+
+       if (_current_command == _commands.end()) {
+               _timer.Stop ();
+               cout << "ST: finished.\n";
+               return;
+       }
+
+       switch (_current_command->type) {
+               case Command::OPEN:
+                       LoadDCP(_current_command->string_param);
+                       ++_current_command;
+                       break;
+               case Command::PLAY:
+                       cout << "ST: play\n";
+                       _controls->play ();
+                       ++_current_command;
+                       break;
+               case Command::WAIT:
+                       /* int_param here is the number of milliseconds to wait */
+                       if (_wait_remaining) {
+                               _wait_remaining = *_wait_remaining - CHECK_INTERVAL;
+                               if (_wait_remaining < 0) {
+                                       cout << "ST: wait done.\n";
+                                       _wait_remaining = optional<int>();
+                                       ++_current_command;
+                               }
+                       } else {
+                               _wait_remaining = _current_command->int_param;
+                               cout << "ST: waiting for " << *_wait_remaining << ".\n";
+                       }
+                       break;
+               case Command::STOP:
+                       cout << "ST: stop\n";
+                       _controls->stop ();
+                       ++_current_command;
+                       break;
+               case Command::NONE:
+                       ++_current_command;
+                       break;
+               case Command::SEEK:
+                       /* int_param here is a number between 0 and 4095, corresponding to the possible slider positions */
+                       cout << "ST: seek to " << _current_command->int_param << "\n";
+                       _controls->seek (_current_command->int_param);
+                       ++_current_command;
+                       break;
+       }
+}
+
diff --git a/src/wx/player_stress_tester.h b/src/wx/player_stress_tester.h
new file mode 100644 (file)
index 0000000..40686bc
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+    Copyright (C) 2017-2020 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <wx/wx.h>
+#include <boost/signals2.hpp>
+#include <boost/filesystem.hpp>
+
+class wxWindow;
+class Controls;
+
+class Command
+{
+public:
+       enum Type {
+               NONE,
+               OPEN,
+               PLAY,
+               WAIT,
+               STOP,
+               SEEK,
+       };
+
+       Command(std::string line);
+
+       Type type;
+       std::string string_param;
+       int int_param;
+};
+
+class PlayerStressTester
+{
+public:
+       PlayerStressTester ();
+
+       void setup (wxWindow* parent, Controls* controls);
+       void load_script (boost::filesystem::path file);
+       void set_suspended (bool s) {
+               _suspended = s;
+       }
+
+       boost::signals2::signal<void (boost::filesystem::path)> LoadDCP;
+
+private:
+       void check_commands ();
+
+       wxWindow* _parent;
+       Controls* _controls;
+       wxTimer _timer;
+       bool _suspended;
+       std::list<Command> _commands;
+       std::list<Command>::const_iterator _current_command;
+       /** Remaining time that the script must wait, in milliseconds */
+       boost::optional<int> _wait_remaining;
+};
+
index edc4485..72ec7ad 100644 (file)
@@ -52,7 +52,6 @@ PlaylistControls::PlaylistControls (wxWindow* parent, shared_ptr<FilmViewer> vie
        , _stop_button (new Button(this, _("Stop")))
        , _next_button (new Button(this, "Next"))
        , _previous_button (new Button(this, "Previous"))
-       , _timer (this)
 {
        _button_sizer->Add (_previous_button, 0, wxEXPAND);
        _button_sizer->Add (_play_button, 0, wxEXPAND);
@@ -455,7 +454,6 @@ PlaylistControls::viewer_finished ()
        }
 }
 
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
 void
 PlaylistControls::play ()
 {
@@ -467,4 +465,3 @@ PlaylistControls::stop ()
 {
        stop_clicked ();
 }
-#endif
index 4609242..4f14483 100644 (file)
@@ -37,10 +37,8 @@ public:
        */
        boost::signals2::signal<void (boost::weak_ptr<Film>)> ResetFilm;
 
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
        void play ();
        void stop ();
-#endif
 
 private:
        void play_clicked ();
@@ -81,6 +79,4 @@ private:
        std::vector<SPL> _playlists;
        boost::optional<int> _selected_playlist;
        int _selected_playlist_position;
-
-       wxTimer _timer;
 };
index e9a31c8..5df89f8 100644 (file)
@@ -75,7 +75,6 @@ StandardControls::setup_sensitivity ()
        _play_button->Enable (_film && !_film->content().empty() && !active_job);
 }
 
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
 void
 StandardControls::play ()
 {
@@ -89,4 +88,3 @@ StandardControls::stop ()
        _play_button->SetValue (false);
        play_clicked ();
 }
-#endif
index f79e4a1..1436241 100644 (file)
@@ -25,10 +25,8 @@ class StandardControls : public Controls
 public:
        StandardControls (wxWindow* parent, boost::shared_ptr<FilmViewer> viewer, bool editor_controls);
 
-#ifdef DCPOMATIC_PLAYER_STRESS_TEST
        void play ();
        void stop ();
-#endif
 
 private:
        void check_play_state ();
index 2685ba8..66c88f8 100644 (file)
@@ -100,6 +100,7 @@ sources = """
           password_entry.cc
           player_config_dialog.cc
           player_information.cc
+          player_stress_tester.cc
           playhead_to_timecode_dialog.cc
           playhead_to_frame_dialog.cc
           playlist_controls.cc
diff --git a/wscript b/wscript
index c61b867..fe14313 100644 (file)
--- a/wscript
+++ b/wscript
@@ -73,7 +73,6 @@ def options(opt):
     opt.add_option('--workaround-gssapi', action='store_true', default=False, help='link to gssapi_krb5')
     opt.add_option('--force-cpp11',       action='store_true', default=False, help='force use of C++11')
     opt.add_option('--variant',           help='build variant (swaroop-studio, swaroop-theater)', choices=['swaroop-studio', 'swaroop-theater'])
-    opt.add_option('--enable-player-stress-test', action='store_true', default=False, help='build the player with stress testing enabled') 
     opt.add_option('--use-lld',           action='store_true', default=False, help='use lld linker')
 
 def configure(conf):
@@ -134,9 +133,6 @@ def configure(conf):
         if conf.options.variant.startswith('swaroop-'):
             conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_VARIANT_SWAROOP')
 
-    if conf.options.enable_player_stress_test:
-        conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_PLAYER_STRESS_TEST')
-
     if conf.options.use_lld:
         try:
             conf.find_program('ld.lld')