From 7c730205e50014347bd96ab9735346d0b5922798 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 24 Jul 2019 21:17:50 +0100 Subject: [PATCH] Re-work idle handling from previous commit. --- src/lib/player.cc | 1 + src/wx/film_viewer.cc | 62 ++++++++++++++++++++++++++++++++----------- src/wx/film_viewer.h | 7 ++++- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/src/lib/player.cc b/src/lib/player.cc index 6f0cfd1af..08e138fe6 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -48,6 +48,7 @@ #include "image_decoder.h" #include "compose.hpp" #include "shuffler.h" +#include "timer.h" #include #include #include diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index edb451e74..78efc77f6 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -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,33 @@ 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; + 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) { @@ -231,12 +259,12 @@ FilmViewer::refresh_view () _state_timer.unset (); } -/** @param lazy true if it is *not* important that the display be updated as quickly as possible. - * If lazy is true we will try to return from this method quickly and postpone any time-consuming - * work until the UI is next idle. Otherwise we will block here and try to get the image on - * screen as soon as possible. +/** 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. */ -void +bool FilmViewer::get (bool lazy) { DCPOMATIC_ASSERT (_butler); @@ -246,8 +274,14 @@ FilmViewer::get (bool lazy) Butler::Error e; _player_video = _butler->get_video (!lazy, &e); if (!_player_video.first && e == Butler::AGAIN) { - signal_manager->when_idle (boost::bind(&FilmViewer::get, this, lazy)); - 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 && @@ -262,11 +296,10 @@ FilmViewer::get (bool lazy) error_dialog (_video_view->get(), e.what()); } - if (lazy) { - signal_manager->when_idle (boost::bind(&FilmViewer::display_player_video, this)); - } else { - display_player_video (); - } + display_player_video (); + PositionChanged (); + + return true; } void @@ -332,7 +365,6 @@ FilmViewer::timer () } get (false); - PositionChanged (); DCPTime const next = _video_position + one_video_frame(); if (next >= _film->length()) { @@ -550,13 +582,11 @@ FilmViewer::seek (DCPTime t, bool accurate) _closed_captions_dialog->clear (); _butler->seek (t, accurate); - get (true); + request_idle_get (); if (was_running) { start (); } - - PositionChanged (); } void diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index 298e9dd00..a37d7581e 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -151,7 +151,9 @@ private: void timer (); void calculate_sizes (); void player_change (ChangeType type, int, bool); - void get (bool lazy); + bool get (bool lazy); + void idle_handler (); + void request_idle_get (); void display_player_video (); void film_change (ChangeType, Film::Property); void recreate_butler (); @@ -210,5 +212,8 @@ private: StateTimer _state_timer; int _gets; + /** true if an get() is required next time we are idle */ + bool _idle_get; + boost::signals2::scoped_connection _config_changed_connection; }; -- 2.30.2