Merge branch 'v2.15.x' of ssh://localhost:2222/home/carl/git/dcpomatic into v2.15.x
[dcpomatic.git] / src / wx / film_viewer.cc
index a2b055934e9a1fdda844115f9628132172493006..89702ac0cbe519d56d4a7bb897d3d315f445b709 100644 (file)
@@ -95,6 +95,7 @@ FilmViewer::FilmViewer (wxWindow* p)
 #endif
        , _state_timer ("viewer")
        , _gets (0)
+       , _idle_get (false)
 {
        switch (Config::instance()->video_view_type()) {
        case Config::VIDEO_VIEW_OPENGL:
@@ -119,6 +120,34 @@ FilmViewer::~FilmViewer ()
        stop ();
 }
 
+/** Ask for ::get() to be called next time we are idle */
+void
+FilmViewer::request_idle_get ()
+{
+       if (_idle_get) {
+               return;
+       }
+
+       _idle_get = true;
+       DCPOMATIC_ASSERT (signal_manager);
+       signal_manager->when_idle (boost::bind(&FilmViewer::idle_handler, this));
+}
+
+void
+FilmViewer::idle_handler ()
+{
+       if (!_idle_get) {
+               return;
+       }
+
+       if (get(true)) {
+               _idle_get = false;
+       } else {
+               /* get() could not complete quickly so we'll try again later */
+               signal_manager->when_idle (boost::bind(&FilmViewer::idle_handler, this));
+       }
+}
+
 void
 FilmViewer::set_film (shared_ptr<Film> film)
 {
@@ -231,18 +260,29 @@ FilmViewer::refresh_view ()
        _state_timer.unset ();
 }
 
-void
-FilmViewer::get ()
+/** Try to get a frame from the butler and display it.
+ *  @param lazy true to return false quickly if no video is available quickly (i.e. we are waiting for the butler).
+ *  false to ask the butler to block until it has video (unless it is suspended).
+ *  @return true on success, false if we did nothing because it would have taken too long.
+ */
+bool
+FilmViewer::get (bool lazy)
 {
        DCPOMATIC_ASSERT (_butler);
        ++_gets;
 
        do {
                Butler::Error e;
-               _player_video = _butler->get_video (&e);
+               _player_video = _butler->get_video (!lazy, &e);
                if (!_player_video.first && e == Butler::AGAIN) {
-                       signal_manager->when_idle (boost::bind(&FilmViewer::get, this));
-                       return;
+                       if (lazy) {
+                               /* No video available; return saying we failed */
+                               return false;
+                       } else {
+                               /* Player was suspended; come back later */
+                               signal_manager->when_idle (boost::bind(&FilmViewer::get, this, false));
+                               return false;
+                       }
                }
        } while (
                _player_video.first &&
@@ -258,6 +298,9 @@ FilmViewer::get ()
        }
 
        display_player_video ();
+       PositionChanged ();
+
+       return true;
 }
 
 void
@@ -322,8 +365,7 @@ FilmViewer::timer ()
                return;
        }
 
-       get ();
-       PositionChanged ();
+       get (false);
        DCPTime const next = _video_position + one_video_frame();
 
        if (next >= _film->length()) {
@@ -541,13 +583,11 @@ FilmViewer::seek (DCPTime t, bool accurate)
 
        _closed_captions_dialog->clear ();
        _butler->seek (t, accurate);
-       get ();
+       request_idle_get ();
 
        if (was_running) {
                start ();
        }
-
-       PositionChanged ();
 }
 
 void