diff options
author | wm4 <wm4@nowhere> | 2015-10-31 13:19:38 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-10-31 13:21:16 +0100 |
commit | 8fd63c8f0cfb6c95a534f61942a5d0a0f5623b25 (patch) | |
tree | b7067d1ea7118f2ab29f59e11d27b2258c00331c | |
parent | b92fd602ced5f71e843ef87edf3de6cf68b05b12 (diff) | |
download | mpv-8fd63c8f0cfb6c95a534f61942a5d0a0f5623b25.tar.bz2 mpv-8fd63c8f0cfb6c95a534f61942a5d0a0f5623b25.tar.xz |
video: fix another A/V difference bug in display-sync mode
This didn't show up with cases where the frame pattern has a cycle of 1
or 2 like it is the case with 24-on-24 fps, or 24-on-60 fps. It did show
up with 25-on-60 fps. (We don't slow down 25 fps video to 24 on default
settings.)
In this case, we must not add the timing error of the next frame to the
A/V difference estimation of the current frame. Use the previous timing
error instead.
This is another bug resulting from the confusion about whether we
calculate parameters for the currently playing frame, or the one we're
about to queue.
-rw-r--r-- | player/video.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/player/video.c b/player/video.c index 857fb017bc..6c0135ea34 100644 --- a/player/video.c +++ b/player/video.c @@ -1011,6 +1011,7 @@ static void handle_display_sync_frame(struct MPContext *mpctx, double frame_duration = adjusted_duration / video_speed_correction; double ratio = (frame_duration + mpctx->display_sync_error) / vsync; int num_vsyncs = MPMAX(floor(ratio + 0.5), 0); + double prev_error = mpctx->display_sync_error; mpctx->display_sync_error += frame_duration - num_vsyncs * vsync; frame->vsync_offset = mpctx->display_sync_error * 1e6; @@ -1030,8 +1031,8 @@ static void handle_display_sync_frame(struct MPContext *mpctx, time_left = MPMAX(time_left, 0); // We also know that the timing is (necessarily) off, because we have to // align frame timings on the vsync boundaries. This is unavoidable, and - // for the sake of the video sync calculations we pretend it's perfect. - time_left -= mpctx->display_sync_error; + // for the sake of the A/V sync calculations we pretend it's perfect. + time_left += prev_error; // Likewise, we know sync is off, but is going to be compensated. time_left += drop_repeat * vsync; |