View Full Version : I Have Published a HDR10 to HLG Converter
Pages :
1
2
[
3]
4
5
6
7
8
9
10
FranceBB
17th January 2022, 19:15
Well, left you have 4000 nits, right you have 1000 nits:
https://i.imgur.com/8rvqGyi.png
The script is:
video=FFVideoSource("\\mibctvan000.avid.mi.bc.sky.it\Ingest\MEDIA\temp\GraySteps All.mkv")
audio=BlankClip(length=719, fps=24000, fps_denominator=1001, audio_rate=48000, channels=1)
AudioDub(video, audio)
propClearAll()
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:full", resample_filter_uv="spline64", dither_type="error_diffusion")
bbc4000=Cube("C:\Program Files (x86)\AviSynth+\LUTs\2a_PQ4000_HLG_mode-nar_in-nar_out-nar_nocomp.cube", fullrange=true)
bbc1000=Cube("C:\Program Files (x86)\AviSynth+\LUTs\1a_PQ1000_HLG_mode-nar_in-nar_out-nar_nocomp.cube", fullrange=true)
StackHorizontal(bbc4000, bbc1000)
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:std-b67:2020:full=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
and indeed you can see more steps in the 4000 nits one, just take a look at the whites.
wswartzendruber
17th January 2022, 19:19
I'll mess with all this once I get off work.
ErazorTT
17th January 2022, 19:29
and indeed you can see more steps in the 4000 nits one, just take a look at the whites.
Yes there are more steps in the 4000nits. But actually its too many steps. The BBC lut looks to be wrong, as I wrote in my previous post:
Hm that is weird. The BBC lut produces two steps at almost exactly the same non-white brightness (red arrows in the grayBBC.png picture). These steps are apart 5% of the signal, which for PQ is really a lot in absolute terms. So that must be wrong!
Addionally, I took out my colorspace calculation sheet and found that a 4000nits white is at a 8bit value of 198 for a limited range signal. So actually in the picture the step with an orange arrow should already have been completly white, since that is at a value of 202.
Also look at the files I posted there.
ErazorTT
17th January 2022, 19:32
I'll mess with all this once I get off work.
Currently I don't think you should do any changes to your code. Your result appears to be on point for me. (In contrast to the BBC lut, which appears to be somehow messed up)
At least for a luma-scale of 1.0. For Factors above I'm not so sure, I still think there is something fishy.
wswartzendruber
17th January 2022, 20:27
At least for a luma-scale of 1.0. For Factors above I'm not so sure, I still think there is something fishy.
From a theoretical standpoint, the PQ to HLG conversion process fundamentally has one parameter: Lw. This controls the reference peak luminance.
Now, I could have pq2hlg alter this value according to MaxCLL after any --lum-scale adjustment, but as BT.2408-4 page 23 explains, "the signal level for diffuse white will vary." I made a decision early on that Lw would always be fixed to 1,000 nits, which is what BT.2408 calls for.
Ergo, the pq2hlg process consists of three fundamental steps:
1. Scale luminosity to get reference white where it should be (if specified).
2. Tone map everything from the working maximum down to 1,000 nits.
3. Perform the PQ-to-HLG conversion process.
FranceBB
17th January 2022, 22:59
Tomorrow I'll repeat the test with the Warner Bros approved one and I'll compare it to the BBC one and we're gonna see the differences. Ironically, Warner didn't approve the BBC one, which probably means that there must be something odd indeed.
ErazorTT
18th January 2022, 00:20
@wswartzendruber: I rechecked what I was doing in 16bits, and as it appears everything is fine just as you said. It's doing exactly the right thing for lum-scale!
Doing things in 10bits made it appear that the "point of max whiteness" was moving to the dark side on a greyscale ramp when lum-scale was increased. But that was only due to rounding errors on 10 bits. Interesting, I would have thought that 10bits would be enough precision for anything I'm doing.
@FranceBB: yes, that would be interesting as well
wswartzendruber
18th January 2022, 04:12
Looks like I'm at odds with the BBC on what a 4,000 nit LUT should do:
http://wswartzendruber.net/images/bbc-vs-pq2hlg-4000-nits.png
Telling pq2hlg that the MaxCLL is 10,000 nits produces a much closer result to the BBC's LUT:
http://wswartzendruber.net/images/bbc-vs-pq2hlg-10000-nits.png
FranceBB
18th January 2022, 09:31
Ok, looks like the BBC 4000 nits LUT is doing something particular indeed, but if anything the WB approved one is even... more peculiar, let's put it this way.
This is the Warner 4000 nits LUT:
video=FFVideoSource("\\mibctvan000.avid.mi.bc.sky.it\Ingest\MEDIA\temp\GraySteps All.mkv")
audio=BlankClip(length=719, fps=24000, fps_denominator=1001, audio_rate=48000, channels=1)
AudioDub(video, audio)
propClearAll()
#From 4:2:2 16bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#From PQ to HLG with 16bit precision
Cube("C:\Program Files (x86)\AviSynth+\LUTs\WarnerBros_PQToHLG_MaxCLL_4000.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV422 10bit planar Narrow Range with dithering
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:std-b67:2020:limited=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
Warner 4000 nits left, BBC 4000 nits right:
https://i.imgur.com/fSAFvoo.png
Color Saturation Steps Warner Bros approved LUT 4000 nits encode: https://we.tl/t-JezXgoCRzm
Grey Steps All Warner Bros approved LUT 4000 nits encode: https://we.tl/t-QZ5iX3gvOI
@wswartzendruber... can you check if this one checks out with your output?
ErazorTT
18th January 2022, 13:47
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#From PQ to HLG with 16bit precision
Cube("C:\Program Files (x86)\AviSynth+\LUTs\WarnerBros_PQToHLG_MaxCLL_4000.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV422 10bit planar Narrow Range with dithering
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:std-b67:2020:limited=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
Why the heck are you converting to limied range rgb and then have the lut run on full range?
FranceBB
18th January 2022, 14:19
Why the heck are you converting to limied range rgb and then have the lut run on full range?
the full range thick there doesn't matter, that particular LUT is Narrow Range in - Narrow Range Out, so basically Limited TV Range in, Limited TV Range Out.
If you set it to false, it's not gonna work correctly, 'cause every time you convert to RGB with something like Convertto etc it will expand levels to Full Range and at that point it's too late.
FranceBB
18th January 2022, 14:34
This is a 1000 nits movie.
FFVideoSource("\\Mibcpmcs011.avid.mi.bc.sky.it\raid0\MASTERFILES\Godzilla vs Kong H.265 UHD HDR PQ BT2020 YUV422 23,976p 10bit.ts")
propClearAll()
#From 4:2:2 16bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#From PQ to HLG with 16bit precision
Cube("C:\Program Files (x86)\AviSynth+\LUTs\WarnerBros_PQToHLG_MaxCLL_1000.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV422 10bit planar Narrow Range with dithering
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:std-b67:2020:limited=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
https://i.imgur.com/IVBa70o.png
As you can see black sits perfectly at 4096 ('cause we're working in 16bits) and everything is nice and dandy.
Same goes for frame 1382:
https://i.imgur.com/Ji8LtRU.png
Now, here's what happens with this other script:
FFVideoSource("\\Mibcpmcs011.avid.mi.bc.sky.it\raid0\MASTERFILES\Godzilla vs Kong H.265 UHD HDR PQ BT2020 YUV422 23,976p 10bit.ts")
propClearAll()
ConvertBits(16)
ConvertToPlanarRGB()
Cube("C:\Program Files (x86)\AviSynth+\LUTs\WarnerBros_PQToHLG_MaxCLL_1000.cube", fullrange=false)
ConverttoYUV422()
The result is CLEARLY wrong:
https://i.imgur.com/PGzhLpZ.png
and indeed you can see the black sitting far too high:
https://i.imgur.com/q30pDR2.png
and this is ALSO WRONG:
FFVideoSource("\\Mibcpmcs011.avid.mi.bc.sky.it\raid0\MASTERFILES\Godzilla vs Kong H.265 UHD HDR PQ BT2020 YUV422 23,976p 10bit.ts")
propClearAll()
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
Cube("C:\Program Files (x86)\AviSynth+\LUTs\WarnerBros_PQToHLG_MaxCLL_1000.cube", fullrange=false)
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:std-b67:2020:limited=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
https://i.imgur.com/iLuN5yy.png
as you can clearly see that the black is far too high.
So, in a nutshell, to recap the officially used LUTs:
-> The BBC one works in Full PC Range RGB
-> The WB approved one works in Studio RGB (i.e Limited TV Range)
therefore, for the Warner Bros approved one, you need to first bring everything to Studio RGB 16bit planar and THEN apply the LUT, then go back to Limited TV Range YUV without touching the levels. This is pretty common in the industry and honestly the only reason why the BBC one works in full range is that they made two version of the same LUT one that works in Full Range RGB and the other that works in Limited TV Range RGB.
I've been encoding plenty of movies this way and never had any problems as they all passed QC before going on air, so no worries, I know what I'm doing ehehehehehe
Besides, this is the main reason why I've been using avsresize in all my workflows here at work.
ErazorTT
18th January 2022, 15:56
that particular LUT is Narrow Range in - Narrow Range Out
ok that's the answer. So in contrast to the lut generator these are for the narrow range. I wasn't aware of that.
SeeMoreDigital
18th January 2022, 16:38
Color Saturation Steps Warner Bros approved LUT 4000 nits encode: https://we.tl/t-JezXgoCRzm
Grey Steps All Warner Bros approved LUT 4000 nits encode: https://we.tl/t-QZ5iX3gvOI
Newbie question...
Is there any particular reason why these samples have been encoded in 10-bit AVC instead of 10-bit HEVC?
There's very little hardware SoC playback support for 10-bit AVC.
Cheers
wswartzendruber
18th January 2022, 17:17
Is anyone using SoC devices to compare these clips?
SeeMoreDigital
18th January 2022, 17:47
Is anyone using SoC devices to compare these clips?
The media players on loads of 'smart' televisions support HLG HDR encoded using HEVC in either .mkv, .mp4 or .m2ts...
ErazorTT
18th January 2022, 19:17
I wasn't even aware that these were AVC's that FranceBB was sharing. I would think that for actual encoding HEVC would be his prefered format as well, but here we're just sharing test clips for quick assessment.
Me at least, I'm encoding anyhting 8bits in AVC and anything 10bits in HEVC.
FranceBB
18th January 2022, 19:19
Newbie question...
Is there any particular reason why these samples have been encoded in 10-bit AVC instead of 10-bit HEVC?
There's very little hardware SoC playback support for 10-bit AVC.
Every file I encode is not intended for consumers SoC but for professional SoC.
What professional SoC like Versio want is an XAVC Intra Class 300 with PCM audio muxed in MXF.
In a nutshell, it's a file in which all frames are intra and their weight is exactly the same, it's level 5.2, 4:2:2, 10bit H.264.
http://www.avsol.net/images/stories/virtuemart/product/Versio.png
Just FYI if you're a consumer, those kind of files are the ones which are re-encoded live in H.265 4:2:0 25Mbit/s 10bit with AC3 audio, muxed in .TS ;)
SeeMoreDigital
18th January 2022, 19:31
Every file I encode is not intended for consumers SoC but for professional SoC.
What professional SoC like Versio want is an XAVC Intra Class 300 with PCM audio muxed in MXF.
I don't think the 'professional' end of the market was the spec wswartzendruber was originally aiming for...
wswartzendruber
18th January 2022, 19:48
I don't think the 'professional' end of the market was the spec wswartzendruber was originally aiming for...
They're just expendable test clips that show us output signal level for a given signal input and LUT transform. They're not at all intended for end user viewing.
My personal HLG library is encoded as 10-bit HEVC.
What these test clips are encoded as is irrelevent so long as they convey the information correctly and thread participants can see them. These aren't meant for viewing, but for study with dedicated equipment.
FranceBB
18th January 2022, 19:50
I don't think the 'professional' end of the market was the spec wswartzendruber was originally aiming for...
Sure, but those are just samples, it doesn't really matter how I deliver them. Why would I change a BAT that I know works for something that I have to create from scratch?
I'm at work, I don't have any consumer BAT files, I encoded what was more convenient for me eheheheh
What these test clips are encoded as is irrelevent so long as they convey the information correctly and thread participants can see them. These aren't meant for viewing, but for study with dedicated equipment.
Exactly. :)
SeeMoreDigital
18th January 2022, 19:57
Thanks guys,
Needless to say, I'd be most interested in seeing some of 'before' (HEVC HDR10) and 'after' (HEVC HDR10 HLG) HEVC encoded samples, to see how well my TV and OPPO handles them ;)
FranceBB
18th January 2022, 20:07
Thanks guys,
Needless to say, I'd be most interested in seeing some of 'before' (HEVC HDR10) and 'after' (HEVC HDR10 HLG) HEVC encoded samples, to see how well my TV and OPPO handles them ;)
Fine.
I'm a consumer myself, by the way, regardless of my job I watch TV series too, so my library is made of consumer BD eheheheh
I can share a sample, I should have something somewhere, but it's gonna be short. Perhaps Gemini Man could be a good fit. I'll do that tomorrow, though, right now I'm at dinner and later I'm gonna watch Brighton Vs Chelsea ;)
wswartzendruber
18th January 2022, 20:23
Thanks guys,
Needless to say, I'd be most interested in seeing some of 'before' (HEVC HDR10) and 'after' (HEVC HDR10 HLG) HEVC encoded samples, to see how well my TV and OPPO handles them ;)
Here are some HDR10 demos that I've converted to HLG:
http://wswartzendruber.net/videos/
EDIT: What is "HDR10 HLG?"
FranceBB
18th January 2022, 20:47
EDIT: What is "HDR10 HLG?"
Nothing, he probably means H.265 10bit HLG eheheheh
frank
19th January 2022, 20:18
The LG TV displays the HLG HDR logo for 5 seconds at the top right when you play an HLG video.
ErazorTT
20th January 2022, 16:48
There is something that I still cannot wrap my head around. The PQ standard is very obvious and strict in that it's actualy a standard of absolute luminosity. Why do the movies then need such a wide range of lum-scale to equalize them?
wswartzendruber
20th January 2022, 21:48
There is something that I still cannot wrap my head around. The PQ standard is very obvious and strict in that it's actualy a standard of absolute luminosity. Why do the movies then need such a wide range of lum-scale to equalize them?
SMPTE says reference white goes at 100 nits. The ITU says that value should be 203 nits.
Alita: Battle Angel puts it around 47 nits (the darkest I've encountered). Shazam's is something stupid like 500+ (the brightest I've encountered).
I have no idea why studios are all over the place with it.
EDIT: I've noticed something somewhat common. Once you adjust the luminosity, the internal MaxCLL value ends up being very close to 1,000 nits. Sometimes I wonder if these movies aren't graded to 1,000 nits with reference white at 203 nits, and then scaled down so that TVs that can't reach 1,000 nits can still display more of the originally intended changes in brightness.
EDIT: And I was wrong about Shazam. It's reference white level is only 369 nits or thereabouts.
ErazorTT
21st January 2022, 10:05
EDIT: I've noticed something somewhat common. Once you adjust the luminosity, the internal MaxCLL value ends up being very close to 1,000 nits. Sometimes I wonder if these movies aren't graded to 1,000 nits with reference white at 203 nits, and then scaled down so that TVs that can't reach 1,000 nits can still display more of the originally intended changes in brightness.
How do I get a hold on the internal MaxCLL?
wswartzendruber
21st January 2022, 17:11
(internal MaxCLL) = --max-cll * --lum-scale
or
(internal MaxCLL) = --max-cll * (203 / --ref-white)
It's not something you really need to take into consideration, however. pq2hlg determines this value for you. If it exceeds 1,000 nits, then pq2hlg will generate a tone map curve specific to the internal MaxCLL value.
FranceBB
21st January 2022, 19:19
Little update: I'll delay the encode and share of a real life sample a bit 'cause FFMpeg 5.0 introduced IMF decoding and it's something I've been waiting since April 2016 (when no one really knew anything about it and there was no way to work with it) (https://forum.doom9.org/showthread.php?t=173372) so I'm as happy as Larry :D
frank
22nd January 2022, 11:38
Alita has 5 different cll metadata:
LIGHT 285 63
LIGHT 737 130
LIGHT 1000 18
LIGHT 257 1
LIGHT 505 13
The core movie at 737 130.
Includes HDR10, DoVi, and HDR10+
That is the culprit. Someone played with parameters without changing the content.
The mastering display has 1000 nit / 0.0001 nit.
So stay on the standard with the PQ_to_HLG matrix (1000nit), and you will get a perfect HLG conversion.
Testet on LG OLED48CX.
frank
22nd January 2022, 12:24
Content light metadata are only used if the display has not the desired luminosity. HDR10 strictly follows smpte2084. The TV scales itself brightness and contrast.
HLG arib-std-b67 is based on max 1000nit. The TV knows that and scales brightness automatically without HDR metadata.
repeat-headers for HLG is not necessary.
wswartzendruber
22nd January 2022, 18:36
Alita has 5 different cll metadata:
LIGHT 285 63
LIGHT 737 130
LIGHT 1000 18
LIGHT 257 1
LIGHT 505 13
The core movie at 737 130.
Includes HDR10, DoVi, and HDR10+
That is the culprit. Someone played with parameters without changing the content.
The mastering display has 1000 nit / 0.0001 nit.
So stay on the standard with the PQ_to_HLG matrix (1000nit), and you will get a perfect HLG conversion.
Testet on LG OLED48CX.
That produces a result that is extremely dark when viewed on SDR.
frank
22nd January 2022, 22:23
Oh, I still have to test on SDR...
wswartzendruber
23rd January 2022, 01:24
Oh, I still have to test on SDR...
pq2hlg -m 737 -l 4.75 -s 65 pq2hlg-alita.cube
frank
24th January 2022, 19:42
Thanks.
I tested -m 1000 -r173
because of 130 x 4/3 = 173
Is better but I am not satified.
Let's go with your findings.
frank
24th January 2022, 19:57
Please change back the status lines like
# Generated by PQ2HLG 0.4.0
# ref-white: 203
# max-cll: 1000
...
in pq2hlg.
It is better for later doc of the cube.
wswartzendruber
25th January 2022, 04:20
Please change back the status lines like
# Generated by PQ2HLG 0.4.0
# ref-white: 203
# max-cll: 1000
...
in pq2hlg.
It is better for later doc of the cube.
Fresh out of the oven: PQ2HLG 0.4.1 (https://github.com/wswartzendruber/hlg-tools/releases/tag/release%2F0.4.1)
frank
27th January 2022, 22:02
Thank you! :)
On my Alita tests I saw a big issue. VLC and mpv have different display outputs. mpv goes much earlier into level saturation!
I only can go until -l 2.5...3.0 for HLG. Otherwise you will be dazzled by white.
Which prog does it right? Different specs? max cll 100 vs 203?
I'll make further tests with the built-in player of LG TV.
--------------
System: Win 10 Pro on Dell XPS 15 9510
wswartzendruber
27th January 2022, 22:07
Do not use MPV for critical monitoring. It adjusts gain as the video plays back.
wswartzendruber
31st January 2022, 17:59
@FranceBB: What's the latest here? Surely you can understand why I would want someone with access to professional equipment assessing my work against industry assets.
FranceBB
1st February 2022, 18:46
@FranceBB: What's the latest here? Surely you can understand why I would want someone with access to professional equipment assessing my work against industry assets.
I'm busy with IMF guys... :(
wswartzendruber
3rd February 2022, 17:13
Whos parliament do I have to contact to get you out of this? :)
FranceBB
3rd February 2022, 17:35
Whos parliament do I have to contact to get you out of this? :)
Send an email to my boss saying: Hey, Doom9/Avisynth/LUTs are part of Frank's job, he's not doing those for fun.
(The fact that I have fun with this is different eheheheh)
Jokes aside, I have an idea. I sent you a PM.
wswartzendruber
5th February 2022, 05:45
Send an email to my boss saying: Hey, Doom9/Avisynth/LUTs are part of Frank's job, he's not doing those for fun.
(The fact that I have fun with this is different eheheheh)
Jokes aside, I have an idea. I sent you a PM.
Lemme get this together. I've had other crap going on.
Balling
8th February 2022, 06:21
Well in the course of studying this HLG reference white issue, I've discovered that I'm not scaling linear display brightness correctly. So I'm adding a gamma correction step as called for in BT.2446 section 4.1.2.
SIDE NOTE: Last March, a bunch of stuff seemingly moved out of BT.2390 and into BT.2408, including PQ->HLQ transcoding and PQ tone mapping.
BT.2408 is only supported in --vo=gpu-next, not --vo=gpu
Untill like 10 days ago gpu-next was not even decoding YCbCr correctly (like gray was not even equal in all 3 channels after to R'G'B'), so be more careful with it. We are still testing it. See https://github.com/haasn/libplacebo/commit/953dcdb3806d1df47b6a560bd3b699d698241a68
wswartzendruber
8th February 2022, 17:27
BT.2408 is only supported in --vo=gpu-next, not --vo=gpu
Untill like 10 days ago gpu-next was not even decoding YCbCr correctly (like gray was not even equal in all 3 channels after to R'G'B'), so be more careful with it. We are still testing it. See https://github.com/haasn/libplacebo/commit/953dcdb3806d1df47b6a560bd3b699d698241a68
That original post turned out to not be true. I was scaling luminosity correctly.
Now what's this about BT.2408 not being supported. What part of BT.2408? It's gotten rather comprehensive.
Balling
11th February 2022, 13:20
That original post turned out to not be true. I was scaling luminosity correctly.
Now what's this about BT.2408 not being supported. What part of BT.2408? It's gotten rather comprehensive.
It is not supported in stable --vo gpu. Only in --vo gpu-next.
wswartzendruber
25th February 2022, 21:13
There are some comparisons I am going to soon be doing to compare pq2hlg against commercial variants. Before that, there is a rare case I would like to be able to handle. HLG limits the maximum level any color channel can reach by itself.
Red, by itself, maxes out at 201.1 nits instead of 262.7.
Green, by itself, maxes out at 627.3 nits instead of 678.0.
Blue, by itself, maxes out at 33.7 nits instead of 59.3.
Now I could just hard-clip a channel that violates this. But what I'm considering is elevating the other channels to reach the same luminance that the single color channel calls for. This will produce the same level of brightness, but slightly desaturate those pixels.
I'll listen to any remarks on this approach before proceeding to implement it.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.