diff options
author | wm4 <wm4@nowhere> | 2018-03-02 15:37:34 +0100 |
---|---|---|
committer | Jan Ekström <jeebjp@gmail.com> | 2018-03-03 02:38:01 +0200 |
commit | 775b86212d4fbe1a25ce0f1552478e0fb9a7c25e (patch) | |
tree | 1ecfd53ab5896234a4f850f808e96d6068c61dbc /player | |
parent | c917992359fdcae867b53ceab1427a1a9c6c8e78 (diff) | |
download | mpv-775b86212d4fbe1a25ce0f1552478e0fb9a7c25e.tar.bz2 mpv-775b86212d4fbe1a25ce0f1552478e0fb9a7c25e.tar.xz |
video: add option to reduce latency by 1 or 2 frames
The playback start logic explicitly waits until the first frame has been
displayed. Usually this will introduce a wait of 1 vsync. For normal
playback this doesn't matter, but with respect to low latency needs,
this only leads to additional data getting queued up in the demuxer or
network buffers.
Another thing is that the timing logic decodes 1 frame ahead (= 1 frame
extra latency) to determine the exact duration of a frame.
To be fair, there doesn't really seem to be a hard reason why this is
needed. With the current code, enabling the option does lead to A/V
desync sometimes (if the demuxer FPS is too inaccurate), and also frame
drops at playback start in some situations. But this all seems to be
avoidable, if the timing logic were to be rewritten completely, which
should probably happen in the future. Thus the new option comes with the
warning that it can be removed any time. This is also why the option has
"hack" in the name.
Diffstat (limited to 'player')
-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 b47b7293d0..e91c4ce631 100644 --- a/player/video.c +++ b/player/video.c @@ -413,13 +413,15 @@ static int get_req_frames(struct MPContext *mpctx, bool eof) if (mpctx->opts->untimed || mpctx->video_out->driver->untimed) return 1; + 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 : 2; + return mpctx->opts->video_sync == VS_DEFAULT ? 1 : min; int req = vo_get_num_req_frames(mpctx->video_out); - return MPCLAMP(req, 2, MP_ARRAY_SIZE(mpctx->next_frames) - 1); + return MPCLAMP(req, min, MP_ARRAY_SIZE(mpctx->next_frames) - 1); } // Whether it's fine to call add_new_frame() now. @@ -1149,8 +1151,10 @@ void write_video(struct MPContext *mpctx) if (mpctx->video_status < STATUS_PLAYING) { mpctx->video_status = STATUS_READY; // After a seek, make sure to wait until the first frame is visible. - vo_wait_frame(vo); - MP_VERBOSE(mpctx, "first video frame after restart shown\n"); + if (!opts->video_latency_hacks) { + vo_wait_frame(vo); + MP_VERBOSE(mpctx, "first video frame after restart shown\n"); + } } screenshot_flip(mpctx); |