summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2017-04-19 09:24:59 +0100
committerCarl Hetherington <cth@carlh.net>2017-04-19 23:04:32 +0100
commit0a2fe723109c6a8fbb61ea5721b5a475e4b480d0 (patch)
tree513782d152de6976646e900b55c2665c4cd1e80e /src
parent0dc26c2ec9aba5fd5f4ca281711fb8ac5a76612b (diff)
Various fixes to seeking with audio.
Diffstat (limited to 'src')
-rw-r--r--src/lib/audio_merger.cc11
-rw-r--r--src/lib/ffmpeg_decoder.cc4
-rw-r--r--src/lib/player.cc19
-rw-r--r--src/lib/resampler.cc6
-rw-r--r--src/lib/resampler.h1
-rw-r--r--src/wx/film_viewer.cc6
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<AudioBuffers> 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<pair<shared_ptr<AudioBuffers>, 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<const AudioBuffers> 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<const AudioBuffers> 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<FFmpegAudioStream> 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> piece, AudioStreamPtr stream)
}
pair<shared_ptr<const AudioBuffers>, 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> piece, AudioStreamPtr stream)
void
Player::audio_transform (shared_ptr<AudioContent> 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<AudioContent> content, AudioStreamPtr stream
void
Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_audio)
{
+ DCPOMATIC_ASSERT (content_audio.audio->frames() > 0);
+
shared_ptr<Piece> piece = wp.lock ();
if (!piece) {
return;
@@ -770,6 +778,9 @@ Player::audio (weak_ptr<Piece> wp, AudioStreamPtr stream, ContentAudio content_a
if (stream->frame_rate() != content->resampled_frame_rate()) {
shared_ptr<Resampler> r = resampler (content, stream, true);
pair<shared_ptr<const AudioBuffers>, 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<Piece> 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<AudioBuffers> 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<Piece> 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<boost::shared_ptr<const AudioBuffers>, Frame> run (boost::shared_ptr<const AudioBuffers>, Frame);
std::pair<boost::shared_ptr<const AudioBuffers>, 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