mpv icon indicating copy to clipboard operation
mpv copied to clipboard

washed out/overexposed output with macvk + gpu-next

Open Akemi opened this issue 3 months ago • 15 comments

mpv Information

mpv v0.40.0-357-g17a3ac4cf-dirty Copyright © 2000-2025 mpv/MPlayer/mplayer2 projects
 built on Oct  4 2025 18:54:12
libplacebo version: v7.356.0 (v7.351.0-80-g76c7076c)
FFmpeg version: 8.0
FFmpeg library versions:
   libavcodec      62.11.100
   libavdevice     62.1.100
   libavfilter     11.4.100
   libavformat     62.3.100
   libavutil       60.8.100
   libswresample   6.1.100
   libswscale      9.1.100

Other Information

- macOS version: 15.6.1
- Source of mpv: master build
- Latest known working version: N/A
- Issue started after the following happened: update of libplacebo to master

Reproduction Steps

any video with mpv --no-config

Expected Behavior

same output as current nightly build with libplacebo 7.351

Actual Behavior

output is washed out/overexposed. behavior with --no-config top left with libplacebo 7.351 (expcted) top right with libplacebo master (slightly overexposed) bottom left libplacebo master + --target-trc=bt.1886 --target-prim=bt.709 (overexposed) bottom right libplacebo master + --target-trc=bt.1886 --target-prim=bt.709 --target-colorspace-hint=yes (slightly overexposed) smaller window on the right vo=libmpv (same output as top left)

Image

same as above just with my current config (without no-config)

Image

Log File

with no-config: log libplacebo 7.351 (working): placebo-7.351.log log libplacebo master (broken): placebo-master.log

without no-config: log libplacebo 7.351 (working): placebo-7.351.log log libplacebo master (broken): placebo-master.log

Sample Files

No response

I carefully read all instruction and confirm that I did the following:

  • [x] I tested with the latest mpv version to validate that the issue is not already fixed.
  • [x] I provided all required information including system and mpv version.
  • [x] I produced the log file with the exact same set of files, parameters, and conditions used in "Reproduction Steps", with the addition of --log-file=output.txt.
  • [x] I produced the log file while the behaviors described in "Actual Behavior" were actively observed.
  • [x] I attached the full, untruncated log file.
  • [x] I attached the backtrace in the case of a crash.

Akemi avatar Oct 04 '25 17:10 Akemi

following without no-config, the issue starts with following commit on libplacebo https://github.com/haasn/libplacebo/commit/f09e25d8abe34d633f882111d3c4c6f7347ddf06 top left libplacebo 7.351 (working) top right libplacebo https://github.com/haasn/libplacebo/commit/46ae6c97800511c0eee9d8e37ddefa2ecabf59b0 (working commit before the mentioned above) bottom left libplacebo https://github.com/haasn/libplacebo/commit/f09e25d8abe34d633f882111d3c4c6f7347ddf06 (broken commit mentioned above) bttom right libplacebo https://code.videolan.org/videolan/libplacebo/-/merge_requests/751 (slightly different output than the working one)

Image

using --target-colorspace-hint=yes on libplacebo master produced a similar result than with top left libplacebo 7.351 (slightly less exposed/more saturated)

Image

Akemi avatar Oct 04 '25 17:10 Akemi

Thank you so much for this report. I never seen so complete format selection in Vulkan colorspaces.

I see 10+6 different images / configuration, but only 4 logs, anyway, let's focus on what we have.

I wanted to post detailed reply, but there are two small bugs in format selection, that shadows the main issue. It's like onion, it has layers... So before proceeding, could you retest with https://github.com/mpv-player/mpv/pull/16877 and https://code.videolan.org/videolan/libplacebo/-/merge_requests/752 ?

This way we will have little bit better behavior in surface format selection and can focus on the other issue.

top right with libplacebo master (slightly overexposed)

This looks correct. libplacebo coverts to linear using inverse of bt.1886. While the surface format selection is bit wrong, because without hint, this shouldn't happen, so let's retest first so we don't discuss unrelated issues.

kasper93 avatar Oct 04 '25 23:10 kasper93

I see 10+6 different images / configuration, but only 4 logs, anyway, let's focus on what we have.

sorry if you would have liked them too. i didn't provide them for several reasons, i didn't want to overload the issue with even more information (hence why i provided only a log of the basic problem case and the previous behaviour for comparison), the logs without no-config were only provided because of the gamma2.2 remark on irc, all the other cases were more like a "i tried this already but it didn't work (completely)", and i wanted to tackle one problem after another step by step (basically what you already said with the onion).

on a side note since i just noticed it. some of the screenshots above (the ones with >=4 windows on them) were size optimised because they reached the upload limit of github. this unfortunately also stripped the colour profile attached. so not all screenshots are comparable between each other. i will compress the screenshots as jpg from now on.

anyway here we go, everything with no-config for now:

mpv master + libplacebo 1 commit before broken one (top left https://github.com/haasn/libplacebo/commit/46ae6c97800511c0eee9d8e37ddefa2ecabf59b0): master-placebo-okay.log mpv master + libplacebo 7.351 (top right): master-placebo-7.351.log mpv master + libplacebo master (bottom left): master-placebo-master.log mpv #16877 + libplacebo #752 (bottom right): 16877-placebo-752.log

Image

both at the top look identical, both at the bottom look identical besides the text rendering (stats a bit darker). comparing top to bottom, still the same washed out difference.

Akemi avatar Oct 05 '25 12:10 Akemi

for completeness sake, same as above but without no-config:

mpv master + libplacebo 1 commit before broken one (top left): master-placebo-okay.log mpv master + libplacebo 7.351 (top right): master-placebo-7.351.log mpv master + libplacebo master (bottom left): master-placebo-master.log mpv https://github.com/mpv-player/mpv/pull/16877 + libplacebo #752 (bottom right): 16877-placebo-752.log

Image

the complete overexposure is gone with both those fixes, but it still looks bit more washed out than before (same/similar as above).

Akemi avatar Oct 05 '25 12:10 Akemi

both at the top look identical, both at the bottom look identical besides the text rendering (stats a bit darker). comparing top to bottom, still the same washed out difference.

mpv master + libplacebo 1 commit before broken one (top left https://github.com/haasn/libplacebo/commit/46ae6c97800511c0eee9d8e37ddefa2ecabf59b0): master-placebo-okay.log

Previously, the status quo was that BT.1886 (SDR) was sent to an sRGB-configured swapchain. We recently changed this behavior to instead follow the swapchain configuration. This is the main concern at the moment. It alters the visual appearance but is technically more correct. Although in some cases it may still be wrong. I’ll try to summarize as concisely as possible (for more detail, see https://github.com/mpv-player/mpv/issues/16791).

mpv/libplacebo assumes that SDR content is intended for display on a BT.1886 display. At the same time, the default output target is sRGB. These are not equivalent. To handle this, the inverse of BT.1886 is applied first, followed by sRGB. This ensures that video appears as if it were shown on a BT.1886 display, with contrast adjusted according to the --target-contrast option.

There are two major assumptions here (explicitly stated, though historically not widely followed):

  1. BT.709 content implies BT.1886 transfer. The problem is that some videos are not actually mastered for BT.1886, especially screen recordings. These are often tagged as BT.709 but are in practice sRGB. This can be corrected with --vf=format=gamma=srgb or with autoprofiles.

  2. The target display is assumed to be sRGB. This can be controlled using the target-trc option.

(note if target and source trc is the same, mpv will not convert gamma)

In general, this change is the correct approach, since we configure and send sRGB to the compositor. The compositor then knows how to linearize the signal and apply the proper display transfer. If we don’t do this (as before), the compositor may apply an incorrect conversion—for example, treating an sRGB TRC as if it were BT.1886.

Historically, without color management, an sRGB swapchain was assumed to be passed through directly. This assumption is no longer valid, particularly when targeting HDR displays. There is also some disagreement on Wayland's side about what "sRGB" actually means: they argue it should be encoded as gamma 2.2, while Vulkan continues to treat it as sRGB.

In short, I believe current status is correct. While may not be the most pragmatic thing, I don't see how to "hack" it to workaround badly tagged sources. Historically when everything was SDR, the strategy was "don't care" and just ignore any differences between transfers, and as SDR is display referred, it get displayed in one way or another. The tricky part now is that we may need to convert to say PQ, in which case we need to know source transfer exactly to emulate the nits it would produce.

mpv master + libplacebo 7.351 (top right): master-placebo-7.351.log

there is not difference, to 1st. It's the same picture.

mpv master + libplacebo master (bottom left): master-placebo-master.log

master/master is slightly broken (without patches), because it would pick linear transfer, even if hint is disabled. But good thing that you confirmed that it looks the same as 4th, because this means that linear output is working correctly.

mpv https://github.com/mpv-player/mpv/pull/16877 + libplacebo #752 (bottom right): 16877-placebo-752.log

Looks correct, bt.1886 is converted to sRGB, which is default output without colorspace hint.

I should have mention before, default is --target-colorspace-hint=auto in which case hint is enabled only if target_csp() callback is enabled. Else we just fallback to sRGB.

Could you try with --target-colorspace-hint=yes? It should pick VK_COLOR_SPACE_BT709_NONLINEAR_EXT and output bt.1886 without conversion on mpv side. (curious how macOS implements bt.1886)

for completeness sake, same as above but without no-config:

User side ICC profiles are inherently not compatible with color management done in system. Depending how you created ICC profile, you may have included correction to conversion done in system. How it works is platform specific.

You apply ICC profile in mpv, but then your compositor may apply the same or similar ICC profile before outputting to the display. So in order to make it work you should manually configure swapchain to consistent values that work for your ICC profile.

I wanted to use VK_COLOR_SPACE_PASS_THROUGH_EXT for ICC profiles, but there is disagreement about this from Wayland guys https://github.com/haasn/libplacebo/issues/324

I think we should somehow plug option to use VK_COLOR_SPACE_PASS_THROUGH_EXT still.

kasper93 avatar Oct 05 '25 19:10 kasper93

I wanted to use VK_COLOR_SPACE_PASS_THROUGH_EXT for ICC profiles, but there is disagreement about this from Wayland guys haasn/libplacebo#324

I like https://code.videolan.org/videolan/libplacebo/-/merge_requests/717 for this reason, rather than blanket disabling PASS_THROUGH on all platforms.

llyyr avatar Oct 06 '25 01:10 llyyr

... In short, I believe current status is correct. While may not be the most pragmatic thing, I don't see how to "hack" it to workaround badly tagged sources. Historically when everything was SDR, the strategy was "don't care" and just ignore any differences between transfers, and as SDR is display referred, it get displayed in one way or another. The tricky part now is that we may need to convert to say PQ, in which case we need to know source transfer exactly to emulate the nits it would produce.

since the complete overexposure is fixed (my main issue) i don't really have an issue here any more. since it is a deliberate change of behaviour from the previous one, i probably wouldn't notice the difference without comparing side by side and it's pretty 'minuscule'.

Could you try with --target-colorspace-hint=yes? It should pick VK_COLOR_SPACE_BT709_NONLINEAR_EXT and output bt.1886 without conversion on mpv side. (curious how macOS implements bt.1886)

yes, seems to be the case. master-placebo-master.log Image

User side ICC profiles are inherently not compatible with color management done in system. Depending how you created ICC profile, you may have included correction to conversion done in system. How it works is platform specific.

You apply ICC profile in mpv, but then your compositor may apply the same or similar ICC profile before outputting to the display. So in order to make it work you should manually configure swapchain to consistent values that work for your ICC profile.

maybe we are talking past each other and sorry if i am misunderstanding something.

i only use my ICC profile with target-colorspace-hint=no and i also made sure that the colorspace set on the layer (via moltenvk) was either nil or the icc profile itself. both would mean noop in terms of color transformation on the OS color management side. that was the old behaviour and i believe the right one.

tested with master again, now it picks kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1 (https://developer.apple.com/documentation/coregraphics/cgcolorspace/srgb https://github.com/KhronosGroup/MoltenVK/blob/main/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm#L518-L521), which is wrong i would say.

I wanted to use VK_COLOR_SPACE_PASS_THROUGH_EXT for ICC profiles, but there is disagreement about this from Wayland guys https://github.com/haasn/libplacebo/issues/324

I think we should somehow plug option to use VK_COLOR_SPACE_PASS_THROUGH_EXT still.

yeah, i believe VK_COLOR_SPACE_PASS_THROUGH_EXT would be the right behaviour in this case on macOS+moltenvk too, see https://github.com/KhronosGroup/MoltenVK/blob/main/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.mm#L562-L565.

Akemi avatar Oct 18 '25 11:10 Akemi

I wanted to use VK_COLOR_SPACE_PASS_THROUGH_EXT for ICC profiles, but there is disagreement about this from Wayland guys haasn/libplacebo#324

I think we should somehow plug option to use VK_COLOR_SPACE_PASS_THROUGH_EXT still.

@kasper93 From MoltenVK code, I think on macOS VK_COLOR_SPACE_PASS_THROUGH_EXT basically behaves the same as Wayland, it just doesn't mark any colorspace metadata to the surface, and this should mean that's also using sRGB actually.

Headcrabed avatar Oct 23 '25 18:10 Headcrabed

@kasper93 Also do you think it's related to the issue we discussed here? https://github.com/mpv-player/mpv/pull/16915#issuecomment-3427162984

Headcrabed avatar Oct 23 '25 18:10 Headcrabed

@Akemi can you try target-colorspace-hint=yes target-contrast=10000?

Headcrabed avatar Oct 23 '25 18:10 Headcrabed

This is my test result, use newest code with both PR merged, left is target-contrast=auto, and right is target-contrast=10000: Image

Headcrabed avatar Oct 23 '25 19:10 Headcrabed

@Akemi can you try target-colorspace-hint=yes target-contrast=10000?

This is my test result, use newest code with both PR merged, left is target-contrast=auto, and right is target-contrast=10000:

It's not related. linear output is not used on macOS.

kasper93 avatar Oct 24 '25 05:10 kasper93

yeah, i believe VK_COLOR_SPACE_PASS_THROUGH_EXT would be the right behaviour in this case on macOS+moltenvk too

I think this is the remaining item in this issue? Not sure how we want to handle this?

kasper93 avatar Nov 05 '25 16:11 kasper93

yeah, i believe VK_COLOR_SPACE_PASS_THROUGH_EXT would be the right behaviour in this case on macOS+moltenvk too

I think this is the remaining item in this issue? Not sure how we want to handle this?

Let's just drop it. That's undefined behavior, though looks similar to Wayland implementation.

Headcrabed avatar Nov 05 '25 17:11 Headcrabed

I think this is the remaining item in this issue? Not sure how we want to handle this?

yes, as far as i am aware for now.

Akemi avatar Nov 05 '25 18:11 Akemi