diff options
author | wm4 <wm4@nowhere> | 2017-10-25 14:18:51 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-10-25 16:39:33 +0200 |
commit | 56d9dafbbb1a5051a40968dec297e018d04a950f (patch) | |
tree | ba93cb0f8a0bee128247ea2548ec178bf8e8e895 /demux/demux.c | |
parent | 8bf399e02ef7390becf8efddb312417ee0b82a9c (diff) | |
download | mpv-56d9dafbbb1a5051a40968dec297e018d04a950f.tar.bz2 mpv-56d9dafbbb1a5051a40968dec297e018d04a950f.tar.xz |
demux: respect timeline boundaries for cache seeks
With the timeline code, a packet at the start or end of a segment can
refer to an invisible frame. So it doesn't extend the seek range, and
the timestamp should be clipped to the actual segment range.
Also restructure recompute_keyframe_target_pts() to be hopefully less
confusing.
Diffstat (limited to 'demux/demux.c')
-rw-r--r-- | demux/demux.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/demux/demux.c b/demux/demux.c index 03895610a6..39828627fc 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -557,17 +557,25 @@ static double get_refresh_seek_pts(struct demux_internal *in) // This function does not assume dp->keyframe==true, because it deals with weird // cases like apparently seeking to non-keyframes, or pruning the complete // backbuffer, which might end up with non-keyframes even at queue start. +// The caller assumption is that the first frame decoded from this packet +// position will result in a frame with the PTS returned from this function. +// (For corner cases with non-key frames, assuming those packets are skipped.) static double recompute_keyframe_target_pts(struct demux_packet *dp) { - int keyframes = 0; + bool in_keyframe_range = false; double res = MP_NOPTS_VALUE; while (dp) { - if (dp->keyframe) - keyframes++; - if (keyframes == 2) - break; - if (keyframes == 1) - res = MP_PTS_MIN(res, dp->pts); + if (dp->keyframe) { + if (in_keyframe_range) + break; + in_keyframe_range = true; + } + if (in_keyframe_range) { + double ts = dp->pts; + if (dp->segmented && (ts < dp->start || ts > dp->end)) + ts = MP_NOPTS_VALUE; + res = MP_PTS_MIN(res, ts); + } dp = dp->next; } return res; @@ -1966,6 +1974,8 @@ static int cached_demux_control(struct demux_internal *in, int cmd, void *arg) double ts = PTS_OR_DEF(ds->queue_head->dts, ds->queue_head->pts); r->ts_start = MP_PTS_MIN(r->ts_start, ts); + if (ds->queue_tail->segmented) + r->ts_max = MP_PTS_MIN(r->ts_max, ds->queue_tail->end); } } } |