if (!_film) {
_player.reset ();
- _closed_captions_dialog->set_player (_player);
recreate_butler ();
_frame.reset ();
refresh_panel ();
return;
}
- _closed_captions_dialog->set_player (_player);
-
_player->set_always_burn_open_subtitles ();
_player->set_play_referenced ();
_butler->disable_audio ();
}
+ _closed_captions_dialog->set_butler (_butler);
+
if (was_running) {
start ();
}
_audio.startStream ();
}
- cout << "start playback at " << to_string(_video_position) << "\n";
-
_playing = true;
_dropped = 0;
timer ();
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
}
}
+DCPTime
+FilmViewer::uncorrected_time () const
+{
+ if (_audio.isStreamRunning ()) {
+ return DCPTime::from_seconds (const_cast<RtAudio*>(&_audio)->getStreamTime());
+ }
+
+ return _video_position;
+}
+
DCPTime
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) {