From d4014e6e3de7cdf8168a82621cf6a5a6d47379c8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 5 Jul 2016 09:49:00 +0100 Subject: [PATCH] Fix excessive seeking with negative audio delay. Before this commit, an audio delay of -110ms on a test project would result in a seek on every video and audio fetch. This commit does two things to fix that: 1. Don't discard audio data that arrives with a timestamp before the last seek time. In the case that we are fixing we had the following sequence: - video seeks to some frame F - this causes audio data to arrive a little before F - this audio data is discarded - and audio get happens just after F - the audio code thinks it must seek rather than just pass()ing since it has no data If we keep the audio data from before the seek our _decoded will be much closer to the audio request, so a pass() is more likely to happen. 2. Extend the length of time that we will happily pass() for rather than seeking when looking for audio data. Seeking is really bad so we can tolerate quite long times here. The sensible length of this value should probably be investigated as the one in this commit is a finger-in-the-air guess. --- src/lib/audio_decoder_stream.cc | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/lib/audio_decoder_stream.cc b/src/lib/audio_decoder_stream.cc index a254356ef..bdcef598d 100644 --- a/src/lib/audio_decoder_stream.cc +++ b/src/lib/audio_decoder_stream.cc @@ -68,8 +68,14 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate) Frame const end = frame + length - 1; - if (frame < _decoded.frame || end > (_decoded.frame + length * 4)) { - /* Either we have no decoded data, or what we do have is a long way from what we want: seek */ + /* If we are less than (about) 5 seconds behind the data that we want we'll + run through it rather than seeking. + */ + Frame const slack = 5 * 48000; + + if (frame < _decoded.frame || end > (_decoded.frame + _decoded.audio->frames() + slack)) { + /* Either we have no decoded data, all our data is after the time that we + want, or what we do have is a long way from what we want: seek */ _decoder->seek (ContentTime::from_frames (frame, _content->resampled_frame_rate()), accurate); } @@ -162,20 +168,6 @@ AudioDecoderStream::audio (shared_ptr data, ContentTime time padded->copy_from (data.get(), data->frames(), 0, delta_frames); data = padded; time -= delta; - } else if (delta_frames < 0) { - /* This data comes before the seek time. Throw some data away */ - Frame const to_discard = min (-delta_frames, static_cast (data->frames())); - Frame const to_keep = data->frames() - to_discard; - if (to_keep == 0) { - /* We have to throw all this data away, so keep _seek_reference and - try again next time some data arrives. - */ - return; - } - shared_ptr trimmed (new AudioBuffers (data->channels(), to_keep)); - trimmed->copy_from (data.get(), to_keep, to_discard, 0); - data = trimmed; - time += ContentTime::from_frames (to_discard, frame_rate); } _seek_reference = optional (); } -- 2.30.2