From: Carl Hetherington Date: Sun, 15 Mar 2020 23:44:31 +0000 (+0100) Subject: Move stress testing code into a separate class and always build it. X-Git-Tag: v2.15.48~5 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=19760ad4cf6d348416444e515b5e709be565f81e Move stress testing code into a separate class and always build it. Fix stress script generation to always reload a DCP rather than expecting it to be available after it has finished playback. --- diff --git a/hacks/stress.py b/hacks/stress.py index 4e20fa236..34fe17b07 100644 --- a/hacks/stress.py +++ b/hacks/stress.py @@ -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) diff --git a/src/tools/dcpomatic_player.cc b/src/tools/dcpomatic_player.cc index bbbbe3a1d..8ee657261 100644 --- a/src/tools/dcpomatic_player.cc +++ b/src/tools/dcpomatic_player.cc @@ -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 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(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(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 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(); - ++_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 dcp (new DCPContent(dir)); shared_ptr job (new ExamineContentJob(_film, dcp)); _examine_job_connection = job->Finished.connect(bind(&DOMFrame::add_dcp_to_film, this, weak_ptr(job), weak_ptr(dcp))); @@ -538,7 +418,7 @@ public: } _film->add_content (content); - _stress_suspended = false; + _stress.set_suspended (false); } void reset_film_weak (weak_ptr 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 _commands; - list::const_iterator _current_command; - /** Remaining time that the script must wait, in milliseconds */ - optional _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 _stress; -#endif }; IMPLEMENT_APP (App) diff --git a/src/wx/controls.cc b/src/wx/controls.cc index 27139f1f5..92103637c 100644 --- a/src/wx/controls.cc +++ b/src/wx/controls.cc @@ -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 diff --git a/src/wx/controls.h b/src/wx/controls.h index c11d6e8e3..b9c4604b6 100644 --- a/src/wx/controls.h +++ b/src/wx/controls.h @@ -52,11 +52,11 @@ public: virtual void log (wxString) {} virtual void set_film (boost::shared_ptr film); -#ifdef DCPOMATIC_PLAYER_STRESS_TEST + virtual void play () {}; virtual void stop () {}; void seek (int slider); -#endif + boost::shared_ptr 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 index 000000000..c0e6e8443 --- /dev/null +++ b/src/wx/player_stress_tester.cc @@ -0,0 +1,161 @@ +/* + Copyright (C) 2017-2020 Carl Hetherington + + 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 . + +*/ + +#include "player_stress_tester.h" +#include "controls.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 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(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(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 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(); + ++_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 index 000000000..40686bc24 --- /dev/null +++ b/src/wx/player_stress_tester.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2017-2020 Carl Hetherington + + 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 . + +*/ + +#include +#include +#include + +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 LoadDCP; + +private: + void check_commands (); + + wxWindow* _parent; + Controls* _controls; + wxTimer _timer; + bool _suspended; + std::list _commands; + std::list::const_iterator _current_command; + /** Remaining time that the script must wait, in milliseconds */ + boost::optional _wait_remaining; +}; + diff --git a/src/wx/playlist_controls.cc b/src/wx/playlist_controls.cc index edc4485e6..72ec7ad1f 100644 --- a/src/wx/playlist_controls.cc +++ b/src/wx/playlist_controls.cc @@ -52,7 +52,6 @@ PlaylistControls::PlaylistControls (wxWindow* parent, shared_ptr 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 diff --git a/src/wx/playlist_controls.h b/src/wx/playlist_controls.h index 460924217..4f144834a 100644 --- a/src/wx/playlist_controls.h +++ b/src/wx/playlist_controls.h @@ -37,10 +37,8 @@ public: */ boost::signals2::signal)> ResetFilm; -#ifdef DCPOMATIC_PLAYER_STRESS_TEST void play (); void stop (); -#endif private: void play_clicked (); @@ -81,6 +79,4 @@ private: std::vector _playlists; boost::optional _selected_playlist; int _selected_playlist_position; - - wxTimer _timer; }; diff --git a/src/wx/standard_controls.cc b/src/wx/standard_controls.cc index e9a31c86b..5df89f8fe 100644 --- a/src/wx/standard_controls.cc +++ b/src/wx/standard_controls.cc @@ -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 diff --git a/src/wx/standard_controls.h b/src/wx/standard_controls.h index f79e4a178..143624126 100644 --- a/src/wx/standard_controls.h +++ b/src/wx/standard_controls.h @@ -25,10 +25,8 @@ class StandardControls : public Controls public: StandardControls (wxWindow* parent, boost::shared_ptr viewer, bool editor_controls); -#ifdef DCPOMATIC_PLAYER_STRESS_TEST void play (); void stop (); -#endif private: void check_play_state (); diff --git a/src/wx/wscript b/src/wx/wscript index 2685ba8b4..66c88f8d0 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -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 c61b86782..fe1431316 100644 --- 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')