Skip to content

Commit

Permalink
cocoa-cb: add support for macOS color space transformation (EDR/HDR)
Browse files Browse the repository at this point in the history
by default utilises the color space of the screen on which the window is
located. if a specific value is defined, it will instead be utilised.

depending on the chosen color space the macOS EDR (HDR) support is
activated and that OS's transformation (tone mapping) is used.

Fixes mpv-player#7341
  • Loading branch information
Akemi committed May 5, 2024
1 parent cb75ecf commit 9530c25
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 2 deletions.
31 changes: 31 additions & 0 deletions DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6285,6 +6285,37 @@ them.

macOS and cocoa-cb only.

``--cocoa-cb-output-csp=<csp>``
This sets the color space of the layer to activate the macOS color
transformation. Depending on the color space used the system's EDR (HDR)
support will be activated. To get correct results, this needs to be set to
the color primaries/transfer characteristics of the VO target. It is recommended
to use this switch together with ``--target-trc`` and ``--target-prim``.

``<csp>`` can be one of the following:

:auto: Sets the color space to the icc profile of the
screen (default).
:display-p3: DCI P3 primaries, a D65 white point and the sRGB
transfer function.
:display-p3-hlg: DCI P3 primaries, a D65 white point and the Hybrid
Log-Gamma (HLG) transfer function.
:display-p3-pq: DCI P3 primaries, a D65 white point and the Perceptual
Quantizer (PQ) transfer function.
:display-p3-linear: DCI P3 primaries, a D65 white point and linear transfer function.
:dci-p3: DCI P3 color space.
:bt.2020: ITU BT.2020 color space.
:bt.2020-linear: ITU BT.2020 color space and linear transfer function.
:bt.2100-hlg: ITU BT.2100 and the Hybrid Log-Gamma (HLG) transfer function.
:bt.2100-pq: ITU BT.2100 and the Perceptual Quantizer (PQ) transfer function.
:bt.709: ITU BT.709 color space.
:srgb: sRGB colorimetry and non-linear transfer function.
:srgb-linear: Same as sRGB but linear transfer function.
:rgb-linear: RGB and linear transfer function.
:adobe: Adobe RGB (1998) color space.

macOS and cocoa-cb only.

``--macos-title-bar-appearance=<appearance>``
Sets the appearance of the title bar (default: auto). Not all combinations
of appearances and ``--macos-title-bar-material`` materials make sense or
Expand Down
12 changes: 12 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,18 @@ if features['cocoa'] and features['swift']
'video/out/mac/window.swift')
endif

macos_11_features = get_option('macos-11-features').require(
macos_sdk_version.version_compare('>= 11'),
error_message: 'A macos sdk version >= 11 could not be found!',
)
features += {'macos-11-features': macos_11_features.allowed()}

macos_12_features = get_option('macos-12-features').require(
macos_sdk_version.version_compare('>= 12'),
error_message: 'A macos sdk version >= 12 could not be found!',
)
features += {'macos-12-features': macos_12_features.allowed()}

macos_cocoa_cb = get_option('macos-cocoa-cb').require(
features['cocoa'] and features['gl-cocoa'] and features['swift'],
error_message: 'Either cocoa, gl-cocoa or swift could not be found!',
Expand Down
2 changes: 2 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ option('videotoolbox-pl', type: 'feature', value: 'auto', description: 'Videotoo
option('vulkan-interop', type: 'feature', value: 'auto', description: 'Vulkan graphics interop')

# macOS features
option('macos-11-features', type: 'feature', value: 'auto', description: 'macOS 11 SDK Features')
option('macos-12-features', type: 'feature', value: 'auto', description: 'macOS 12 SDK Features')
option('macos-cocoa-cb', type: 'feature', value: 'auto', description: 'macOS libmpv backend')
option('macos-media-player', type: 'feature', value: 'auto', description: 'macOS Media Player support')
option('macos-touchbar', type: 'feature', value: 'auto', description: 'macOS Touch Bar support')
Expand Down
19 changes: 19 additions & 0 deletions osdep/mac/app_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ enum {
RENDER_TIMER_PRECISE,
};

enum {
MAC_CSP_AUTO = -1,
MAC_CSP_DISPLAY_P3,
MAC_CSP_DISPLAY_P3_HLG,
MAC_CSP_DISPLAY_P3_PQ,
MAC_CSP_DISPLAY_P3_LINEAR,
MAC_CSP_DCI_P3,
MAC_CSP_BT_2020,
MAC_CSP_BT_2020_LINEAR,
MAC_CSP_BT_2100_HLG,
MAC_CSP_BT_2100_PQ,
MAC_CSP_BT_709,
MAC_CSP_SRGB,
MAC_CSP_SRGB_LINEAR,
MAC_CSP_RGB_LINEAR,
MAC_CSP_ADOBE,
};

struct macos_opts {
int macos_title_bar_appearance;
int macos_title_bar_material;
Expand All @@ -46,6 +64,7 @@ struct macos_opts {
int macos_render_timer;
int cocoa_cb_sw_renderer;
bool cocoa_cb_10bit_context;
int cocoa_cb_output_csp;
};

void cocoa_init_media_keys(void);
Expand Down
19 changes: 18 additions & 1 deletion osdep/mac/app_bridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,22 @@
{"cocoa-cb-sw-renderer", OPT_CHOICE(cocoa_cb_sw_renderer,
{"auto", -1}, {"no", 0}, {"yes", 1})},
{"cocoa-cb-10bit-context", OPT_BOOL(cocoa_cb_10bit_context)},
{"cocoa-cb-output-csp", OPT_CHOICE(cocoa_cb_output_csp,
{"auto", MAC_CSP_AUTO},
{"display-p3", MAC_CSP_DISPLAY_P3},
{"display-p3-hlg", MAC_CSP_DISPLAY_P3_HLG},
{"display-p3-pq", MAC_CSP_DISPLAY_P3_PQ},
{"display-p3-linear", MAC_CSP_DISPLAY_P3_LINEAR},
{"dci-p3", MAC_CSP_DCI_P3},
{"bt.2020", MAC_CSP_BT_2020},
{"bt.2020-linear", MAC_CSP_BT_2020_LINEAR},
{"bt.2100-hlg", MAC_CSP_BT_2100_HLG},
{"bt.2100-pq", MAC_CSP_BT_2100_PQ},
{"bt.709", MAC_CSP_BT_709},
{"srgb", MAC_CSP_SRGB},
{"srgb-linear", MAC_CSP_SRGB_LINEAR},
{"rgb-linear", MAC_CSP_RGB_LINEAR},
{"adobe", MAC_CSP_ADOBE})},
{0}
},
.size = sizeof(struct macos_opts),
Expand All @@ -63,7 +79,8 @@
.macos_fs_animation_duration = -1,
.macos_render_timer = RENDER_TIMER_CALLBACK,
.cocoa_cb_sw_renderer = -1,
.cocoa_cb_10bit_context = true
.cocoa_cb_10bit_context = true,
.cocoa_cb_output_csp = MAC_CSP_AUTO,
},
};

Expand Down
8 changes: 8 additions & 0 deletions osdep/mac/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ if get_option('optimization') != '0'
swift_flags += '-O'
endif

if macos_11_features.allowed()
swift_flags += ['-D', 'HAVE_MACOS_11_FEATURES']
endif

if macos_12_features.allowed()
swift_flags += ['-D', 'HAVE_MACOS_12_FEATURES']
endif

if macos_cocoa_cb.allowed()
swift_flags += ['-D', 'HAVE_MACOS_COCOA_CB']
endif
Expand Down
50 changes: 49 additions & 1 deletion video/out/cocoa_cb_common.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,55 @@ class CocoaCB: Common, EventSubscriber {
}

libmpv.setRenderICCProfile(colorSpace)
layer?.colorspace = colorSpace.cgColorSpace
layer?.colorspace = getColorSpace()
}

func getColorSpace() -> CGColorSpace? {
guard let colorSpace = window?.screen?.colorSpace?.cgColorSpace else {
log.warning("Couldn't retrieve ICC Profile, no color space available")
return nil
}

let outputCsp = Int(option.mac.cocoa_cb_output_csp)

switch outputCsp {
case MAC_CSP_AUTO: return colorSpace
case MAC_CSP_DISPLAY_P3: return CGColorSpace(name: CGColorSpace.displayP3)
case MAC_CSP_DISPLAY_P3_HLG: return CGColorSpace(name: CGColorSpace.displayP3_HLG)
case MAC_CSP_DISPLAY_P3_PQ: return CGColorSpace(name: CGColorSpace.displayP3_PQ)
case MAC_CSP_DCI_P3: return CGColorSpace(name: CGColorSpace.dcip3)
case MAC_CSP_BT_2020: return CGColorSpace(name: CGColorSpace.itur_2020)
case MAC_CSP_BT_709: return CGColorSpace(name: CGColorSpace.itur_709)
case MAC_CSP_SRGB: return CGColorSpace(name: CGColorSpace.sRGB)
case MAC_CSP_SRGB_LINEAR: return CGColorSpace(name: CGColorSpace.linearSRGB)
case MAC_CSP_RGB_LINEAR: return CGColorSpace(name: CGColorSpace.genericRGBLinear)
case MAC_CSP_ADOBE: return CGColorSpace(name: CGColorSpace.adobeRGB1998)
default: break
}

#if HAVE_MACOS_11_FEATURES
if #available(macOS 11.0, *) {
switch outputCsp {
case MAC_CSP_BT_2100_HLG: return CGColorSpace(name: CGColorSpace.itur_2100_HLG)
case MAC_CSP_BT_2100_PQ: return CGColorSpace(name: CGColorSpace.itur_2100_PQ)
default: break
}
}
#endif

#if HAVE_MACOS_12_FEATURES
if #available(macOS 12.0, *) {
switch outputCsp {
case MAC_CSP_DISPLAY_P3_LINEAR: return CGColorSpace(name: CGColorSpace.linearDisplayP3)
case MAC_CSP_BT_2020_LINEAR: return CGColorSpace(name: CGColorSpace.linearITUR_2020)
default: break
}
}
#endif

log.warning("Couldn't retrieve configured color space, falling back to auto")

return colorSpace
}

override func windowDidEndAnimation() {
Expand Down
2 changes: 2 additions & 0 deletions video/out/mac/common.swift
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,8 @@ class Common: NSObject {
titleBar?.set(material: Int(option.mac.macos_title_bar_material))
case TypeHelper.toPointer(&option.macPtr.pointee.macos_title_bar_color):
titleBar?.set(color: option.mac.macos_title_bar_color)
case TypeHelper.toPointer(&option.macPtr.pointee.cocoa_cb_output_csp):
updateICCProfile()
default:
break
}
Expand Down
1 change: 1 addition & 0 deletions video/out/mac/gl_layer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class GLLayer: CAOpenGLLayer {
super.init()
autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
backgroundColor = NSColor.black.cgColor
wantsExtendedDynamicRangeContent = true

if bufferDepth > 8 {
contentsFormat = .RGBA16Float
Expand Down
1 change: 1 addition & 0 deletions video/out/mac/view.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class View: NSView, CALayerDelegate {
super.init(frame: frame)
autoresizingMask = [.width, .height]
wantsBestResolutionOpenGLSurface = true
wantsExtendedDynamicRangeOpenGLSurface = true
registerForDraggedTypes([ .fileURL, .URL, .string ])
}

Expand Down

0 comments on commit 9530c25

Please sign in to comment.