diff options
author | wm4 <wm4@nowhere> | 2016-01-22 00:24:49 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-01-22 00:25:44 +0100 |
commit | 657dd4b8072934e26b1df1f37daa829fe6b36ede (patch) | |
tree | 85d97027539920bb8e39b40a997f2b2ebc94a848 | |
parent | 50c701574dc6b52a695e417586875aa0066592e8 (diff) | |
download | mpv-657dd4b8072934e26b1df1f37daa829fe6b36ede.tar.bz2 mpv-657dd4b8072934e26b1df1f37daa829fe6b36ede.tar.xz |
video: don't wait for last video frame in the normal case
Even though the timing logic is correct, it tends to mess with looping
videos and such in unappreciated ways.
It also has to be admitted that most file formats seem not to properly
define the duration of the last video frame (or libavformat does not
export it in a useful way), so whether or not we should use the demuxer
reported framerate for the last frame is questionable. (Still, why would
you essentially just discard the last frame?)
The timing logic is kept, but disabled for video with "normal" FPS
values. In particular, we want to keep it for displaying images, which
implicitly set the frame duration to 1 second by reporting 1 FPS. It's
also good for slide shows with mf://.
Fixes #2745.
-rw-r--r-- | player/video.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/player/video.c b/player/video.c index 21629b8990..e9f9f5855d 100644 --- a/player/video.c +++ b/player/video.c @@ -1142,8 +1142,9 @@ static void calculate_frame_duration(struct MPContext *mpctx) if (pts0 != MP_NOPTS_VALUE && pts1 != MP_NOPTS_VALUE && pts1 >= pts0) duration = pts1 - pts0; } else { - // E.g. last frame on EOF. - duration = demux_duration; + // E.g. last frame on EOF. Only use it if it's significant. + if (demux_duration >= 0.1) + duration = demux_duration; } // The following code tries to compensate for rounded Matroska timestamps @@ -1207,8 +1208,11 @@ void write_video(struct MPContext *mpctx, double endpts) if (r == VD_EOF) { int prev_state = mpctx->video_status; - mpctx->video_status = - vo_still_displaying(vo) ? STATUS_DRAINING : STATUS_EOF; + mpctx->video_status = STATUS_EOF; + if (mpctx->num_past_frames > 0 && mpctx->past_frames[0].duration > 0) { + if (vo_still_displaying(vo)) + mpctx->video_status = STATUS_DRAINING; + } mpctx->delay = 0; mpctx->last_av_difference = 0; MP_DBG(mpctx, "video EOF (status=%d)\n", mpctx->video_status); |