summaryrefslogtreecommitdiffstats
path: root/demux/demux.h
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-11-09 09:53:46 +0100
committerwm4 <wm4@nowhere>2017-11-09 10:23:57 +0100
commit935e406d6398062ea7978d546f4da6ca8e6a216f (patch)
tree0a817601ab9dec43699c3e63e2dd56d0d992575f /demux/demux.h
parentbd4ec8e4e1e9a18a8c667a0265fe2bb0e324f8bc (diff)
downloadmpv-935e406d6398062ea7978d546f4da6ca8e6a216f.tar.bz2
mpv-935e406d6398062ea7978d546f4da6ca8e6a216f.tar.xz
demux: support multiple seekable cached ranges
Until now, the demuxer cache was limited to a single range. Extend this to multiple range. Should be useful for slow network streams. This commit changes a lot in the internal demuxer cache logic, so there's a lot of room for bugs and regressions. The logic without demuxer cache is mostly untouched, but also involved with the code changes. Or in other words, this commit probably fucks up shit. There are two things which makes multiple cached ranges rather hard: 1. the need to resume the demuxer at the end of a cached range when seeking to it 2. joining two adjacent ranges when the lowe range "grows" into it (and resuming the demuxer at the end of the new joined range) "Resuming" the demuxer means that we perform a low level seek to the end of a cached range, and properly append new packets to it, without adding packets multiple times or creating holes due to missing packets. Since audio and video never line up exactly, there is no clean "cut" possible, at which you could resume the demuxer cleanly (for 1.) or which you could use to detect that two ranges are perfectly adjacent (for 2.). The way how the demuxer interleaves multiple streams is also unpredictable. Typically you will have to expect that it randomly allows one of the streams to be ahead by a bit, and so on. To deal with this, we have heuristics in place to detect when one packet equals or is "behind" a packet that was demuxed earlier. We reuse the refresh seek logic (used to "reread" packets into the demuxer cache when enabling a track), which checks for certain packet invariants. Currently, it observes whether either the raw packet position, or the packet DTS is strictly monotonically increasing. If none of them are true, we discard old ranges when creating a new one. This heavily depends on the file format and the demuxer behavior. For example, not all file formats have DTS, and the packet position can be unset due to libavformat not always setting it (e.g. when parsers are used). At the same time, we must deal with all the complicated state used to track prefetching and seek ranges. In some complicated corner cases, we just give up and discard other seek ranges, even if the previously mentioned packet invariants are fulfilled. To handle joining, we're being particularly dumb, and require a small overlap to be confident that two ranges join perfectly. (This could be done incrementally with as little overlap as 1 packet, but corner cases would eat us: each stream needs to be joined separately, and the cache pruning logic could remove overlapping packets for other streams again.) Another restriction is that switching the cached range will always trigger an asynchronous low level seek to resume demuxing at the new range. Some users might find this annoying. Dealing with interleaved subtitles is not fully handled yet. It will clamp the seekable range to where subtitle packets are.
Diffstat (limited to 'demux/demux.h')
-rw-r--r--demux/demux.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/demux/demux.h b/demux/demux.h
index 81670fac6f..95e0f77c7c 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -40,7 +40,7 @@ enum demux_ctrl {
DEMUXER_CTRL_REPLACE_STREAM,
};
-#define MAX_SEEK_RANGES 1
+#define MAX_SEEK_RANGES 10
struct demux_seek_range {
double start, end;