Differentiate between stop and suspend in player.
authorCarl Hetherington <cth@carlh.net>
Tue, 5 Nov 2019 22:01:24 +0000 (23:01 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 5 Nov 2019 22:02:59 +0000 (23:02 +0100)
This and the previous commit somewhat improve the previously
terrible behaviour when seeking during playback, probably
introduced by the idle update stuff.

src/wx/controls.cc
src/wx/controls.h
src/wx/film_viewer.cc
src/wx/film_viewer.h

index 7cd3163..a3360b2 100644 (file)
@@ -59,7 +59,6 @@ Controls::Controls (wxWindow* parent, shared_ptr<FilmViewer> viewer, bool editor
        , _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096))
        , _viewer (viewer)
        , _slider_being_moved (false)
-       , _was_running_before_slider (false)
        , _outline_content (0)
        , _eye (0)
        , _jump_to_selected (0)
@@ -203,7 +202,7 @@ Controls::slider_moved (bool page)
 
        if (!page && !_slider_being_moved) {
                /* This is the first event of a drag; stop playback for the duration of the drag */
-               _was_running_before_slider = _viewer->stop ();
+               _viewer->suspend ();
                _slider_being_moved = true;
        }
 
@@ -230,10 +229,8 @@ Controls::slider_moved (bool page)
 void
 Controls::slider_released ()
 {
-       if (_was_running_before_slider) {
-               /* Restart after a drag */
-               _viewer->start ();
-       }
+       /* Restart after a drag */
+       _viewer->resume ();
        _slider_being_moved = false;
 }
 
index 88d21de..dfa11e6 100644 (file)
@@ -93,7 +93,6 @@ private:
        typedef std::pair<boost::shared_ptr<dcp::CPL>, boost::filesystem::path> CPL;
 
        bool _slider_being_moved;
-       bool _was_running_before_slider;
 
        wxCheckBox* _outline_content;
        wxChoice* _eye;
index 495b825..9b01cd3 100644 (file)
@@ -84,6 +84,7 @@ FilmViewer::FilmViewer (wxWindow* p)
        , _audio_channels (0)
        , _audio_block_size (1024)
        , _playing (false)
+       , _suspended (0)
        , _latency_history_count (0)
        , _dropped (0)
        , _closed_captions_dialog (new ClosedCaptionsDialog(p, this))
@@ -200,10 +201,11 @@ FilmViewer::set_film (shared_ptr<Film> film)
 void
 FilmViewer::recreate_butler ()
 {
-       bool const was_running = stop ();
+       suspend ();
        _butler.reset ();
 
        if (!_film) {
+               resume ();
                return;
        }
 
@@ -247,9 +249,7 @@ FilmViewer::recreate_butler ()
 
        _closed_captions_dialog->set_film_and_butler (_film, _butler);
 
-       if (was_running) {
-               start ();
-       }
+       resume ();
 }
 
 void
@@ -312,7 +312,7 @@ FilmViewer::display_player_video ()
                return;
        }
 
-       if (_playing && (time() - _player_video.second) > one_video_frame()) {
+       if (_playing && !_suspended && (time() - _player_video.second) > one_video_frame()) {
                /* Too late; just drop this frame before we try to get its image (which will be the time-consuming
                   part if this frame is J2K).
                */
@@ -361,7 +361,7 @@ FilmViewer::display_player_video ()
 void
 FilmViewer::timer ()
 {
-       if (!_film || !_playing) {
+       if (!_film || !_playing || _suspended) {
                return;
        }
 
@@ -435,6 +435,28 @@ FilmViewer::calculate_sizes ()
        _player->set_video_container_size (_out_size);
 }
 
+void
+FilmViewer::suspend ()
+{
+       ++_suspended;
+       if (_audio.isStreamRunning()) {
+               _audio.abortStream();
+       }
+}
+
+void
+FilmViewer::resume ()
+{
+       --_suspended;
+       if (_playing && !_suspended) {
+               if (_audio.isStreamOpen()) {
+                       _audio.setStreamTime (_video_position.seconds());
+                       _audio.startStream ();
+               }
+               timer ();
+       }
+}
+
 void
 FilmViewer::start ()
 {
@@ -579,16 +601,19 @@ FilmViewer::seek (DCPTime t, bool accurate)
                t = _film->length ();
        }
 
-       bool const was_running = stop ();
+       suspend ();
 
        _closed_captions_dialog->clear ();
        _butler->seek (t, accurate);
 
-       if (!was_running) {
+       if (!_playing) {
                request_idle_get ();
        } else {
-               start ();
+               /* Make sure we get a frame so that _video_position is set up before we resume */
+               while (!get(true)) {}
        }
+
+       resume ();
 }
 
 void
index a37d758..1f20c33 100644 (file)
@@ -75,6 +75,8 @@ public:
 
        void start ();
        bool stop ();
+       void suspend ();
+       void resume ();
        bool playing () const {
                return _playing;
        }
@@ -186,6 +188,7 @@ private:
        int _audio_channels;
        unsigned int _audio_block_size;
        bool _playing;
+       int _suspended;
        boost::shared_ptr<Butler> _butler;
 
        std::list<Frame> _latency_history;