From f881a520fd7381a01232d8560a2825a66020974c Mon Sep 17 00:00:00 2001 From: "Avi Halachmi (:avih)" Date: Tue, 10 Mar 2015 20:25:30 +0200 Subject: [PATCH] win32: support get display fps --- video/out/w32_common.c | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/video/out/w32_common.c b/video/out/w32_common.c index a568880a58..db60c71aa2 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -105,6 +105,9 @@ struct vo_w32_state { int high_surrogate; ITaskbarList2 *taskbar_list; + + // updates on move/resize/displaychange + double display_fps; }; typedef struct tagDropTarget { @@ -563,6 +566,48 @@ static void wakeup_gui_thread(void *ctx) PostMessage(w32->window, WM_USER, 0, 0); } +static double vo_w32_get_display_fps(void) +{ + DEVMODE dm; + dm.dmSize = sizeof(DEVMODE); + dm.dmDriverExtra = 0; + if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm)) + return -1; + + // May return 0 or 1 which "represent the display hardware's default refresh rate" + // https://msdn.microsoft.com/en-us/library/windows/desktop/dd183565%28v=vs.85%29.aspx + // mpv validates this value with a threshold of 1, so don't return exactly 1 + if (dm.dmDisplayFrequency == 1) + return 0; + + // dm.dmDisplayFrequency is an integer which is rounded down, so it's + // highly likely that 23 represents 24/1.001, 59 represents 60/1.001, etc. + // A caller can always reproduce the original value by using floor. + double rv = dm.dmDisplayFrequency; + switch (dm.dmDisplayFrequency) { + case 23: + case 29: + case 59: + case 71: + case 119: + rv = (rv + 1) / 1.001; + } + + return rv; +} + +static void update_display_fps(void *ctx) +{ + struct vo_w32_state *w32 = ctx; + + double fps = vo_w32_get_display_fps(); + if (fps != w32->display_fps) { + w32->display_fps = fps; + signal_events(w32, VO_EVENT_WIN_STATE); + MP_VERBOSE(w32, "display-fps: %f\n", fps); + } +} + static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -588,6 +633,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, ClientToScreen(w32->window, &p); w32->window_x = p.x; w32->window_y = p.y; + update_display_fps(w32); // if we moved between monitors MP_VERBOSE(w32, "move window: %d:%d\n", w32->window_x, w32->window_y); break; } @@ -596,6 +642,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, if (GetClientRect(w32->window, &r) && r.right > 0 && r.bottom > 0) { w32->dw = r.right; w32->dh = r.bottom; + update_display_fps(w32); // if we moved between monitors signal_events(w32, VO_EVENT_RESIZE); MP_VERBOSE(w32, "resize window: %d:%d\n", w32->dw, w32->dh); } @@ -745,6 +792,9 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, mouse_button = HIWORD(wParam) == 1 ? MP_MOUSE_BTN5 : MP_MOUSE_BTN6; mouse_button |= MP_KEY_STATE_UP; break; + case WM_DISPLAYCHANGE: + update_display_fps(w32); + break; } if (mouse_button) { @@ -1279,6 +1329,10 @@ static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg) talloc_free(title); return VO_TRUE; } + case VOCTRL_GET_DISPLAY_FPS: + update_display_fps(w32); + *(double*) arg = w32->display_fps; + return VO_TRUE; } return VO_NOTIMPL; }