pot/merge.
[dcpomatic.git] / src / lib / player.cc
index 7e21ef937b82a98f5ff3198ac07c2ea0a469cbfb..499aa2a389c0c1545d82b915f17daef218d8df4e 100644 (file)
@@ -109,7 +109,7 @@ Player::setup_pieces ()
                        continue;
                }
 
-               shared_ptr<Decoder> decoder = decoder_factory (i, _film->log());
+               shared_ptr<Decoder> decoder = decoder_factory (i, _film->log(), _fast);
                FrameRateChange frc (i->active_video_frame_rate(), _film->video_frame_rate());
 
                if (!decoder) {
@@ -151,6 +151,7 @@ Player::setup_pieces ()
                }
        }
 
+       _stream_states.clear ();
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
                if (i->content->audio) {
                        BOOST_FOREACH (AudioStreamPtr j, i->content->audio->streams()) {
@@ -189,6 +190,7 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque
                property == SubtitleContentProperty::SHADOW ||
                property == SubtitleContentProperty::EFFECT_COLOUR ||
                property == FFmpegContentProperty::SUBTITLE_STREAM ||
+               property == FFmpegContentProperty::FILTERS ||
                property == VideoContentProperty::COLOUR_CONVERSION
                ) {
 
@@ -345,8 +347,8 @@ DCPTime
 Player::content_video_to_dcp (shared_ptr<const Piece> piece, Frame f) const
 {
        /* See comment in dcp_to_content_video */
-       DCPTime const d = DCPTime::from_frames (f * piece->frc.factor(), piece->frc.dcp) - DCPTime (piece->content->trim_start (), piece->frc);
-       return max (DCPTime (), d + piece->content->position ());
+       DCPTime const d = DCPTime::from_frames (f * piece->frc.factor(), piece->frc.dcp) - DCPTime(piece->content->trim_start(), piece->frc);
+       return d + piece->content->position();
 }
 
 Frame
@@ -425,6 +427,7 @@ Player::set_always_burn_subtitles (bool burn)
        _always_burn_subtitles = burn;
 }
 
+/** Sets up the player to be faster, possibly at the expense of quality */
 void
 Player::set_fast ()
 {
@@ -452,7 +455,7 @@ Player::get_reel_assets ()
 
                scoped_ptr<DCPDecoder> decoder;
                try {
-                       decoder.reset (new DCPDecoder (j, _film->log()));
+                       decoder.reset (new DCPDecoder (j, _film->log(), false));
                } catch (...) {
                        return a;
                }
@@ -524,8 +527,14 @@ Player::pass ()
        optional<DCPTime> earliest_time;
 
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
-               if (!i->done) {
-                       DCPTime const t = content_time_to_dcp (i, i->decoder->position());
+               if (i->done) {
+                       continue;
+               }
+
+               DCPTime const t = content_time_to_dcp (i, i->decoder->position());
+               if (t > i->content->end()) {
+                       i->done = true;
+               } else {
                        /* Given two choices at the same time, pick the one with a subtitle so we see it before
                           the video.
                        */
@@ -594,14 +603,15 @@ Player::pass ()
        list<pair<shared_ptr<AudioBuffers>, DCPTime> > audio = _audio_merger.pull (pull_to);
        for (list<pair<shared_ptr<AudioBuffers>, DCPTime> >::iterator i = audio.begin(); i != audio.end(); ++i) {
                if (_last_audio_time && i->second < *_last_audio_time) {
-                       /* There has been an accurate seek and we have received some audio before the seek time;
-                          discard it.
-                       */
+                       /* This new data comes before the last we emitted (or the last seek); discard it */
                        pair<shared_ptr<AudioBuffers>, DCPTime> cut = discard_audio (i->first, i->second, *_last_audio_time);
                        if (!cut.first) {
                                continue;
                        }
                        *i = cut;
+               } else if (_last_audio_time && i->second > *_last_audio_time) {
+                       /* There's a gap between this data and the last we emitted; fill with silence */
+                       fill_audio (DCPTimePeriod (*_last_audio_time, i->second));
                }
 
                emit_audio (i->first, i->second);