From 9301991f6e77f16c6cefe3f0c92fdc02da687f8b Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 3 Apr 2013 22:29:04 +0200 Subject: vtl: video-monitor interaction * Menu > View > Video Monitor -- bi-directional communication with xjadeo for window-state and OSD. * fix saving state on session close (wait for xjadeo to terminate) --- gtk2_ardour/ardour.menus.in | 7 +++ gtk2_ardour/editor.h | 7 +++ gtk2_ardour/editor_actions.cc | 95 ++++++++++++++++++++++++++++++++++++++- gtk2_ardour/public_editor.h | 1 + gtk2_ardour/system_exec.cc | 2 +- gtk2_ardour/video_monitor.cc | 100 ++++++++++++++++++++++++++++++++++++++++-- gtk2_ardour/video_monitor.h | 7 +++ gtk2_ardour/video_timeline.cc | 32 +++++++++++++- gtk2_ardour/video_timeline.h | 1 + 9 files changed, 245 insertions(+), 7 deletions(-) diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in index 608f4dd6e4..f101a9dc4f 100644 --- a/gtk2_ardour/ardour.menus.in +++ b/gtk2_ardour/ardour.menus.in @@ -440,6 +440,13 @@ #ifdef WITH_VIDEOTIMELINE + + + + + + + #endif diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 6155dea745..c287a259ea 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -928,9 +928,16 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD ArdourCanvas::Group* videotl_group; Glib::RefPtr ruler_video_action; Glib::RefPtr xjadeo_proc_action; + Glib::RefPtr xjadeo_ontop_action; + Glib::RefPtr xjadeo_timecode_action; + Glib::RefPtr xjadeo_frame_action; + Glib::RefPtr xjadeo_osdbg_action; + Glib::RefPtr xjadeo_fullscreen_action; void set_xjadeo_proc (); void toggle_xjadeo_proc (int state=-1); void set_xjadeo_sensitive (bool onoff); + void set_xjadeo_viewoption (int); + void toggle_xjadeo_viewoption (int what, int state=-1); void toggle_ruler_video (bool onoff) {ruler_video_action->set_active(onoff);} int videotl_bar_height; /* in units of timebar_height; default: 4 */ int get_videotl_bar_height () const { return videotl_bar_height; } diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index a8c381cd5f..8c81a6122e 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -544,8 +544,17 @@ Editor::register_actions () ruler_timecode_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-timecode-ruler"), _("Timecode"), sigc::bind (sigc::mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_metric_timecode))); ruler_minsec_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-minsec-ruler"), _("Min:Sec"), sigc::bind (sigc::mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_metric_minsec))); #ifdef WITH_VIDEOTIMELINE + + ActionManager::register_action (editor_menu_actions, X_("VideoMonitorMenu"), _("Video Monitor")); + ruler_video_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-video-ruler"), _("Video"), sigc::bind (sigc::mem_fun(*this, &Editor::toggle_ruler_visibility), ruler_video_timeline))); - xjadeo_proc_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (editor_actions, X_("ToggleJadeo"), _("Show Video Monitor"), sigc::mem_fun (*this, &Editor::set_xjadeo_proc))); + xjadeo_proc_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (editor_actions, X_("ToggleJadeo"), _("Video Monitor"), sigc::mem_fun (*this, &Editor::set_xjadeo_proc))); + + xjadeo_ontop_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-ontop"), _("Always on Top"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 1))); + xjadeo_timecode_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-timecode"), _("Timecode"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 2))); + xjadeo_frame_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-frame"), _("Framenumber"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 3))); + xjadeo_osdbg_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-osdbg"), _("Timecode Background"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 4))); + xjadeo_fullscreen_action = Glib::RefPtr::cast_static (ActionManager::register_toggle_action (editor_actions, X_("toggle-vmon-fullscreen"), _("Fullscreen"), sigc::bind (sigc::mem_fun (*this, &Editor::set_xjadeo_viewoption), (int) 5))); #endif @@ -562,6 +571,16 @@ Editor::register_actions () ruler_video_action->set_active (false); xjadeo_proc_action->set_active (false); xjadeo_proc_action->set_sensitive (false); + xjadeo_ontop_action->set_active (false); + xjadeo_ontop_action->set_sensitive (false); + xjadeo_timecode_action->set_active (false); + xjadeo_timecode_action->set_sensitive (false); + xjadeo_frame_action->set_active (false); + xjadeo_frame_action->set_sensitive (false); + xjadeo_osdbg_action->set_active (false); + xjadeo_osdbg_action->set_sensitive (false); + xjadeo_fullscreen_action->set_active (false); + xjadeo_fullscreen_action->set_sensitive (false); #endif if (Profile->get_sae()) { ruler_bbt_action->set_active (true); @@ -760,6 +779,7 @@ Editor::set_xjadeo_sensitive (bool onoff) { xjadeo_proc_action->set_sensitive(onoff); } + void Editor::toggle_xjadeo_proc (int state) { @@ -774,6 +794,12 @@ Editor::toggle_xjadeo_proc (int state) xjadeo_proc_action->set_active(!xjadeo_proc_action->get_active()); break; } + bool onoff = xjadeo_proc_action->get_active(); + xjadeo_ontop_action->set_sensitive(onoff); + xjadeo_timecode_action->set_sensitive(onoff); + xjadeo_frame_action->set_sensitive(onoff); + xjadeo_osdbg_action->set_sensitive(onoff); + xjadeo_fullscreen_action->set_sensitive(onoff); } void @@ -785,6 +811,73 @@ Editor::set_xjadeo_proc () ARDOUR_UI::instance()->video_timeline->close_video_monitor(); } } + +void +Editor::toggle_xjadeo_viewoption (int what, int state) +{ + Glib::RefPtr action; + switch (what) { + case 1: + action = xjadeo_ontop_action; + break; + case 2: + action = xjadeo_timecode_action; + break; + case 3: + action = xjadeo_frame_action; + break; + case 4: + action = xjadeo_osdbg_action; + break; + case 5: + action = xjadeo_fullscreen_action; + break; + default: + return; + } + + switch(state) { + case 1: + action->set_active(true); + break; + case 0: + action->set_active(false); + break; + default: + action->set_active(!action->get_active()); + break; + } +} + +void +Editor::set_xjadeo_viewoption (int what) +{ + Glib::RefPtr action; + switch (what) { + case 1: + action = xjadeo_ontop_action; + break; + case 2: + action = xjadeo_timecode_action; + break; + case 3: + action = xjadeo_frame_action; + break; + case 4: + action = xjadeo_osdbg_action; + break; + case 5: + action = xjadeo_fullscreen_action; + break; + default: + return; + } + if (action->get_active()) { + ARDOUR_UI::instance()->video_timeline->control_video_monitor(what, 1); + } else { + ARDOUR_UI::instance()->video_timeline->control_video_monitor(what, 0); + } +} #endif void diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 0dabc5f5e8..ce21b8a40d 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -296,6 +296,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible { virtual void queue_visual_videotimeline_update () = 0; virtual void toggle_ruler_video (bool) = 0; virtual void toggle_xjadeo_proc (int) = 0; + virtual void toggle_xjadeo_viewoption (int, int) = 0; virtual void set_xjadeo_sensitive (bool onoff) = 0; virtual int get_videotl_bar_height () const = 0; virtual void set_video_timeline_height (const int h) = 0; diff --git a/gtk2_ardour/system_exec.cc b/gtk2_ardour/system_exec.cc index 00b212710e..3af660ef77 100644 --- a/gtk2_ardour/system_exec.cc +++ b/gtk2_ardour/system_exec.cc @@ -418,7 +418,7 @@ SystemExec::terminate () if (pid) { ::fprintf(stderr, "Child process is running. trying SIGTERM\n"); ::kill(pid, SIGTERM); - ::usleep(10000); + ::usleep(50000); wait(WNOHANG); } if (pid) { diff --git a/gtk2_ardour/video_monitor.cc b/gtk2_ardour/video_monitor.cc index f29712e326..fabe4201dd 100644 --- a/gtk2_ardour/video_monitor.cc +++ b/gtk2_ardour/video_monitor.cc @@ -39,10 +39,14 @@ VideoMonitor::VideoMonitor (PublicEditor *ed, std::string xjadeo_bin_path) sync_by_manual_seek = false; _restore_settings_mask = 0; clock_connection = sigc::connection(); + state_connection = sigc::connection(); debug_enable = false; + state_clk_divide = 0; + starting = 0; + osdmode = 10; // 1: frameno, 2: timecode, 8: box process = new SystemExec(xjadeo_bin_path, X_("-R")); - process->ReadStdout.connect (*this, invalidator (*this), boost::bind (&VideoMonitor::parse_output, this, _1 ,_2), gui_context()); + process->ReadStdout.connect_same_thread (*this, boost::bind (&VideoMonitor::parse_output, this, _1 ,_2)); process->Terminated.connect (*this, invalidator (*this), boost::bind (&VideoMonitor::terminated, this), gui_context()); } @@ -51,6 +55,9 @@ VideoMonitor::~VideoMonitor () if (clock_connection.connected()) { clock_connection.disconnect(); } + if (state_connection.connected()) { + state_connection.disconnect(); + } delete process; } @@ -75,6 +82,8 @@ void VideoMonitor::quit () { if (!is_started()) return; + if (state_connection.connected()) { state_connection.disconnect(); } + if (clock_connection.connected()) { clock_connection.disconnect(); } process->write_to_stdin("get windowsize\n"); process->write_to_stdin("get windowpos\n"); process->write_to_stdin("get letterbox\n"); @@ -92,13 +101,14 @@ VideoMonitor::quit () int timeout = 40; while (is_started() && --timeout) { usleep(50000); + sched_yield(); } - if (timeout == 0) { + if (timeout <= 0) { printf("xjadeo connection: time-out. session may not be saved.\n"); + process->terminate(); } #endif - process->terminate(); - if (clock_connection.connected()) { clock_connection.disconnect(); } + save_session(); } void @@ -106,7 +116,9 @@ VideoMonitor::open (std::string filename) { if (!is_started()) return; manually_seeked_frame = 0; + osdmode = 10; // 1: frameno, 2: timecode, 8: box sync_by_manual_seek = false; + starting = 7; process->write_to_stdin("load " + filename + "\n"); process->write_to_stdin("set fps -1\n"); process->write_to_stdin("window resize 100%\n"); @@ -119,9 +131,29 @@ VideoMonitor::open (std::string filename) if (skip_setting(it->first)) { continue; } process->write_to_stdin(it->first + " " + it->second + "\n"); } + if (!state_connection.connected()) { + starting = 7; + querystate(); + state_clk_divide = 0; + /* TODO once every two second or so -- state_clk_divide hack below */ + state_connection = ARDOUR_UI::RapidScreenUpdate.connect (sigc::mem_fun (*this, &VideoMonitor::querystate)); + } xjadeo_sync_setup(); } +void +VideoMonitor::querystate () +{ + /* clock-divider hack -- RapidScreenUpdate == every_point_one_seconds */ + state_clk_divide = (state_clk_divide + 1) % 15; // every 1.5 seconds + if (state_clk_divide != 0) return; + + process->write_to_stdin("get fullscreen\n"); + process->write_to_stdin("get ontop\n"); + process->write_to_stdin("get osdcfg\n"); + process->write_to_stdin("get letterbox\n"); +} + bool VideoMonitor::skip_setting (std::string which) { @@ -136,6 +168,44 @@ VideoMonitor::skip_setting (std::string which) return false; } +void +VideoMonitor::send_cmd (int what, int param) +{ + bool osd_update = false; + if (!is_started()) return; + switch (what) { + case 1: + if (param) process->write_to_stdin("window ontop on\n"); + else process->write_to_stdin("window ontop off\n"); + break; + case 2: + if (param) osdmode |= 2; + else osdmode &= ~2; + osd_update = true; + break; + case 3: + if (param) osdmode |= 1; + else osdmode &= ~1; + osd_update = true; + break; + case 4: + if (param) osdmode |= 8; + else osdmode &= ~8; + osd_update = true; + break; + case 5: + if (param) process->write_to_stdin("window zoom on\n"); + else process->write_to_stdin("window zoom off\n"); + break; + default: + break; + } + if (osd_update >= 0) { + std::ostringstream osstream; osstream << "osd mode " << osdmode << "\n"; + process->write_to_stdin(osstream.str()); + } +} + bool VideoMonitor::is_started () { @@ -196,12 +266,32 @@ VideoMonitor::parse_output (std::string d, size_t s) } else if(key == "windowsize") { xjadeo_settings["window size"] = value; } else if(key == "windowontop") { + if (starting || xjadeo_settings["window ontop"] != value) { + starting &= ~2; + if (atoi(value.c_str())) { UiState("xjadeo-window-ontop-on"); } + else { UiState("xjadeo-window-ontop-off"); } + } xjadeo_settings["window ontop"] = value; } else if(key == "fullscreen") { + if (starting || xjadeo_settings["window zoom"] != value) { + starting &= ~4; + if (atoi(value.c_str())) { UiState("xjadeo-window-fullscreen-on"); } + else { UiState("xjadeo-window-fullscreen-off"); } + } xjadeo_settings["window zoom"] = value; } else if(key == "letterbox") { xjadeo_settings["window letterbox"] = value; } else if(key == "osdmode") { + if (starting || xjadeo_settings["osd mode"] != value) { + starting &= ~1; + osdmode = atoi(value.c_str()); + if ((osdmode & 1) == 1) { UiState("xjadeo-window-osd-frame-on"); } + if ((osdmode & 1) == 0) { UiState("xjadeo-window-osd-frame-off"); } + if ((osdmode & 2) == 2) { UiState("xjadeo-window-osd-timecode-on"); } + if ((osdmode & 2) == 0) { UiState("xjadeo-window-osd-timecode-off"); } + if ((osdmode & 8) == 8) { UiState("xjadeo-window-osd-box-on"); } + if ((osdmode & 8) == 0) { UiState("xjadeo-window-osd-box-off"); } + } xjadeo_settings["osd mode"] = value; } else if(key == "offset") { xjadeo_settings["set offset"] = value; @@ -218,6 +308,7 @@ VideoMonitor::parse_output (std::string d, size_t s) void VideoMonitor::terminated () { + process->terminate(); // from gui-context clean up save_session(); Terminated(); } @@ -298,6 +389,7 @@ VideoMonitor::get_custom_setting (const std::string k) { return (xjadeo_settings[k]); } + #define NO_OFFSET (1<<31) //< skip setting or modifying offset -- TODO check ARDOUR::frameoffset_t max value. void VideoMonitor::srsupdate () diff --git a/gtk2_ardour/video_monitor.h b/gtk2_ardour/video_monitor.h index 7bb74c7e05..be3b76f9a4 100644 --- a/gtk2_ardour/video_monitor.h +++ b/gtk2_ardour/video_monitor.h @@ -71,9 +71,12 @@ class VideoMonitor : public sigc::trackable , public ARDOUR::SessionHandlePtr, p void set_offset (ARDOUR::frameoffset_t); void manual_seek (ARDOUR::framepos_t, bool, ARDOUR::frameoffset_t); void srsupdate (); + void querystate (); bool synced_by_manual_seeks() { return sync_by_manual_seek; } sigc::signal Terminated; + PBD::Signal1 UiState; + void send_cmd (int what, int param); #if 1 void set_debug (bool onoff) { debug_enable = onoff; } @@ -99,6 +102,10 @@ class VideoMonitor : public sigc::trackable , public ARDOUR::SessionHandlePtr, p ARDOUR::framepos_t manually_seeked_frame; bool sync_by_manual_seek; sigc::connection clock_connection; + sigc::connection state_connection; + int state_clk_divide; + int starting; + int osdmode; #if 1 bool debug_enable; #endif diff --git a/gtk2_ardour/video_timeline.cc b/gtk2_ardour/video_timeline.cc index dd47a82970..d68df6bc2f 100644 --- a/gtk2_ardour/video_timeline.cc +++ b/gtk2_ardour/video_timeline.cc @@ -155,8 +155,8 @@ VideoTimeLine::close_session () if (video_duration == 0) { return; } - close_video_monitor(); save_session(); + close_video_monitor(); remove_frames(); video_filename = ""; @@ -581,6 +581,26 @@ VideoTimeLine::gui_update(std::string const & t) { editor->toggle_xjadeo_proc(0); //close_video_monitor(); editor->set_xjadeo_sensitive(false); + } else if (t == "xjadeo-window-ontop-on") { + editor->toggle_xjadeo_viewoption(1, 1); + } else if (t == "xjadeo-window-ontop-off") { + editor->toggle_xjadeo_viewoption(1, 0); + } else if (t == "xjadeo-window-osd-timecode-on") { + editor->toggle_xjadeo_viewoption(2, 1); + } else if (t == "xjadeo-window-osd-timecode-off") { + editor->toggle_xjadeo_viewoption(2, 0); + } else if (t == "xjadeo-window-osd-frame-on") { + editor->toggle_xjadeo_viewoption(3, 1); + } else if (t == "xjadeo-window-osd-frame-off") { + editor->toggle_xjadeo_viewoption(3, 0); + } else if (t == "xjadeo-window-osd-box-on") { + editor->toggle_xjadeo_viewoption(4, 1); + } else if (t == "xjadeo-window-osd-box-off") { + editor->toggle_xjadeo_viewoption(4, 0); + } else if (t == "xjadeo-window-fullscreen-on") { + editor->toggle_xjadeo_viewoption(5, 1); + } else if (t == "xjadeo-window-fullscreen-off") { + editor->toggle_xjadeo_viewoption(5, 0); } } @@ -688,6 +708,7 @@ VideoTimeLine::open_video_monitor() { vmonitor = new VideoMonitor(editor, _xjadeo_bin); vmonitor->set_session(_session); vmonitor->Terminated.connect (sigc::mem_fun (*this, &VideoTimeLine::terminated_video_monitor)); + vmonitor->UiState.connect (*this, invalidator (*this), boost::bind (&VideoTimeLine::gui_update, this, _1), gui_context()); } else if (vmonitor->is_started()) { return; } @@ -723,6 +744,15 @@ VideoTimeLine::close_video_monitor() { } } +void +VideoTimeLine::control_video_monitor(int what, int param) { + if (!vmonitor || !vmonitor->is_started()) { + return; + } + vmonitor->send_cmd(what, param); +} + + void VideoTimeLine::terminated_video_monitor () { if (vmonitor) { diff --git a/gtk2_ardour/video_timeline.h b/gtk2_ardour/video_timeline.h index ef889af452..ab1a9a92d8 100644 --- a/gtk2_ardour/video_timeline.h +++ b/gtk2_ardour/video_timeline.h @@ -78,6 +78,7 @@ class VideoTimeLine : public sigc::trackable, public ARDOUR::SessionHandlePtr, p void open_video_monitor (); void close_video_monitor (); + void control_video_monitor (int, int); void terminated_video_monitor (); void manual_seek_video_monitor (framepos_t pos); -- cgit v1.2.3