summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2020-01-08 22:22:01 +0100
committerCarl Hetherington <cth@carlh.net>2020-01-08 22:22:01 +0100
commit579d18cb7770efe2da03afaf6a33faaf624119e3 (patch)
treecc303d8c74e64fff8eb5a663941cac4455154ae9 /src/tools
parentdde431cafbb20ed3356ad5592be56af1d4458f46 (diff)
parent23590dc430e4ef2351209e30a26ba04fecca2872 (diff)
Merge a set of changes which run the OpenGL video updates in a separatev2.15.40
thread, hopefully making things more elegant and robust.
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/dcpomatic.cc9
-rw-r--r--src/tools/dcpomatic_player.cc160
-rwxr-xr-xsrc/tools/stress57
-rw-r--r--src/tools/wscript2
4 files changed, 225 insertions, 3 deletions
diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc
index 68bf20732..47851a218 100644
--- a/src/tools/dcpomatic.cc
+++ b/src/tools/dcpomatic.cc
@@ -92,6 +92,9 @@
#include <wx/preferences.h>
#include <wx/splash.h>
#include <wx/wxhtml.h>
+#ifdef __WXGTK__
+#include <X11/Xlib.h>
+#endif
#ifdef __WXMSW__
#include <shellapi.h>
#endif
@@ -1503,7 +1506,11 @@ public:
: wxApp ()
, _frame (0)
, _splash (0)
- {}
+ {
+#ifdef DCPOMATIC_LINUX
+ XInitThreads ();
+#endif
+ }
private:
diff --git a/src/tools/dcpomatic_player.cc b/src/tools/dcpomatic_player.cc
index f68d0ead2..328093d8a 100644
--- a/src/tools/dcpomatic_player.cc
+++ b/src/tools/dcpomatic_player.cc
@@ -66,10 +66,14 @@
#include <wx/preferences.h>
#include <wx/progdlg.h>
#include <wx/display.h>
+#ifdef __WXGTK__
+#include <X11/Xlib.h>
+#endif
#ifdef __WXOSX__
#include <ApplicationServices/ApplicationServices.h>
#endif
#include <boost/bind.hpp>
+#include <boost/algorithm/string.hpp>
#include <iostream>
#ifdef check
@@ -90,8 +94,61 @@ using boost::optional;
using boost::dynamic_pointer_cast;
using boost::thread;
using boost::bind;
+using dcp::raw_convert;
using namespace dcpomatic;
+#ifdef DCPOMATIC_PLAYER_STRESS_TEST
+#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,
@@ -136,7 +193,10 @@ public:
, _system_information_dialog (0)
, _view_full_screen (0)
, _view_dual_screen (0)
- {
+#ifdef DCPOMATIC_PLAYER_STRESS_TEST
+ , _timer (this)
+#endif
+{
dcpomatic_log.reset (new NullLog());
#if defined(DCPOMATIC_WINDOWS)
@@ -233,6 +293,70 @@ public:
#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 (_current_command == _commands.end()) {
+ _timer.Stop ();
+ cout << "ST: finished.\n";
+ return;
+ }
+
+ switch (_current_command->type) {
+ case Command::OPEN:
+ cout << "ST: load " << _current_command->string_param << "\n";
+ load_dcp (_current_command->string_param);
+ ++_current_command;
+ break;
+ case Command::PLAY:
+ cout << "ST: play\n";
+ _controls->play ();
+ ++_current_command;
+ break;
+ case Command::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 ()
{
@@ -1001,11 +1125,20 @@ 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;
+ optional<int> _wait_remaining;
+#endif
};
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 }
};
@@ -1044,7 +1177,11 @@ public:
App ()
: wxApp ()
, _frame (0)
- {}
+ {
+#ifdef DCPOMATIC_LINUX
+ XInitThreads ();
+#endif
+ }
private:
@@ -1117,6 +1254,16 @@ private:
}
}
+#ifdef DCPOMATIC_PLAYER_STRESS_TEST
+ if (_stress) {
+ try {
+ _frame->stress (_stress.get());
+ } 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));
if (Config::instance()->check_for_updates ()) {
@@ -1150,6 +1297,12 @@ 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;
}
@@ -1210,6 +1363,9 @@ private:
DOMFrame* _frame;
string _dcp_to_load;
+#ifdef DCPOMATIC_PLAYER_STRESS_TEST
+ boost::optional<string> _stress;
+#endif
};
IMPLEMENT_APP (App)
diff --git a/src/tools/stress b/src/tools/stress
new file mode 100755
index 000000000..f861753e6
--- /dev/null
+++ b/src/tools/stress
@@ -0,0 +1,57 @@
+#!/usr/bin/python3.7
+
+import argparse
+import subprocess
+import sys
+import random
+
+def hms_to_seconds(h):
+ s = h.split(':')
+ assert(1 <= len(s) and len(s) <= 3)
+ if len(s) == 1:
+ return int(h)
+ elif len(s) == 2:
+ return int(s[0]) * 60 + int(s[1])
+ elif len(s) == 3:
+ return ((int(s[0]) * 60 + int(s[1])) * 60) + int(s[2])
+
+def seek(dcp_seconds):
+ print("O %s" % args.dcp)
+ print("P")
+ test_seconds = hms_to_seconds(args.length)
+ while test_seconds > 0:
+ wait = random.randint(500, dcp_seconds * 1000)
+ # Wait some milliseconds
+ print("W %d" % wait)
+ # Seek
+ print("S %d" % random.randint(0, 4095))
+ # Make sure we're stil playing
+ print("P")
+ test_seconds -= wait / 1000
+
+def repeat(dcp_seconds):
+ print("O %s" % args.dcp)
+ test_seconds = hms_to_seconds(args.length)
+ while test_seconds > 0:
+ print("P")
+ print("W %d" % (dcp_seconds * 1000))
+ test_seconds -= dcp_seconds
+
+parser = argparse.ArgumentParser()
+parser.add_argument('-d', '--dcp', help='DCP to make a script for', required=True)
+parser.add_argument('-t', '--type', help='script type: seek - seek a lot, repeat - play back DCP over and over', required=True)
+parser.add_argument('-l', '--length', help='approximate test length in H:M:S', required=True)
+args = parser.parse_args()
+
+for l in subprocess.run(['dcpinfo', args.dcp], capture_output=True).stdout.splitlines():
+ if l.startswith(b'Total:'):
+ b = l.split(b':')
+ dcp_seconds = (int(b[1]) * 60 + int(b[2])) * 60 + int(b[3])
+if args.type == 'seek':
+ seek(dcp_seconds)
+elif args.type == 'repeat':
+ repeat(dcp_seconds)
+else:
+ print('Unknown type %s' % args.type, file=sys.stderr)
+ sys.exit(1)
+
diff --git a/src/tools/wscript b/src/tools/wscript
index 8fd23cfb3..3b2c0a04c 100644
--- a/src/tools/wscript
+++ b/src/tools/wscript
@@ -68,6 +68,8 @@ def build(bld):
obj.uselib += ' WXWIDGETS'
if not bld.env.TARGET_OSX:
obj.uselib += ' GL GLU'
+ if bld.env.TARGET_LINUX:
+ obj.uselib += ' X11'
obj.includes = ['..']
obj.use = ['libdcpomatic2', 'libdcpomatic2-wx']
obj.source = '%s.cc' % t