|author||wm4 <wm4@nowhere>||2019-10-06 22:20:10 +0200|
|committer||wm4 <wm4@nowhere>||2019-10-06 23:31:58 +0200|
video: always decode 2 frames on playback restart
Unless --video-latency-hacks, always decode 2 frames on playback restart. This in turn will always compute the correct frame duration (even for the first frame), which in turn happens to fix that playback with an image at the beginning breaks display. If a still image precedes video, and the size/format of the frame is different from that of the video following it, the incorrect frame duration caused vo_reconfig2() to be called early, causing the window to resize, and the renderer to clear the image to black. Specifically, it hit the default value of 1 second duration (for still images), so the image was displayed for 1 second, and changed to black until the next proper video frame was displayed. Normally this does not happen. Even if a video file displays still images, it normally repeats the still image at the video's FPS (which is sane). But you can construct such files, or use EDL to construct something similarly behaving. This change may increase seek latency a bit in audio video-sync mode (the default). It needs to wait until 2 frames are decoded, before it bothers to display the first frame. This is done even when seeking. In theory it might be good to introduce a "seek preview" mode, which shows the target image without all the preparations needed for starting playback. (For example, it could not decode audio.) But since I'm using video-sync=display-resample, which already needed to always decode 2 frames, I don't think this is a terribly high priority, nor do I consider the slightly slower seeking a regression. Fixes: #6765
1 files changed, 2 insertions, 2 deletions
diff --git a/player/video.c b/player/video.c
index 58115081d1..1d800a96d3 100644
@@ -417,12 +417,12 @@ static int get_req_frames(struct MPContext *mpctx, bool eof)
if (mpctx->opts->untimed || mpctx->video_out->driver->untimed)
+ // Normally require at least 2 frames, so we can compute a frame duration.
int min = mpctx->opts->video_latency_hacks ? 1 : 2;
// On the first frame, output a new frame as quickly as possible.
- // But display-sync likes to have a correct frame duration always.
if (mpctx->video_pts == MP_NOPTS_VALUE)
- return mpctx->opts->video_sync == VS_DEFAULT ? 1 : min;
+ return min;
int req = vo_get_num_req_frames(mpctx->video_out);
return MPCLAMP(req, min, MP_ARRAY_SIZE(mpctx->next_frames) - 1);