summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-05-13 16:25:39 +0200
committerwm4 <wm4@nowhere>2018-05-24 19:56:34 +0200
commit2fc59ea8b34691a66811a6481b2a6f0a61ed62e5 (patch)
tree90655c7d9c31164097c22b8546246cf65139e456
parent9ceccd6fca553ec4f310685d02b1f088117cd9ba (diff)
downloadmpv-2fc59ea8b34691a66811a6481b2a6f0a61ed62e5.tar.bz2
mpv-2fc59ea8b34691a66811a6481b2a6f0a61ed62e5.tar.xz
demux: streams that reached EOF shouldn't restrict the seek range
Normally, the seek range is the minimum overlap of the cached ranges of each stream. But if one of the streams ends earlier, this leads to the seek range getting cut off, even if you could seek there. Change it so that EOF streams cannot restrict the end of the seek range. They can only extend it. This is the opposite from not-EOF streams, so they need to be handled separately. In particular, they get exluded from normal end range calculation, but when full EOF is reached, all streams are EOF, and the maximum end time can be used to set the seek end time. (In theory we could also take the max with the demuxer signaled total file duration, but let's not for now.) Also, if a stream is completely empty, essentially skip it, instead of considering the range unseekable. (Also, we don't need to mess with seek_start in this case, because it will be NOPTS and is skipped anyway.)
-rw-r--r--demux/demux.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 73d4927002..aba950b9ab 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -508,23 +508,32 @@ static void update_seek_ranges(struct demux_cached_range *range)
range->is_bof = true;
range->is_eof = true;
+ double max_end_pts = MP_NOPTS_VALUE;
+
for (int n = 0; n < range->num_streams; n++) {
struct demux_queue *queue = range->streams[n];
if (queue->ds->selected && queue->ds->eager) {
range->seek_start = MP_PTS_MAX(range->seek_start, queue->seek_start);
- range->seek_end = MP_PTS_MIN(range->seek_end, queue->seek_end);
+
+ if (queue->is_eof) {
+ max_end_pts = MP_PTS_MAX(max_end_pts, queue->seek_end);
+ } else {
+ range->seek_end = MP_PTS_MIN(range->seek_end, queue->seek_end);
+ }
range->is_eof &= queue->is_eof;
range->is_bof &= queue->is_bof;
- if (queue->seek_start >= queue->seek_end) {
- range->seek_start = range->seek_end = MP_NOPTS_VALUE;
- break;
- }
+ bool empty = queue->is_eof && !queue->head;
+ if (queue->seek_start >= queue->seek_end && !empty)
+ goto broken;
}
}
+ if (range->is_eof)
+ range->seek_end = max_end_pts;
+
// Sparse stream behavior is not very clearly defined, but usually we don't
// want it to restrict the range of other streams, unless
// This is incorrect in any of these cases:
@@ -552,7 +561,12 @@ static void update_seek_ranges(struct demux_cached_range *range)
}
if (range->seek_start >= range->seek_end)
- range->seek_start = range->seek_end = MP_NOPTS_VALUE;
+ goto broken;
+
+ return;
+
+broken:
+ range->seek_start = range->seek_end = MP_NOPTS_VALUE;
}
// Remove queue->head from the queue. Does not update in->fw_bytes/in->fw_packs.