diff --git a/configure.ac b/configure.ac index 717fe6f4b..1b2ec96dc 100644 --- a/configure.ac +++ b/configure.ac @@ -141,9 +141,9 @@ PKG_CHECK_MODULES(LUMIERA_COMMON_LIBS, [sigc++-2.0 >= 2.0.17]) # gtk+-2.0 >= 2.12 gtkmm-2.4 >= 2.12 for Debian Lenny compatibility PKG_CHECK_MODULES(LUMIERA_GUI, [ - gtk+-2.0 >= 2.8 gtkmm-2.4 >= 2.8 - gdl-1.0 >= 0.6.1 cairomm-1.0 >= 0.6.0 - gavl >= 0.2.5 librsvg-2.0 >= 2.18.1]) + gtk+-2.0 >= 2.8 gtkmm-2.4 >= 2.8 gdl-1.0 >= 0.6.1 + cairomm-1.0 >= 0.6.0 gavl >= 0.2.5 librsvg-2.0 >= 2.18.1 + gthread-2.0 >= 2.12.4]) # END Gtk Dependancies diff --git a/src/gui/controller/playback-controller.cpp b/src/gui/controller/playback-controller.cpp index d69d3f7ce..44251278a 100644 --- a/src/gui/controller/playback-controller.cpp +++ b/src/gui/controller/playback-controller.cpp @@ -26,30 +26,94 @@ namespace gui { namespace controller { -void -PlaybackController::play() +PlaybackController::PlaybackController() : + finish_playback_thread(false), + playing(false) { - pull_frame(); + start_playback_thread(); +} + +PlaybackController::~PlaybackController() +{ + mutex.lock(); + finish_playback_thread = true; + mutex.unlock(); + thread->join(); } void -PlaybackController::attach_viewer(const sigc::slot& on_frame) +PlaybackController::play() +{ + Glib::Mutex::Lock lock(mutex); + playing = true; +} + +void +PlaybackController::pause() +{ + Glib::Mutex::Lock lock(mutex); + playing = false; +} + +void +PlaybackController::stop() +{ + Glib::Mutex::Lock lock(mutex); + playing = false; +} + +bool +PlaybackController::is_playing() +{ + Glib::Mutex::Lock lock(mutex); + return playing; +} + +void +PlaybackController::start_playback_thread() +{ + dispatcher.connect(sigc::mem_fun(this, &PlaybackController::on_frame)); + thread = Glib::Thread::create (sigc::mem_fun( + this, &PlaybackController::playback_thread), true); +} + +void +PlaybackController::attach_viewer( + const sigc::slot& on_frame) { frame_signal.connect(on_frame); } -void PlaybackController::playback_thread() -{ - pull_frame(); +void +PlaybackController::playback_thread() +{ + for(;;) + { + { + Glib::Mutex::Lock lock(mutex); + if(finish_playback_thread) + return; + } + + if(is_playing()) + pull_frame(); + + Glib::Thread::yield(); + } } -void PlaybackController::pull_frame() +void +PlaybackController::pull_frame() { - unsigned char buffer[320 * 240 * 4]; - for(int i = 0; i < 320*240*4; i++) buffer[i] = rand(); - + + dispatcher.emit(); +} + +void +PlaybackController::on_frame() +{ frame_signal.emit(buffer); } diff --git a/src/gui/controller/playback-controller.hpp b/src/gui/controller/playback-controller.hpp index 601fb9d2b..9333fcbc2 100644 --- a/src/gui/controller/playback-controller.hpp +++ b/src/gui/controller/playback-controller.hpp @@ -24,6 +24,7 @@ */ #include +#include #ifndef PLAYBACK_CONTROLLER_HPP #define PLAYBACK_CONTROLLER_HPP @@ -35,17 +36,44 @@ class PlaybackController { public: + PlaybackController(); + + ~PlaybackController(); + void play(); + + void pause(); + + void stop(); + + bool is_playing(); void attach_viewer(const sigc::slot& on_frame); private: + void start_playback_thread(); + void playback_thread(); void pull_frame(); + void on_frame(); + private: + + Glib::Thread *thread; + + Glib::StaticMutex mutex; + + Glib::Dispatcher dispatcher; + + volatile bool finish_playback_thread; + + volatile bool playing; + + unsigned char buffer[320 * 240 * 4]; + sigc::signal frame_signal; }; diff --git a/src/gui/gtk-lumiera.cpp b/src/gui/gtk-lumiera.cpp index a2147b72d..eb8fbe023 100644 --- a/src/gui/gtk-lumiera.cpp +++ b/src/gui/gtk-lumiera.cpp @@ -57,6 +57,7 @@ namespace gui { void GtkLumiera::main(int argc, char *argv[]) { + Glib::thread_init(); Main kit(argc, argv); diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index ea8215aaf..0c7a566cb 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -123,16 +123,13 @@ TimelinePanel::~TimelinePanel() void TimelinePanel::on_play_pause() { - workspace.get_controller().get_playback_controller().play(); - - // TEST CODE! if(!is_playing()) { play(); } else { - frameEvent.disconnect(); + pause(); } update_playback_buttons(); @@ -141,12 +138,8 @@ TimelinePanel::on_play_pause() void TimelinePanel::on_stop() { - // TEST CODE! - /*timelineWidget.set_playback_point(GAVL_TIME_UNDEFINED); - frameEvent.disconnect(); - show_time(timelineWidget.get_playback_period_start()); - - update_playback_buttons();*/ + workspace.get_controller().get_playback_controller().stop(); + update_playback_buttons(); } void @@ -288,20 +281,21 @@ TimelinePanel::update_zoom_buttons() void TimelinePanel::play() +{ + workspace.get_controller().get_playback_controller().play(); +} + +void +TimelinePanel::pause() { - /*if(timelineWidget.get_playback_point() == GAVL_TIME_UNDEFINED) - timelineWidget.set_playback_point( - timelineWidget.get_playback_period_start()); - frameEvent = Glib::signal_timeout().connect( - sigc::mem_fun(this, &TimelinePanel::on_frame), - 1000 / 25);*/ + workspace.get_controller().get_playback_controller().pause(); } bool TimelinePanel::is_playing() const { - // TEST CODE! - this should be hooked up to the real playback control - return frameEvent.connected(); + return workspace.get_controller().get_playback_controller(). + is_playing(); } void diff --git a/src/gui/panels/timeline-panel.hpp b/src/gui/panels/timeline-panel.hpp index 463130f5c..9c860b05a 100644 --- a/src/gui/panels/timeline-panel.hpp +++ b/src/gui/panels/timeline-panel.hpp @@ -87,6 +87,9 @@ private: void update_zoom_buttons(); void play(); + + void pause(); + bool is_playing() const; void set_tool(gui::widgets::timeline::ToolType tool); @@ -137,7 +140,6 @@ private: private: // TEST CODE bool on_frame(); - sigc::connection frameEvent; //----- Constants -----// private: diff --git a/src/gui/widgets/video-display-widget.cpp b/src/gui/widgets/video-display-widget.cpp index 1f9dca844..4a31af101 100644 --- a/src/gui/widgets/video-display-widget.cpp +++ b/src/gui/widgets/video-display-widget.cpp @@ -67,21 +67,6 @@ VideoDisplayWidget::on_realize() add_events(Gdk::ALL_EVENTS_MASK); } -bool -VideoDisplayWidget::on_button_press_event (GdkEventButton* event) -{ - (void)event; - - unsigned char buffer[320 * 240 * 4]; - - for(int i = 0; i < 320*240*4; i++) - buffer[i] = rand(); - - displayer->put((void*)buffer); - - return true; -} - Displayer* VideoDisplayWidget::createDisplayer( Gtk::Widget *drawingArea, int width, int height ) { diff --git a/src/gui/widgets/video-display-widget.hpp b/src/gui/widgets/video-display-widget.hpp index 5ea827d81..6587362cf 100644 --- a/src/gui/widgets/video-display-widget.hpp +++ b/src/gui/widgets/video-display-widget.hpp @@ -47,9 +47,6 @@ public: /* ===== Overrides ===== */ private: virtual void on_realize(); - - // TEST CODE!!!! - virtual bool on_button_press_event (GdkEventButton* event); /* ===== Internals ===== */ private: