More fixes for errors / crashes / misbehaviour with content changes
[dcpomatic.git] / src / wx / film_viewer.cc
index 8c1a79113c732d33d2ca054307569eba039b1b90..0e0fc4315ad7a58ff339d32c8cf4df4590718952 100644 (file)
@@ -203,7 +203,6 @@ FilmViewer::set_film (shared_ptr<Film> film)
 
        if (!_film) {
                _player.reset ();
-               _closed_captions_dialog->set_player (_player);
                recreate_butler ();
                _frame.reset ();
                refresh_panel ();
@@ -222,8 +221,6 @@ FilmViewer::set_film (shared_ptr<Film> film)
                return;
        }
 
-       _closed_captions_dialog->set_player (_player);
-
        _player->set_always_burn_open_subtitles ();
        _player->set_play_referenced ();
 
@@ -277,6 +274,8 @@ FilmViewer::recreate_butler ()
                _butler->disable_audio ();
        }
 
+       _closed_captions_dialog->set_butler (_butler);
+
        if (was_running) {
                start ();
        }
@@ -529,8 +528,6 @@ FilmViewer::start ()
                _audio.startStream ();
        }
 
-       cout << "start playback at " << to_string(_video_position) << "\n";
-
        _playing = true;
        _dropped = 0;
        timer ();
@@ -770,7 +767,10 @@ FilmViewer::set_position (DCPTime p)
 void
 FilmViewer::set_position (shared_ptr<Content> content, ContentTime t)
 {
-       set_position (_player->content_time_to_dcp (content, t));
+       optional<DCPTime> dt = _player->content_time_to_dcp (content, t);
+       if (dt) {
+               set_position (*dt);
+       }
 }
 
 void
@@ -883,6 +883,16 @@ FilmViewer::config_changed (Config::Property p)
        }
 }
 
+DCPTime
+FilmViewer::uncorrected_time () const
+{
+       if (_audio.isStreamRunning ()) {
+               return DCPTime::from_seconds (const_cast<RtAudio*>(&_audio)->getStreamTime());
+       }
+
+       return _video_position;
+}
+
 DCPTime
 FilmViewer::time () const
 {
@@ -897,7 +907,14 @@ FilmViewer::time () const
 int
 FilmViewer::audio_callback (void* out_p, unsigned int frames)
 {
-       _butler->get_audio (reinterpret_cast<float*> (out_p), frames);
+       while (true) {
+               optional<DCPTime> t = _butler->get_audio (reinterpret_cast<float*> (out_p), frames);
+               if (!t || DCPTime(uncorrected_time() - *t) < one_video_frame()) {
+                       /* There was an underrun or this audio is on time; carry on */
+                       break;
+               }
+               /* The audio we just got was (very) late; drop it and get some more. */
+       }
 
         boost::mutex::scoped_lock lm (_latency_history_mutex, boost::try_to_lock);
         if (lm) {