From fb7c5804bbb6046472406f3fa8426784cbda4408 Mon Sep 17 00:00:00 2001 From: Akemi Date: Thu, 16 Jun 2016 19:28:14 +0200 Subject: cocoa: fix actual display refresh rate retrieval We have two problems here. 1. CVDisplayLinkGetActualOutputVideoRefreshPeriod, like the name suggests, returns a frame period and not a refresh rate. using this as screen_fps just leads to a slideshow. why didn't this break video playback on OS X completely? the answer to this leads us to the second problem. 2. it seems that CVDisplayLinkGetActualOutputVideoRefreshPeriod always returns 0 if used without CVDisplayLinkSetOutputCallback and hence always fell back to CVDisplayLinkGetNominalOutputVideoRefreshPeriod. adding a callback to CVDisplayLink solves this problem. the callback function at this moment doesn't do anything but could possibly used in the future. --- video/out/cocoa_common.m | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index e1d1e18d57..bd841d3a88 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -49,6 +49,9 @@ #include "common/msg.h" +static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, + const CVTimeStamp* outputTime, CVOptionFlags flagsIn, + CVOptionFlags* flagsOut, void* displayLinkContext); static int vo_cocoa_fullscreen(struct vo *vo); static void cocoa_rm_fs_screen_profile_observer(struct vo_cocoa_state *s); static void cocoa_add_screen_reconfiguration_observer(struct vo *vo); @@ -373,21 +376,26 @@ static void vo_cocoa_update_screen_fps(struct vo *vo) CVDisplayLinkRef link; CVDisplayLinkCreateWithActiveCGDisplays(&link); + CVDisplayLinkSetOutputCallback(link, &displayLinkCallback, NULL); CVDisplayLinkStart(link); CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext( link, s->cgl_ctx, CGLGetPixelFormat(s->cgl_ctx)); - s->screen_fps = CVDisplayLinkGetActualOutputVideoRefreshPeriod(link); + double display_period = CVDisplayLinkGetActualOutputVideoRefreshPeriod(link); - if (s->screen_fps == 0) { + if (display_period > 0) { + s->screen_fps = 1/display_period; + } else { // Fallback to using Nominal refresh rate from DisplayLink, // CVDisplayLinkGet *Actual* OutputVideoRefreshPeriod seems to // return 0 on some Apple devices. Use the nominal refresh period // instead. const CVTime t = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link); - if (!(t.flags & kCVTimeIsIndefinite)) + if (!(t.flags & kCVTimeIsIndefinite)) { s->screen_fps = (t.timeScale / (double) t.timeValue); + MP_VERBOSE(vo, "Falling back to %f for display sync.\n", s->screen_fps); + } } CVDisplayLinkRelease(link); @@ -395,6 +403,13 @@ static void vo_cocoa_update_screen_fps(struct vo *vo) flag_events(vo, VO_EVENT_WIN_STATE); } +static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, + const CVTimeStamp* outputTime, CVOptionFlags flagsIn, + CVOptionFlags* flagsOut, void* displayLinkContext) +{ + return kCVReturnSuccess; +} + static void vo_cocoa_update_screen_info(struct vo *vo, struct mp_rect *out_rc) { struct vo_cocoa_state *s = vo->cocoa; -- cgit v1.2.3