summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkemi <der.richter@gmx.de>2016-06-16 19:28:14 +0200
committerwm4 <wm4@nowhere>2016-06-18 19:15:34 +0200
commitfb7c5804bbb6046472406f3fa8426784cbda4408 (patch)
tree48656ec6f4b2320fea7736ff2214f3c3d5cbe2f0
parent0fd5a24ecb9a0b1d716224b2eafa487b3e2574d5 (diff)
downloadmpv-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.
-rw-r--r--video/out/cocoa_common.m21
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;