diff options
Diffstat (limited to 'video/out/cocoa_cb_common.swift')
-rw-r--r-- | video/out/cocoa_cb_common.swift | 138 |
1 files changed, 85 insertions, 53 deletions
diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift index dd0738f7e3..b2910dba85 100644 --- a/video/out/cocoa_cb_common.swift +++ b/video/out/cocoa_cb_common.swift @@ -17,11 +17,11 @@ import Cocoa -class CocoaCB: Common { +class CocoaCB: Common, EventSubscriber { var libmpv: LibmpvHelper var layer: GLLayer? - @objc var isShuttingDown: Bool = false + var isShuttingDown: Bool = false enum State { case uninitialized @@ -30,22 +30,24 @@ class CocoaCB: Common { } var backendState: State = .uninitialized - - @objc init(_ mpvHandle: OpaquePointer) { - let newlog = mp_log_new(UnsafeMutablePointer<MPContext>(mpvHandle), mp_client_get_log(mpvHandle), "cocoacb") - libmpv = LibmpvHelper(mpvHandle, newlog) - super.init(newlog) + init(_ mpv: OpaquePointer) { + let log = LogHelper(mp_log_new(UnsafeMutablePointer(mpv), mp_client_get_log(mpv), "cocoacb")) + let option = OptionHelper(UnsafeMutablePointer(mpv), mp_client_get_global(mpv)) + libmpv = LibmpvHelper(mpv, log) + super.init(option, log) layer = GLLayer(cocoaCB: self) + AppHub.shared.event?.subscribe(self, event: .init(name: "MPV_EVENT_SHUTDOWN")) } func preinit(_ vo: UnsafeMutablePointer<vo>) { - mpv = MPVHelper(vo, log) + self.vo = vo + input = InputHelper(vo.pointee.input_ctx, option) if backendState == .uninitialized { backendState = .needsInit guard let layer = self.layer else { - log.sendError("Something went wrong, no GLLayer was initialized") + log.error("Something went wrong, no GLLayer was initialized") exit(1) } @@ -57,17 +59,19 @@ class CocoaCB: Common { func uninit() { window?.orderOut(nil) window?.close() - mpv = nil } func reconfig(_ vo: UnsafeMutablePointer<vo>) { - mpv?.vo = vo + self.vo = vo if backendState == .needsInit { DispatchQueue.main.sync { self.initBackend(vo) } - } else { + } else if option.vo.auto_window_resize { DispatchQueue.main.async { self.updateWindowSize(vo) self.layer?.update(force: true) + if self.option.vo.focus_on == 2 { + NSApp.activate(ignoringOtherApps: true) + } } } } @@ -83,17 +87,13 @@ class CocoaCB: Common { } func updateWindowSize(_ vo: UnsafeMutablePointer<vo>) { - guard let targetScreen = getTargetScreen(forFullscreen: false) ?? NSScreen.main else - { - log.sendWarning("Couldn't update Window size, no Screen available") + guard let targetScreen = getTargetScreen(forFullscreen: false) ?? NSScreen.main else { + log.warning("Couldn't update Window size, no Screen available") return } let wr = getWindowGeometry(forScreen: targetScreen, videoOut: vo) - if !(window?.isVisible ?? false) && - !(window?.isMiniaturized ?? false) && - !NSApp.isHidden - { + if !(window?.isVisible ?? false) && !(window?.isMiniaturized ?? false) && !NSApp.isHidden { window?.makeKeyAndOrderFront(nil) } layer?.atomicDrawingStart() @@ -101,11 +101,10 @@ class CocoaCB: Common { } override func displayLinkCallback(_ displayLink: CVDisplayLink, - _ inNow: UnsafePointer<CVTimeStamp>, - _ inOutputTime: UnsafePointer<CVTimeStamp>, - _ flagsIn: CVOptionFlags, - _ flagsOut: UnsafeMutablePointer<CVOptionFlags>) -> CVReturn - { + _ inNow: UnsafePointer<CVTimeStamp>, + _ inOutputTime: UnsafePointer<CVTimeStamp>, + _ flagsIn: CVOptionFlags, + _ flagsOut: UnsafeMutablePointer<CVOptionFlags>) -> CVReturn { libmpv.reportRenderFlip() return kCVReturnSuccess } @@ -116,14 +115,60 @@ class CocoaCB: Common { override func updateICCProfile() { guard let colorSpace = window?.screen?.colorSpace else { - log.sendWarning("Couldn't update ICC Profile, no color space available") + log.warning("Couldn't update ICC Profile, no color space available") return } libmpv.setRenderICCProfile(colorSpace) - if #available(macOS 10.11, *) { - 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() { @@ -167,19 +212,11 @@ class CocoaCB: Common { layer?.update(force: true) } - var controlCallback: mp_render_cb_control_fn = { ( v, ctx, e, request, d ) -> Int32 in + var controlCallback: mp_render_cb_control_fn = { ( v, ctx, e, request, data ) -> Int32 in let ccb = unsafeBitCast(ctx, to: CocoaCB.self) - // the data pointer can be a null pointer, the libmpv control callback - // provides nil instead of the 0 address like the usual control call of - // an internal vo, workaround to create a null pointer instead of nil - var data = UnsafeMutableRawPointer.init(bitPattern: 0).unsafelyUnwrapped - if let dunwrapped = d { - data = dunwrapped - } - guard let vo = v, let events = e else { - ccb.log.sendWarning("Unexpected nil value in Control Callback") + ccb.log.warning("Unexpected nil value in Control Callback") return VO_FALSE } @@ -187,10 +224,9 @@ class CocoaCB: Common { } override func control(_ vo: UnsafeMutablePointer<vo>, - events: UnsafeMutablePointer<Int32>, - request: UInt32, - data: UnsafeMutableRawPointer) -> Int32 - { + events: UnsafeMutablePointer<Int32>, + request: UInt32, + data: UnsafeMutableRawPointer?) -> Int32 { switch mp_voctrl(request) { case VOCTRL_PREINIT: DispatchQueue.main.sync { self.preinit(vo) } @@ -208,9 +244,9 @@ class CocoaCB: Common { return super.control(vo, events: events, request: request, data: data) } - func shutdown(_ destroy: Bool = false) { + func shutdown() { isShuttingDown = window?.isAnimating ?? false || - window?.isInFullscreen ?? false && Bool(mpv?.opts.native_fs ?? 1) + window?.isInFullscreen ?? false && option.vo.native_fs if window?.isInFullscreen ?? false && !(window?.isAnimating ?? false) { window?.close() } @@ -219,22 +255,18 @@ class CocoaCB: Common { uninit() uninitCommon() - libmpv.deinitRender() - libmpv.deinitMPV(destroy) + layer?.lockCglContext() + libmpv.uninit() + layer?.unlockCglContext() } func checkShutdown() { if isShuttingDown { - shutdown(true) + shutdown() } } - @objc func processEvent(_ event: UnsafePointer<mpv_event>) { - switch event.pointee.event_id { - case MPV_EVENT_SHUTDOWN: - shutdown() - default: - break - } + func handle(event: EventHelper.Event) { + if event.name == String(describing: MPV_EVENT_SHUTDOWN) { shutdown() } } } |