diff options
author | Akemi <der.richter@gmx.de> | 2016-06-16 19:28:14 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-06-18 19:15:34 +0200 |
commit | fb7c5804bbb6046472406f3fa8426784cbda4408 (patch) | |
tree | 48656ec6f4b2320fea7736ff2214f3c3d5cbe2f0 /video | |
parent | 0fd5a24ecb9a0b1d716224b2eafa487b3e2574d5 (diff) | |
download | mpv-fb7c5804bbb6046472406f3fa8426784cbda4408.tar.bz2 mpv-fb7c5804bbb6046472406f3fa8426784cbda4408.tar.xz |
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.
Diffstat (limited to 'video')
-rw-r--r-- | video/out/cocoa_common.m | 21 |
1 files 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; |