From 657dd4b8072934e26b1df1f37daa829fe6b36ede Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 22 Jan 2016 00:24:49 +0100 Subject: [PATCH] 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. --- player/video.c | 12 ++++++++---- 1 file 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);