}
try {
- _player.reset (new Player (_film, _film->playlist ()));
+ _player.reset (new Player(_film, _film->playlist(), _film->length()));
_player->set_fast ();
if (_dcp_decode_reduction) {
_player->set_dcp_decode_reduction (_dcp_decode_reduction);
_film->LengthChange.connect (boost::bind(&FilmViewer::film_length_change, this));
_player->Change.connect (boost::bind (&FilmViewer::player_change, this, _1, _2, _3));
+ film_change (CHANGE_TYPE_DONE, Film::VIDEO_FRAME_RATE);
+ film_change (CHANGE_TYPE_DONE, Film::THREE_D);
+ film_length_change ();
+
/* Keep about 1 second's worth of history samples */
_latency_history_count = _film->audio_frame_rate() / _audio_block_size;
return;
}
+ /* We are about to set up the audio stream from the position of the video view.
+ If there is `lazy' seek in progress we need to wait for it to go through so that
+ _video_view->position() gives us a sensible answer.
+ */
+ while (_idle_get) {
+ idle_handler ();
+ }
+
+ /* Take the video view's idea of position as our `playhead' and start the
+ audio stream (which is the timing reference) there.
+ */
if (_audio.isStreamOpen()) {
_audio.setStreamTime (_video_view->position().seconds());
_audio.startStream ();
}
if (t >= _film->length ()) {
- t = _film->length ();
+ t = _film->length() - one_video_frame();
}
suspend ();
_butler->seek (t, accurate);
if (!_playing) {
+ /* We're not playing, so let the GUI thread get on and
+ come back later to get the next frame after the seek.
+ */
request_idle_display_next_frame ();
} else {
+ /* We're going to start playing again straight away
+ so wait for the seek to finish.
+ */
while (!_video_view->display_next_frame(false)) {}
}
return _video_view->dropped ();
}
+
+int
+FilmViewer::errored () const
+{
+ return _video_view->errored ();
+}
+
+
int
FilmViewer::gets () const
{