summaryrefslogtreecommitdiff
path: root/src/lib/audio_decoder_stream.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2016-10-07 16:22:38 +0100
committerCarl Hetherington <cth@carlh.net>2016-11-17 01:06:31 +0000
commit97d39f46795af78b84d5f7bc9118a188f2864781 (patch)
tree354ad3d03ba0bf545fc76102c907dab2d31a0b08 /src/lib/audio_decoder_stream.cc
parent987e2daa218ab39c6ddc3780667eedaab1c0872e (diff)
A possibly-better approach to seeking.
Before this commit, decoders try to guess whether they should request a seek based on what they have in their buffers. This seems reasonable for video and audio, which will always (I think) have some data lying around to give an indication of where their parent decoders are in the timeline. It doesn't work so well for subtitles, as the storage of subs is cleared out based on time (+/- 5s of "now") so there is a good chance that the storage will be empty. This gives the subtitle decoder no chance of knowing where its parent is, so it's very likely to seek. This commit asks the parent decoder to seek if it wants to, and it decides based on a knowledge of roughly where it is in the timeline. Hence the sub-decoders just see if they have got the data that is being requested, and if not they suggest to the parent that it might like to seek. They then start calling pass(). Hence the parent should only seek if some calls to pass() are not going to elicit the required data in a reasonable time.
Diffstat (limited to 'src/lib/audio_decoder_stream.cc')
-rw-r--r--src/lib/audio_decoder_stream.cc30
1 files changed, 18 insertions, 12 deletions
diff --git a/src/lib/audio_decoder_stream.cc b/src/lib/audio_decoder_stream.cc
index b7b96ddd4..c14dc654e 100644
--- a/src/lib/audio_decoder_stream.cc
+++ b/src/lib/audio_decoder_stream.cc
@@ -70,17 +70,23 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
_log->log (String::compose ("-> ADS has request for %1 %2", frame, length), LogEntry::TYPE_DEBUG_DECODE);
- Frame const end = frame + length - 1;
-
- /* 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;
+ Frame const from = frame;
+ Frame const to = from + length;
+ Frame const have_from = _decoded.frame;
+ Frame const have_to = _decoded.frame + _decoded.audio->frames();
+
+ optional<Frame> missing;
+ if (have_from > from || have_to < to) {
+ /* We need something */
+ if (have_from < from && from < have_to) {
+ missing = have_to;
+ } else {
+ missing = from;
+ }
+ }
- 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);
+ if (missing) {
+ _decoder->maybe_seek (ContentTime::from_frames (*missing, _content->resampled_frame_rate()), accurate);
}
/* Offset of the data that we want from the start of _decoded.audio
@@ -98,7 +104,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
if (accurate) {
/* Keep stuffing data into _decoded until we have enough data, or the subclass does not want to give us any more */
while (
- (_decoded.frame > frame || (_decoded.frame + _decoded.audio->frames()) < end) &&
+ (_decoded.frame > frame || (_decoded.frame + _decoded.audio->frames()) <= to) &&
!_decoder->pass (Decoder::PASS_REASON_AUDIO, accurate)
)
{}
@@ -106,7 +112,7 @@ AudioDecoderStream::get (Frame frame, Frame length, bool accurate)
decoded_offset = frame - _decoded.frame;
_log->log (
- String::compose ("Accurate ADS::get has offset %1 from request %2 and available %3", decoded_offset, frame, _decoded.frame),
+ String::compose ("Accurate ADS::get has offset %1 from request %2 and available %3", decoded_offset, frame, have_from),
LogEntry::TYPE_DEBUG_DECODE
);
} else {