Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
22nd December 2018, 10:33 | #1 | Link | ||
Guest
Posts: n/a
|
A tone mapping alternative?
I’ve decided to make a 1080p 8-bit color depth encode from this year 2018 Gladiator 2000 Extended 2160p HDR release.
Its main properties: Quote:
The screens on the first row are from the UHD HDR source: on the left - captured as 10-bit, on the right - as 8-bit. (the difference between them in PSNR is: PSNR r:49.949585 g:52.792138 b:48.647578 a:inf average:51.392461 min:51.392461 max:51.392461) The screens on the second row are: on the left - tone mapped encode, on the right - the original 2000 HD SDR release. From what is seen, the tone mapping drastically changes the colors. I've decided to work with an 8-bit color video obtained by simply truncating the two LSB of pixels' codes. (z_ConvertFormat(pixel_type="YV12",dither_type="none")) First of all, this operation doesn't change the working color space at all. Second, while a video is processed per BT.1886 and BT.709 or BT.2020 it is SDR. The question is: How close the truncated 8-bit color codes represent the 10-bit HDR source colors (we don't see them)? Well, I've used PSNR to evaluate this. In essence, I’ve converted three small clips (573 frames 227625-228198) to the XYZ color space. The three clips were from the HDR source, its truncated version, and the encode. All of them the size 1920x800 (cropped). I’ve used the conversion function ConvertYUVtoXYZ() part of the Plugin HDRTools for Avisynth. https://forum.doom9.org/showthread.php?t=175488 The function handles Color - (Set the color mode of the data.) 0: BT2100, 1: BT2020, 2: BT709 HDRMode - 0: PQ mode I’ve used its OutputMode - 1: The output will be RGB64. Its results piped to ffmpeg to put in rgba64le .rgb files. As a metric I used PSNR for: the truncated clip converted as HDR/PQ compared to the HDR/PQ source clip and the encode clip compared to HDR/PQ source clip. Results: Quote:
EDIT I've run one more test with the idea to confirm my saying "Second, while a video is processed per BT.1886 and BT.709 or BT.2020 it is SDR." I've generated an HEVC 10-bit almost lossless encode. (Almost because despite the options --qp 0 --lossless the result is Avg QP:4.00 ) I've converted it to XYZ color space two ways: One, per BT.1886/BT.2020 and second per BT.2100/ST 2084 - PQ. I'd had the HDR source clip converted the same two ways. The PSNR are: enc/BT.2100/PQ vs src/BT.2100/PQ PSNR r:92.338017 g:93.516001 b:91.773375 a:inf average:93.732726 min:88.603434 max:99.871103 enc/BT.2020 vs src/BT.2100/PQ PSNR r:19.122429 g:19.371534 b:21.351350 a:inf average:21.089880 min:16.807380 max:27.109646 enc/BT.2020 vs src/BT.2020 PSNR r:73.855851 g:74.760043 b:72.664415 a:inf average:74.924192 min:71.660317 max:78.200645 Last edited by SpasV; 22nd December 2018 at 16:55. |
||
22nd December 2018, 18:01 | #2 | Link | |||||
Registered User
Join Date: Sep 2007
Posts: 5,374
|
Quote:
--qp 0 by itself isn't necessarily lossless , it just disables quantization . But the --lossless switch means lossless and will give you an Avg QP of 4 https://x265.readthedocs.io/en/latest/lossless.html Quote:
Quote:
Quote:
Did you try DGHDRtoSDR or DGTonemap ? Quote:
Or how are you resolving 10bit vs. 8bit truncated ? It's not really valid for PSNR . Are you upconverting 8bit to compare, or downconverting 8bit to 10? Last edited by poisondeathray; 22nd December 2018 at 18:07. |
|||||
22nd December 2018, 18:26 | #3 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,903
|
Please note that you won't get the exact same result, as the HDR PQ version has been graded by a colorist in one way and the official SDR one has been graded by a colorist in a different way.
In other words, you won't be able to get a tone-mapping that matches the exact result of the original BT709 one. Anyway, I noticed that you tried to play with HDRTools and you made a few attempts; can you share your script? Have you tried DGHDRtoSDR? Give Reinhard a shot, 'cause it's the most natural tone-mapping algorithm I have used. You could also try using AvisynthOptimizer in order to try to get as close as possible to the SDR result, as I did here: Link Also take a look at the comparison I made between Hable, Mobius and Reinhard here: Link |
22nd December 2018, 19:53 | #4 | Link |
Guest
Posts: n/a
|
Thanks for answering.
First, I’ve tried the two AviSynth scripts - DGHDRtoSDR and DGTonemap. As to the comparisons, both the source and the (truncate/encode) have been processed the same two ways. Converting HEVC compressed clip in .hevc file to XYZ color space in .rgb file 1) One, to work with HDR (BT.2100) avs2yuv64 -frames 573 DGS2Convert(YUV2XUZ).hdr-PQ.avs - | ffmpeg -i - -f rawvideo -s 1920x800 -r 24000/1001 -pix_fmt rgba64le hdr-PQ.rgb DGS2Convert(YUV2XUZ).hdr-PQ.avs { DGSource("Gladiator.2160p.10-bit.cropped.dgi",resize_w=1920,resize_h=800,i420=true,fulldepth=true) ConvertYUVtoXYZ(Color=0,OutputMode=1,HDRMode=0) } 2) Two, to work with SDR (BT.2020) avs2yuv64 -frames 573 DGS2Convert(YUV2XUZ).hdr.avs - | ffmpeg -i - -f rawvideo -s 1920x800 -r 24000/1001 -pix_fmt rgba64le hdr.rgb DGS2Convert(YUV2XUZ).hdr.avs { DGSource("Gladiator.2160p.10-bit.cropped.dgi",resize_w=1920,resize_h=800,i420=true,fulldepth=true) ConvertYUVtoXYZ(Color=1,OutputMode=1) } ConvertYUVtoXYZ(int Color,int OutputMode,int HDRMode,float HLGLb, float HLGLw,int HLGColor, bool OOTF,bool EOTF,bool fullrange,bool mpeg2c, float Rx,float Ry,float Gx,float Gy,float Bx,float By,float Wx,float Wy, int threads,bool logicalCores,bool MaxPhysCore,bool SetAffinity,bool sleep,int prefetch) Color - 0: BT2100, 1: BT2020, 2: BT709 OutputMode - 1: The output will be RGB64. HDRMode - 0: PQ mode Truncated version has additional z_ConvertFormat() function Its version for HDR comparisons: DGS2Convert(YUV2XUZ).trn-PQ.avs { DGSource("Gladiator.2160p.10-bit.cropped.dgi",resize_w=1920,resize_h=800,i420=true,fulldepth=true) z_ConvertFormat(pixel_type="YV12",dither_type="none") ConvertYUVtoXYZ(Color=0,OutputMode=1,HDRMode=0) } then PSNR generation ffmpeg -f rawvideo -pix_fmt rgba64le -video_size 1920x800 -i enc-PQ.rgb -f rawvideo -pix_fmt rgba64le -video_size 1920x800 -i .hdr-PQ.rgb -lavfi psnr -frames:v 573 -f null - Last edited by SpasV; 22nd December 2018 at 20:29. |
22nd December 2018, 20:16 | #5 | Link | |
Guest
Posts: n/a
|
Quote:
But the PSNR shows the truncated version is much more close to the HDR colors than the tone mapped version. On another hand there is a question: Why back to the old release changing what the new release has achieved? Again, I think PSNR shows unchanged 10-bit source version processed per BT.2020 is much better than BT.709 version So, I think If something does matter it is to get the best from the HDR release. I don't think to repeat the old BT.709 colors is the best thing to do. Last edited by SpasV; 22nd December 2018 at 20:26. |
|
22nd December 2018, 20:43 | #6 | Link | |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,903
|
Quote:
Are trying to go from BT2100 HDR PQ 10bit to BT2020 SDR 10bit and re-encoding in HEVC? If that's correct, can you upload on WeTransfer a small sample we can play with? (Even just a few seconds between a scene-change). |
|
22nd December 2018, 21:25 | #7 | Link | |
Guest
Posts: n/a
|
Quote:
I couldn't get colors especially the human skin color and decided not to leave BT.2020 color space. Later, I've read HDR SMPTE Presentation March 21, 2017 https://www.smpte.org/sites/default/...compressed.pdf On page 49 the authors talking about Conversions say: "Any modifications we make to a colour are going to change at least one of Hue, Sat or Lum. We've worked so hard to get our HDR (luminance) values correct, do we really want to change this in a colour space mapping?" which impressed me much. Here is a link https://drive.google.com/file/d/12My...ew?usp=sharing you can download from. The clip I used for the tests is a part from this which is 1:24 min. Edit. Having seen this question "Are trying to go from BT2100 HDR PQ 10bit to BT2020 SDR 10bit and re-encoding in HEVC?" again I've decided to add something more. I think if an encode is to be made from an HDR source it would be better not to change the source BT.2020 color space. Whether the encode be 8-bit or 10-bit the player should process it per BT.1886 i.e. it should be SDR. Last edited by SpasV; 22nd December 2018 at 23:07. |
|
23rd December 2018, 04:00 | #8 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,903
|
I played with it a bit and the results are not bad, actually.
I tried to get the SDR version as close as possible to the HDR one. This is the official HDR PQ 10bit: Link This is the tone-mapped SDR BT2020 10bit: Link Code:
#Indexing FFVideoSource("Gladiator-split (226315,228337).mkv") #From 10bit to 16bit ConvertBits(16) #Reverse upscale to FULL HD with 16bit precision DeBilinearResizeMT(1920, 1080) #From YUV to XYZ with 16bit precision ConvertYUVtoXYZ(Color=0, OutputMode=1, HDRMode=0, fullrange=false) #Tone-mapping with 16bit precision ConvertXYZ_Reinhard_HDRtoSDR(exposure_X=14.0, contrast_X=0.5, exposure_Y=14.0, contrast_Y=0.5, exposure_Z=14.0, contrast_Z=0.5) #From XYZ back to YUV 4:4:4 with 16bit precision ConvertXYZtoYUV(pColor=2) #Converting back to 4:2:0 with 16bit precision Converttoyuv420(interlaced=false, matrix="Rec.2020") #Dithering to 10bit with the Floyd-Steinberg error diffusion ConvertBits(bits=10, dither=1) #Clipping Limiter(min_luma=64, max_luma=940, min_chroma=64, max_chroma=940) Code:
#Indexing FFVideoSource("Gladiator-split (226315,228337).mkv") #From 10bit to 16bit ConvertBits(16) #Reverse upscale to FULL HD with 16bit precision DeBilinearResizeMT(1920, 1080) #From YUV to XYZ with 16bit precision ConvertYUVtoXYZ(Color=0, OutputMode=1, HDRMode=0, fullrange=false) #Tone-mapping with 16bit precision ConvertXYZ_Reinhard_HDRtoSDR(exposure_X=14.0, contrast_X=0.5, exposure_Y=14.0, contrast_Y=0.5, exposure_Z=14.0, contrast_Z=0.5) #From XYZ back to YUV 4:4:4 with 16bit precision ConvertXYZtoYUV(pColor=0) #Converting back to 4:2:0 with 16bit precision Converttoyuv420(interlaced=false, matrix="Rec.709") #Dithering to 8bit with the Floyd-Steinberg error diffusion ConvertBits(bits=8, dither=1) #Clipping Limiter(min_luma=16, max_luma=235, min_chroma=16, max_chroma=240) The reason why I used a reverse upscaler as DeBilinear instead of Lanczos or Spline downscalers is that I'm not 100% sure they scanned it from scratch at 2160p, but even if they did, it doesn't seem to benefit much from such an high resolution 'cause it looks blurry without any other added detail other than grain. Anyway, as to the tone-mapping, I used Reinhard as I think that Hable produces colours that are too saturated and Mobius slightly loses details on the highlights. Reinhard instead offers a very nice-looking tone-mapping with colours that are not too saturated and contrast not exasperated at all. Anyway, as you can see, the chroma is slightly different as result of the tone-mapping, but most importantly, a few details in the background are lost; this is because SDR can't (and never will) look as HDR and you have to choose what you wanna preserve. Let me explain this. In the HDR version, we have a maximum of 1000 nits and a minimum 0.0050 nits. In the SDR version, we are gonna have 100 nits. The scene I used for the comparison is not very bright, but it does have the light coming from the left, very visible in the foreground. Then, we have the background which is not hit by the same light and it's way darker than the foreground. People use to think about HDR as "very bright", but it's also very useful to preserve blacks. Thanks to the BT2100 HDR PQ curve, it's possible to have details in the background and preserve the light in the foreground, however, when you tone-map and you go to SDR, you don't have such precision and you have to decide what you wanna preserve: if you preserve the light in the foreground, the background is gonna be dark and it will lose detail, however, if you preserve the background, the foreground is gonna be too bright and it will lose details. The compromise I went for was to preserve the foreground light (more or less) and lose details in the background. Note: images are saved correctly as .png lossless, but there's a chance that imgur will screw them up. Apply the script I posted yourself on your computer to see the results. Last edited by FranceBB; 23rd December 2018 at 04:07. |
23rd December 2018, 08:22 | #9 | Link |
Guest
Posts: n/a
|
Thank you for showing your work.
I wish I had such a knowledge and experience. I think I wasn’t clear enough with my initial post, the comparisons shown as Results are not quite correct, so I’ll try to express myself another way. Let’s talk about the 8-bit truncated version of the HDR source. First, there are four screenshots shown. These two seem similar and are seen when the HDR source and its truncated version are displayed on the PC Monitor (8-bit sRGB probably). These two seem similar also and are seen when the tone mapped encode and the original Gladiator 2000 SDR are displayed on the same PC Monitor. The two on the second row are displayed as they were meant to. So, they are real. What about the two on the first row? Are they real or changed? Well, the HDR source is not real. Its real image is 10-bit and its pixel codes are encoded per ST 2084/PQ. The PC monitor cannot correctly display it. The problem is its truncated version. What I know about it is, its pixel codes were changed by dividing by four and it is BT.2020 color space - no changes were applied. Is it a better alternative to the tone mapped encode? By truncating the HDR source pixel codes their value range has been changed from (white-black) 940 – 64 to 235-16 which is in the SDR range. { decimal - binary - decimal conversions 940 -> 0000001110101100; 00000011101011 → 235 64 → 1000000; 10000 → 16 } No pixel would be displayed having a luminance greater than 100 Nits. How do the pixel encoded values represent the source colors if they are displayed on an BT.1886 capable monitor.? Here is how i think it is measured by PSNR For the tone mapped encode Conversion avs2yuv64 -seek 227625 -frames 573 C:\Users\Spas\Desktop\AVS\DGS2Convert(YUV2XUZ).264.avs - | ffmpeg -i - -f rawvideo -s 1920x800 -r 24000/1001 -pix_fmt rgba64le 227625-228198.264.16-bit.rgb DGS2Convert(YUV2XUZ).264.avs { DGSource("F:\Gladiator-1080p\Gladiator.264.dgi",i420=true) ConvertYUVtoXYZ(Color=2,OutputMode=1) } Metric ffmpeg -f rawvideo -pix_fmt rgba64le -video_size 1920x800 -i 227625-228198.264.16-bit.rgb -f rawvideo -pix_fmt rgba64le -video_size 1920x800 -i 227625-228198.hdr-PQ.16-bit.rgb -lavfi psnr -frames:v 573 -y -f null - PSNR r:16.379366 g:16.680370 b:19.262877 a:inf average:18.512116 min:13.949773 max:26.850662 For the truncate version Conversion avs2yuv64 -seek 227625 -frames 573 C:\Users\Spas\Desktop\AVS\DGS2Convert(YUV2XUZ).227625-228198.trn.avs - | ffmpeg -i - -f rawvideo -s 1920x800 -r 24000/1001 -pix_fmt rgba64le 227625-228198.trn.16-bit.rgb DGS2Convert(YUV2XUZ).227625-228198.trn.avs { DGSource("F:\gladiator.work\227625-228198\Gladiator.2160p.227625-228198.10-bit.cropped.dgi",resize_w=1920,resize_h=800,i420=true,fulldepth=true) z_ConvertFormat(pixel_type="YV12",dither_type="none") ConvertYUVtoXYZ(Color=1,OutputMode=1) } Metric ffmpeg -f rawvideo -pix_fmt rgba64le -video_size 1920x800 -i 227625-228198.trn.16-bit.rgb -f rawvideo -pix_fmt rgba64le -video_size 1920x800 -i 227625-228198.hdr-PQ.16-bit.rgb -lavfi psnr -frames:v 573 -y -f null - 227625-228198.trn.16-bit.rgb vs 227625-228198.hdr-PQ.16-bit.rgb PSNR r:19.121085 g:19.371231 b:21.350033 a:inf average:21.088929 min:16.804140 max:27.108897 Comparison trn vs HDR source PSNR r:19.121085 g:19.371231 b:21.350033 a:inf average:21.088929 min:16.804140 max:27.108897 enc vs HDR source PSNR r:16.379366 g:16.680370 b:19.262877 a:inf average:18.512116 min:13.949773 max:26.850662 Last edited by SpasV; 23rd December 2018 at 15:10. |
23rd December 2018, 19:59 | #10 | Link | ||
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,903
|
Quote:
Quote:
Last edited by FranceBB; 23rd December 2018 at 22:39. |
||
23rd December 2018, 20:55 | #11 | Link | |
Registered User
Join Date: Sep 2007
Posts: 5,374
|
Quote:
I think you're mixing up bpp vs. bpc concepts In that windows dialog, "32bit true color" for a monitor/display indicates 32bpp (bits per pixel) but only 8bit per channel (bpc), with an alpha R,G,B,A. ie. It's "only" ~16.7M colors, whereas 10bpc would be 2^10 * 2^10 * 2^10 ~ >1B colors In monitor "language" , "true color" is really 8bpc; the term "deep color" to indicate 10,12,16 bit per channel https://www.pcmag.com/encyclopedia/t...83/color-depth Most consumer panels are 6,8 bit , but 10bit is increasingly more common , but in the past was only used in the high end. You can't "see" 10bpc properly on a 8bpc display . When you take a PNG screenshot at 8bit, that's obviously not 10bit either... In order to "see" 10bit properly on a computer display, the GPU has to be capable as well, and the connection has to support 10bit+ (display port or HDMI 1.3+ ) |
|
23rd December 2018, 21:01 | #12 | Link | |
Angel of Night
Join Date: Nov 2004
Location: Tangled in the silks
Posts: 9,559
|
Quote:
|
|
23rd December 2018, 23:46 | #13 | Link | ||||||
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,903
|
Quote:
Quote:
Quote:
Quote:
Anyway, that's the reason why i knew about dithering. But again, SpasV is asking: Quote:
The first two are the original HDR PQ BT2100 truncated to 8bit and displayed on an 8bit monitor and they are gonna look wrong, no matter what. Quote:
To avoid a re-encode, there are players that can actually apply dithering and tone-mapping "on the fly" like MPC-HC using MadVR, but I don't see any other way to display such a content on an SDR 8bit display. Last edited by FranceBB; 24th December 2018 at 03:53. |
||||||
24th December 2018, 08:47 | #14 | Link | ||
Guest
Posts: n/a
|
OK. Thanks
My Idea was to justify using PSNR for a color closeness metric as long as we cannot use the PC monitors for it. Let me remind the idea. Convert clip’s video frames into RGB64 frame and put them in an .rgb video clip avs2yuv64 source-convert.avs - | ffmpeg -i - -f … -pix_fmt rgba64le converted.rgb Generate PSNR evaluated.rgb source-PQ.rgb Quote:
Having used this procedure for the truncated version with parameters for its source Color=0 (BT.2100), HDRMode=0 (PQ mode) I’ve got avs2yuv64 -frames 573 DGS2Convert(YUV2XUZ).227625-228198.trn-PQ.avs - | ffmpeg -i - -f rawvideo -s 1920x800 -r 24000/1001 -pix_fmt rgba64le 227625-228198.trn-PQ.16-bit.rgb DGS2Convert(YUV2XUZ).227625-228198.trn-PQ.avs { DGSource("Gladiator.2160p.227625-228198.10-bit.cropped.dgi",resize_w=1920,resize_h=800,i420=true,fulldepth=true) z_ConvertFormat(pixel_type="YV12",dither_type="none") ConvertYUVtoXYZ(Color=0,OutputMode=1,HDRMode=0) } ffmpeg -f rawvideo -pix_fmt rgba64le -video_size 1920x800 -i 227625-228198.trn-PQ.16-bit.rgb -f rawvideo -pix_fmt rgba64le -video_size 1920x800 -i 227625-228198.hdr-PQ.16-bit.rgb -lavfi psnr -frames:v 573 -y -f null - PSNR r:81.627111 g:82.903858 b:81.400816 a:inf average:83.178027 min:77.251916 max:92.759690 This is the result I'm interesting in. Even the min PSNR value 77.2519 dB is very high closeness. Have you seen compared pictures having average: PSNR of 83.178 dB ever? I have to see the source and its truncated version on an HDR TV monitor. EDIT (Not fully understanding conversion function I run some tests) This time the script is: Quote:
Last edited by SpasV; 25th December 2018 at 20:09. |
||
26th December 2018, 16:04 | #15 | Link | |
Guest
Posts: n/a
|
I’ve run one more test, hope final.
The comparison clips are generated by these scripts: Quote:
EDIT: I’m going to simplify these formulae. Assuming, for simplicity, the pixels' code values differences equal over all frames it is possible to calculate some estimation for the average pixels' code value difference I've denoted delta - the small triangle. Conversion for MSE are shown on the left hand site. Expression for delta through PSNR and R - on the right. R turned out to be 65535 and delta = 5.2 Last edited by SpasV; 27th December 2018 at 17:38. |
|
31st December 2018, 14:41 | #16 | Link | |
Guest
Posts: n/a
|
Color Distance
The FFMPEG PSNR filter generates statistics containing frames' MSE - Mean squared error, "that is, the average squared difference between the estimated values and what is estimated".
I'll use the expression SQRT(Rmse + Gmse + Bmse) to evaluate the pixels colors' differences. The graph on the left is for the lossless encode which turned out not to be "lossless". The graph on the center is for truncated version and the last - on the right - for the tone mapped version. Quote:
EDIT: I thought to show another color distance comparison from an 3D Avatar encode for which I've got PSNR = 100 dB for a screenshoot (frame #27,349). (https://forum.doom9.org/showthread.php?t=169651&page=49) However, the clips' color comparison (frame 26984 to 27574) generated PSNR r:inf g:inf b:inf, so nothing to show but Color distance equal to zero. Last edited by SpasV; 2nd January 2019 at 13:05. |
|
31st December 2018, 17:06 | #17 | Link | |
Registered User
Join Date: Sep 2007
Posts: 5,374
|
Quote:
If lossless isn't "lossless", there is probably error in your method or procedures If you measure 10bit 4:2:0 source vs. say 10bit 4:2:0 lossless encode with x264/x265/ffv1 etc... at 10bit 4:2:0 it will be lossless. Maybe one of your procedures, such as conversion to XYZ, 16bit or whatever you're doing that introduced the differences. Maybe frames are not aligned etc... So you might want to review your procedures and assumptions about what your tests are actually showing Code:
[Parsed_psnr_2 @ 000000449dafcc80] PSNR y:inf u:inf v:inf average:inf min:inf max:inf |
|
31st December 2018, 19:27 | #18 | Link | |
Guest
Posts: n/a
|
Quote:
Nevertheless, this isn't a strict research, so I'm not going to do anything about it. I've used a lossless encode with the idea to see a perfect color match. This one is almost perfect. Besides, I've seen worse from x265 although I've used it only three times, maybe. As to me, a lossless compression mode is inconsistent with QP > 0. "HEVC main profile bypasses transform, quantization, and in-loop filters." |
|
3rd January 2019, 02:38 | #19 | Link | |
Angel of Night
Join Date: Nov 2004
Location: Tangled in the silks
Posts: 9,559
|
Quote:
Especially if you think your intuition overrides the ratified HEVC specs. |
|
Thread Tools | Search this Thread |
Display Modes | |
|
|