Fix video flickering when seeking near the end of the film.
authorCarl Hetherington <cth@carlh.net>
Wed, 26 Apr 2017 10:01:44 +0000 (11:01 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 26 Apr 2017 10:01:44 +0000 (11:01 +0100)
src/lib/butler.cc
src/lib/butler.h

index b9aa0a5db42c0a1944f8212347b63be119f8c863..89095613d1eb3db09a8639e208c37f38c33ac947 100644 (file)
@@ -42,9 +42,9 @@ Butler::Butler (weak_ptr<const Film> film, shared_ptr<Player> player, AudioMappi
        , _pending_seek_accurate (false)
        , _finished (false)
        , _died (false)
+       , _stop_thread (false)
        , _audio_mapping (audio_mapping)
        , _audio_channels (audio_channels)
-       , _stop_thread (false)
        , _disable_audio (false)
 {
        _player_video_connection = _player->Video.connect (bind (&Butler::video, this, _1, _2));
@@ -55,7 +55,11 @@ Butler::Butler (weak_ptr<const Film> film, shared_ptr<Player> player, AudioMappi
 
 Butler::~Butler ()
 {
-       _stop_thread = true;
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               _stop_thread = true;
+       }
+
        _thread->interrupt ();
        try {
                _thread->join ();
@@ -65,6 +69,7 @@ Butler::~Butler ()
        delete _thread;
 }
 
+/** Caller must hold a lock on _mutex */
 bool
 Butler::should_run () const
 {
@@ -97,7 +102,8 @@ try
                        lm.unlock ();
                        bool const r = _player->pass ();
                        lm.lock ();
-                       if (r) {
+                       /* We must check _pending_seek_position again here as it may have been set while lm was unlocked */
+                       if (r && !_pending_seek_position) {
                                _finished = true;
                                _arrived.notify_all ();
                                break;
index 2cb49c1a6c2ab49fd6cf3961e97fe5544f77b26e..c2c5d8ca5e990a75c8516992b0bf0fc6f6371505 100644 (file)
@@ -58,19 +58,19 @@ private:
        VideoRingBuffers _video;
        AudioRingBuffers _audio;
 
+       /** mutex to protect _pending_seek_position, _pending_seek_acurate, _finished, _died, _stop_thread */
        boost::mutex _mutex;
        boost::condition _summon;
        boost::condition _arrived;
        boost::optional<DCPTime> _pending_seek_position;
        bool _pending_seek_accurate;
-
        bool _finished;
        bool _died;
+       bool _stop_thread;
 
        AudioMapping _audio_mapping;
        int _audio_channels;
 
-       bool _stop_thread;
        bool _disable_audio;
 
        boost::signals2::scoped_connection _player_video_connection;