summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-10-31 13:19:38 +0100
committerwm4 <wm4@nowhere>2015-10-31 13:21:16 +0100
commit8fd63c8f0cfb6c95a534f61942a5d0a0f5623b25 (patch)
treeb7067d1ea7118f2ab29f59e11d27b2258c00331c
parentb92fd602ced5f71e843ef87edf3de6cf68b05b12 (diff)
downloadmpv-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.c5
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;