Skip to content
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

dither-depth=auto is broken on vo=gpu-next. #11862

Closed
ghost opened this issue Jun 30, 2023 · 73 comments
Closed

dither-depth=auto is broken on vo=gpu-next. #11862

ghost opened this issue Jun 30, 2023 · 73 comments
Labels
down-upstream features and bugs that need to be implemented and fixed upstream vo:gpu-next

Comments

@ghost
Copy link

ghost commented Jun 30, 2023

Important Information

Reproduction steps

Use vo=gpu and dither-depth=auto to watch any(?) video, preferably with an 8-bit monitor or forced 8-bit output in the GPU driver. Observe the log or info page and what it says about dithering. Then contrast with what happens when you use vo=gpu-next and dither-depth=auto.

Expected behavior

dither-depth=auto should always result in 8-bit dithering for an 8-bit output.

Actual behavior

On my 8-bit monitor, 8-bit dithering fine for vo=gpu, regardless of the gpu-api setting. But, when switching to vo=gpu-next, the behavior changes. With gpu-api=d3d11, the bit depth is incorrectly set to 10. And with gpu-api=vulkan, no dithering is performed at all. Both do work fine if dither-depth=8 is specified manually.

Log file

vo=gpu https://pomf2.lain.la/f/xhm706vw.txt
vo=gpu-next -gpu-api=d3d11 https://pomf2.lain.la/f/takytfgg.txt
vo=gpu-next -gpu-api=vulkan https://pomf2.lain.la/f/npq8090s.txt

Sample files

https://pomf2.lain.la/f/k1fahjqe.webm

@hooke007
Copy link
Contributor

hooke007 commented Jun 30, 2023

You have to manually set depth for vulkan because

static int color_depth(struct ra_swapchain *sw)
{
return 0; // TODO: implement this somehow?
}

@haasn
Copy link
Member

haasn commented Jun 30, 2023

Working as intended. You are getting a 16-bit backbuffer with vulkan and a 10-bit backbuffer with d3d11. Dithering is not needed at 16 bit depth.

@ghost
Copy link
Author

ghost commented Jun 30, 2023

That makes sense for intermediate rendering steps, but couldn't naively sending a 16-bit texture to be displayed at the end cause banding if it's not explicitly dithered to 8 bits first? That happens to me in Krita anyway.

@ghost
Copy link
Author

ghost commented Jun 30, 2023

Off-topic, but will libplacebo's blue and white noise dithering ever be exposed in mpv?

@hooke007
Copy link
Contributor

bluenoise →→ dither=fruit

@natural-harmonia-gropius
Copy link
Contributor

cause banding

auto results banding to me too, 8 is fine.

@Raza-0007
Copy link

Working as intended. You are getting a 16-bit backbuffer with vulkan and a 10-bit backbuffer with d3d11. Dithering is not needed at 16 bit depth.

I have a similar issue, on my 8 bit (6 bit + FRC) display , with dither-depth=auto, vo=gpu-next dithers at 10 bit on all videos, while vo=gpu dithers at the expected 8 bit.

Is this a bug or is this how gpu-next is supposed to dither?

Here are my tests, keeping everything else exact same, except the vo and gpu-api:

--vo=gpu-next --dither-depth=auto --gpu-api=vulkan ------> Dithering at 10 bits
--vo=gpu-next --dither-depth=auto --gpu-api=d3d11 ------> Dithering at 10 bits

--vo=gpu --dither-depth=auto --gpu-api=vulkan ------> Dithering at 8 bits
--vo=gpu --dither-depth=auto --gpu-api=d3d11 ------> Dithering at 8 bits

This is on Windows 10, mpv 0.35.0-436-g1c82d6ae (June 11 2023) bundled with the latest SMPlayer.

I can post logs if needed, but since it happens on all the videos, it should be easy to replicate on any 8 bit display.

~Raza

@hooke007
Copy link
Contributor

hooke007 commented Jul 3, 2023

@Raza-0007 Your question's answer is there #10881

@ghost
Copy link
Author

ghost commented Jul 3, 2023

@haasn's last reply there seems to contradict his first reply here. Am I dumb?

@Raza-0007
Copy link

@hooke007 Thanks. I did not consider checking as far back at Nov 2022. I thought this was a recent change.

I am not an expert on video rendering engines, but I thought that dithering to 10 bits on a 8 bit display will cause quality issues. Something like over dithering. But reading the other discussion, @haasn seems to say that it should not cause any issues. I will of course take his word as he obviously knows more than I do about this.

@sizumam This is what I thought that when dether-depth=auto, it should either choose the exact bit depth of the display or otherwise default to 8 bit. This is why I thought it was a bug in gpu-next as it was dithering to 10 bits on auto on my 8 bit display. If it does not cause quality issues then I am ok with it.

@Raza-0007
Copy link

I did another test on an 8-bit (H264) encoded video, on my 8 bit display. vo=gpu-next is still dithering to 10 bits!

Again I am not an expert, but isn't this a bit pointless! Neither the video has nor the display is capable of displaying more than 8 bits of information, what would be gained by dithering it to 10 bits!

And yet again if someone can verify that it does not effect video quality, then I am ok with it.

~Raza

@hooke007
Copy link
Contributor

hooke007 commented Jul 3, 2023

I thought this was a recent change.

As I said, what you did is what I did in that issue. It's not a recent change.

@Raza-0007
Copy link

Raza-0007 commented Jul 3, 2023

@hooke007 What I meant was that I did a search on this issue before posting, but I did not go beyond the last 3 months, as I thought it was a recent change. Thats why I missed your Nov 2022 post

@ghost
Copy link
Author

ghost commented Jul 3, 2023

Again I am not an expert, but isn't this a bit pointless! Neither the video has nor the display is capable of displaying more than 8 bits of information, what would be gained by dithering it to 10 bits!

It would reduce rounding errors in intermediate steps. But that should just be a matter of it using a 10-bit FBO, and dithering should still be to 8 bits at the end I would think...

@haasn
Copy link
Member

haasn commented Jul 3, 2023

That makes sense for intermediate rendering steps, but couldn't naively sending a 16-bit texture to be displayed at the end cause banding if it's not explicitly dithered to 8 bits first? That happens to me in Krita anyway.

Do you see visual banding? Test on a 16-bit gradient, e.g.:

Gradient-16bit

gradient.mp4

If you do, that means it's a driver/platform bug. The system should not advertise a texture format higher than the monitor depth if it does not perform internal dithering..

@haasn
Copy link
Member

haasn commented Jul 3, 2023

If the driver really doesn't dither internally despite advertising 16-bit backbuffers, then maybe we could work around it like this:

diff --git a/src/vulkan/swapchain.c b/src/vulkan/swapchain.c
index c3d9295c..f3d10031 100644
--- a/src/vulkan/swapchain.c
+++ b/src/vulkan/swapchain.c
@@ -192,10 +192,12 @@ static bool pick_surf_format(pl_swapchain sw, const struct pl_color_space *hint)
                 break; // accept
             continue;
 
-        // Accept 16-bit formats for everything
+        // Only accept 16-bit formats for non-SDR
         case VK_FORMAT_R16G16B16_UNORM:
         case VK_FORMAT_R16G16B16A16_UNORM:
-             break; // accept
+            if (pl_color_transfer_is_hdr(space.transfer))
+                break; // accept
+            continue;
 
         default: continue;
         }

Of course, this would still pick 10-bit backbuffers if available. There's almost fundamentally no way around this, because we don't know the true monitor bit depth and have to rely on the compositor not lying to us.

@natural-harmonia-gropius
Copy link
Contributor

I don't know is screenshot can show banding.

win11 d3d11 nvidia 536.40

depth 8
image
depth auto (10bit)
image

@haasn
Copy link
Member

haasn commented Jul 3, 2023

Screenshot is irrelevant, unless you can do a capture of the video signal coming into the monitor (e.g. HDMI capture card). Do you see banding visually?

@natural-harmonia-gropius
Copy link
Contributor

Do you see banding visually?

yes, very noticeable in dark aera.

@ghost
Copy link
Author

ghost commented Jul 3, 2023

vo=gpu + gpu-api=d3d11 + dither-depth=no = banding !
vo=gpu + gpu-api=d3d11 + dither-depth=auto = no banding
vo=gpu + gpu-api=d3d11 + dither-depth=8 = no banding
vo=gpu + gpu-api=vulkan + dither-depth=no = banding !
vo=gpu + gpu-api=vulkan + dither-depth=auto = no banding
vo=gpu + gpu-api=vulkan + dither-depth=8 = no banding
vo=gpu-next + gpu-api=d3d11 + dither-depth=no = no banding
vo=gpu-next + gpu-api=d3d11 + dither-depth=auto = no banding
vo=gpu-next + gpu-api=d3d11 + dither-depth=8 = no banding
vo=gpu-next + gpu-api=vulkan + dither-depth=no = banding !
vo=gpu-next + gpu-api=vulkan + dither-depth=auto = banding !
vo=gpu-next + gpu-api=vulkan + dither-depth=8 = no banding

@haasn
Copy link
Member

haasn commented Jul 3, 2023

And does the above patch fix it?

@Raza-0007
Copy link

Of course, this would still pick 10-bit backbuffers if available. There's almost fundamentally no way around this, because we don't know the true monitor bit depth and have to rely on the compositor not lying to us.

@haasn Since you are here, I just wanted to ask, as my original issue was not related to 16-bit backbuffer. Below are two log files of a 8 bit video that I am playing on a 8 bit display. All options are the same except the --vo and --dither-depth=auto for both.

vo=gpu-next.txt

vo=gpu.txt

--gpu-next chooses to dither to 10 bits, while --gpu dithers to 8 bits.

From what I have read, you are saying that --gpu-next does this by design and there is no quality loss in the output by dithering to 10 bits for this setup. Is this correct?

@haasn
Copy link
Member

haasn commented Jul 3, 2023

From what I have read, you are saying that --gpu-next does this by design and there is no quality loss in the output by dithering to 10 bits for this setup. Is this correct?

Assuming your graphics driver / compositor is working correctly, yes.

@ghost
Copy link
Author

ghost commented Jul 3, 2023

And does the above patch fix it?

@haasn no. All 12 results are the same on my machine with that patch.
[ 0.255][v][vo/gpu-next/libplacebo] Picked surface configuration 22: VK_FORMAT_R16G16B16A16_UNORM + VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
https://pomf2.lain.la/f/p9zb7tm.txt

@hooke007
Copy link
Contributor

hooke007 commented Jul 3, 2023

Screenshot is irrelevant, unless you can do a capture of the video signal coming into the monitor (e.g. HDMI capture card).

His screenshots showed clear banding in dark area...

@Raza-0007
Copy link

Assuming your graphics driver / compositor is working correctly, yes.

Thank You!

@haasn
Copy link
Member

haasn commented Jul 4, 2023

And does the above patch fix it?

@haasn no. All 12 results are the same on my machine with that patch. [ 0.255][v][vo/gpu-next/libplacebo] Picked surface configuration 22: VK_FORMAT_R16G16B16A16_UNORM + VK_COLOR_SPACE_SRGB_NONLINEAR_KHR https://pomf2.lain.la/f/p9zb7tm.txt

Are you sure you had the patch applied? It should be impossible to pick that format combination with the above patch.

@llyyr
Copy link
Contributor

llyyr commented Jul 4, 2023

https://github.com/mpv-player/mpv/blob/master/video/out/vulkan/context.c#L277

--dither-depth=auto is not implemented for the vulkan context, you should use d3d11 if you want it to be auto detected, or set it to 8 manually.

@hooke007
Copy link
Contributor

hooke007 commented Jul 4, 2023

--dither-depth=auto is not implemented for the vulkan context, you should use d3d11 if you want it to be auto detected, or set it to 8 manually.

It was already answered here #11862 (comment)

@haasn
Copy link
Member

haasn commented Jul 4, 2023

https://github.com/mpv-player/mpv/blob/master/video/out/vulkan/context.c#L277

--dither-depth=auto is not implemented for the vulkan context, you should use d3d11 if you want it to be auto detected, or set it to 8 manually.

This is irrelevant, it affects only --vo=gpu, but OP was talking about --vo=gpu-next.

@lextra2
Copy link

lextra2 commented Mar 5, 2024

With Windows 11, the compositor can dither, too, if Auto Color Management (ACM) is used.
That would be in total 4 steps of dithering (MPV > GPU > Windows > TV/Monitor)

Pure madness

llyyr added a commit to llyyr/mpv that referenced this issue Mar 5, 2024
Fixes the issue described in mpv-player#11862
for SDR files.

Note that this doesn't actually fix the "bug" in question, but just
works around it for SDR files by always dithering down to 8 bit. mpv
will still pick 16 bit depth backbuffers for HDR content if it's
available and do no dithering.
llyyr added a commit to llyyr/mpv that referenced this issue Mar 5, 2024
This was forgotten when the libplacebo API was merged, and it fixes the
issue described in mpv-player#11862 for
SDR files. Note that this doesn't actually fix the bug in question, but
just works around it for SDR files by always dithering down to 8 bit.
kasper93 added a commit to kasper93/mpv that referenced this issue Mar 6, 2024
kasper93 added a commit to kasper93/mpv that referenced this issue Mar 6, 2024
@kasper93
Copy link
Contributor

kasper93 commented Mar 6, 2024

I've added support for --dither-depth=auto for gpu-next, on supported APIs. #13646

kasper93 added a commit to kasper93/mpv that referenced this issue Mar 6, 2024
kasper93 added a commit to kasper93/mpv that referenced this issue Mar 6, 2024
kasper93 added a commit to kasper93/mpv that referenced this issue Mar 6, 2024
llyyr pushed a commit to llyyr/mpv that referenced this issue Mar 6, 2024
llyyr added a commit to llyyr/mpv that referenced this issue Mar 6, 2024
Fixes the issue described in mpv-player#11862
for SDR files for non-d3d11 gpu-api. We currently don't have a smarter
way to get the real on-the-wire bpc for other APIs, so this is the best
that can be done.
@sfan5 sfan5 closed this as completed in 7265bde Mar 17, 2024
llyyr added a commit to llyyr/mpv that referenced this issue Mar 17, 2024
Fixes the issue described in mpv-player#11862
for SDR files for non-d3d11 gpu-api. We currently don't have a smarter
way to get the real on-the-wire bpc for other APIs, so this is the best
that can be done.
llyyr added a commit to llyyr/mpv that referenced this issue Mar 19, 2024
Fixes the issue described in mpv-player#11862
for SDR files for non-d3d11 gpu-api. We currently don't have a smarter
way to get the real on-the-wire bpc for other APIs, so this is the best
that can be done.
llyyr added a commit to llyyr/mpv that referenced this issue Mar 19, 2024
Fixes the issue described in mpv-player#11862
for SDR files for non-d3d11 gpu-api. We currently don't have a smarter
way to get the real on-the-wire bpc for other APIs, so this is the best
that can be done.
kasper93 pushed a commit that referenced this issue Mar 19, 2024
Fixes the issue described in #11862
for SDR files for non-d3d11 gpu-api. We currently don't have a smarter
way to get the real on-the-wire bpc for other APIs, so this is the best
that can be done.
@Raza-0007
Copy link

I just wanted add this here in case somebody else has noticed this issue. Since the change where dither-depth=auto now defaults to 8 on gpu-api=vulkan with vo=gpu-next, the colors have become a touch less vibrant, and the image a touch less sharp on my system. For example, reds are slightly less redder etc. and image looks less vibrant.

I had earlier asked on this same thread whether dithering to 10 bits on my 8 bit displays will compromise image quality. And I was told by haasn that as long as my drivers and compositor was working correctly, it will not. So I have been using dither-depth=auto (10 bits on my system) since then without any issues.

But now with the change I have noticed the slight loss of image quality when mpv dithers to 8 bits. Changing dither-depth=10 fixes the issue, and restores the colors and image quality back. The tests were done with gpu-api=vulkan on vo=gpu-next and keeping everything else constant, just changing the dither-depth between auto and 10.

I do not have any explanation other than this that mpv always picks a 10 bit surface configuration on my system with 8 bit displays, so maybe mpv needs to dither to 10 bits to give me the best image quality.

By the way, I never had any banding issues that others here have experienced, so if someone was experiencing banding, then a slight loss of image quality is acceptable.

~Raza

@ghost
Copy link

ghost commented Mar 23, 2024

Placebo.

@lextra2
Copy link

lextra2 commented Mar 23, 2024

@Raza-0007
What OS and what GPU?
If on windows, go to System32 folder and doubleclick on vulkaninfo.exe and post the output here

If on linux, do this for vulkaninfo

@haasn
Copy link
Member

haasn commented Mar 23, 2024

I just wanted add this here in case somebody else has noticed this issue. Since the change where dither-depth=auto now defaults to 8 on gpu-api=vulkan with vo=gpu-next, the colors have become a touch less vibrant, and the image a touch less sharp on my system. For example, reds are slightly less redder etc. and image looks less vibrant.

I had earlier asked on this same thread whether dithering to 10 bits on my 8 bit displays will compromise image quality. And I was told by haasn that as long as my drivers and compositor was working correctly, it will not. So I have been using dither-depth=auto (10 bits on my system) since then without any issues.

But now with the change I have noticed the slight loss of image quality when mpv dithers to 8 bits. Changing dither-depth=10 fixes the issue, and restores the colors and image quality back. The tests were done with gpu-api=vulkan on vo=gpu-next and keeping everything else constant, just changing the dither-depth between auto and 10.

I do not have any explanation other than this that mpv always picks a 10 bit surface configuration on my system with 8 bit displays, so maybe mpv needs to dither to 10 bits to give me the best image quality.

By the way, I never had any banding issues that others here have experienced, so if someone was experiencing banding, then a slight loss of image quality is acceptable.

~Raza

Screenshots?

@Raza-0007
Copy link

Raza-0007 commented Mar 23, 2024

@lextra2, This is on Windows 11, with Nvidia 1070 GTX

Here is the vulkaninfo
vulkaninfo.txt

@haasn, I do not notice the issue in screenshots. Could be due to the jpg compression. Since screenshots are unscaled, could the scalers in my config have anything to do with this? I have a simple config, nothing special, but everything was enabled during the test, I only changed the dither-depth.
mpv config.txt

But if none of you are experiencing this, then it might just be me. Changing dither-depth=10 fixes it for me for now. I will continue doing more tests on it to rule out bias caused by my eyes.

Thanks.

~Raza

@haasn
Copy link
Member

haasn commented Mar 23, 2024

@haasn, I do not notice the issue in screenshots. Could be due to the jpg compression. Since screenshots are unscaled, could the scalers in my config have anything to do with this? I have a simple config, nothing special, but everything was enabled during the test, I only changed the dither-depth.

Make a screenshot of your screen (printscreen), not a screenshot inside mpv.

@lextra2
Copy link

lextra2 commented Mar 24, 2024

format = FORMAT_A2B10G10R10_UNORM_PACK32
colorSpace = COLOR_SPACE_SRGB_NONLINEAR_KHR

Your GPU driver supports vulkan with 10bit, so if you've selected 10bit in the gpu control panel, you should use dither-depth=10 which you manually have to set yourself since Vulkan has no extension to check for the current displays bit depth.

@Raza-0007
Copy link

@haasn, I have taken multiple screenshots (printscreen) with different types of media for the last hour, but strangely, I cannot see the difference in the screenshots. I can notice it when the media is played. It is only a slight difference, image with 10 bit dithering is slightly more smoother... better. But I guess, since screenshots don't show this even after zooming into them, so it must be just my eyes, and not mpv. Here are four samples in the zip archive, but they are identical.

Screenshots.zip

@lextra2, This 10 bit format FORMAT_A2B10G10R10_UNORM_PACK32 is exactly what mpv selects for me every time. And previously at dither-depth=auto it used to dither at 10 bit too. Now with 8 bit dithering, the image is not bad, I think my eyes are used to the 10 bit dithering, so I can tell the difference. It only a very slight difference. But I have set my dither depth at 10 for now, which makes everything the same as it used to be.

But thank you, both of you for trying to help. It is clearly an issue on my system only, and most likely it is just me. I thought I should mention it here in case someone else was experiencing something similar, but I guess no one else is 😊

~Raza

@lextra2
Copy link

lextra2 commented Mar 24, 2024

I have taken multiple screenshots (printscreen) with different types of media for the last hour, but strangely, I cannot see the difference in the screenshots.

Maybe related to Nvidias dithering. You can't capture that via screenshots.
Try disabling dithering with one of these:

https://forums.blurbusters.com/viewtopic.php?f=27&t=12953

https://forums.guru3d.com/threads/nvidia-and-dithering-controls-how-to-enable.436621/#post-5885004

Note: Any of those registry changes require a reboot to take effect.

Edit: Or this app:
https://github.com/Maassoft/ColorControl

@Raza-0007
Copy link

@lextra2, thanks for the links, some good info there. I see that the registry fixes mentioned on that thread are for fixing eye strain caused by temporal dithering, therefore, I am hesitant to try them or the colorcontrol utility on my system, because my issue is trivial, and can be easily fixed by forcing dither-depth=10 in config. Everything else is working fine. I don't want to inadvertently introduce a bigger issue by editing these settings.

~Raza

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
down-upstream features and bugs that need to be implemented and fixed upstream vo:gpu-next
Projects
None yet
Development

No branches or pull requests

9 participants