From e5a4dae004733c76dbae186af92080b72d28e345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 11 Dec 2021 18:09:17 +0800 Subject: [PATCH] HDR: Use MPV instead of ffmpeg to detect primaries and trc Pros: Much easier to detect HDR content, including cases of swtiching video track, play list and network resources. The code can also be simplified. Cons: Display-P3 will no longer be enabled because MPV doesn't honor mastering display metadata. Fixes #6 --- iina/Base.lproj/InspectorWindowController.xib | 102 ++++++++++++------ iina/InspectorWindowController.swift | 22 ++-- iina/MPVController.swift | 4 + iina/PlayerCore.swift | 12 ++- iina/VideoView.swift | 62 +++-------- .../InspectorWindowController.strings | 4 +- 6 files changed, 106 insertions(+), 100 deletions(-) diff --git a/iina/Base.lproj/InspectorWindowController.xib b/iina/Base.lproj/InspectorWindowController.xib index 128b8c6babb..5772df0617a 100644 --- a/iina/Base.lproj/InspectorWindowController.xib +++ b/iina/Base.lproj/InspectorWindowController.xib @@ -23,7 +23,6 @@ - @@ -46,12 +45,13 @@ + - + @@ -64,19 +64,19 @@ - + - + - + - + @@ -84,7 +84,7 @@ - + @@ -140,7 +140,10 @@ - + + + + @@ -156,7 +159,7 @@ - + @@ -204,7 +207,7 @@ - + @@ -212,7 +215,7 @@ - + @@ -278,6 +281,17 @@ + + + + + + + + + + + @@ -311,15 +325,24 @@ - + + + + + + + + + + @@ -331,7 +354,8 @@ - + + @@ -342,10 +366,14 @@ + + + + @@ -354,17 +382,22 @@ + + + + + @@ -372,20 +405,30 @@ + + + + + + + + + + @@ -395,24 +438,34 @@ + + + + + + + + + + @@ -824,22 +877,6 @@ - - - - - - - - - - - - - - - - @@ -858,7 +895,6 @@ - @@ -868,7 +904,6 @@ - @@ -879,13 +914,10 @@ - - - @@ -1164,7 +1196,7 @@ - + diff --git a/iina/InspectorWindowController.swift b/iina/InspectorWindowController.swift index d6e83ad8777..30dfb25f321 100644 --- a/iina/InspectorWindowController.swift +++ b/iina/InspectorWindowController.swift @@ -31,6 +31,7 @@ class InspectorWindowController: NSWindowController, NSTableViewDelegate, NSTabl @IBOutlet weak var vformatField: NSTextField! @IBOutlet weak var vcodecField: NSTextField! @IBOutlet weak var vdecoderField: NSTextField! + @IBOutlet weak var vcolorspaceField: NSTextField! @IBOutlet weak var vprimariesField: NSTextField! @IBOutlet weak var voField: NSTextField! @@ -44,7 +45,6 @@ class InspectorWindowController: NSWindowController, NSTableViewDelegate, NSTabl @IBOutlet weak var abitrateField: NSTextField! @IBOutlet weak var asamplerateField: NSTextField! - @IBOutlet weak var filePrimariesField: NSTextField! @IBOutlet weak var trackIdField: NSTextField! @IBOutlet weak var trackDefaultField: NSTextField! @IBOutlet weak var trackForcedField: NSTextField! @@ -143,12 +143,6 @@ class InspectorWindowController: NSWindowController, NSTableViewDelegate, NSTabl let fileSize = controller.getInt(MPVProperty.fileSize) self.fileSizeField.stringValue = "\(FloatingPointByteCountFormatter.string(fromByteCount: fileSize))B" - - let sigPeak = controller.getDouble(MPVProperty.videoParamsSigPeak); - self.filePrimariesField.stringValue = sigPeak > 0 - ? "\(controller.getString(MPVProperty.videoParamsPrimaries) ?? "?") / \(controller.getString(MPVProperty.videoParamsGamma) ?? "?") (\(sigPeak > 1 ? "H" : "S")DR)" - : "N/A"; - self.setLabelColor(self.filePrimariesField, by: sigPeak > 0) // track list @@ -199,14 +193,20 @@ class InspectorWindowController: NSWindowController, NSTableViewDelegate, NSTabl v.stringValue = value ?? "N/A" self.setLabelColor(v, by: value != nil) } + + let sigPeak = controller.getDouble(MPVProperty.videoParamsSigPeak); + self.vprimariesField.stringValue = sigPeak > 0 + ? "\(controller.getString(MPVProperty.videoParamsPrimaries) ?? "?") / \(controller.getString(MPVProperty.videoParamsGamma) ?? "?") (\(sigPeak > 1 ? "H" : "S")DR)" + : "N/A"; + self.setLabelColor(self.vprimariesField, by: sigPeak > 0) - if controller.fileLoaded { + if PlayerCore.lastActive.mainWindow.loaded && controller.fileLoaded { let colorspace = PlayerCore.lastActive.mainWindow.videoView.videoLayer.colorspace?.name; - self.vprimariesField.stringValue = colorspace == nil ? "Unspecified (SDR)" : String(colorspace!) + " (HDR)" + self.vcolorspaceField.stringValue = colorspace == nil ? "Unspecified (SDR)" : String(colorspace!) + " (HDR)" } else { - self.vprimariesField.stringValue = "N/A" + self.vcolorspaceField.stringValue = "N/A" } - self.setLabelColor(self.vprimariesField, by: controller.fileLoaded) + self.setLabelColor(self.vcolorspaceField, by: controller.fileLoaded) } } diff --git a/iina/MPVController.swift b/iina/MPVController.swift index 69b6509ccd9..151ad1d66a3 100644 --- a/iina/MPVController.swift +++ b/iina/MPVController.swift @@ -770,6 +770,10 @@ class MPVController: NSObject { player.postNotification(.iinaVIDChanged) player.sendOSD(.track(player.info.currentTrack(.video) ?? .noneVideoTrack)) + if #available(macOS 10.15, *) { + player.refreshEdrMode() + } + case MPVOption.TrackSelection.aid: player.info.aid = Int(getInt(MPVOption.TrackSelection.aid)) guard player.mainWindow.loaded else { break } diff --git a/iina/PlayerCore.swift b/iina/PlayerCore.swift index 22330e66b59..c6b86bdb452 100644 --- a/iina/PlayerCore.swift +++ b/iina/PlayerCore.swift @@ -1119,10 +1119,6 @@ class PlayerCore: NSObject { NowPlayingInfoManager.updateInfo(withTitle: true) } - if #available(macOS 10.15, *), !info.isNetworkResource { - mainWindow.videoView.requestHdrModeForFile(path) - } - // Auto load backgroundQueueTicket += 1 let shouldAutoLoadFiles = info.shouldAutoLoadFiles @@ -1245,6 +1241,14 @@ class PlayerCore: NSObject { } } + @available(macOS 10.15, *) + func refreshEdrMode() { + guard mainWindow.loaded else { return } + DispatchQueue.main.async { + self.mainWindow.videoView.refreshEdrMode() + } + } + @objc private func reEnableOSDAfterFileLoading() { info.disableOSDForFileLoading = false diff --git a/iina/VideoView.swift b/iina/VideoView.swift index c87bba2e51d..7ab1bb48e30 100644 --- a/iina/VideoView.swift +++ b/iina/VideoView.swift @@ -40,9 +40,6 @@ class VideoView: NSView { var pendingRedrawAfterEnteringPIP = false; - // HDR - var hdrMetadata: (primaries: String?, transfer: String?, max_luminance: Float?, min_luminance: Float?)?; - // MARK: - Attributes override var mouseDownCanMoveWindow: Bool { @@ -265,14 +262,10 @@ class VideoView: NSView { @available(macOS 10.15, *) extension VideoView { - func requestHdrModeForFile(_ path: String) { - hdrMetadata = importFileColorSpace(path) - refreshEdrMode() - } - func refreshEdrMode() { - guard let displayId = currentDisplay, let meta = hdrMetadata else { return }; - let edrEnabled = requestEdrMode(meta.primaries, meta.transfer, meta.max_luminance, meta.min_luminance) + guard player.mainWindow.loaded else { return } + guard let displayId = currentDisplay else { return }; + let edrEnabled = requestEdrMode() let edrAvailable = edrEnabled != false if player.info.hdrAvailable != edrAvailable { player.mainWindow.quickSettingView.pleaseChangeHdrAvailable(available: edrAvailable) @@ -280,20 +273,22 @@ extension VideoView { if edrEnabled != true { setICCProfile(displayId) } } - func requestEdrMode(_ primaries: String?, _ transfer: String?, _ max_luminance: Float?, _ min_luminance: Float?) -> Bool? { - guard let transfer = transfer, let primaries = primaries else { - // SDR content - return false; - } + func requestEdrMode() -> Bool? { + guard let mpv = player.mpv else { return false } + + guard mpv.getDouble(MPVProperty.videoParamsSigPeak) > 1.0 else { return false } // SDR content + guard (window?.screen?.maximumPotentialExtendedDynamicRangeColorComponentValue ?? 1.0) > 1.0 else { Logger.log("HDR: HDR video was found but the display does not support EDR mode"); return false; } + guard let primaries = mpv.getString(MPVProperty.videoParamsPrimaries), let gamma = mpv.getString(MPVProperty.videoParamsGamma) else { return false } + var name: CFString? = nil; switch primaries { case "display-p3": - switch transfer { + switch gamma { case "pq": if #available(macOS 10.15.4, *) { name = CGColorSpace.displayP3_PQ @@ -307,7 +302,7 @@ extension VideoView { } case "bt.2020": // deprecated - switch transfer { + switch gamma { case "pq": if #available(macOS 11.0, *) { name = CGColorSpace.itur_2020_PQ @@ -324,11 +319,8 @@ extension VideoView { name = CGColorSpace.itur_2020 } - case "dci-p3": - name = CGColorSpace.dcip3 - default: - Logger.log("HDR: Unknown HDR color space information transfer=\(transfer) primaries=\(primaries)"); + Logger.log("HDR: Unknown HDR color space information gamma=\(gamma) primaries=\(primaries)"); return false; } @@ -338,36 +330,10 @@ extension VideoView { videoLayer.colorspace = CGColorSpace(name: name!) player.mpv.setString(MPVOption.GPURendererOptions.iccProfile, "") - player.mpv.setString(MPVOption.GPURendererOptions.targetTrc, transfer) + player.mpv.setString(MPVOption.GPURendererOptions.targetTrc, gamma) player.mpv.setString(MPVOption.GPURendererOptions.targetPrim, primaries) - // videoLayer.edrMetadata = CAEDRMetadata.hdr10(minLuminance: min_luminance, maxLuminance: max_luminance, opticalOutputScale: 100); // OpenGL layer doesn't support edrMetadata return true; } - - private func importFileColorSpace(_ path: String) -> (primaries: String?, transfer: String?, max_luminance: Float?, min_luminance: Float?) - { - var result: (primaries: String?, transfer: String?, max_luminance: Float?, min_luminance: Float?) - guard let colorspaceData = FFmpegController.getColorSpaceMetadata(forFile: path) else { return result } - - colorspaceData.forEach { (k, v) in - switch k as? String { - case "primaries": - result.primaries = v as? String - case "color-trc": - result.transfer = v as? String - case "max_luminance": - result.max_luminance = (v as? NSNumber)?.floatValue - case "min_luminance": - result.min_luminance = (v as? NSNumber)?.floatValue - default: - break - } - } - - Logger.log("HDR: Received color space metadata for HDR activation: \(result)") - - return result; - } } fileprivate func displayLinkCallback( diff --git a/iina/zh-Hans.lproj/InspectorWindowController.strings b/iina/zh-Hans.lproj/InspectorWindowController.strings index d714ac6db4f..99a57912939 100644 --- a/iina/zh-Hans.lproj/InspectorWindowController.strings +++ b/iina/zh-Hans.lproj/InspectorWindowController.strings @@ -85,8 +85,8 @@ /* Class = "NSTextFieldCell"; title = "Editions:"; ObjectID = "POj-mQ-zP9"; */ "POj-mQ-zP9.title" = "集数:"; -/* Class = "NSTextFieldCell"; title = "Primaries:"; ObjectID = "tpN-Ov-ew9"; */ -"tpN-Ov-ew9.title" = "色域:"; +/* Class = "NSTextFieldCell"; title = "Primaries:"; ObjectID = "1kw-LO-KmJ"; */ +"1kw-LO-KmJ.title" = "色域:"; /* Class = "NSTextFieldCell"; title = "Format:"; ObjectID = "PQD-yB-mm6"; */ "PQD-yB-mm6.title" = "格式:";