+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ MonitorChecker::instance()->StateChanged.connect(boost::bind(&DOMFrame::monitor_checker_state_changed, this));
+ MonitorChecker::instance()->run ();
+ LockFileChecker::instance()->StateChanged.connect(boost::bind(&DOMFrame::lock_checker_state_changed, this));
+ LockFileChecker::instance()->run ();
+#endif
+ setup_screen ();
+
+#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 (_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:
+ /* 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 ()
+ {
+ if (!MonitorChecker::instance()->ok()) {
+ _viewer->stop ();
+ error_dialog (this, _("The required display devices are not connected correctly."));
+ }
+ }
+
+ void lock_checker_state_changed ()
+ {
+ if (!LockFileChecker::instance()->ok()) {
+ _viewer->stop ();
+ error_dialog (this, _("The lock file is not present."));
+ }
+ }
+#endif
+
+ void setup_main_sizer (Config::PlayerMode mode)
+ {
+ wxSizer* main_sizer = new wxBoxSizer (wxVERTICAL);
+ if (mode != Config::PLAYER_MODE_DUAL) {
+ main_sizer->Add (_viewer->panel(), 1, wxEXPAND | wxALIGN_CENTER_VERTICAL);
+ }
+ main_sizer->Add (_controls, mode == Config::PLAYER_MODE_DUAL ? 1 : 0, wxEXPAND | wxALL, 6);
+ main_sizer->Add (_info, 0, wxEXPAND | wxALL, 6);
+ _overall_panel->SetSizer (main_sizer);
+ _overall_panel->Layout ();
+ }
+
+ bool playback_permitted ()
+ {
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ if (!MonitorChecker::instance()->ok()) {
+ error_dialog (this, _("The required display devices are not connected correctly."));
+ return false;
+ }
+ if (!LockFileChecker::instance()->ok()) {
+ error_dialog (this, _("The lock file is not present."));
+ return false;
+ }
+#endif
+ 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;
+ }
+ }
+
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ BOOST_FOREACH (shared_ptr<Content> i, _film->content()) {
+ shared_ptr<FFmpegContent> c = dynamic_pointer_cast<FFmpegContent>(i);
+ if (c && !c->kdm_timing_window_valid()) {
+ ok = false;
+ }
+ }
+#endif
+
+ if (!ok) {
+ error_dialog (this, _("The KDM does not allow playback of this content at this time."));
+ }
+
+ return ok;
+ }
+
+ void playback_started (DCPTime time)
+ {
+ /* XXX: this only logs the first piece of content; probably should be each piece? */
+ if (_film->content().empty()) {
+ return;
+ }
+
+ shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent>(_film->content().front());
+ if (dcp) {
+ DCPExaminer ex (dcp, true);
+ shared_ptr<dcp::CPL> playing_cpl;
+ BOOST_FOREACH (shared_ptr<dcp::CPL> i, ex.cpls()) {
+ if (!dcp->cpl() || i->id() == *dcp->cpl()) {
+ playing_cpl = i;
+ }
+ }
+ DCPOMATIC_ASSERT (playing_cpl);
+
+ _controls->log (
+ wxString::Format(
+ "playback-started %s %s %s",
+ time.timecode(_film->video_frame_rate()).c_str(),
+ dcp->directories().front().string().c_str(),
+ playing_cpl->annotation_text().c_str()
+ )
+ );
+ }
+
+ shared_ptr<FFmpegContent> ffmpeg = dynamic_pointer_cast<FFmpegContent>(_film->content().front());
+ if (ffmpeg) {
+ _controls->log (
+ wxString::Format(
+ "playback-started %s %s",
+ time.timecode(_film->video_frame_rate()).c_str(),
+ ffmpeg->path(0).string().c_str()
+ )
+ );
+ }
+ }
+
+ void playback_stopped (DCPTime time)
+ {
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+ try {
+ boost::filesystem::remove (Config::path("position"));
+ } catch (...) {
+ /* Never mind */
+ }
+#endif
+
+ _controls->log (wxString::Format("playback-stopped %s", time.timecode(_film->video_frame_rate()).c_str()));