Fix length of player output so it can be either the film's length or playlist's lengt...
[dcpomatic.git] / src / wx / film_viewer.cc
index f921f83bd7ac4285f5cd358471ca5924446a849c..cac6e8c28aebbb4687d5c21b3164c419b129be9f 100644 (file)
@@ -164,7 +164,7 @@ FilmViewer::set_film (shared_ptr<Film> film)
        }
 
        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);
@@ -182,6 +182,10 @@ FilmViewer::set_film (shared_ptr<Film> film)
        _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;
 
@@ -286,6 +290,7 @@ FilmViewer::suspend ()
 void
 FilmViewer::resume ()
 {
+       DCPOMATIC_ASSERT (_suspended > 0);
        --_suspended;
        if (_playing && !_suspended) {
                if (_audio.isStreamOpen()) {
@@ -309,6 +314,17 @@ FilmViewer::start ()
                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 ();
@@ -446,7 +462,7 @@ FilmViewer::seek (DCPTime t, bool accurate)
        }
 
        if (t >= _film->length ()) {
-               t = _film->length ();
+               t = _film->length() - one_video_frame();
        }
 
        suspend ();
@@ -455,8 +471,14 @@ FilmViewer::seek (DCPTime t, bool accurate)
        _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)) {}
        }
 
@@ -657,6 +679,14 @@ FilmViewer::dropped () const
        return _video_view->dropped ();
 }
 
+
+int
+FilmViewer::errored () const
+{
+       return _video_view->errored ();
+}
+
+
 int
 FilmViewer::gets () const
 {