summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-09-10 23:24:35 +0200
committerwm4 <wm4@nowhere>2020-09-10 23:24:35 +0200
commit09d3a4d39d68c3ae0b26369c0ec6cc6359ec70d1 (patch)
tree9e434d4bf04bbd8f4d4b7365edc7976fcc12063f
parent78bbd62d3b7facd1886443e1553cda32a73163f8 (diff)
downloadmpv-09d3a4d39d68c3ae0b26369c0ec6cc6359ec70d1.tar.bz2
mpv-09d3a4d39d68c3ae0b26369c0ec6cc6359ec70d1.tar.xz
player: clamp relative seek base time to nominal duration
Since b74c09efbf7, audio-only files let you seek to arbitrary points beyond the end of the file (but still displayed the time clamped to the nominal file duration). This was confusing and just not wanted. The reason is probably that the commit removed setting the audio PTS for data before the seek target, so if you seek past the end of the file, the audio PTS is never set. This in turn means the logic to determine the current playback time has no PTS at all, and thus falls back to the seek PTS. This happened in the past for other reasons (like efe43d768f). I have enough of this, so I'm just changing the code to clamp the seek timestamp to a "known" range. Do this when seeking ends, because in the fallback case, the playback time shouldn't be stuck at e.g. "end + seek_argument". Also do it when initiating a new seek (mp_seek), because if the previous seek hasn't finished yet, it shouldn't add them up and allow it to go "out of range" either. The latter is especially relevant for hr-seeks. Doing this clamping is problematic because the duration is a possibly invalid value from the demuxer, or just missing. Especially with timestamp resets, fun sometimes happens, and in these situations it might be better not to clamp. One could argue you should just use the last audio timestamp returned by the decoder or demuxer (even if that directly conflicts with --end), but that sounds even more hairy. In summary: what a dumb waste of time, what the fuck.
-rw-r--r--player/playloop.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/player/playloop.c b/player/playloop.c
index 44ccb4819b..0c78ca5940 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -261,7 +261,7 @@ static void mp_seek(MPContext *mpctx, struct seek_params seek)
return;
bool hr_seek_very_exact = seek.exact == MPSEEK_VERY_EXACT;
- double current_time = get_current_time(mpctx);
+ double current_time = get_playback_time(mpctx);
if (current_time == MP_NOPTS_VALUE && seek.type == MPSEEK_RELATIVE)
return;
if (current_time == MP_NOPTS_VALUE)
@@ -1150,6 +1150,12 @@ static void handle_playback_restart(struct MPContext *mpctx)
mpctx->playback_pts, mp_status_str(mpctx->audio_status),
mp_status_str(mpctx->video_status));
+ // To avoid strange effects when using relative seeks, especially if
+ // there are no proper audio & video timestamps (seeks after EOF).
+ double length = get_time_length(mpctx);
+ if (mpctx->last_seek_pts != MP_NOPTS_VALUE && length >= 0)
+ mpctx->last_seek_pts = MPCLAMP(mpctx->last_seek_pts, 0, length);
+
// Continuous seeks past EOF => treat as EOF instead of repeating seek.
if (mpctx->seek.type == MPSEEK_RELATIVE && mpctx->seek.amount > 0 &&
mpctx->video_status == STATUS_EOF &&