-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Use float OpenGL buffer and extended linear colorspaces for HDR playback #4174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Added a nasty hack to workaround a weird behavior about set Basically once |
+1! I pulled this PR and tested with some of my own HDR videos and will confirm they look 10x better, especially on my MacBook's built-in display, but also on my HDR display. Hopefully the maintainers can take a look at it soon. CC @CarterLi |
iina/VideoView.swift
Outdated
videoLayer.wantsExtendedDynamicRangeContent = false | ||
// It seems that once there is a layer with colorspace set to something extended linear, | ||
// then setting colorspace to nil will cause falling back to ExtendedLinearsRGB | ||
videoLayer.colorspace = CGColorSpaceCreateDeviceRGB() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
colorspace is nil by default. Disabling HDR mode should revert all changes to the default value as HDR was never enabled. In addition, since we are testing videoLayer.colorspace != nil
in Line 286, setting videoLayer.colorspace
to non-nil makes the resetting code be executed every time when setICCProfile being called
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem was, as I mentioned in the commit, once videoLayer.colorspace
was set to CGColorspace.extendedLinear*
before, then setting it to nil
would not clear it, instead, it would fallback to kCGColorspaceExtendedLinearSRGB
and completely throw off SDR color. I'm not sure whether it is the intended behavior.
Setting it to CGColorspaceCreateDeviceSRGB()
should also turn off color management on the buffer like nil
. I do agree condition should be updated, though.
Attached is the screenshot trying to turn off HDR without the last commit d943877.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It turns out that it is kCGLPFAColorFloat, kCGLPFAColorSize, CGLPixelFormatAttribute(64),
that makes nil fallback to kCGColorSpaceExtendedLinearSRGB
. You may remove these code and try again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static let SRGB = CGColorSpaceCreateDeviceRGB()
videoLayer.colorspace = VideoView.SRGB
if videoLayer.colorspace != VideoView.SRGB {
videoLayer.colorspace = VideoView.SRGB
...
In addition, videoLayer.colorspace = VideoView.SRGB
should be set in init()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It turns out that it is
kCGLPFAColorFloat, kCGLPFAColorSize, CGLPixelFormatAttribute(64),
that makes nil fallback tokCGColorSpaceExtendedLinearSRGB
. You may remove these code and try again
The problem is output of 10-bit color depth videos would be incorrect without them. These ensure pixel format of OpenGL buffer be 16-bit float-point instead of default 8-bit.
The following test pattern Mehanik HDR10 test patterns/03. Grayscale/04. 10bit test/01. test_10-bit_23.976.mp4
from https://www.avsforum.com/threads/hdr10-test-patterns-set.2943380/ will demonstrate the problem. Unfortunately, because all screenshots I could take would be clamped to 8-bit color depth, I cannot directly provide a picture here.
Direct download link: test-10bit.mp4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a lot of HDR test videos.
I meant that it was not once videoLayer.colorspace was set to CGColorspace.extendedLinear* before
caused the problem
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right indeed, the comment and problematic commit message were removed.
|
Yes, that's right. So current code should work, but it just doesn't (so we have #3772 and probably #4075). In that term I agree with @low-batt and believe switch to MoltenVK and Metal would be the long-term solution. But now at least we can try to make current result a little better. |
Tested. While I didn't see much difference for PQ, HLG was improved greatly. However there are several issues should be addressed. |
7751179
to
1406085
Compare
Compare IINA 1.3.1 to Quicktime playing New York 8k | 4k HDR specifically looking at the clock in the beginning. Playing that video IINA's image of the clock face looks pretty close to that displayed by Quicktime. When that video is played with IINA built with the changes in this PR the video is darker than before and definitely looks worse than IINA 1.3.1. When I play the video shown at the start of this PR with IINA 1.3.1 I see the blown out highlights shown in the screenshots. Playing that video with IINA built with the changes in this PR the video is significantly improved. But it does not match Quicktime. The picture is now slightly dimmer than Quicktime. This is especially visible when comparing the light bulb in the lamp. From the comments in the PR I was expecting the picture to match? I'm testing on a MacBookPro18,2 with the XDR display running macOS 13.1. I believe @CarterLi has added this fix to IINA+, so I also tested with IINA+. I had to build it myself since builds are failing reporting:
With IINA+ the test video is darker still. Possibly the difference is that IINA+ is setting
|
Can we apply this patch only to HLG videos and keep PQ videos as it was? So that PQ videos can be displayed without any conversion. |
6dd3bcf
to
c04649f
Compare
That's a great idea. I did some experiments and found that actually mapping everything to PQ seeming to also solve HLG problem. And this approach can avoid the mess for getting mpv output linear values. |
c04649f
to
ad84162
Compare
Comparing IINA built with the latest version of this PR to Quicktime when playing New York 8k | 4k HDR the results are pretty close. If stop the video at the beginning and look at the shutters above the clock you can see the picture displayed by Quicktime is slightly brighter. When I play the video shown at the start of this PR the results are again pretty close. It also looks to me that Quicktime is just slightly brighter. There are open mpv issues with trying to match Quicktime behavior. We may be up against those issues. This is definitely an improvement. @CarterLi do you approve of these changes or still have concerns? |
LGTM |
I suggest that iina should adopt iina-plus's manual tone-mapping setting feature, for low max-brightness monitors ( < 1000 nit ) |
On adopting iina-plus's manual tone-mapping setting, I've been hoping we'd figure out a way to automatically determine a display's brightness. By the way, the IINA+ builds are still failing. The latest one seems to be stuck in the queued state. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pulled PR locally, built and tested. Definitely an improvement over the current behavior with the HDR videos I tested.
FYI: #4075 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a small change, other parts LGTM
Description:
This WWDC 2021 presentation suggested to use floating point OpenGL buffers (see 20:56) and extended linear colorspaces (see 18:08) for EDR content.
One may also note that original mpv mac output code also use floating point OpenGL buffers for 10-bit playback, which format are most HDR videos in. Further, the official Apple Documentation notes that
itur_2020_PQ
colorspaces are deprecated.It turns out that these are all we need to match
QuickTime.app
's HDR output.Device: Macbook Pro 14" with M1 pro
Test clip: download
develop
branch