mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
27.79k stars 2.86k forks source link

HDR tonemapping producing subpar results with default config #6405

Closed NSQY closed 5 years ago

NSQY commented 5 years ago

mpv version and platform

Windows 10 1809

mpv 0.29.0-107-gd6d6da4711 Copyright © 2000-2018 mpv/MPlayer/mplayer2 projects built on Sun Dec 16 00:57:00 UTC 2018 ffmpeg library versions: libavutil 56.24.101 libavcodec 58.42.102 libavformat 58.24.101 libswscale 5.4.100 libavfilter 7.46.101 libswresample 3.4.100 ffmpeg version: git-2018-12-15-be60dc21

Reproduction steps

Attempt to watch HDR content on SDR monitor

Expected behavior

Accurate reproduction of colours and brightness levels

Actual behavior

Colours (particularly in the red spectrum) are not accurately reproduced, light often behaves unnaturally and visibly shifts mid-scene

Log file

https://0x0.st/sdlQ.txt

Sample files

If someone can tell me how to losslessly cut an mkv with HDR metadata intact I can provide samples

From what I can tell, tonemapping with mpv currently has two major issues what make it rather unpleasant to the end user: Reds are awful, I don't know if there's something special about this part of the spectrum but mpv does not play well with them at all - at least with the default settings. I've found I can improve reds dramatically by tweaking some settings such as the following but this comes with the cost of interfering with the rest of the film. tone-mapping-desaturate=0 hdr-compute-peak=no

Here are some examples of reds/yellows not behaving correctly, I'll be using madVR as a pseudo reference as I don't have the SDR BD on hand and they seem to have no such issues with their tonemapping solution. These examples are from The Dark Knight 2008, mpv (default) has no HDR-specific config, mpv (tweaked) users the aforementioned config from the previous paragraph. Full gallery for easier viewing: https://imgbox.com/g/DvoY5yAjFH Examples:

Fire - madVR: https://images2.imgbox.com/db/c3/TRqmFfaz_o.png mpv (default): https://images2.imgbox.com/50/1b/L9crP04w_o.png mpv (tweaked): https://images2.imgbox.com/e6/0d/HROmk5iG_o.png

Explosion - madVR: https://images2.imgbox.com/5d/0d/KzBne9Hd_o.png mpv (default): https://images2.imgbox.com/a8/8a/kDpQb97n_o.png mpv (tweaked): https://images2.imgbox.com/e4/5b/eji8jTxh_o.png

Secondly, hdr-compute-peak often causes noticeable shifts in brightness throughout the film even when there's not much going on. I noticed this while watching The Big Lebowski for example, while they were standing around talking the brightness suddenly shifted and it was very noticeable and uncomfortable. Here's an example of it shifting dramatically within a few frames, again, from The Dark Knight 2008: https://images2.imgbox.com/75/a9/LuuoGHun_o.png https://images2.imgbox.com/a9/0c/SpBDirqQ_o.png

One thing in paricular that I've noticed about this is it's at its most egregious during sudden shifts, such as cutting from a dark scene directly to an explosion; perhaps it would be possible for mpv to scan ahead of time so such shifts can be accounted for?

haasn commented 5 years ago

Btw, another thing we can try doing is using a different method of estimating the overall frame brightness (rather than the current naive/linear average).

I played around with

  1. averaging sqrt(sig) (poor man's gamma function)
  2. averaging log(sig) (approximation of HVS)

In particular, the approach 2 I think worked out pretty interesting. I'm not yet sure whether it's an improvement, but it does solve a lot of the "brightness" issues I think.

diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c
index 5dbc0db7ca..099bbdb40c 100644
--- a/video/out/gpu/video.c
+++ b/video/out/gpu/video.c
@@ -2491,10 +2491,10 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool
     if (detect_peak && !p->hdr_peak_ssbo) {
         struct {
             float average[2];
-            uint32_t frame_sum;
-            uint32_t frame_max;
+            int32_t frame_sum;
+            int32_t frame_max;
             uint32_t counter;
-        } peak_ssbo = {0};
+        } peak_ssbo = { .frame_max = -100000 };

         struct ra_buf_params params = {
             .type = RA_BUF_TYPE_SHADER_STORAGE,
@@ -2515,8 +2515,8 @@ static void pass_colormanage(struct gl_video *p, struct mp_colorspace src, bool
         pass_is_compute(p, 8, 8, true); // 8x8 is good for performance
         gl_sc_ssbo(p->sc, "PeakDetect", p->hdr_peak_ssbo,
             "vec2 average;"
-            "uint frame_sum;"
-            "uint frame_max;"
+            "int frame_sum;"
+            "int frame_max;"
             "uint counter;"
         );
     }
diff --git a/video/out/gpu/video_shaders.c b/video/out/gpu/video_shaders.c
index 5673db2ff7..c84f3fe2ea 100644
--- a/video/out/gpu/video_shaders.c
+++ b/video/out/gpu/video_shaders.c
@@ -576,15 +576,20 @@ static void hdr_update_peak(struct gl_shader_cache *sc,
     GLSL(    sig_peak = max(1.00, average.y);)
     GLSL(});

+    // Chosen to avoid overflowing on an 8K buffer
+    float log_min = 1e-3;
+    float sig_scale = 400.0;
+
     // For performance, and to avoid overflows, we tally up the sub-results per
     // pixel using shared memory first
     GLSLH(shared uint wg_sum;)
     GLSLH(shared uint wg_max;)
     GLSL(wg_sum = wg_max = 0;)
     GLSL(barrier();)
-    GLSLF("uint sig_uint = uint(sig_max * %f);\n", MP_REF_WHITE);
-    GLSL(atomicAdd(wg_sum, sig_uint);)
-    GLSL(atomicMax(wg_max, sig_uint);)
+    GLSLF("float sig_log = log(max(sig_max, %f));\n", log_min);
+    GLSLF("uint sig_int = int(sig_log * %f);\n", sig_scale);
+    GLSL(atomicAdd(wg_sum, sig_int);)
+    GLSL(atomicMax(wg_max, sig_int);)

     // Have one thread per work group update the global atomics
     GLSL(memoryBarrierShared();)
@@ -602,7 +607,7 @@ static void hdr_update_peak(struct gl_shader_cache *sc,
     GLSL(if (gl_LocalInvocationIndex == 0 && atomicAdd(counter, 1) == num_wg - 1) {)
     GLSL(    counter = 0;)
     GLSL(    vec2 cur = vec2(frame_sum / num_wg, frame_max);)
-    GLSLF("  cur *= 1.0/%f;\n", MP_REF_WHITE);
+    GLSLF("  cur = exp(1.0/%f * cur);\n", sig_scale);

     // Use an IIR low-pass filter to smooth out the detected values, with a
     // configurable decay rate based on the desired time constant (tau)
@@ -617,7 +622,8 @@ static void hdr_update_peak(struct gl_shader_cache *sc,
     GLSL(    average = mix(average, cur, weight);)

     // Reset SSBO state for the next frame
-    GLSL(    frame_max = frame_sum = 0;)
+    GLSL(    frame_sum = 0;)
+    GLSL(    frame_max = -100000;)
     GLSL(    memoryBarrierBuffer();)
     GLSL(})
 }
Doofussy2 commented 5 years ago

Just testing other movies. The beginning of Alien: Covenant was always problematic. Now it looks just like passing the metadata to the display.

This config is a winner!

hdr-compute-peak=no tone-mapping=hable tone-mapping-desaturate=1.0 tone-mapping-desaturate-exponent=0.0

haasn commented 5 years ago

@Doofussy2 Well, that config is probably what your display is doing internally - since it's the "simplest" possible way to do things. (Actually, that's what we did way way way back in the day)

If it works on your particular test samples and you like the look, then I guess feel free to use the values; but I'm not going to make them the default because they seriously degrade the accuracy of all colors.

Doofussy2 commented 5 years ago

Oh for sure. I wouldn't expect it to be default. And I eagerly await testing the other new developments that you made, today. I just have to wait until they get rolled in :)

Doofussy2 commented 5 years ago

Just realized I hadn't tried using hable on it's own, with no compute peak or desaturation. That works great!

Just look at this result (I know you don't want to use this video). That is so close to how it is when my display handles the metadata. The color, saturation and lighting are amazing!

mpv-shot0002

And compare it to what I did, earlier. (I think I was doing to much) 50577352-7137ec00-0ddb-11e9-88e4-1370b0255bc5

haasn commented 5 years ago

I'm not yet sure whether it's an improvement, but it does solve a lot of the "brightness" issues I think.

Decided to go through with it. For comparison, this is what I get on that chess scene with the new defaults + the new logarithmic averaging commit.

new defaults

haasn commented 5 years ago

Now, with mobius, it's almost a bit too over the top:

mobius

Doofussy2 commented 5 years ago

I wish I could show you just how close the last picture I posted is to 'actual' HDR. I don't think I can tell them apart. You have done excellent work, today @haasn !

Those last two were with compute peak, yes?

haasn commented 5 years ago

I also realized that much of the effective brightness of the output image is very much dictated by the constant 0.25 hard-coded into the mpv tone mapping algorithm. That constant was very much chosen ad-hoc with no real justification other than "it's close to the mid point of the gamma function".

If we changed that constant to, say, 0.30 instead, you would see a brighter result than before. It's possible that we simply need to tune this parameter as well. I could expose it as an option too.

Those last two were with compute peak, yes?

Yes.

I wish I could show you just how close the last picture I posted is to 'actual' HDR.

The one with mobius?

Doofussy2 commented 5 years ago

The one with mobius?

No, the one I just post only using hable.

hdr-compute-peak=no tone-mapping=hable

This one

mpv-shot0002

This is just about perfect! I can't separate it from 'actual' HDR on my display. The colors, the luminance and the saturation, are spot on!

haasn commented 5 years ago

I added a new (undocumented for now) option --tone-mapping-target-avg to control this 0.25 constant. Pushed it to #6415 as well.

@shinchiro could I trouble you to make a build of that branch again? would like to get some testing in so we can ideally pick better defaults and maybe also remove some of the options that we agree on values for. (Having too many options is not always a good thing, even for mpv...)

haasn commented 5 years ago

Anyway, it goes without saying, that local tests should be done on actual movies if possible; I'm only using the chess clip since it seems to be the common denominator / clip we all have lying around.

Doofussy2 commented 5 years ago

Anyway, it goes without saying, that local tests should be done on actual movies if possible; I'm only using the chess clip since it seems to be the common denominator / clip we all have lying around.

Yup! I agree. And to that point, I just tested one of my favorite test scenes (for the colors and glowy things). The movie is Lucy.

mpv-shot0004

I've wrestled to get this right, and now it is.

Doofussy2 commented 5 years ago

Couple more examples

Avengers mpv-shot0006

mpv-shot0007

Justice League mpv-shot0005

(glowy thing in the back looking good) mpv-shot0008

haasn commented 5 years ago

@Doofussy2 I'd like to know more about your test environment, though. What kind of display are you using and what curve is it calibrated to? What's the actual peak brightness in SDR mode and how are you making comparisons?

Doofussy2 commented 5 years ago

I have a Vizio M55-E0 (2017). I have not had it optimally calibrated. I use it as my desktop, too. That's how I can run off tests, so quickly. So the settings are dialed for my desktop. I have a GTX 1060, connected directly to the display via DP 1.4. I do have the digital vibrance dialed to 65%. That helps boost the luminance a little. Not so far as to make it out of range, still not at bright as when the display is in HDR10. HDMI 1 is the only input that allows 10 bit gamut. That is enabled separately to HDR10 being switched on. So that is always on.

This is the best info I can find about my display. https://www.rtings.com/tv/reviews/vizio/m-series-xled-2017

Color temp = Computer Black detail = Medium Colorspace = Auto Gamma = 2.2

Oh, I forgot the Nvidia settings. Here they are snapshot_128

Doofussy2 commented 5 years ago

The comparisons I make are using madVR to play the media (default settings). I take screenshots in mpv and compare it to what I just saw. I repeat it a few times, so I have a clear image in my mind.

laichiaheng commented 5 years ago

@Doofussy2 Are they all using hdr-compute-peak=no tone-mapping=hable tone-mapping-desaturate=0?

Doofussy2 commented 5 years ago

Just hdr-compute-peak=no and tone-mapping=hable. And yes, wilth all of them.

shinchiro commented 5 years ago

Here you go: mpv-x86_64-20190102-git-7db407a.zip

NSQY commented 5 years ago

@haasn Thank you for the fantastic updates, these improvements are stunning; and thank you @shinchiro for the updated builds

I don't have that movie in HDR unfortunately, can you get a clip to me somehow?

I come bearing gifts Troublesome Mad max: https://0x0.st/sR8M.mkv Interstellar scene that Doofussy mentioned: https://0x0.st/sR8u.mkv I can also confirm that https://github.com/mpv-player/mpv/pull/6415 has fixed the artifacts, thanks for that!

If you want any further samples please feel free to @ me and I'll see what I can do

haasn commented 5 years ago

Thanks. When I wake up I'll probably start comparing the interstellar clip to the SDR blu-ray version to see how close we're getting to the "artist's intent". (That's ultimately my goal here - recreating what the mastering engineers want us to see on SDR screens, rather than trying to recreate the look of the HDR clip per se)

aufkrawall commented 5 years ago

I've tried the new build kindly provided by shinchiro, and yay, the LG chess demo doesn't suffer anymore the sudden brightness loss with peak detection. :) And also looks great otherwise.

Regarding the Samsung Chasing the Light video: The "smearing ringing" effect is also noticeable in motion when the sunflower petals are moving in the wind, it doesn't look as clean as when setting --tone-mapping-desaturate=1.0 --tone-mapping-desaturate-exponent=0.0. This is also the case with hdr-compute-peak=yes, just less obvious than with =no.

One more scene where it is very obvious is second 35. Default settings: https://abload.de/img/defzafix.png

--tone-mapping-desaturate=1.0 --tone-mapping-desaturate-exponent=0.0: https://abload.de/img/08oif4.png

There are differences in brightness between the screenshots due to seeking and peak detection, but the artifacts among the dark lines in the center are 100% reproducible and very noticeable during playback. But you surely have a good point that this video might be overproduced, as I haven't spotted such artifacts anywhere else. I won't mention it anymore if you don't want to hear from that video again.

I also looked at "The World in 4k", available on YouTube: https://www.youtube.com/watch?v=tO01J-M3g0U The pulsating brightness has been greatly reduced by the new peak detection, but it's still noticeable. One scene where this is very apparent is second 27, it suddenly turns way darker: https://abload.de/img/27vocq9.png Peak detection is a bit too dark in general in this video (judged by viewing on a sRGB IPS display with gamma of 2.2), and some scenes like second 27 are even darker than the average.

NSQY commented 5 years ago

I noticed towards the end of the Mad Max sample that I provided there's a scene with some extremely bright areas which seem to be clipping, I've been playing around with the new config options but I can't seem to resolve this; happens at about 1:40 in my sample mpv (new defaults): https://0x0.st/sRKi.png madvr: https://0x0.st/sR85.jpg

I also noticed that madvr is using BT.2390, opposed to mpv using BT.2100; this post https://forum.doom9.org/showthread.php?p=1709584 claims that it's "used to compress highlights", do you think we would see any advantage by swapping?

btw any and all samples that I provide should be x265/HDR, which should allow for easy testing of variable configs

haasn commented 5 years ago

The pulsating brightness has been greatly reduced by the new peak detection, but it's still noticeable.

You can try fiddling around with the parameters maybe? Of interest are:

haasn commented 5 years ago

I also noticed that madvr is using BT.2390, opposed to mpv using BT.2100; this post https://forum.doom9.org/showthread.php?p=1709584 claims that it's "used to compress highlights", do you think we would see any advantage by swapping?

Those two documents are not comparable. As for BT.2390, it's just a report (not a standard) and it documents several ways of doing tone mapping:

BT.2390

We use something like option "3) YRGB", madVR uses option "4) R'G'B'". Or, more precisely, with the new desaturation, we switch between YR'G'B' and R'G'B' tone mapping based on the brightness level.

As for the actual curve they present, they suggest using a hermite spline to roll-off the knee, as follows:

hermite Which I've played around with in the past but didn't think it was noticeably different from the existing curves (in particular, mobius already is a linear-with-knee function whose graph looks similar to the graph they provide).

re: that mad max clipping sample, for some reason the red channel in the image is almost entirely black, which leads to the weird blue color. this happens before even tone mapping. I'll investigate it in a bit. Also, I fixed another bug related to the new code that specifically affects the first few frames after a seek - but that one wouldn't cause any clipping.

red

Doofussy2 commented 5 years ago

Haasn, is there something in particular you'd like to test for? I'll be home in a few hours and I'll be able to test.

haasn commented 5 years ago

Found the culprit, it's due to the gamut reduction, which brings some values into the negative range. To fix it, we need to perform tone mapping before gamut reduction - while this can (and will) still introduce clipping as part of the gamut reduction, this is known and pretty much unavoidable.

The previous code's idea of trying to compensate for gamut reduction via tone mapping was, to put it simply, not correct. I've fixed it (not pushed yet).

That also explains why some of these issues went away when I was using the ICC profile (as I almost always do), since LittleCMS does a much better job reducing the gamut compared to our built-in gamut adaptation code - and more importantly - the ICC profile happens after tone mapping.

haasn commented 5 years ago

Also, I'd like to point out that this flame thing is slightly blue in the original source file. This is what it looks like using only linear scale adjustments (no tone mapping whatsoever):

blue-ish flames

This test raises an interesting question of how we want to balance the desaturation. This is what it looks like using the new default settings (+ the bug fixed):

new defaults

This is what it looks like if I bump up the desaturation strength to 1.0:

desat 1.0

And finally, this is what it looks like if I also drop the desaturation exponent to 0.0:

desat only

The default settings do make the blue flame kind of funny looking, but as you can also see, it's sort of in the source to begin with. So in a way, it's more faithful to the file, which to me seems like a good reason to keep it that way.

That said, mad max was almost surely not mastered on hardware actually capable of 10,000 nits, and the mastering engineer probably tuned this color based on that they saw on their screens. If their screen did desaturation tone mapping to reasonable brightness levels, then they would have shipped the file with that weird blue tint without realizing it? Speculation at this point...

lvml commented 5 years ago

@Doofussy2 : Just wanted to second your positive experience with "hable" as the tone mapping function - on my LG OLED TV, HDR content is also displayed by the TV-internal player very much like mpv looks with "hable" - with the TV's internal player however being much worse with regards to banding artefacts, that mpv does not suffer from.

Doofussy2 commented 5 years ago

@haasn my preference would be desaturation 1.0 (the third picture), though I'll be honest, I can't see any difference between 2 and 3. The last one is losing too much color around the lightning.

Doofussy2 commented 5 years ago

Just testing --tone-mapping=mobius --hdr-compute-peak=yes when playing Interstellar. The results are good. Definitely brighter than hable. Using --tone-mapping-param=0.1 didn't tone it down, noticeably. Mobius is a little too bright for me, but I don't see anything negative happening to the image. And it's a huge improvement over what we had, before. I think that could easily be the default.

NSQY commented 5 years ago

I'm unsure if we should take example from HDR TVs, they're tonemapping too and from what I've heard their algorithms aren't particularly impressive, results vary wildly between manufacturers and even models within a product line. From what I've read many people online prefer to use madvr instead of their TVs internal tonemapping solution for a superior result.

Doofussy2 commented 5 years ago

I'm unsure if we should take example from HDR TVs, they're tonemapping too and from what I've heard their algorithms aren't particularly impressive and it results vary wildly between manufacturers and even models within a product line. From what I've read many people online prefer to use madvr instead of their TVs internal tonemapping solution for a superior result.

Do you mean TV shows, like Netfix? Or hlg broadcast?

NSQY commented 5 years ago

Do you mean TV shows, like Netfix? Or hlg broadcast?

I mean, as I understand it, HDR TVs do not display a "true" result, See this quote:

"Well, this might be splitting hairs, but I already disagree with the wording you're using. When you say "the HDR version" that sounds as if what your OLED shows is to be considered to original reference HDR version, but it's not.

I know it's something people need to wrap their head around first. But official HDR displays are not really all that different from old SDR displays. The key difference is that official HDR displays have a firmware which supports tone mapping. There's no secret sauce. The display's aren't physically built in a different way, like different OLED materials or something. It's all just tone mapping in the firmware. Ok, maybe manufacturers are pulling some extra things to squeeze a bit more brightness out of their technology, so they don't have to tone map as much (as they would otherwise have to). But still, in the end the key thing an official HDR display has is just a firmware which supports tone mapping.

So if you let madVR convert HDR video to SDR, basically you're comparing madVR's tone mapping algorithm to LG's tone mapping algorithm. If you fully embrace that fact, it should be easy to understand that we can't start with the assumption that LG implemented a perfect tone mapping algorithm, and madVR did not. Actually, I'm hearing from various insiders lots and lots of complaints about the very bad quality of the tone mapping implementations of most TVs out there today.

So in the same way you wouldn't assume that your OLED must be better at upscaling compared to madVR (for whatever reason), you also shouldn't assume that your OLED must be better at tone mapping compared to madVR."

laichiaheng commented 5 years ago

@HyerrDoktyer Is MPV Player able to output wide gamut color directly to a HDR TV while using its tone mapping algorithm on Linux?

NSQY commented 5 years ago

@HyerrDoktyer Is MPV Player able to output wide gamut color directly to a HDR TV while using its tone mapping algorithm on Linux?

I believe so I'm not entirely sure, perhaps this issue may help: https://github.com/mpv-player/mpv/issues/5521

Regarding Mad Max, it seems that most if not all of the explosions in this film suffer from this "blue" effect,

--target-trc=linear linear

I do like the way other tonemapping methods handle these oddities, they seem to output bright yellow/white in these areas and I think the end result is far more realistic

default: fire

madvr: madvr

VLC: vlc

haasn commented 5 years ago

The key difference is that official HDR displays have a firmware which supports tone mapping.

I don't think this is the full story. The author is making the assumption that the display in HDR mode is just the same as the SDR mode except with a different transfer function. But for example, my "HDR" display (i.e. IPS display with FALD) makes a very big distinction: It will not activate the FALD algorithm in "SDR" mode, so it's literally just a normal SDR display (1000:1 contrast). Many other displays based on FALD technology will have similar limitations in SDR mode - you need to put them into HDR mode to unlock the extra dynamic range. More importantly, no HDR display that has a white point significantly higher than the SDR levels is going to enable its full brightness range in SDR mode. That would just be insane, since SDR signals are not designed to be displayed at >1000 cd/m^2, and the displays are similarly unequipped to handle such signals. The only real exception here is OLED displays, since OLED is high dynamic range by design, and most OLED displays typically max out at something like 400 cd/m^2 anyway, so they just treat SDR and HDR as the exact same thing. So this post is basically only true when talking about OLED displays exclusively.

Also, tone mapping HDR->HDR is very different from tone mapping HDR->SDR, in my opinion. In the HDR->HDR case, you have a display that has essentially the same standard range capabilities as the reference display, but a different peak brightness - you can preserve faithfully all standard range content while only adjusting the levels of the peaks. (This is what e.g. "mobius" is designed to do. In fact, for a HDR output display, mobius is 100% accurate for standard range content). This is also what BT.2390 talks about, and what your display is doing internally. This is comparatively also easy to do. The difficult part is tone mapping HDR->SDR, because you need to make sacrifices. Since you only have the "standard range" available, you have throw out some of the standard dynamic range so you can fit room for the highlights. This is what "hable" or "reinhard" are designed to do.

In my opinion, the correct comparison when discussing the HDR->SDR tone mapping algorithm is between the HDR and SDR versions of the same source material, and only where the SDR version was graded by a human (rather than an automatic tone mapping algorithm). This is because SDR mastering in the studio involves making the same tradeoffs that we are trying to recreate in our HDR->SDR tone mapping algorithm.

(And for HDR->HDR tone mapping, you can just turn off peak detection, set the curve to mobius, configure the --target-peak and be done with it.)

haasn commented 5 years ago

I do like the way other tonemapping methods handle these oddities, they seem to output bright yellow/white in these areas and I think the end result is far more realistic

Are those mpv screenshots taken with commit b29e4485c? As I already pointed out, there was an underflow on this scene due to the combination of the explosion being very bright and out of gamut, which makes this "blue" effect much worse than it's supposed to be, even in in the source. (note: you can work around it by setting --target-prim=bt.2020, but this will skip gamut mapping so the colors will be undersaturated compared to bt.709)

And yes, I think that for this clip, the only explanation I have is that the mastering engineer in charge of grading these samples was relying on his/her own display cancelling out the blue spots. If you look at the source, the MaxCLL is 9918 cd/m^2 (and we can certainly agree that this movie has insane brightness levels), while the mastering display metadata says it was mastered on a display with only 4000 cd/m^2 luminance. So without a doubt, the mastering engineer was seeing a tone mapped version. (Clear evidence that they fucked up, you should never master to levels that exceed your own display's capabilities for precisely this reason...)

Fortunately, that actually gives us a way to work around it (and movies like it): We could tone map twice; once using the fully desaturated, dumb/naive "TV-style" tone mapping algorithm, to bring it from the MaxCLL levels (9918 nits) down to the mastering levels (4000 nits). Then we can tone map a second time to bring it down from the mastering levels to the display levels (i.e. 100 nits for an SDR display), and the second time around we can use the full tone mapping algorithm in its chromatically accurate / content-adaptive mode.

NSQY commented 5 years ago

In my opinion, the correct comparison when discussing the HDR->SDR tone mapping algorithm is between the HDR and SDR versions of the same source material

Would a clip of the SDR version of Mad Max be helpful? Or do you already have your hands on that?

Are those mpv screenshots taken with commit b29e448?

No, they were taken with shinchiros latest build I would prefer to compile my own builds so I can test these patches as you push them but I've had nothing but trouble cross compiling; probably PEBCAK more than anything. I had no issues compiling on a liveUSB but that's obviously a temporary solution and unfortunately as of now I don't have a more permanent environment. MSYS2 repos are satan I can't even get 1KB/s from them, it took over 4 hours to get the dependencies

haasn commented 5 years ago

Would a clip of the SDR version of Mad Max be helpful? Or do you already have your hands on that?

It would!

No, they were taken with shinchiros latest build

Okay. Well, I made screenshots of a different frame with that bug fixed. You can compare it against that one if you want. But we already know what the madVR result will be, since we can more or less recreate it ourselves by setting the desaturation exponent to 0. (It should be the same as the bottom screenshot in my post)

NSQY commented 5 years ago

I had to cut the start to save on filesize, so it won't be frame accurate; sorry. https://0x0.st/sRmM.mp4

mad max storm sdr 00_01_08 193 0001

shinchiro commented 5 years ago

New build to test: mpv-x86_64-20190103-git-b29e448.zip

haasn commented 5 years ago

Okay, I made some comparisons between the HDR and SDR versions of Interstellar:

These are all with the new default tone mapping settings.

Some observations:

Overall I'm relatively okay with how this turned out.

haasn commented 5 years ago

To recover some of that detail in the ultra bright scenes we'd really need to start selectively expanding the dynamic range in addition to just darkening it. The problem is that the source content is very "flat", i.e. the SDR version has a greater contrast than the HDR version (ironically). Most likely the mastering engineers decided to boost the contrast of these scenes to bring out the details more.

In theory we could detect such "flat" scenes and boost the contrast dynamically ourselfes. But I won't open that can of worms.

NSQY commented 5 years ago

The HDR version seems to be more green-tinted, and also has a different crop, compared to the SDR version I have. This seems to be in the source; I can't get rid of it by using different tone mapping settings. Most likely we should ignore this.

From my experience, this seems like the correct decision. Most HDR releases have a slight tint to them (usually yellow) The Big Lebowski is probably the most egregious example I can think of

SDR (Old BD): 1

HDR: 2

SDR (Old BD): 3

HDR: 4

haasn commented 5 years ago

Comparing the mad max clip however, it seems like "mobius" matches the SDR version very well in most scenes, but in other scenes (especially bright ones), "hable" matches the SDR version better. Again, it's hit and miss. I think both are passable, but I would stick with "hable" personally.

I'll make some four-way comparisons between the HDR version as-is, the SDR version, the HDR version with mobius, and the HDR version with the "simulated mastering display" I described earlier; once I get around to implementing that.

haasn commented 5 years ago

@HyerrDoktyer sounds like a hollywood trick to increase sales of the HDR blu-ray by artificially exaggerating the difference between the two

NSQY commented 5 years ago

Potentially, there's a huge amount of resale value with these new releases (HDR10/HDR10+/DV) and I'm sure they're well aware of it. But the point is that a colour shift is basically expected when viewing HDR releases

NSQY commented 5 years ago

Okay so, regarding the comments on your pull request

Is --tone-mapping-max-boost useful? Does it help on dark scenes? Or is it more annoying?

I think Annihilation is an interesting sample as it is basically the opposite of Mad Max, in the sense that it's incredibly dark, so dark in fact that there's almost no detail in many shadows

Here's some comparisons, defaults vs --tone-mapping-max-boost=1.5 https://imgbox.com/g/uGCpUy37oq

Nice improvement