Discard audio received before the time of the last accurate seek.
[dcpomatic.git] / src / lib / player.cc
index 5fb349b0e0870c3b1756564ecf052d6563ae9267..e59451abece83bf7001930b02c621873eb5a6ac1 100644 (file)
@@ -585,12 +585,20 @@ Player::pass ()
        list<pair<shared_ptr<AudioBuffers>, DCPTime> > audio = _audio_merger.pull (pull_from);
        for (list<pair<shared_ptr<AudioBuffers>, DCPTime> >::iterator i = audio.begin(); i != audio.end(); ++i) {
                if (_last_audio_time && i->second < _last_audio_time.get()) {
-                       cout << "FAIL " << to_string(i->second) << " " << to_string(_last_audio_time.get()) << "\n";
+                       /* There has been an accurate seek and we have received some audio before the seek time;
+                          discard it.
+                       */
+                       pair<shared_ptr<AudioBuffers>, DCPTime> cut = discard_audio (i->first, i->second, *_last_audio_time);
+                       if (!cut.first) {
+                               continue;
+                       }
+                       *i = cut;
                }
-               DCPOMATIC_ASSERT (!_last_audio_time || i->second >= _last_audio_time.get());
+
                if (_last_audio_time) {
                        fill_audio (DCPTimePeriod (_last_audio_time.get(), i->second));
                }
+
                Audio (i->first, i->second);
                _last_audio_time = i->second + DCPTime::from_frames(i->first->frames(), _film->audio_frame_rate());
        }
@@ -795,17 +803,13 @@ Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_a
 
        /* Remove anything that comes before the start or after the end of the content */
        if (time < piece->content->position()) {
-               DCPTime const discard_time = piece->content->position() - time;
-               Frame discard_frames = discard_time.frames_round(_film->audio_frame_rate());
-               Frame remaining_frames = content_audio.audio->frames() - discard_frames;
-               if (remaining_frames <= 0) {
+               pair<shared_ptr<AudioBuffers>, DCPTime> cut = discard_audio (content_audio.audio, time, piece->content->position());
+               if (!cut.first) {
                        /* This audio is entirely discarded */
                        return;
                }
-               shared_ptr<AudioBuffers> cut (new AudioBuffers (content_audio.audio->channels(), remaining_frames));
-               cut->copy_from (content_audio.audio.get(), remaining_frames, discard_frames, 0);
-               content_audio.audio = cut;
-               time += discard_time;
+               content_audio.audio = cut.first;
+               time = cut.second;
        } else if (time > piece->content->end()) {
                /* Discard it all */
                return;
@@ -907,6 +911,8 @@ Player::seek (DCPTime time, bool accurate)
                i->second->reset ();
        }
 
+       _audio_merger.clear ();
+
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
                i->done = false;
                if (i->content->position() <= time && time < i->content->end()) {
@@ -917,11 +923,9 @@ Player::seek (DCPTime time, bool accurate)
        if (accurate) {
                _last_video_time = time - one_video_frame ();
                _last_audio_time = time;
-               cout << "_last_audio_time -> " << to_string(time) << "\n";
        } else {
                _last_video_time = optional<DCPTime> ();
                _last_audio_time = optional<DCPTime> ();
-               cout << "_last_audio_time -> []\n";
        }
 }
 
@@ -990,3 +994,17 @@ Player::one_video_frame () const
 {
        return DCPTime::from_frames (1, _film->video_frame_rate ());
 }
+
+pair<shared_ptr<AudioBuffers>, DCPTime>
+Player::discard_audio (shared_ptr<const AudioBuffers> audio, DCPTime time, DCPTime discard_to) const
+{
+       DCPTime const discard_time = discard_to - time;
+       Frame const discard_frames = discard_time.frames_round(_film->audio_frame_rate());
+       Frame remaining_frames = audio->frames() - discard_frames;
+       if (remaining_frames <= 0) {
+               return make_pair(shared_ptr<AudioBuffers>(), DCPTime());
+       }
+       shared_ptr<AudioBuffers> cut (new AudioBuffers (audio->channels(), remaining_frames));
+       cut->copy_from (audio.get(), remaining_frames, discard_frames, 0);
+       return make_pair(cut, time + discard_time);
+}