From 0a2fe723109c6a8fbb61ea5721b5a475e4b480d0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 19 Apr 2017 09:24:59 +0100 Subject: [PATCH] Various fixes to seeking with audio. --- src/lib/audio_merger.cc | 11 +++++++++++ src/lib/ffmpeg_decoder.cc | 4 +++- src/lib/player.cc | 19 ++++++++++++++++++- src/lib/resampler.cc | 6 ++++++ src/lib/resampler.h | 1 + src/wx/film_viewer.cc | 6 ++++++ 6 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/lib/audio_merger.cc b/src/lib/audio_merger.cc index 4bed4b3a5..ecfdfdc27 100644 --- a/src/lib/audio_merger.cc +++ b/src/lib/audio_merger.cc @@ -64,22 +64,31 @@ AudioMerger::pull (DCPTime time) BOOST_FOREACH (Buffer i, _buffers) { if (i.period().to <= time) { /* Completely within the pull period */ + DCPOMATIC_ASSERT (i.audio->frames() > 0); out.push_back (make_pair (i.audio, i.time)); } else if (i.time < time) { /* Overlaps the end of the pull period */ shared_ptr audio (new AudioBuffers (i.audio->channels(), frames(DCPTime(time - i.time)))); audio->copy_from (i.audio.get(), audio->frames(), 0, 0); + DCPOMATIC_ASSERT (audio->frames() > 0); out.push_back (make_pair (audio, i.time)); i.audio->trim_start (audio->frames ()); i.time += DCPTime::from_frames(audio->frames(), _frame_rate); + DCPOMATIC_ASSERT (i.audio->frames() > 0); new_buffers.push_back (i); } else { /* Not involved */ + DCPOMATIC_ASSERT (i.audio->frames() > 0); new_buffers.push_back (i); } } _buffers = new_buffers; + + for (list, DCPTime> >::const_iterator i = out.begin(); i != out.end(); ++i) { + DCPOMATIC_ASSERT (i->first->frames() > 0); + } + return out; } @@ -88,6 +97,7 @@ void AudioMerger::push (boost::shared_ptr audio, DCPTime time) { DCPOMATIC_ASSERT (time >= _last_pull); + DCPOMATIC_ASSERT (audio->frames() > 0); DCPTimePeriod period (time, time + DCPTime::from_frames (audio->frames(), _frame_rate)); @@ -129,6 +139,7 @@ AudioMerger::push (boost::shared_ptr audio, DCPTime time) if (before == _buffers.end() && after == _buffers.end()) { /* New buffer */ + DCPOMATIC_ASSERT (part->frames() > 0); _buffers.push_back (Buffer (part, time, _frame_rate)); } else if (before != _buffers.end() && after == _buffers.end()) { /* We have an existing buffer before this one; append new data to it */ diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 604864a14..4635cd5a3 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -339,7 +339,9 @@ FFmpegDecoder::seek (ContentTime time, bool accurate) avcodec_flush_buffers (video_codec_context()); } - /* XXX: should be flushing audio buffers? */ + BOOST_FOREACH (shared_ptr i, ffmpeg_content()->ffmpeg_audio_streams()) { + avcodec_flush_buffers (i->stream(_format_context)->codec); + } if (subtitle_codec_context ()) { avcodec_flush_buffers (subtitle_codec_context ()); diff --git a/src/lib/player.cc b/src/lib/player.cc index 44e2d1652..2a5452e1e 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -699,6 +699,10 @@ Player::audio_flush (shared_ptr piece, AudioStreamPtr stream) } pair, Frame> ro = r->flush (); + if (ro.first->frames() == 0) { + return; + } + ContentAudio content_audio; content_audio.audio = ro.first; content_audio.frame = ro.second; @@ -713,6 +717,8 @@ Player::audio_flush (shared_ptr piece, AudioStreamPtr stream) void Player::audio_transform (shared_ptr content, AudioStreamPtr stream, ContentAudio content_audio, DCPTime time) { + DCPOMATIC_ASSERT (content_audio.audio->frames() > 0); + /* Gain */ if (content->gain() != 0) { @@ -758,6 +764,8 @@ Player::audio_transform (shared_ptr content, AudioStreamPtr stream void Player::audio (weak_ptr wp, AudioStreamPtr stream, ContentAudio content_audio) { + DCPOMATIC_ASSERT (content_audio.audio->frames() > 0); + shared_ptr piece = wp.lock (); if (!piece) { return; @@ -770,6 +778,9 @@ Player::audio (weak_ptr wp, AudioStreamPtr stream, ContentAudio content_a if (stream->frame_rate() != content->resampled_frame_rate()) { shared_ptr r = resampler (content, stream, true); pair, Frame> ro = r->run (content_audio.audio, content_audio.frame); + if (ro.first->frames() == 0) { + return; + } content_audio.audio = ro.first; content_audio.frame = ro.second; } @@ -797,6 +808,7 @@ Player::audio (weak_ptr wp, AudioStreamPtr stream, ContentAudio content_a return; } else if (end > piece->content->end()) { Frame const remaining_frames = DCPTime(piece->content->end() - time).frames_round(_film->audio_frame_rate()); + DCPOMATIC_ASSERT (remaining_frames > 0); shared_ptr cut (new AudioBuffers (content_audio.audio->channels(), remaining_frames)); cut->copy_from (content_audio.audio.get(), remaining_frames, 0, 0); content_audio.audio = cut; @@ -887,10 +899,15 @@ Player::seek (DCPTime time, bool accurate) _audio_processor->flush (); } + for (ResamplerMap::iterator i = _resamplers.begin(); i != _resamplers.end(); ++i) { + i->second->flush (); + i->second->reset (); + } + BOOST_FOREACH (shared_ptr i, _pieces) { + i->done = false; if (i->content->position() <= time && time < i->content->end()) { i->decoder->seek (dcp_to_content_time (i, time), accurate); - i->done = false; } } diff --git a/src/lib/resampler.cc b/src/lib/resampler.cc index 1a0c6073d..4498dccb5 100644 --- a/src/lib/resampler.cc +++ b/src/lib/resampler.cc @@ -200,3 +200,9 @@ Resampler::flush () delete[] buffer; return make_pair (out, _next_out.get ()); } + +void +Resampler::reset () +{ + src_reset (_src); +} diff --git a/src/lib/resampler.h b/src/lib/resampler.h index 9d620b962..9e9304fb4 100644 --- a/src/lib/resampler.h +++ b/src/lib/resampler.h @@ -33,6 +33,7 @@ public: std::pair, Frame> run (boost::shared_ptr, Frame); std::pair, Frame> flush (); + void reset (); void set_fast (); private: diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 942a0fedc..40efdce61 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -666,9 +666,15 @@ FilmViewer::seek (DCPTime t, bool accurate) return; } + bool const was_running = stop (); + _butler->seek (t, accurate); _last_seek_accurate = accurate; get (); + + if (was_running) { + start (); + } } void -- 2.30.2