Move sound output driver selection into new preferences tab.
[dcpomatic.git] / src / wx / film_viewer.cc
index 78efc77f655b97073cdd133badc66fc58fa225c3..893e1bf0fe4569dec8ede2d80bf75acc213b7beb 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))
@@ -129,6 +130,7 @@ FilmViewer::request_idle_get ()
        }
 
        _idle_get = true;
+       DCPOMATIC_ASSERT (signal_manager);
        signal_manager->when_idle (boost::bind(&FilmViewer::idle_handler, this));
 }
 
@@ -199,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;
        }
 
@@ -246,9 +249,7 @@ FilmViewer::recreate_butler ()
 
        _closed_captions_dialog->set_film_and_butler (_film, _butler);
 
-       if (was_running) {
-               start ();
-       }
+       resume ();
 }
 
 void
@@ -311,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).
                */
@@ -360,7 +361,7 @@ FilmViewer::display_player_video ()
 void
 FilmViewer::timer ()
 {
-       if (!_film || !_playing) {
+       if (!_film || !_playing || _suspended) {
                return;
        }
 
@@ -434,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 ()
 {
@@ -578,15 +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);
-       request_idle_get ();
 
-       if (was_running) {
-               start ();
+       if (!_playing) {
+               request_idle_get ();
+       } else {
+               /* Make sure we get a frame so that _video_position is set up before we resume */
+               while (!get(true)) {}
        }
+
+       resume ();
 }
 
 void
@@ -727,7 +754,7 @@ FilmViewer::dcp_decode_reduction () const
 DCPTime
 FilmViewer::one_video_frame () const
 {
-       return DCPTime::from_frames (1, _film->video_frame_rate());
+       return DCPTime::from_frames (1, _film ? _film->video_frame_rate() : 24);
 }
 
 /** Open a dialog box showing our film's closed captions */