mirror of https://github.com/mpv-player/mpv
player: set playback_pts in hr-seek past EOF case
Hr-seek past the last frame instantly enters EOF, which means handle_playback_time() will not set playback_pts to the video PTS (as all video frames are skipped), which leads to the playback time being taken from the last seek target. This results in confusing behavior, especially since the seek time will be clipped to the file duration for display, but not for further relative seeks. Obviously, the time should be set to the last video frame, so use the last video frame as fallback if both audio and video have ended. Also, since the same problem exists with audio-only playback, add a fallback for audio PTS too. We don't know which was the "last" fragment of media played (to decide whether to use the audio or video PTS as the fallback), but it doesn't matter since the maximum works. This could lead to some undesired effects. In particular the audio PTS is basically a bad guess, and is for example not clipped against --end. (But the ridiculous way audio syncing and clamping currently works, I'm not going to touch that shit unless I rewrite it completely.) The cover art case is slightly broken: using --keep-open with keyframe seeks will result in 0 as playback PTS (the video PTS). OK, who cares, it got late. Also casually get rid of last_vo_pts, since that barely made any sense at all. Fixes: #7487
This commit is contained in:
parent
009d1ffda6
commit
efe43d768f
|
@ -6211,7 +6211,7 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags,
|
|||
struct mp_decoder_wrapper *dec = track ? track->dec : NULL;
|
||||
if (dec) {
|
||||
mp_decoder_wrapper_control(dec, VDCTRL_REINIT, NULL);
|
||||
double last_pts = mpctx->last_vo_pts;
|
||||
double last_pts = mpctx->video_pts;
|
||||
if (last_pts != MP_NOPTS_VALUE)
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, last_pts, MPSEEK_EXACT, 0);
|
||||
}
|
||||
|
|
|
@ -369,10 +369,8 @@ typedef struct MPContext {
|
|||
/* timestamp of video frame currently visible on screen
|
||||
* (or at least queued to be flipped by VO) */
|
||||
double video_pts;
|
||||
// Last seek target.
|
||||
double last_seek_pts;
|
||||
// As video_pts, but is not reset when seeking away. (For the very short
|
||||
// period of time until a new frame is decoded and shown.)
|
||||
double last_vo_pts;
|
||||
// Frame duration field from demuxer. Only used for duration of the last
|
||||
// video frame.
|
||||
double last_frame_duration;
|
||||
|
|
|
@ -1390,7 +1390,6 @@ static void play_current_file(struct MPContext *mpctx)
|
|||
mpctx->filename = NULL;
|
||||
mpctx->shown_aframes = 0;
|
||||
mpctx->shown_vframes = 0;
|
||||
mpctx->last_vo_pts = MP_NOPTS_VALUE;
|
||||
mpctx->last_chapter_seek = -2;
|
||||
mpctx->last_chapter_pts = MP_NOPTS_VALUE;
|
||||
mpctx->last_chapter = -2;
|
||||
|
|
|
@ -947,7 +947,6 @@ static void handle_keep_open(struct MPContext *mpctx)
|
|||
if (mpctx->vo_chain) {
|
||||
if (!vo_has_frame(mpctx->video_out)) // EOF not reached normally
|
||||
seek_to_last_frame(mpctx);
|
||||
mpctx->playback_pts = mpctx->last_vo_pts;
|
||||
}
|
||||
if (opts->keep_open_pause) {
|
||||
if (mpctx->ao)
|
||||
|
@ -1075,6 +1074,15 @@ static void handle_playback_time(struct MPContext *mpctx)
|
|||
mpctx->audio_status < STATUS_EOF)
|
||||
{
|
||||
mpctx->playback_pts = playing_audio_pts(mpctx);
|
||||
} else if (mpctx->video_status == STATUS_EOF &&
|
||||
mpctx->audio_status == STATUS_EOF)
|
||||
{
|
||||
double apts =
|
||||
mpctx->ao_chain ? mpctx->ao_chain->last_out_pts : MP_NOPTS_VALUE;
|
||||
double vpts = mpctx->video_pts;
|
||||
double mpts = MP_PTS_MAX(apts, vpts);
|
||||
if (mpts != MP_NOPTS_VALUE)
|
||||
mpctx->playback_pts = mpts;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1169,7 +1169,6 @@ void write_video(struct MPContext *mpctx)
|
|||
}
|
||||
|
||||
mpctx->video_pts = mpctx->next_frames[0]->pts;
|
||||
mpctx->last_vo_pts = mpctx->video_pts;
|
||||
mpctx->last_frame_duration =
|
||||
mpctx->next_frames[0]->pkt_duration / mpctx->video_speed;
|
||||
|
||||
|
|
Loading…
Reference in New Issue