mpv icon indicating copy to clipboard operation
mpv copied to clipboard

hdr tonemapping: target-contrast and peak affects saturation with trc=bt.1886 and srgb, breaks the image in dark scenes (saturation, contrast, brightness)

Open geextahslex opened this issue 1 year ago • 15 comments

mpv Information

mpv v0.39.0-355-g45c1c586 Copyright © 2000-2024 mpv/MPlayer/mplayer2 projects
 built on Nov 19 2024 00:07:00
libplacebo version: v7.349.0 (v7.349.0-26-g5788a82-dirty)
FFmpeg version: N-117832-ge9c3698ed
FFmpeg library versions:
   libavcodec      61.25.100
   libavdevice     61.4.100
   libavfilter     10.6.101
   libavformat     61.9.100
   libavutil       59.47.100
   libswresample   5.4.100
   libswscale      8.9.101

Other Information

Windows version: Windows 10 22H2 Build 19045.4170)
GPU model, driver and version: intel HD Graphics 4600, driver: 20.19.15.5171
Source of mpv: https://sourceforge.net/projects/mpv-player-windows/files/
Introduced in version: present since v38.0

Reproduction Steps

With target-trc=bt.1886 and target-prim=bt.709 when you set target-contrast=1000 and target-peak=auto the image gets almost black and white in a dark scene. When you change target-peak to 10 then you get the colors back.

target-prim=bt.709
target-trc=bt.1886
tone-mapping=st2094-10
hdr-compute-peak=no
allow-delayed-peak-detect=yes

Expected Behavior

saturation stays the same

Actual Behavior

dark scenes get desaturated and look washed out

Log File

full output output full.txt gpu-debug output.txt

Sample Files

almost black and white black and white

normal normal4545

washed out washed out

normal normal3

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.

geextahslex avatar Nov 19 '24 20:11 geextahslex

Likely duplicate of #12707 you can try with target-contrast=inf

kasper93 avatar Nov 20 '24 20:11 kasper93

This doesn't fix it, this messes up the contrast or black levels

geextahslex avatar Nov 20 '24 21:11 geextahslex

It seems like I would need to disable this "feature" that desatures the image

// Avoid raising saturation excessively when raising brightness, and // also desaturate when reducing brightness greatly to account for the // reduction in gamut volume.

https://github.com/mpv-player/mpv/issues/12707#issuecomment-1774077987

"shaders/colorspace: scale down saturation when raising brightness" https://code.videolan.org/videolan/libplacebo/-/merge_requests/477/diffs

https://github.com/mpv-player/mpv/issues/12707#issuecomment-1778651176

I reverted that patch and recompiled and saturation looks fine now. This piece of code is responsible for the described effect in dark scenes.

How to patch this out? I have no experience with this...

geextahslex avatar Nov 20 '24 23:11 geextahslex

@haasn My suggestion would be to add an percantage option to this function, so you can turn it on, off or fine-tune it to your liking.

is this the code responsible for this? https://github.com/mpv-player/mpv/blob/master/video/out/gpu/video_shaders.c

 if (!opts->gamut_mode || opts->gamut_mode == GAMUT_DESATURATE) {
            GLSL(float cmin = min(min(color.r, color.g), color.b);)
            GLSL(if (cmin < 0.0) {
                     float luma = dot(dst_luma, color.rgb);
                     float coeff = cmin / (cmin - luma);
                     color.rgb = mix(color.rgb, vec3(luma), coeff);
                 })
            GLSLF("float cmax = 1.0/%f * max(max(color.r, color.g), color.b);\n",
                  dst.hdr.max_luma / MP_REF_WHITE);
            GLSL(if (cmax > 1.0) color.rgb /= cmax;)
        }
    }

geextahslex avatar Nov 21 '24 00:11 geextahslex

Hey @geextahslex .... I want to understand more about this: How did you find out that vf=format=sig-peak=4.926 deactivates the feature. What does this do exactly?

Wouldn't it be the same to set target-peak = 1000 ?

So what you want is the Brightness of the HDR picture, but you do NOT want the washed out colors, mhh?

Did you try out the spline tone-mapping instead of st2094 ? It really works out as the best i think. The algorithm makes really sense.

stonix015 avatar Nov 22 '24 08:11 stonix015

https://code.videolan.org/videolan/libplacebo/-/merge_requests/683

haasn avatar Nov 22 '24 10:11 haasn

@stonix015

I want to understand more about this: How did you find out that vf=format=sig-peak=4.926 deactivates the feature. What does this do exactly?

I found this out by accident, and kasper gave me this line to fix it.

Wouldn't it be the same to set target-peak = 1000 ?

From my understanding no, because target-peak is kinda your output target and the metadata nits is the input to the pipeline. You can see it at the top in these screenshots.

almost black and white black and white

normal normal4545

So what you want is the Brightness of the HDR picture, but you do NOT want the washed out colors, mhh?

Yes, I dont want the desaturation effect.

Did you try out the spline tone-mapping instead of st2094 ? It really works out as the best i think. The algorithm makes really sense.

At this point I tried out everything, spline, hable, rainhard etc. For me st2094-10 works kinda the best.

geextahslex avatar Nov 22 '24 12:11 geextahslex

https://github.com/haasn/libplacebo/issues/304

geextahslex avatar Nov 23 '24 15:11 geextahslex

So after further testing I noticed that this behaviour only occurs when you set the target-trc to srgb/bt.1886 instead of the default pq and pq gives you crushed blacks/artifacting

geextahslex avatar Nov 27 '24 17:11 geextahslex

So after further testing I ended up using hdr-toys for all of the "color space" stuff (gamut-mapping and transfer function) and mpv only does the tone-mapping with 2094-10.

On a SDR TV this gives you the best result. No clipped highlights, no crushed blacks, no washed out colors. Also good performance on crappy hardware :)

target-prim=bt.2020
target-trc=pq
tone-mapping=st2094-10
gamut-mapping-mode=clip (clip because hdr-toys handles this)
target-peak=100
hdr-compute-peak=yes
allow-delayed-peak-detect

glsl-shader=~~/shaders/hdr-toys/transfer-function/pq_inv.glsl
glsl-shader=~~/shaders/hdr-toys/utils/black_point_compensation.glsl
glsl-shader=~~/shaders/hdr-toys/gamut-mapping/jedypod.glsl
glsl-shader=~~/shaders/hdr-toys/transfer-function/bt1886.glsl
glsl-shader-opts=L_hdr=1000,L_sdr=100

1 dd 2 dd

geextahslex avatar Dec 01 '24 14:12 geextahslex

@geextahslex I always get a lot of brightness fluctuation when trying HDR Toys. With this mix do you manage to get stable brightness? I'm also shooting for 100 nits output.

danbezerra avatar Dec 16 '24 20:12 danbezerra

what do you mean by "brightness fluctuation"? Yes this setup above should work, it is stable to me. I don't know mybe it behaves differently with the latest version. I use this one mpv v0.38.0-717-g92f052c1

geextahslex avatar Dec 16 '24 21:12 geextahslex

Thanks. It's when the brightness keeps changing within the same scene, and you see it "pumping" in the background of the image. However, with your solution you leave MPV to take care of the tone-mapping. This can be a good choice. I will test it later.

danbezerra avatar Dec 16 '24 22:12 danbezerra

Okay, so with hdr-toys it works nice.

geextahslex avatar Dec 16 '24 23:12 geextahslex

ok so what I can add to this is that the lower the PQ-Y Average goes like 10-5%, the more you have to add saturation manually, like about +50 to counter this effect

geextahslex avatar May 15 '25 12:05 geextahslex

@geextahslex Btw have you actually tested if https://code.videolan.org/videolan/libplacebo/-/merge_requests/683 helps?

Headcrabed avatar Aug 24 '25 16:08 Headcrabed

@Headcrabed yes I was responsible to stop this patch as it made it look even worse https://github.com/mpv-player/mpv/discussions/15375

geextahslex avatar Aug 24 '25 17:08 geextahslex