View Full Version : I Have Published a HDR10 to HLG Converter
Pages :
1
2
3
4
5
6
7
8
[
9]
10
FranceBB
31st December 2023, 01:54
Thank you for the sample!
Well, as I said with Goodfellas before, we're really getting closer and closer to the limit of what was actually on the physical film with these 4K scans.
Still, the fact that there are still details coming out of it compared to the FULL HD version is astonishing (I'm currently back to my parents' house for the holidays so I don't have the FHD version handy for a quick comparison).
If you take a look at this, it may not look like much:
https://i.imgur.com/grf9hoF.png
until you realize it actually comes out of this:
https://i.imgur.com/ZWOumgu.png
(pictures in BT709 SDR only for reference)
Every time I think about the amount of info the physical film reel used to hold back in the days and how much that was squeezed into 480i / 576i CRT at the time, it's just incredible.
Here are we are, 26 years after the movie was shot, finally seeing the details the original reel had on consumer hardware. Amazing.
By the way, this film is actually better preserved than others I've seen in the past, which is something to keep into consideration.
Who knows if we'll talk about this again when 8K will finally be a thing... ehehehehe
If you want something up in the original PQ, I can do that too so long as it's kept under two minutes.
Nah, I'm fine with HLG. :)
This scene here was probably 287 nits in PQ because of the clipped out sky and I can see that it's well below 0.52V in HLG which is fine as it won't burn the eyes of the viewer this way (just like it wouldn't in PQ). :)
https://i.imgur.com/qWuATtI.png
https://i.imgur.com/DRDA4i6.png
in BT709 SDR as a reference:
https://i.imgur.com/M424KGK.png
wswartzendruber
31st December 2023, 21:57
Surely something there is above 0.52V... That should be like 83 nits in a reference environment.
EDIT: I'm tempted to generate a custom LUT that converts this to BT.2020 SDR, because that's more or less what it is.
FranceBB
2nd January 2024, 10:15
Surely something there is above 0.52V...
Is there? XD
I'm tempted to generate a custom LUT that converts this to BT.2020 SDR, because that's more or less what it is.
Yeah that would actually make a lot of sense.
I mean, fake 283 nits aside, it does come from an SDR source in the first place anyway, so...
wswartzendruber
3rd January 2024, 03:52
If that's my HLG YouTube clip, the sky in that frame should be right at 75% HLG.
EDIT: Time to get work on this custom LUT!
EDIT: It's a smidge above SDR. This has peak white at 1.6X reference white, roughly. SDR is typically graded to put peak white at 1.25X reference white.
EDIT: Okay, clip is uploading.
wswartzendruber
3rd January 2024, 08:34
Titanic: Rose Arrives in Southampton [SDR-WCG] (https://www.youtube.com/watch?v=eFEyHcWAmDw)
Does this even play as BT.2020 SDR? It didn't on the HDR-equipped laptop I have, but I also know that YouTube encodes BT.709 first and then goes on to BT.2020/2100.
FranceBB
3rd January 2024, 10:09
Arg, nope, it reports BT709 SDR from the internal YouTube conversion...
Looks like it's internally converting to BT709 8bit... :(
wswartzendruber
3rd January 2024, 15:16
Bah. Fine.
https://wswartzendruber.net/uploads/titanic-rose-arrives-in-southampton-bt2020sdr.mkv
FranceBB
4th January 2024, 10:49
Looks good now and even in SDR there's still headroom. :)
https://i.imgur.com/OggqlgL.png
BT2020 SDR
https://i.imgur.com/StYM8Ae.png
BT709 SDR (as reference)
https://i.imgur.com/LUtxscQ.png
It's also nice to see the grain in the shot now that I have a sample encoded from you and not one murdered by YouTube's VP9:
https://i.imgur.com/qXX9kBn.png
wswartzendruber
4th January 2024, 15:43
Well I'm glad it came out good. Here's the LUT if you want it:
https://wswartzendruber.net/uploads/titanic-bt2020-sdr.cube
ErazorTT
10th January 2024, 11:52
EDIT: Increasing image exposure via linear RGB appears to be "correct" for now anyway. Oklab does return different brightness levels when monochroming an image (like in preview mode).
Actually I think this detour was at least a nice double check that things work correctly. Concerning the monochroming, well yes, I always thought there is something wrong the way it is usually done. Looking at monochrome from BT709 and comparing it to monochrome from BT2020 was way too different in the reds.
wswartzendruber
12th January 2024, 23:42
Actually I think this detour was at least a nice double check that things work correctly. Concerning the monochroming, well yes, I always thought there is something wrong the way it is usually done. Looking at monochrome from BT709 and comparing it to monochrome from BT2020 was way too different in the reds.
I guess it's time to get 2.0.0 released and then move the documentation over to the wiki.
ErazorTT
23rd January 2024, 18:51
So apparently you have released with the oklab conversion, meaning that its now using exposure instand of lumscale.
For reference, this is how exposure and lumsacle relate to eachother:
lumscale = exposure^3
exposure = lumscale^(1/3)
I actually prefered the old linear behaviour of lumsacle since its interplay with max-cll was much easier to understand. lumscale*max-cll was meaningful value which the whole tonemapping depended on.
So I would suggest to add the above scaling to your application and let the user insert lumscale as before, you can then calculate exposure internally.
Independently of that and independently of the version used (1.0, 1.1 or 2.0) by coincidence I ran into the following issue:
Here you see a ramp of red to blue. When iterpreded as a PQ source and applying a lut with max-cll=2000 and lum-scale=4 (or exposure=1.587) I get an unexpected output.
source:
https://i.postimg.cc/JGknbb2t/red-blue-PQ-small.png (https://postimg.cc/JGknbb2t)
HLG:
https://i.postimg.cc/Xr6vxpRL/red-blue-HLG-small.png (https://postimg.cc/Xr6vxpRL)
Click and open the bigger images, I added two green arrows to show where the issue is. For me this appears to be something related to one of the e1, e2, e3 or e4 of the EETF, you probably know what I mean.
wswartzendruber
23rd January 2024, 20:23
EDIT: Disregard everything before this.
You're driving max red on the left and max blue on the right. Because you're maxing out a color channel (regardless of which one), that's going to push your effective MaxCLL up to 10,000 nits. Remember that MaxCLL isn't just how bright the overall pixel is, it's how bright that pixel would be if all of its color channels were aligned with its highest one.
With that said, I've found a bug in the "rgb" tone mapping mode. I need to investigate that. There's some weird fuchsia banding going on... This, fortunately, is not the default tone mapping mode.
Also, I can add --lum-scale back in.
EDIT: My good friend "NaN" is back in the generated LUT for the "rgb" tone mapping method...
* Loads lever-action rifle. *
I'm going to put this pain-in-the-ass down once and for all...
wswartzendruber
24th January 2024, 01:52
* BANG!!! *
Anyway, here's 2.1.0: https://github.com/wswartzendruber/hlg-tools/releases/tag/release%2F2.1.0
I've added a battalion of unit tests to ensure that NaN, Inf, or anything outside the range of 0.0...1.0 never shows up in a LUT ever again.
Oh and --lum-scale is back. :-)
ErazorTT
24th January 2024, 16:23
* BANG!!! *
Anyway, here's 2.1.0: https://github.com/wswartzendruber/hlg-tools/releases/tag/release%2F2.1.0
Awesome!
Going back to my issue of the color ramp. Yes, the colors are driven to the max, yes. So this shows what happens when the values overshoot the range set via max-cll. I think that overshooting should still not lead to the hue and brightness changes seen. The rgb tonemapping LUT does not show this behaviour.
wswartzendruber
24th January 2024, 17:09
Awesome!
Going back to my issue of the color ramp. Yes, the colors are driven to the max, yes. So this shows what happens when the values overshoot the range set via max-cll. I think that overshooting should still not lead to the hue and brightness changes seen. The rgb tonemapping LUT does not show this behaviour.
Well, there's no single best way to do tone mapping. The MaxRGB method is a somewhat recent addition to BT.2408. It typically provides the best results for commercial productions, but not always. You may very well conclude that it's objectively inferior to RGB and that's fine. That's why I didn't remove RGB when adding MaxRGB.
ErazorTT
26th January 2024, 18:41
I just have made another test with the following script:
BlankClip(color=$000000,length=30*24,pixel_type="RGBP16",width=960,height=540,fps=24000,fps_denominator=1001).RGBAdjust(rb=49271,gb=49271,bb=49271)
Cube("lut_1.0_1000.cube",interp=1)
The script creates a uniform gray at RGB value (49271,49271,49271) which is exactly at 1000nits in PQ terms (in 10 bit YUV this would be 723,512,512).
With LUTs of increasing size the output value is getting nearer to the max of 65535 but is never really getting there. With a LUT of size 65 I'm getting 65387, and even with a LUT of size 126 I'm getting 65526.
While at the first glance this does not sould very surprising, of course bigger LUTs give better results, for me it was unexpected because I would have thought to be at the very max of the LUT, where I would have not expected any interpolation anymore and would have thought to always get 65535 independently of the LUT size.
(Why does my expectaion not hold that at these input levels we should be at the max of the LUT, where there would be no interpolation? Why is that not the case?) => See next post!
As settings for the LUTs I used a max-cll of 1000 and a lum-scale of 1.0. RGB or MaxRGB does have no influence. And the same findings also apply to FranceBBs PQ_to_HLG LUT.
I know it nitpicking, but 65387 is 985 nits and not 1000 nits.
ErazorTT
26th January 2024, 19:30
Ok I found out what what my misconception was. The LUT has as input the whole range, not just the relevant part of 0-49271. Since the points are placed evenly on the whole range one can find out which LUT would have a point nearest to the desired value of 75.18%. I made that very simple calculation and it turns out that the LUT with a point nearest to that is of size 138. And that one indeed has the expected max value of 65535 for an input of 49271. However, a LUT of that size is rather impractical, since it does not fit in almost any CPU cache (except of the L3 of modern CPUs).
The LUTs of the following sizes are optimal in the sense, that they provide the highest output at an input of 1000nits PQ (=49271=75.18%) compared to the LUTs of the sizes inbetween them:
5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,70,74,78,82,86,90,94,98,102,106,110,114,118,122,126,130,134,138
(While the absolute best is 138 since it's the only one actually delivering the max out channels at the given max input.)
So if you choose a LUT size for PQ to HLG conversions, be sure that it has one of these sizes.
ErazorTT
28th January 2024, 19:15
Ok, so I'm now about to finish my monologue :D
To sum up what I figuered out: Depeding on the settings to pq2hlg it is possible to cut down the LUT to remove unnecessary values as long as the LUT does not have the whole PQ range as input. For a LUT with max-cll of 1000 and a lum-scale of 1.0 this means that all input values above 75.18% can be removed from the LUT. This makes the LUT less then half as big (0.7518^3=0.425). For this it is necessary to use the DOMAIN_MAX attribute inside the LUT, setting it to the input level of the highest available point in the trimmed LUT, which is going to be something slightly higher then 0.7518. This DOMAIN_MAX attribute is suppored by both VSCube and DGCube.
If anybody is interested in this, I have written a small application which does this trimming. And if wswartzendruber thinks it's worth to halve the sizes of the LUTs created by his pq2hlg, he could implement this trimming into it.
wswartzendruber
1st February 2024, 21:18
In one post you're talking about overdriving MaxCLL and now you're talking about limiting the input domain. ��
EDIT: We can't put emojis in text?
ErazorTT
19th February 2024, 20:44
@wswartzendruber, yeah sorry I was all over the place with my thoughts.
In the meantime I have sorted my thoughts and came to the following conclusion: Having one LUT for the process of tonemapping the PQ down to 1000 nits AND converting to HLG is proably not the most optimal way of doing it.
The main argument here is that all the different maxcll and lumascales are part of the tonemapping, which can be done with a 1D-LUT (one for each combination of maxcll and lumascale) while the conversion to HLG can be done with a static 3D-LUT, which absolutely never changes.
Since that 1D-LUT can be generated extremenly fast for each combination of maxcll and lumascale, this opens the possibility for dynamic tonemapping.
So I went and implemented exactly that in DoViBaker. It now provides the possibility to have dynamic tonemapping, based on a 1D-LUT generated in memory on the fly. And then on top of that the user can apply the conversion to HLG with a static 3D-LUT. Of course there is also the possibility to have static tonemapping in case the input is just PQ without DolbyVision.
I think that this is an impoved workflow since on top of the addition of dynamic tonemapping, I can also circument the issue with the maximal output brightness of the HLG conversion, by allowing the intermediate output after the tonemapping to be scaled such that it fills the whole singal range. The then adjusted HLG conversion 3D-LUT uses the whole input range, which solves that problem. And also that adjusted 3D-LUT can be much smaller since now all LUT-points are used, and not only those below maxcll.
So instead of having a 65x65x65 LUT where only the lower 50x50x50 points are used, I can now directly use an adjusted 50x50x50 LUT, which has the same fidelity as the usual 65x65x65 LUT but now also hits the absolute max output brightness perfectly, while being less than half the file size (and CPU cache size).
wswartzendruber
20th February 2024, 00:25
hlg-tools inherently can't handle dynamic metedata because it generates static LUTs. If something else comes along and is a better way to do things, that won't bother me none.
kolak
20th February 2024, 15:27
@wswartzendruber, yeah sorry I was all over the place with my thoughts.
In the meantime I have sorted my thoughts and came to the following conclusion: Having one LUT for the process of tonemapping the PQ down to 1000 nits AND converting to HLG is proably not the most optimal way of doing it.
The main argument here is that all the different maxcll and lumascales are part of the tonemapping, which can be done with a 1D-LUT (one for each combination of maxcll and lumascale) while the conversion to HLG can be done with a static 3D-LUT, which absolutely never changes.
Since that 1D-LUT can be generated extremenly fast for each combination of maxcll and lumascale, this opens the possibility for dynamic tonemapping.
.
This is an idea behind Dolby tone mapping. It's done per shot or even per frame (eg. for live content) with some 'smoothing'.
2 pass mapping sounds like most optimal.
wswartzendruber
27th February 2024, 22:47
I actually don't know that I'm as done with this as I thought I was...
If can I figure out how to efficiently calculate a device-dependent color space's maximum C value in OKLCH, I can quickly do gamut reduction without impacting perceptual brightness. This would let me efficiently:
1. Perform Y-based tonemapping which is not commonly done as it can produce out-of-gamut results.
2. Deal with maximum saturation on a single color channel which causes HLG to clip on that channel.
ErazorTT
28th February 2024, 11:35
This is an idea behind Dolby tone mapping. It's done per shot or even per frame (eg. for live content) with some 'smoothing'.
2 pass mapping sounds like most optimal.
This is exactly what DoViBaker does. If a DolbyVision substream is available it reads it and steers the tonemapping accordingly. And if no DolbyVision substream is available, the stream can be scanned which creates the necessary information which is then again used for the tonemapping.
ErazorTT
28th February 2024, 11:40
I actually don't know that I'm as done with this as I thought I was...
If can I figure out how to efficiently calculate a device-dependent color space's maximum C value in OKLCH, I can quickly do gamut reduction without impacting perceptual brightness.
That sound interesting, however looking at https://oklch.com/ it appears to me that the numerical range of the C varialbe has a complicated functional form depeding on the other two variables (this "mountain range" on the top right of the page). How do you plan to use this for gamut reduction?
wswartzendruber
28th February 2024, 17:31
That sound interesting, however looking at https://oklch.com/ it appears to me that the numerical range of the C varialbe has a complicated functional form depeding on the other two variables (this "mountain range" on the top right of the page). How do you plan to use this for gamut reduction?
Right now, I am using brute force to reduce C by an incredibly small amount until converting to RGB has everything in the 0.0-1.0 range. I have generated an experimental BT.2020-to-BT.709 LUT with this method and sent that off to FranceBB for evaluation.
Example Screenshot of Joker HLG (https://wswartzendruber.net/images/bt2020to709-1/bt2020to709-joker-hlg.png)
The OKLAB author mentions elsewhere a far more efficient method that I may implement. It relies on color gamut being the shape of a triangle.
FranceBB
29th February 2024, 16:00
Right now, I am using brute force to reduce C by an incredibly small amount until converting to RGB has everything in the 0.0-1.0 range. I have generated an experimental BT.2020-to-BT.709 LUT with this method and sent that off to FranceBB for evaluation.
Yes and I'm really really really sorry, but I'm still "having fun" with generating DolbyE 5.1 20bit big endian muxed in aiff...
Once that one is sorted, I'll take a very close look at it.
Apologies for the delay... :(
wswartzendruber
29th February 2024, 18:29
Well, I threw the LUT your direction without speaking to you about it prior. You have every right to simply ignore it.
With that said, I am quite thankful that you are willing to review it.
FranceBB
29th February 2024, 22:37
I would never do that, I consider you my friend, we even did a video call together, I would never ignore you. :)
Unfortunately spare time project thingies are piling up. I also still have to review a pull request by frank for videotek which is still there pending... :(
It's not easy when you clock in at 08.30AM and you leave your desk at 09.37PM... :(
wswartzendruber
1st March 2024, 03:32
I would never do that, I consider you my friend, we even did a video call together, I would never ignore you. :)
Unfortunately spare time project thingies are piling up. I also still have to review a pull request by frank for videotek which is still there pending... :(
It's not easy when you clock in at 08.30AM and you leave your desk at 09.37PM... :(
The priority for you might be some rest and relaxation before looking at the LUT.
FranceBB
15th March 2024, 21:28
Ok, I finally had time to review the LUT.
The LUT has been tested against BT2020 SDR 100 nits contents.
Those contents were way more common in early 2013-2015 when the very first UHD H.265 50p 10bit broadcasting began and streams were just WCG (i.e Wide Color Gamut) but there was no standardization around using actual different logarithmic transfer characteristics.
It goes without saying that the world in 2013 was a very different place. Back then, we didn't expect things to end up the way they are now with logarithmic transfers, because the change in standard was already pretty massive without it!
We were effectively moving from H.264 FULL HD 25i TFF BT709 8bit to H.265 UHD 50p BT2020 10bit, so aside from the resolution and the codec, the very big swing was finally going progressive by saying goodbye to interlacing and finally going to 10bit.
As to the BT2020, given that the overwhelming majority of native BT2020 SDR 100 nits contents were coming from sport events (especially football), everything else was mostly still BT709 SDR 100 nits.
This meant that back then the supply chains around the BT2020/BT709 conversions were made to provide an easy roundtrip by effectively allowing to map BT709 points to BT2020 and remap those down to BT709 almost perfectly in a similar way of what was done for BT709/BT601. This meant it was possible to convert a native BT709 content without "inventing" anything but rather by just remapping the points to the right BT2020 coefficients so that those could then be mapped back (eventually) to BT709 if it was needed.
Back then little did we know that we would end up broadcasting different transfer characteristics, in fact working with logarithmic curves was common but not standardized and it was only an intermediate step in the production process and given that there was no standard everyone came up with its own implementation, the likes of Sony with Slog, Canon with Clog, Arri with LogC, ImagineVision with ZLog for their ZCam etc. What was worse was that each manufacturer included this info either as proprietary metadata in the file (Sony) or by writing the metadata as additional info, so in the "wrong" place in the file (Arri, ImagineVision) or even by blatantly lying and saying BT709 and then including the actual info in a sidecar XML (Canon).
This is still relevant today 'cause if we have HLG is thanks to the development and efforts done in those early days to standardize the whole thing and with the concept that people who still own a BT2020 SDR TV can still watch the stream.
As for the BT709 SDR -> BT2020 SDR -> BT709 SDR roundtrip, it was due to the fact that it was commonly thought back then that we would have been having a single master for everything in BT2020 SDR from which everything else needed to be obtained, a bit like what happened for BT709 (in fact I'd say that 100% of the BT601 SDR versions in 2013 were obtained automatically from the BT709 master). I made several tests with Jean Philippe Scotto di Rinaldi back then and in fact it's possible to apply a perfectly valid roundtrip in his HDR Tools like so:
#BT709 to BT2020
ConvertYUVtoXYZ()
ConvertXYZtoYUV(Color=1, pColor=2)
#BT2020 to BT709
ConvertYUVtoXYZ(Color=1)
ConvertXYZtoYUV(pColor=1)
This can be shown as follows (roundtrip BT709-2020-709):
BT709
BT2020
BT709
https://i.imgur.com/63OSOf5.png
https://i.imgur.com/9WBuF92.png
https://i.imgur.com/5IJBU5f.png
As you can see, the roundtrip is performed correctly.
Now, enough of that, on with the tests:
https://i.imgur.com/NBM2np9.png
https://i.imgur.com/ug7mAcd.png
https://i.imgur.com/kqQxUHK.png
https://i.imgur.com/1XspL7P.png
https://i.imgur.com/PnhNxdt.png
https://i.imgur.com/smNdknQ.png
https://i.imgur.com/b9wI0hq.png
https://i.imgur.com/th6qiYy.png
Note that I've just labelled the results obtained with William's LUT "HLG Tools" although he said that it's still experimental and he hasn't included it yet.
Here we can see that OKLAB (the algorithm he based his LUT on) seems to be producing a darker output, thus producing a slight shift in chroma. In some scenes it's much more noticeable, while in some others it's harder to spot. For instance, in the blue of the ambulance it's pretty noticeable. The overall result, however, is not bad and if someone didn't have something to compare it against, he would never be able to notice the difference.
If I have time, I'll try with some sport footage next time.
wswartzendruber
16th March 2024, 00:07
EDIT: Whoops, nevermind.
FranceBB
18th March 2024, 10:15
New test, this time on Sports, which is actually a true representation of BT2020 SDR 100 nits and I have to say that the results are actually pretty good there.
Both HDR Tools and William's new LUT achieve a very good result. The game was totally watchable and the results were incredibly close. I guess William's new idea of reducing the chroma to make it fall within valid BT709 SDR values works, so... well done. :)
https://i.imgur.com/fe9wwg5.png
https://i.imgur.com/ZjxmWA5.png
https://i.imgur.com/F9u9Boz.png
https://i.imgur.com/yl3TLTZ.png
https://i.imgur.com/OMuCUEM.png
https://i.imgur.com/qnu75xy.png
https://i.imgur.com/FahY82i.png
https://i.imgur.com/VnhnJiw.png
https://i.imgur.com/YBpSoPL.png
https://i.imgur.com/W3weWZF.png
https://i.imgur.com/1FSC00Y.png
wswartzendruber
19th March 2024, 05:53
Yeah so it really does just hard-clip the color gamut. This is typically hard to do because finding a LAB/LCH-based color model than can do this can be a bit difficult. If a color model doesn't cause perceived brightness changes from lowering the chroma, then it will probably cause a hue shift from doing so.
Anyway, here's the OKLAB/OKLCH-based LUT:
https://wswartzendruber.net/uploads/bt2020to709.cube
I find this also works quite well for watching my HLG conversions on my 709 devices:
https://wswartzendruber.net/images/bt2020to709-1
ErazorTT
20th March 2024, 16:46
Since my last replay in here, I also have been working on a LUT generator from PQ down to HLG, 2020 SDR and 709 SDR (DoViLutGen which is now part of DoViBaker (https://github.com/erazortt/DoViBaker)). Including a LAB based mapping to prevent hard clipping for 2020 to 709. And there, what transfere function would you guys think is the proper one to take for going to and from linear, the one from BT709 (scene-referred) or the one from BT1886 (display-referred)? wswartzendruber has apparently used BT1886, which after some back and forth I now also think it probably the right one. But what do you think FranceBB?
FranceBB
20th March 2024, 21:18
And there, what transfer function would you guys think is the proper one to take for going to and from linear, the one from BT709 (scene-referred) or the one from BT1886 (display-referred)?
I'm using display-referred.
wswartzendruber
20th March 2024, 23:18
I've had good results using the same LUT to convert both BT.2100 HLG and BT.2020 SDR into BT.709 SDR.
FranceBB
21st March 2024, 07:32
I've had good results using the same LUT to convert both BT.2100 HLG and BT.2020 SDR into BT.709 SDR.
Yes of course, that's the whole point about HLG.
On a BT709 classic monitor by just converting the matrix/primaries and leaving the transfer alone, you're essentially seeing the same results a person with a BT2020 SDR TV would see when its TV doesn't interpret the transfer. And with HLG the idea is that you're still gonna be able to enjoy a valid result, albeit dimmer.
In the future, hopefully, SD and FULL HD channels will be tossed in favour of one single UHD BT2020 HLG stream per channel, but that future ain't here yet and we still have SD channels... :(
FranceBB
26th March 2024, 13:40
Same test but this time with an HDR HLG source.
The same concept applies, but this time round I included the waveform to make things more clear.
Effectively, by just converting the matrix and primaries the luma is left untouched, which means that the result will be dimmer compared to tonemapping, but it will be very close to what someone with a BT2020 SDR TV would see.
In this example we have the BT2020 HLG source on the left, Reinhard tonemapping to BT709 SDR (HDR Tools) in the middle and then a simple colormatrix and primaries conversion with William's LUT (HLG Tools) on the right:
https://i.imgur.com/alDi2y7.png
https://i.imgur.com/LXwpnFK.png
https://i.imgur.com/nqa2cw6.png
https://i.imgur.com/FkEJ23a.png
https://i.imgur.com/WQ7XxwB.png
as we can see from the luma, this is left untouched by William's LUT and therefore it will peak at the same level as the original HLG source, thus making the white look a bit dimmer. This is exactly what HLG was created for and it's basically the same result someone with a BT2020 SDR TV at home would see. The idea behind HLG is to make it watchable without having to convert the transfer for the BT2020 SDR TVs, so the very same concept can be applied to convert from WCG BT2020 to BT709 leaving the original transfer alone. :)
wswartzendruber
26th March 2024, 17:20
I was thinking about something several days ago and had a realization. With SDR, indoor and outdoor scenes tend to have small variance in where reference white would be. But with HDR, there is a lot more variance between these scenes. With the BBC putting reference white at 75% HLG, and then by viewing this on a SDR display, we effectively have these dimmer indoor scenes "pushed up" towards 75% and the brighter outdoor scenes "pushed down" towards the same level. This seems to go a long way in making HLG look "like it should" despite the greater variance in HDR's levels of indoor vs. outdoor scenes.
As best I can tell, the 75% HLG level for reference white was a BBC innovation, as NHK's original specification called for 50%. Another way to put this is that the NHK seems to have viewed HLG as a hack to have basic monitoring work on existing 10-bit equipment while the BBC wanted HLG to "just work" on existing 10-bit consumer devices.
wswartzendruber
3rd April 2024, 20:37
I've got Planet Earth II showing up on 4K Blu-ray today. :D
For those who don't know, this is what was used to show the world HLG for the first time in 2017 using the BBC's iPlayer app.
As I understand it, the content was natively graded in HLG and then for this disc, converted directly to PQ. So hopefully, reference white is parked neatly at 203 nits and MaxCLL is right at 1,000 nits.
FranceBB
3rd April 2024, 21:51
I've got Planet Earth II showing up on 4K Blu-ray today. :D
uuuuuh David Attenborough, a national legend!
I love the BBC documentaries in HLG, they're always perfect and his voice is so calm.
For those who don't know, this is what was used to show the world HLG for the first time in 2017 using the BBC's iPlayer app.
Yep, the only things I still don't like about the BBC iPlayer are:
A) No 5.1 support
B) No HLG support on the web version
The first one is a bit sad 'cause lots of programs are actually made in 5.1 and yet they're just sent out as stereo (as a long-time subwoofer owner, I care about this).
The second is really sad 'cause you can see the glorious UHD HLG contents if and only if you're using the BBC iPlayer App AND your Smart TV is supported. On one side, I understand that this means that they rigorously test each and every device the app works on (and I'm not joking here, when I met Andrew, one of the guys from the BBC, he said that they absolutely positively test them all to make sure they perform correctly), but on the other side it's a bit sad 'cause it means that whenever it comes to generic things they can't test like the web version they limit the features to the very bare minimum set of what they know is gonna work... :(
FranceBB
2nd May 2024, 11:16
Currently, I'm employing brute force to minutely decrease C until the conversion to RGB falls within the 0.0-1.0 range. Using this approach, I've produced an experimental BT.2020-to-BT.709 LUT, which I've forwarded to FranceBB for assessment.
No, you did no, you useless AI powered bot.
William did, William created it.
Man, I'm starting to miss the old spammers that used to register, post a link and get banned. With AI it's now harder to spot those stuff...
Anyway, I've reported the account, it will be banned soon.
wswartzendruber
2nd May 2024, 21:22
If I respond to the bot, does that count as talking to myself like a crazy person?
wswartzendruber
21st May 2024, 04:52
Here's a comparison between the OKLCH LUT and VLC on Windows:
https://wswartzendruber.net/images/oklch-lut-vs-vlc-windows/ospray-interior.png
https://wswartzendruber.net/images/oklch-lut-vs-vlc-windows/analysts.png
https://wswartzendruber.net/images/oklch-lut-vs-vlc-windows/used-car-lot.png
https://wswartzendruber.net/images/oklch-lut-vs-vlc-windows/mikayla.png
https://wswartzendruber.net/images/oklch-lut-vs-vlc-windows/pursuit.png
https://wswartzendruber.net/images/oklch-lut-vs-vlc-windows/optimus-prime.png
https://wswartzendruber.net/images/oklch-lut-vs-vlc-windows/glenn.png
https://wswartzendruber.net/images/oklch-lut-vs-vlc-windows/autobots-en-route.png
tormento
10th March 2025, 19:46
Version 1.0.1 is out.
I have a strange issue with the anime The Castle of Cagliostro.
The mediainfo reports:
Mastering display luminance : min: 0.0050 cd/m2, max: 1000 cd/m2
Maximum Content Light Level : 1000 cd/m2
Maximum Frame-Average Light Le : 159 cd/m2
Being so dark, I wanted to try your utility, after checking the true values for both of them. I have a MaxCLL of about 450 (with a peak of 2200, probably an artifact) and a Reference white of 160.
I have created two luts: one peaking at 500 and one peaking ad 2200. The very strange part is that, even if they are different, I can see no difference at all in the output, even using the Tektronik plugin by FranceBB. The nit graphics are really identical.
Any idea?
This is the distribution:
https://i.ibb.co/VcKds82n/Cagliostro-UHD-HDR-plot.png (https://ibb.co/VcKds82n)
This is the output with BBC lut for 1000 cd/m2
https://i.ibb.co/ZpWFNxhD/image.png (https://ibb.co/ZpWFNxhD)
This is the output with generated lut for 500 cd/m2
https://i.ibb.co/twHHNLmJ/image.png (https://ibb.co/twHHNLmJ)
This is the output with generated lut for 2200 cd/m2
https://i.ibb.co/nMWQYzKh/image.png (https://ibb.co/nMWQYzKh)
I can see no difference between the last two. Why?
The script is (obv changing the lut):
LoadPlugin("D:\Eseguibili\Media\DGDecNV\DGDecodeNV.dll")
LoadPlugin("D:\Eseguibili\Media\DGCube\DGCube.dll")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\DehaloAlpha\Dehalo_alpha.avsi")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\Dither\mt_xxpand_multi.avsi")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\FineDehalo\FineDehalo.avsi")
DGSource("M:\In\Cagliostro UHD\Cagliostro_UHD.dgi",ct=44,cb=44,cl=0,cr=0)
Y = ConvertToY(matrix="rec2020").DeBilinearResizeMT(1920, 1036, threads=1, prefetch=2, accuracy=2)
U = UToY()
V = VToY()
YToUV(U, V, Y)
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:full", resample_filter_uv="Spline64", dither_type="error_diffusion", use_props=0)
DGCube("D:\Programmi\Media\AviSynth+\cube\BBC LUT 1.7\1a65_PQ1000_HLG_Type1_Transcode_nocomp-v1_7-cicp.cube", in="full", lut="full", out="full")
z_ConvertFormat(pixel_type="YUV420P16"", colorspace_op="rgb:std-b67:2020:full=>2020:std-b67:2020:limited", resample_filter_uv="Spline64", dither_type="error_diffusion", use_props=0)
fmtc_bitdepth (bits=10,dmode=8)
VideoTek(Mode="HLG", Type="nits")
Prefetch(2,6)
wswartzendruber
12th March 2025, 02:38
That looks right to me. Let's start off with establishing some things about how pq2hlg behaves:
Reference White Scaling
If you enter a reference white value (in this case 160 nits), then the linear RGB values will be proportionally scaled to bring that level up to 203 nits. This makes the effective MaxCLL values 571 nits and 2,791 nits, respectively.
Tone Mapping
The effective MaxCLL value (after reference white scaling) is how pq2hlg determines when to apply tone mapping. Simply put, if the effective MaxCLL value is 1,000 nits or less, the process is skipped altogether because it simply isn't needed. So this means that for the first LUT, no tone mapping is done at all, and for the second LUT, tone mapping is calculated based on a MaxCLL of 2,791 nits. So how does this end up working out?
Well, in the case of 2,791 nits, tone mapping doesn't really begin to set in until around the 700 nit mark. Meaning, pq2hlg won't be doing much brightness adjustment on anything dimmer than that. And from what I'm seeing here, the maximum brightness on anything visible is only 400 nits. So...there won't be any visible tone mapping applied.
tormento
12th March 2025, 09:24
That looks right to me.
:thanks:
wswartzendruber
12th March 2025, 15:53
:thanks:
You are most welcome.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.