0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 20:03:10 +02:00

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.
This commit is contained in:
Akemi 2016-06-16 19:28:14 +02:00 committed by wm4
parent 0fd5a24ecb
commit fb7c5804bb

View File

@ -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;