1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-27 17:42:17 +00:00

w32_common: implement icc-profile-auto

This adds basic support for ICC profiles. Per-monitor profiles are
supported. WCS profiles are not supported, but there is an API for
converting WCS profiles to ICC, so they might be supported in future.
I'm just not sure if anyone actually uses them.

Reloading the ICC profile when it's changed in the control panel is also
not supported. This might be possible by using the WCS APIs and watching
the registry for changes, but there is no official API for it, and as
far as I can tell, no other Windows programs can do it.
This commit is contained in:
James Ross-Gowan 2015-11-26 22:11:45 +11:00
parent 4c111fbcde
commit 69ba4f776f
2 changed files with 52 additions and 8 deletions

View File

@ -891,7 +891,8 @@ Available video output drivers are:
Automatically select the ICC display profile currently specified by
the display settings of the operating system.
NOTE: Only implemented on OS X and X11
NOTE: On Windows, the default profile must be an ICC profile. WCS
profiles are not supported.
``icc-cache-dir=<dirname>``
Store and load the 3D LUTs created from the ICC profile in this directory.

View File

@ -30,6 +30,7 @@
#include "input/keycodes.h"
#include "input/input.h"
#include "input/event.h"
#include "stream/stream.h"
#include "common/msg.h"
#include "common/common.h"
#include "vo.h"
@ -63,6 +64,7 @@ struct vo_w32_state {
HMONITOR monitor; // Handle of the current screen
struct mp_rect screenrc; // Size and virtual position of the current screen
char *color_profile; // Path of the current screen's color profile
// last non-fullscreen extends (updated only on fullscreen or on initialization)
int prev_width;
@ -606,7 +608,25 @@ static double get_refresh_rate_from_gdi(const wchar_t *device)
return rv;
}
static void update_display_fps(struct vo_w32_state *w32)
static char *get_color_profile(void *ctx, const wchar_t *device)
{
char *name = NULL;
HDC ic = CreateICW(device, NULL, NULL, NULL);
if (!ic)
goto done;
wchar_t wname[MAX_PATH + 1];
if (!GetICMProfileW(ic, &(DWORD){ MAX_PATH }, wname))
goto done;
name = mp_to_utf8(ctx, wname);
done:
if (ic)
DeleteDC(ic);
return name;
}
static void update_display_info(struct vo_w32_state *w32)
{
HMONITOR monitor = MonitorFromWindow(w32->window, MONITOR_DEFAULTTOPRIMARY);
if (w32->monitor == monitor)
@ -631,12 +651,26 @@ static void update_display_fps(struct vo_w32_state *w32)
w32->display_fps = freq;
signal_events(w32, VO_EVENT_WIN_STATE);
}
char *color_profile = get_color_profile(w32, mi.szDevice);
if ((color_profile == NULL) != (w32->color_profile == NULL) ||
(color_profile && strcmp(color_profile, w32->color_profile)))
{
if (color_profile)
MP_VERBOSE(w32, "color-profile: %s\n", color_profile);
talloc_free(w32->color_profile);
w32->color_profile = color_profile;
color_profile = NULL;
signal_events(w32, VO_EVENT_ICC_PROFILE_CHANGED);
}
talloc_free(color_profile);
}
static void force_update_display_fps(struct vo_w32_state *w32)
static void force_update_display_info(struct vo_w32_state *w32)
{
w32->monitor = 0;
update_display_fps(w32);
update_display_info(w32);
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
@ -664,7 +698,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
update_display_info(w32); // if we moved between monitors
MP_VERBOSE(w32, "move window: %d:%d\n", w32->window_x, w32->window_y);
break;
}
@ -680,7 +714,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
// Window may have been minimized or restored
signal_events(w32, VO_EVENT_WIN_STATE);
update_display_fps(w32);
update_display_info(w32);
break;
}
case WM_SIZING:
@ -825,7 +859,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
mouse_button |= MP_KEY_STATE_UP;
break;
case WM_DISPLAYCHANGE:
force_update_display_fps(w32);
force_update_display_info(w32);
break;
}
@ -1393,9 +1427,18 @@ static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg)
return VO_TRUE;
}
case VOCTRL_GET_DISPLAY_FPS:
update_display_fps(w32);
update_display_info(w32);
*(double*) arg = w32->display_fps;
return VO_TRUE;
case VOCTRL_GET_ICC_PROFILE:
update_display_info(w32);
if (w32->color_profile) {
bstr *p = arg;
*p = stream_read_file(w32->color_profile, NULL,
w32->vo->global, 100000000); // 100 MB
return p->len ? VO_TRUE : VO_FALSE;
}
return VO_FALSE;
}
return VO_NOTIMPL;
}