From ffcad1a72b9a3bf5a7ac5ddcbfa71ec19b6faf9b Mon Sep 17 00:00:00 2001 From: "Avi Halachmi (:avih)" Date: Fri, 1 May 2015 17:05:28 +0300 Subject: [PATCH] vo: improve frame drop logic on high playback rate Commit f1746741dee6000b7fd139e7a10f72aba0674b3b changed the drop logic to have more slack (drop more frames but less frequent) to prevent drops due to timing jitter when the clip and screen have similar rates. However, if the clip has higher rate than the screen (or just higher playback rate), then that policy hurts smoothness since these "chunked drops" look worse than one frame drop at a time. This patch restores the old drop logic when the playback frame rate is higher than ~5% above the screen refresh rate, and solves this issue. Fixes #1897 --- video/out/vo.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/video/out/vo.c b/video/out/vo.c index 70f682263e..0b197763a0 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -608,14 +608,22 @@ static bool render_frame(struct vo *vo) if (!in->hasframe_rendered) duration = -1; // disable framedrop - // if the clip and display have similar/identical fps, it's possible that + // If the clip and display have similar/identical fps, it's possible that // we'll be very slightly late frequently due to timing jitter, or if the // clip/container timestamps are not very accurate. - // so if we dropped the previous frame, keep dropping until we're aligned + // So if we dropped the previous frame, keep dropping until we're aligned // perfectly, else, allow some slack (1 vsync) to let it settle into a rhythm. + // On low clip fps, we don't drop anyway and the slack logic doesn't matter. + // If the clip fps is more than ~5% above screen fps, we remove this slack + // and use "normal" logic to allow more regular drops of 1 frame at a time. + bool use_slack = duration > (0.95 * in->vsync_interval); in->dropped_frame = duration >= 0 && + use_slack ? ((in->dropped_frame && end_time < next_vsync) || - (end_time < prev_vsync)); // hard threshold - 1 vsync late + (end_time < prev_vsync)) // hard threshold - 1 vsync late + : + end_time < next_vsync; // normal frequent drops + in->dropped_frame &= !(vo->driver->caps & VO_CAP_FRAMEDROP); in->dropped_frame &= (vo->global->opts->frame_dropping & 1);