View Full Version : HDRTools vs DitherTools vs ColorMatrix
hello_hello
14th August 2019, 21:37
Would any interested parties care to look at this comparison of color conversion methods? The ColorMatrix version used is this one (https://forum.doom9.org/showthread.php?t=175279).
Edit: For anyone reading this thread, HDRTools was getting the XYZ rec.2020 color conversions correct. Using that method it also converts the color primaries which produce a very different result. The banding problems I think I mentioned at some stage are due to an 8 bit video limitation. HDRTools doesn't cause banding if you use Avisynth+ and convert the video to 16 bit first. The rest of what I didn't understand when starting this thread is explained in post #19 (https://forum.doom9.org/showthread.php?p=1897492#post1897492) and #20, as is why I think ColorMatrix 2.6 shouldn't be used for rec.2020 conversions. Aside from the fact it outputs the same colors as the source when converting between rec.2020 and rec.601, rather than outputting an error message because it doesn't support conversions between rec.2020 and rec.601, I'm still pretty sure it's rec.2020 to rec.709 conversion is incorrect, and it doesn't convert the color primaries either (neither does DitherTools).
There's a bunch of screenshots to go with the tests below. I won't post them here as there's quite a few, but if you follow the link you'll find a gallery and the screenshots are properly named so as to easily see what they represent. Included is a screenshot of how much the images sizes vary after compression to PNG. The biggest changes are the DitherTools images which I suppose must be the result of dithering. The source is animation so there's large areas of single color to make the differences easy to see.
https://postimg.cc/gallery/1r9z2a760/
All testing was done using classic Avisynth on XP, although a quick look indicates nothing changes for Avisynth+.
The source video is HD, downscaled to SD, the various color conversions applied, and the screenshots taken by opening the script with MPC-HC. If I'm doing something wrong I'm happy to learn. Comments welcome!
Rec.709 To Rec.601
All conversion methods seem to agree.
HDRTools Linear looks better than HDRTools XYZ (no banding).
HDRTools XYZ
ConvertYUVtoXYZ(Color=2).ConvertXYZtoYUV(Color=3, pColor=2, OutputMode=2)
HDRTools Linear
ConvertYUVtoLinearRGB(Color=2).ConvertLinearRGBtoYUV(Color=3, OutputMode=2)
DitherTools
Dither_convert_yuv_to_rgb(matrix="709", slice=false).Dither_convert_rgb_to_yuv(matrix="601", output="YV12")
ColorMatrix
ColorMatrix(mode="Rec.709->Rec.601", clamp=0)
Rec.2020 To Rec.601
DitherTools and HDRTools Linear apparently agree.
ColorMatrix is different.
HDRTools XYZ seems borked or I don't know what I'm doing.
HDRTools XYZ
ConvertYUVtoXYZ(Color=1).ConvertXYZtoYUV(Color=3, pColor=1, OutputMode=2)
HDRTools Linear
ConvertYUVtoLinearRGB(Color=1).ConvertLinearRGBtoYUV(Color=3, OutputMode=2)
DitherTools
Dither_convert_yuv_to_rgb(matrix="2020", slice=false).Dither_convert_rgb_to_yuv(matrix="601", output="YV12")
ColorMatrix
ColorMatrix(mode="Rec.2020->Rec.601", clamp=0)
Rec.2020 To 709
I'd only be guessing as nobody agrees.
DitherTools and HDRTools Linear possibly only disagree for "red".
I think ColorMatrix is wrong.
HDRTools XYZ seems borked or I don't know what I'm doing.
HDRTools XYZ
HDRToolsConvertYUVtoXYZ(Color=1).ConvertXYZtoYUV(Color=2, pColor=1, OutputMode=2)
HDRTools Linear
ConvertYUVtoLinearRGB(Color=1).ConvertLinearRGBtoYUV(Color=2, OutputMode=2)
DitherTools
Dither_convert_yuv_to_rgb(matrix="2020", slice=false).Dither_convert_rgb_to_yuv(matrix="709", output="YV12")
ColorMatrix
ColorMatrix(mode="Rec.2020->Rec.709", clamp=0)
Anyone know what the difference between the HDRTools two flavours of Rec.601 might be (BT601_525 & BT601_625)?
When I do this, there's appears to be a difference, unless it's just the conversion and not a color difference,
A = last
B = ConvertYUVtoXYZ(Color=3).ConvertXYZtoYUV(Color=4, pColor=3, OutputMode=2)
C = ConvertYUVtoLinearRGB(Color=3).ConvertLinearRGBtoYUV(Color=4, OutputMode=2)
Compare(A, B)
or
Compare(A, C)
(these are labelled "HDRTools Compare A&B" and "HDRTools Compare A&C" in the gallery.
StvG
15th August 2019, 01:38
ConvertYUVtoXYZ(Color=1).ConvertXYZtoYUV(Color=2, pColor=1, OutputMode=2) is equivalent of z_ConvertFormat(colorspace_op="2020:709:2020=>2020:709:xyz").z_ConvertFormat(colorspace_op="2020:709:xyz=>709:709:709")
and ConvertYUVtoXYZ(Color=1).ConvertXYZtoYUV(Color=2, pColor=2, OutputMode=2) should be equivalent ? of z_ConvertFormat(colorspace_op="2020:709:709=>2020:709:xyz").z_ConvertFormat(colorspace_op="2020:709:xyz=>709:709:709") but it seems HDRTools assumes when matrix is 2020 (Color=1) then primaries of the input are 2020 (pColor=1) too.
z_ConvertFormat(colorspace_op="709=>601",resample_filter_uv="spline36",dither_type="error_diffusion") it's avsresize example of 709->601 conversion.
"Anyone know what the difference between the HDRTools two flavours of Rec.601 might be (BT601_525 & BT601_625)?" - https://en.wikipedia.org/wiki/Rec._601#Primary_chromaticities ; https://en.wikipedia.org/wiki/PAL#PAL_broadcast_systems ; https://en.wikipedia.org/wiki/NTSC#Variants Take a look at "lines".
hello_hello
15th August 2019, 10:51
StvG, Thanks for the reply.
I'm still not clear though as to whether HDRTools XYZ is getting it wrong, or if I'm doing something wrong, and why the other color conversion methods only have one flavour of rec.601 while HDRTools has two.
Your link seems to indicate the two versions of rec.601 are for converting analogue NTSC & PAL to digital. Once it's digital, isn't the colorimetry the same, and if so, would there only be one method required for converting digital rec.601 to another colorimetry etc?
Cheers.
PS. I did try avsresize but couldn't get it to work. I couldn't see any mention of it in the docs, but I assume it's not compatible with XP?
StvG
15th August 2019, 19:33
I guess HDRTools is wrong (bug?) because the output with both pColor=1/2 is the same.
Speaking of DVD content Rec.601 (BT470_BG/ST170_M) is the right setting. Speaking of broadcasting the setting could be different - https://forum.doom9.org/showthread.php?t=133982
The other conversion methods have "240" Dither (SMPTE 240M/BT601_525), "240m" avsresize...
I didn't try avsresize on XP.
hello_hello
15th August 2019, 21:16
StvG,
Would I be able to ask you to compare a rec.2020 to rec.709 conversion between HDRTools "linear", DitherTools and AVSResize, if it's not too inconvenient?
I'm assuming ColorMatrix is wrong but I'd be interested to find out if AVSResize agrees with DitherTools or HDRTools "linear" for rec.2020 to rec.709, as an indication which program is getting it right, given they're slightly different.
I haven't compared them properly, but I think the result is the same when upconverting the colors as it is for downconverting ie
rec.2020 to rec.601 vs rec.601 to rec.2020.
I think if the downconversion is correct for each program the equivalent upconversion is correct too, or if the downconversion is wrong the upconversion is also wrong, but I should check that properly at some stage.
Speaking of DVD content Rec.601 (BT470_BG/ST170_M) is the right setting. Speaking of broadcasting the setting could be different - https://forum.doom9.org/showthread.php?t=133982
That's why I'm still confused as to which HDRTools rec.601 I should be using when upscaling DVD video etc, assuming they're not the same.
Cheers.
StvG
16th August 2019, 00:03
I used your "No-Color-Conversion.png". I converted it to yv24 in the same way for all three methods so all comparison have the same upscaled chroma before the conversion. As a final step I converted yv24 to yv12 so all comparisons have the closest possible matching chroma downscaling.
HDRTools:ImageSource("No-Color-Conversion.png")
ConvertToPlanarRGB()
z_ConvertFormat(pixel_type="yv24", colorspace_op="rgb:709:709:f=>709:709:709:l", resample_filter_uv="spline36", dither_type="error_diffusion")
ConvertYUVtoLinearRGB(Color=1, OutputMode=1)
ConvertLinearRGBtoYUV()
z_ConvertFormat(pixel_type="yv12",resample_filter_uv="spline36",dither_type="error_diffusion")
subtitle("HDRTools")
Dither:ImageSource("No-Color-Conversion.png")
ConvertToPlanarRGB()
z_ConvertFormat(pixel_type="yv24", colorspace_op="rgb:709:709:f=>709:709:709:l", resample_filter_uv="spline36", dither_type="error_diffusion")
Dither_convert_yuv_to_rgb(matrix="2020")
Dither_convert_rgb_to_yuv(matrix="709", output="YV24",lsb=true)
DitherPost(mode=6)
z_ConvertFormat(pixel_type="yv12",resample_filter_uv="spline36",dither_type="error_diffusion")
subtitle("Dither")
avsresize:ImageSource("No-Color-Conversion.png")
ConvertToPlanarRGB()
z_ConvertFormat(pixel_type="yv24", colorspace_op="rgb:709:709:f=>709:709:709:l", resample_filter_uv="spline36", dither_type="error_diffusion")
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020=>rgb", dither_type="error_diffusion")
z_ConvertFormat(pixel_type="yv24", colorspace_op="rgb=>709",dither_type="error_diffusion")
z_ConvertFormat(pixel_type="yv12",resample_filter_uv="spline36",dither_type="error_diffusion")
subtitle("avsresize")
avsresize #1ImageSource("No-Color-Conversion.png")
ConvertToPlanarRGB()
z_ConvertFormat(pixel_type="yv24", colorspace_op="rgb:709:709:f=>709:709:709:l", resample_filter_uv="spline36", dither_type="error_diffusion")
z_ConvertFormat(pixel_type="yuv444p16",resample_filter_uv="spline36", colorspace_op="2020=>709",dither_type="error_diffusion")
z_ConvertFormat(pixel_type="yv12", resample_filter_uv="spline36", dither_type="error_diffusion")
avsresize linear:ImageSource("No-Color-Conversion.png")
ConvertToPlanarRGB()
z_ConvertFormat(pixel_type="yv24", colorspace_op="rgb:709:709:f=>709:709:709:l", resample_filter_uv="spline36", dither_type="error_diffusion")
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:709=>rgb:linear", dither_type="error_diffusion")
z_ConvertFormat(pixel_type="yv24", colorspace_op="rgb:linear=>709:709",dither_type="error_diffusion")
z_ConvertFormat(pixel_type="yv12",resample_filter_uv="spline36",dither_type="error_diffusion")
subtitle("avsresize linear")
gallery (http://imgbox.com/g/u8rsSHV00a)
709->601 is done in 16-bit for all methods but HDRTools and avsresize could use float too for that conversion.
That's why I'm still confused as to which HDRTools rec.601 I should be using when upscaling DVD video etc, assuming they're not the same.
Use BT601_625 for DVD content.
hello_hello
16th August 2019, 03:21
Thanks for doing that.
It was very disappointing to see your result was the same each time, or close enough for me to call them the same (I was hoping you'd get different results as I did).
Obviously I can't replicate your method (avsresize no worky XP) so I tried doing it again a more traditional way, although I've looked at the various screenshots so many times today all I'm seeing is pink elephants at the moment....
I'm not sure I'm taking the same frame from the source as yesterday, and there's several frames in a row without movement and I didn't make a note of the frame number, but here's two screenshots I took today. Today the result is closer to yours, but the difference between converting to YV24 before using HDTools, or not, is noticeable. All I can assume is the difference is/was the YUV to RGB conversion, and for some reason it stood out more with rec.2020 to rec.709. I could duplicate this result, so I don't think it's a rendering problem. They're not massively different, but they are different.
It's frustrating because today the result where I used ConvertToYV24 is very close to yesterday's screenshot where I didn't use it. Hopefully that's just because it's not the same frame from the source. Maybe I need to start over, although at least now I know HDRTools XYZ has problems and ColorMatrix definitely isn't doing rec.2020 conversions correctly, so I've learned something....
https://i.postimg.cc/4Kf97jTG/HDRTools1.png (https://postimg.cc/4Kf97jTG)
https://i.postimg.cc/Cdzb4ynL/HDRTools2.png (https://postimg.cc/Cdzb4ynL)
Thanks again.
PS. I'm still don't really understand why HDRTools has two rec.601 flavours. ;)
StvG
16th August 2019, 08:43
Yes, the difference between HDRTools chroma upscale method and converttoyv24/z_convertformat is noticeable especially if the output is 8-bit (less noticeable with 16-bit output):(#)converttoyv24()
ConvertYUVtoLinearRGB(Color=1, OutputMode=1)
ConvertLinearRGBtoYUV(outputmode=1)
ConvertBits(8)
subtitle("w/(o) converttoyv24")
gallery (http://imgbox.com/g/ap4gOAceAQ)
jpsdr
16th August 2019, 22:33
PS. I'm still don't really understand why HDRTools has two rec.601 flavours. ;)
§2.6 of R-REC-BT.601-7-201103-I!!PDF-E.
jpsdr
16th August 2019, 22:40
I guess HDRTools is wrong (bug?) because the output with both pColor=1/2 is the same.
Answer is in my thread, pColor is just for optimizing Min/Max range in integer mode.
So
ConvertYUVtoXYZ(Color=1).ConvertXYZtoYUV(Color=2, pColor=2, OutputMode=2)
is not
z_ConvertFormat(colorspace_op="2020:709:709=>2020:709:xyz").z_ConvertFormat(colorspace_op="2020:709:xyz=>709:709:709")
You're juste saying that XYZ integer input range are those of BT709 (when they should be those of BT2020).
It's described in the Warning page 3 of ColorConversion.pdf provided with the binaries.
And, i clearly state in the filter doc :
Note about YV12/YV16/YV24 input/ouput:
For ConvertYUVtoxxx functions, convertion to YV24 if input is not YV24 is "quick".
If you want a true correct precise/perfect convertion, i would avise you to use
a resampler and feed directly to YV24.
For ConvertxxxtoYUV functions, if you choose an ouput different from YV24, same
remark, convertion is "quick".
If you want a true correct precise/perfect convertion, i would avise you
to ouput to YV24, and use a resampler to achieve the real output format you want.
StvG
16th August 2019, 23:47
Answer is in my thread, pColor is just for optimizing Min/Max range in integer mode.
So
ConvertYUVtoXYZ(Color=1).ConvertXYZtoYUV(Color=2, pColor=2, OutputMode=2)
is not
z_ConvertFormat(colorspace_op="2020:709:709=>2020:709:xyz").z_ConvertFormat(colorspace_op="2020:709:xyz=>709:709:709")
You're juste saying that XYZ integer input range are those of BT709 (when they should be those of BT2020).
It's described in the Warning page 3 of ColorConversion.pdf provided with the binaries.
Thanks for the clarification.
And, i clearly state in the filter doc :
Note about YV12/YV16/YV24 input/ouput:
For ConvertYUVtoxxx functions, convertion to YV24 if input is not YV24 is "quick".
If you want a true correct precise/perfect convertion, i would avise you to use
a resampler and feed directly to YV24.
For ConvertxxxtoYUV functions, if you choose an ouput different from YV24, same
remark, convertion is "quick".
If you want a true correct precise/perfect convertion, i would avise you
to ouput to YV24, and use a resampler to achieve the real output format you want.
Right, that's why I used the same chroma upscaling/downscaling method for the comparison in #6.
Groucho2004
17th August 2019, 00:07
ColorMatrix definitely isn't doing rec.2020 conversions correctlyHave you tried using "opt = 0" with ColorMatrix?
hello_hello
17th August 2019, 00:24
Have you tried using "opt = 0" with ColorMatrix?
No but it doesn't seem to need it for rec.709 <-> rec.601 conversions.
I'll try it later and report back if it changes anything, but the difference between ColorMatrix and the other programs is fairly substantial. Except for Rec.709 to Rec.2020. That's the one type of Rec.2020 conversion where it's the same.
Natty
17th August 2019, 14:59
will u do up conversions? eg 601 to 709. 709 to 2020.? :thanks:
hello_hello
19th August 2019, 11:56
There's a 709 to 2020 up-conversion here. https://forum.doom9.org/showthread.php?p=1881624#post1881624
Everyone seems to get 601 <-> 709 right. I haven't gone back and redone any more tests to be sure, but I think the result between colorimetries was the same in both directions. If it's correct down-converting, up-converting is okay too.
The one exception was ColorMatrix converting between 709 and 2020. It appears to down-convert incorrectly but the up-conversion is okay. It might pay not to use the ColorMatrix 2020 build though. There's tried and tested 32 and 64 bit builds for HD and SD color conversions.
It appears HDTools XYZ is working correctly but I didn't know how to use it, or possible more accurately, why the results were different. There's info in this post (https://forum.doom9.org/showthread.php?p=1882350#post1882350) and the replies that follow. Keep an eye on that thread. I'm still learning....
kedautinh12
23rd January 2020, 04:07
There's a 709 to 2020 up-conversion here. https://forum.doom9.org/showthread.php?p=1881624#post1881624
Everyone seems to get 601 <-> 709 right. I haven't gone back and redone any more tests to be sure, but I think the result between colorimetries was the same in both directions. If it's correct down-converting, up-converting is okay too.
The one exception was ColorMatrix converting between 709 and 2020. It appears to down-convert incorrectly but the up-conversion is okay. It might pay not to use the ColorMatrix 2020 build though. There's tried and tested 32 and 64 bit builds for HD and SD color conversions.
It appears HDTools XYZ is working correctly but I didn't know how to use it, or possible more accurately, why the results were different. There's info in this post (https://forum.doom9.org/showthread.php?p=1882350#post1882350) and the replies that follow. Keep an eye on that thread. I'm still learning....
Can you share me colormatrix 2.6 x64??
hello_hello
27th January 2020, 02:23
Can you share me colormatrix 2.6 x64??
I don't think version 2.6 has a 64 bit flavour, but there's a link for the 64 bit flavour of version 2.5 in the opening post here.
https://forum.doom9.org/showthread.php?p=1374605#post1374605
I think most people still use version 2.5 anyway. I do.
StainlessS
27th January 2020, 13:00
Dont know where I got this archive, originally named "ColorMatrix26.7z".
Renamed archive to "ColorMatrix26(v2.6_avs+_x86&x64+Src_2020WithoutAsmOpts).7z".
@ MediaFire in my sig, in HOSTED folder, or direct link here:- http://www.mediafire.com/file/5sshv990lyhs9gt/ColorMatrix26%2528v2.6_avs%252B_x86%2526x64%252BSrc_2020WithoutAsmOpts%2529.7z/file
EDIT:
v2.6, 22th February 2018
+ Add Rec.2020 support (without ASM optimization)
v2.5, 25th January 2009
+ Updated d2v parsing to correctly determine frame count for v16 DGIndex project files.
- Fixed a bug causing the mmx/sse2 routines for FCC<->Rec.601 conversions to give incorrect U plane output.
EDIT: Looks like 2020 mod may have been done by Sorayuki:- https://github.com/sorayuki/ColorMatrix/releases
However, name of 7z archive is different, and two separate archives for dll and source, so looks like someone else added avs+ support, recompiled and issued combined archive.
EDIT: Looks like was Groucho2004 that updated for avs+, same archive name[Grouchy 2004 suppository]:- http://www.iol.ie/~schubert/gas/gas.html
From Groucho2004 Avisynth Stuff thread:- https://forum.doom9.org/showthread.php?t=173259
ColorMatrix 2.6.0.0 (x86 & x64)
tritical's ColorMatrix with updated AVS2.6 headers and SoraYuki's REC.2020 addition. Documentation included.
Note:
These ColorMatrix builds do not have the 'opt' parameter. The binaries produced with the Intel C compiler using C/C++ code are at least as fast as the ones with the inline asm.
hello_hello
28th January 2020, 16:00
I ran some more tests to see if I'd still get the same results as last time, and now I understand part of the head-f*#k I was experiencing the last time around. I'm pretty sure the result is the same for the Grouchy versions as it is for the original ColorMatix 2.6.
I didn't notice, probably because I was concentrating on comparing the color conversion results between programs, that ColorMatrix 2.6 conversions between rec.2020 and rec.601 simply don't work in either direction (assuming they're supposed to). The output is the same as the input. In my defence though, I posted samples and nobody else noticed either.
The result was the same as before when comparing rec.2020 and rec.709 conversions between ColorMatrix and DitherTools, For a conversion from rec.709 to rec.2020 the two programs produce the same result. When converting from rec.2020 to rec.709 they don't, and my guess is ColorMatrix 2.6 is the one getting it wrong.
As I eventually learned, ColorMatrix and DitherTools both convert to/from Rec.2020 using a matrix-only method. If there's a point to converting to/from Rec.2020 that way I'd be keen to learn what it is. That's why the CropResize (https://forum.doom9.org/showthread.php?t=176667) script no longer uses either ColorMatrix or DitherTools for rec.2020 conversions. Instead it only converts to/from Rec.2020 with HDRTools, as HDRTools can convert the color primaries too. You can get away with converting between rec.601 and rec.709 using a matrix-only method, because even though it's not technically perfect, the color primaries are so similar it doesn't matter too much. For conversions to/from Rec.2020, I have no idea when it'd make sense not to also convert the color primaries. There's examples of HDRTools doing rec.2020 conversions in the zip file below. For the 601/2020 conversions it's converting to/from the PAL color primaries.
I haven't added images directly to this post because it's a chore to do at doom9 and anyone interested can download my test conversions as a zip file. Aside from the HDRTools conversions, where I used MeGUI to convert in 16 bit with Avisynth+, all the sample screenshots are taken from the Avisynth 2.6 script output using MPC-HC. They're the same resolution, so the same colorimetry would have been used to convert to RGB on playback. While obviously it couldn't be the correct method most of the time, it means the color differences you see in the screenshots are only due to the color conversion in the script, or in the case of conversions to/from Rec.2020 using ColorMatrix, the color differences you don't see.
Sample Color Conversions.zip (https://ufile.io/h6qz0kw5) 3.6 MB (screenshots) Link good for 30 days.
This is a more permanent link (until I run out of space). Sample Color Conversions.zip (https://files.videohelp.com/u/210984/Sample%20Color%20Conversions.zip)
hello_hello
28th January 2020, 18:07
Looking back at the original ColorMatrix 2.6 thread (https://forum.doom9.org/showthread.php?t=175279) it seems it was only intended to support conversions to/from rec.2020 and rec.709, so it's quite a shame the plugin doesn't produce an error when you try to convert between rec.2020 and rec.601.
That sort of information is something the help file should go out of it's way to make obvious, even if it's a poor substitute for producing an error message.
TheFluff
28th January 2020, 18:18
The helpfile should have a huge warning that says "don't use colormatrix", instead.
manolito
29th January 2020, 13:01
Looking back at the original ColorMatrix 2.6 thread (https://forum.doom9.org/showthread.php?t=175279) it seems it was only intended to support conversions to/from rec.2020 and rec.709,
Couldn't one chain two ColorMatrix calls so it first converts REC.2020 to REC.709, then the second call converts from REC.709 to REC.601 ?
And a general question:
For converting a REC.2020 UHD clip to DVD, is it really enough to change the colorimetry to REC.601? Or is some additional tone mapping required?
hello_hello
29th January 2020, 16:56
Couldn't one chain two ColorMatrix calls so it first converts REC.2020 to REC.709, then the second call converts from REC.709 to REC.601 ?
I guess so, but it still should produce an error when trying to convert between rec.2020 and rec.601 and I'm pretty sure the rec.2020 to rec.709 conversion is wrong anyway. It's different to DitherTools and HDRTools (when HDRTools is doing a linearRGB conversion).
And a general question:
For converting a REC.2020 UHD clip to DVD, is it really enough to change the colorimetry to REC.601? Or is some additional tone mapping required?
Sorry if some of this is stuff you already know. I imagine it is, but just to be thorough....
Have a look at the samples attached to my previous post and the color difference between the ColorMatrix/DitherTools matrix-only conversions, and HDRTools converting both the matrix and the color primaries.
The HDRTools conversions look wrong because I used a rec.709 source and it's being displayed using rec.601, but the author of HDRTools says that's the correct way to convert to/from rec.2020, although HDRTools will do a matrix-only conversion too.
I don't have anything that understands the rec.2020 primaries to do a real comparison, but you can maybe get away with a matrix-only conversion when upscaling HD content and encoding with something like x264 while specifying rec.709 as the color primaries and rec.2020 for the color matrix in the command line, and if a player pays attention to that sort of thing it'd probably display correctly, but then again you could just upscale without converting anything while specifying rec.709 for both the primaries and the matrix, and it should display correctly if a player pays attention, much like you can specify rec.709 for both when downscaling HD to SD.
When downscaling from UHD though, if the source is rec.2020 and you didn't convert anything, but just specified rec.2020 for the primaries and matrix, you'd have to be using a player/TV that understands them for it to display correctly. Likewise if you did a matrix only conversion from rec.2020 to rec.709, you'd have to specify rec.709 for the color matrix and rec.2020 for the primaries and once again the player/TV would have to understand the rec.2020 primaries and use the rec.709 matrix on playback.
When downscaling UHD to HD/SD and encoding with a codec or using a player that's oblivious to rec.2020, I don't know how it could display correctly unless you converted both the matrix and color primaries, as the rec.2020 primaries are vastly different to rec.709/rec.601.
Even rec.709 and rec.601 NTSC and rec.601 PAL all use slightly different color primaries, but they're so similar you can get away with a matrix-only conversion. Rec.709 and rec.601 PAL use the same red and blue primaries, while green is a little different. From memory rec.601 NTSC uses different color primaries for each, but red and blue are pretty close to rec.601 PAL/rec.709. Rec.709 was some sort of compromise between PAL and NTSC. It's green color primary sits halfway between the PAL and NTSC green color primaries.
Technically I should be referring to 525 line and 625 line, not PAL or NTSC.
Try doing a color conversion with CropResize (https://forum.doom9.org/showthread.php?t=176667). The options are:
ColorCorrect=1 - ColorMatrix to/from rec.709/rec.601, matrix only.
ColorCorrect=2 - DitherTools to/from rec.709/rec.601, matrix only.
ColorCorrect=3 - HDRTools converting the primaries and matrix. 525 line for the rec.601 primaries.
ColorCorrect=4 - HDRTools converting the primaries and matrix, 625 line for the rec.601 primaries.
HDRTools conversions require AVisynth+ so they can be done in 16 bit, otherwise the output can show color banding.
A matrix-only conversion using DitherTools would look like this:
CropResize(ColorCorrect=2, ColorMode="709-601")
The same conversion converting the primaries too:
CropResize(ColorCorrect=3, ColorMode="709-601")
or
CropResize(ColorCorrect=4, ColorMode="709-601")
You'll sometimes see a slight difference between the methods, so naturally it'd be huge for rec.2020 conversions because the green and red rec.2020 primaries are outside the sRGB color gamut used by rec.709 and rec.601, if memory serves me correctly.
https://upload.wikimedia.org/wikipedia/commons/b/b6/CIExy1931_Rec_2020.svg
https://upload.wikimedia.org/wikipedia/commons/e/ef/CIExy1931_Rec_709.svg
The one thing I'm not sure of is what happens when a rec.2020 source is actually using a wider color gamut than is supported by rec.709/601 and you convert between them (given that was the whole point of rec.2020). I assume the out of range colors must be clipped. I guess that's what happens when you watch rec.2020 video on a rec.2020 display that can only produce RGB colors anyway (probably most of them as most displays are RGB), or maybe the display would try to do some sort of clever color adjustment.
I think if you're using a player/codec that understands rec.2020 and will obey the specified color primaries and matrix, you'd possibly be better off downscaling without converting anything.
manolito
29th January 2020, 19:01
Thanks hello_hello for this detailed explanation.
I did know a few things you mentioned already, but since I am not interested in this UHD stuff personally I do not intend to dig into it too deeply. The reason I got into it is that a friend had an UHD clip that he wanted to watch on his notebook and on his TV, and on both the colors looked unacceptable. AFAIK his TV is a Full HD capable LCD, but no UHD, no 4k, no HDR. He asked me if I could convert the clip to SD resolution, either MPEG2 or AVC, and fix the colors in the process.
So I downloaded a few demo clips from 4kmedia.org, for testing I used the LG New York demo.
Just converting the matrix from BT.2020 to BT.601 did not do much, so I started reading. I ended up using the DGHDRtoSDR tool because it seemed pretty easy to use, and it got very good reviews. The conversion looked pretty good to me (after reducing the blue satuaration a little), but I have a few questions. I used this script:
Audio = LWLibavAudioSource("MySourceFile", stream_index=-1)
Video = LWLibavVideoSource("MySourceFile", stream_index=-1, format="YUV420P16", seek_mode=0).ChangeFPS(25)
Video = Video.Spline36Resize(720,576)
Video = Video.DGHDRtoSDR(mode="pq")
Video = Video.ConvertToYV12(matrix="rec601")
AudioDub(Video, Audio)
Does DGHDRtoSDR do any matrix conversion by itself? The readme does not mention anything about this. If not, is it enough to use the matrix="rec601" parameter in the ConvertToYV12 call? Or do I need to use a different tool for converting the matrix?
I doubt that I could convince my friend to learn AviSynth or VapourSynth, but he may bite if I can give him a working FFmpeg command line which he could easily edit for his needs. I found some examples on the Web, I will have to do more tests tonight and compare the FFmpeg results to DGHDRtoSDR.
hello_hello
29th January 2020, 22:53
I'd not heard of DGHDRtoSDR until now. Probably because I have no real interest in 4K or UHD or HDR myself.
I had a play, but I think those questions are really for videoh to answer. Best as I can tell it's purpose is purely to convert HDR to SDR, so I guess it's also designed to work with rec.2100 (https://en.wikipedia.org/wiki/Rec._2100) sources. It's not clear to me if it also converts the colorimatery in the process.
My guess is it doesn't, because rec.2100 supports a 1920x1080 resolution (the resolution mentioned in the help file) and there's no mention of coloriimtery in the help file, so after using it you'd probably have to do an additional rec.2020 to rec.709/601 conversion if that's where you want to end up, and I'd imagine you'd need to be able to display rec.2020 correctly so as to get the HDR to SDR conversion right first, or at least follow it with a conversion to rec.709/601 in the script if you can't display rec.2020 correctly.
For ConvertToYV12(matrix="rec601"), the matrix option only works when the source is RGB (as far as I know) so for a YUV source, to do a matrix-only conversion with Avisynth+ it'd be:
ConvertToRGB(matrix="rec2020")
ConvertToYV12(matrix="rec601")
You'd probably want to do it in 16 bit or there'll be a good chance of banding. That's the advantage of ColorMatix.dll. It converts the YUV colors without going through an RGB conversion first, so it doesn't produce much/any banding. DitherTools does it by converting to RGB first, but in stacked 16 bit. HDRTools can do it in 8 bit but it converts to RGB first for a matrix-only conversion, or to XYZ first in order to convert the primaries too, so it tends to result in lots'o'banding unless you convert to 16 bit first.
Using Avisynth to convert the matrix is obviously a matrix only conversion. I suspect for the correct colors if you want to convert to rec.601 you should convert the color primaries too, but that's really just my guesses.
I'll try to find and download the source you mentioned previously and play around later on to see if I can convert it to look satisfactory using rec.709 for playback on my PC and I'll let you know if I discover anything interesting.
manolito
30th January 2020, 02:36
Did a few more AVS based tests using AVStoDVD.
All tests were done with my previous script with the exception that I added the "b=1.0" parameter to the DGHDRtoSDR call (with the default the blue was way too much "in your face" for my taste).
Using the ConvertToYV12(matrix="rec601") command did make a difference compared to leaving out the matrix parameter. File size and encoding speed were different, I just could not see any visual difference. With two ColorMatrix calls there was a slight visual difference, but nothing where I could say that one or the other looked better.
I uploaded the results here:
https://www.sendspace.com/file/nqeh05
Maybe you got better eyes or a better monitor than I do.
Anyways, next thing I will do is testing some FFmpeg parameters for HDR to SDR conversions...
videoh
30th January 2020, 03:04
Of course DGHDRtoSDR converts from 2020 to 709! Tempted to add "duh".
Will look at the rest of the thread and answer any other questions I see.
videoh
30th January 2020, 03:09
It's not clear to me if it also converts the colorimetry in the process. My guess is it doesn't... Wrong.
manolito
30th January 2020, 03:56
Of course DGHDRtoSDR converts from 2020 to 709! Tempted to add "duh".
But my target format is DVD, so I need 601 instead of 709. So I need to do this manually after the DGHDRtoSDR call?
hello_hello
30th January 2020, 04:22
Thanks manolito, you helped me find a problem with the CropResize script. I'd added a line for testing and forgotten to remove it, causing HDRTools to throw an error when converting the colors if the source bitdepth was greater than 8.
Here's what I tried with the sample you mentioned. The first encode converted the HDR to SDR and the the colors from rec.2020 to rec.601 including the primaries. I'm not claiming the HDR to SDR conversion is perfect because I just went with the example in the help file.
FFVideoSource("E:\LG New York HDR UHD 4K Demo.mkv", threads=1)
CropResize(720,576, OutDAR=16.0/9.0)
ConvertBits(16)
DGHDRtoSDR(mode="pq",white=1800, impl="sw")
CropResize(NoResize=true, InDAR=16.0/9.0, ColorCorrect=4, ColorMode="2020-601")
ConvertBits(8)
New York HDR to SDR 2020 to 601.mkv (https://ufile.io/0mpwno9j)
Same again, minus the color conversion.
FFVideoSource("E:\LG New York HDR UHD 4K Demo.mkv", threads=1)
CropResize(720,576, OutDAR=16.0/9.0)
ConvertBits(16)
DGHDRtoSDR(mode="pq",white=1800, impl="sw")
ConvertBits(8)
New York HDR to SDR.mkv (https://ufile.io/5b4qonaw)
The version without the rec.2020 to rec.601 color conversion looks better to me, so now I'm just annoyed and confused. Maybe being a demo, the colors are intentionally crap, as in-store demos tend to be, and not converting the colors has functioned as an un-crapper. I don't know.... I expected the result to be effectively the opposite. I double checked the color conversion in the script and I'm sure it's okay. Tomorrow, when I'm less annoyed and confused I might try again using a different source.
Edit: The samples above will download with the names "New York HD to SD 2020 to 601" and "New York HD to SD" when I should have named them "New York HDR to SDR 2020 to 601" and "New York HDR to SDR". Doh!
hello_hello
30th January 2020, 04:25
Wrong.
I'm so unbelievably glad to be wrong. Now I'm no longer annoyed and confused, although I'm not sure how it's even remotely obvious that it does a conversion to rec.709. I don't recall seeing colorimetry get a mention in the help file.
hello_hello
30th January 2020, 04:39
Using the ConvertToYV12(matrix="rec601") command did make a difference compared to leaving out the matrix parameter. File size and encoding speed were different, I just could not see any visual difference.
That seems odd.
http://avisynth.nl/index.php/Convert
string matrix = "Rec601"
Controls the colour coefficients and scaling factors used in RGB↔YUV conversions.
Downloading your samples for a look-see now.
hello_hello
30th January 2020, 04:57
Trying again.
FFVideoSource("E:\LG New York HDR UHD 4K Demo.mkv", threads=1)
CropResize(720,576, OutDAR=16.0/9.0)
ConvertBits(16)
DGHDRtoSDR(mode="pq",white=1800, impl="sw")
CropResize(NoResize=true, InDAR=16.0/9.0, ColorCorrect=1, ColorMode="709-601")
ConvertBits(8)
New York HDR to SDR 709 to 601.mkv (https://ufile.io/wb8vu49f)
manolito,
Your conversion labelled ColorMatrix(source=4,dest=0).ColorMatrix(source=0,dest=2).mpeg looks a bit odd. I guess I led you astray there. I blame it on the lack of information in the help file. :)
The other two do look exactly the same. I don't know why encoding speed would have been different.
PS I'm still dubious about using Colormatrix for a rec.2020 to Rec.709 conversion anyway, but if you compare that encode to mine labelled "New York HDR to SDR 2020 to 601.mkv", even though they both tuned out to be wrong in respect to converting the colors unnecessarily, I guess they're something of an example of the difference between converting the color primaries and not converting them.
Ignoring the fact we now know it's an unnecessary color conversion, here's the difference between Colormatix and DitherTools (both matrix only conversions).
No Conversion
https://i.postimg.cc/MGChscRy/No-Conversion.jpg
ColorMatrix(mode="rec.2020->rec.709")
https://i.postimg.cc/2SykMX9r/Color-Matrix.jpg
Dither_convert_8_to_16()
Dither_convert_yuv_to_rgb(matrix="2020", output="rgb48y", lsb_in=true)
r = SelectEvery (3, 0)
g = SelectEvery (3, 1)
b = SelectEvery (3, 2)
Dither_convert_rgb_to_yuv(r, g, b, matrix="709", lsb=false, mode=0)
https://i.postimg.cc/pVYgZLdF/Dither-Tools.jpg
videoh
30th January 2020, 15:49
I'm not sure how it's even remotely obvious that it does a conversion to rec.709. When one is clueless it behooves one to do basic research, including reading the relevant threads for the tools:
https://forum.doom9.org/showthread.php?p=1847484#post1847484
FranceBB
30th January 2020, 16:07
Sorry if I jump into the topic, but...
Manolito, out of curiosity, would you like me to make an HDR HLG BT2020nc to BT601 SDR and HDR PQ BT2100 to BT601 SDR matrix of linear transformation to add to my LUT collection (https://forum.doom9.org/showthread.php?t=176091)?
I actually never thought about it 'cause I didn't think it was useful, but if it is useful to someone, I can do it. After all, BT601 is pretty close to BT709 so it shouldn't be too hard...
As to the others, I've been using DGHDRtoSDR with good results when I had to tone-map the studio master of Riviera here: Link (http://forum.doom9.net/showthread.php?t=175911)
And of course it converted from from BT2100 HDR PQ to BT709 SDR.
The only catch is that it only works in 4:2:0 planar. Since Donald is here reading the topic I take the chance to ask him: will you add 4:2:2 planar and 4:4:4 planar support in the future?
videoh
30th January 2020, 16:31
The only catch is that it only works in 4:2:0 planar. Since Donald is here reading the topic I take the chance to ask him: will you add 4:2:2 planar and 4:4:4 planar support in the future? It's certainly something I could do. May I ask what source filter you using to deliver 4:2:2 and 4:4:4? A sample script would be helpful.
manolito
30th January 2020, 19:17
@ FranceBB
Manolito, out of curiosity, would you like me to make an HDR HLG BT2020nc to BT601 SDR and HDR PQ BT2100 to BT601 SDR matrix of linear transformation to add to my LUT collection?
I'm sorry, but this would be way over my head.
@videoh
Thanks for the link to this old post, but such posts are not easy to find at Doom9. Neither me nor hello_hello found it, so it would be really nice if you could add this internal workflow to the readme...
@ all
I tested some FFmpeg parameters for this conversion. A complex version posted by Atak and a simpler one posted by Tebasuna. Easy to use, I just pasted it into the "more video filters" field in dmMediaConverter. My head is spinning from comparing the results. They all look a little different, but no idea which one is more correct or better...
You can download the results here:
https://www.sendspace.com/file/xjkl0j
Here are the scripts or parameters I used:
For AviSynth:
Audio = LWLibavAudioSource("MySourceFile", stream_index=-1)
Video = LWLibavVideoSource("MySourceFile", stream_index=-1, format="YUV420P16", seek_mode=0).ChangeFPS(fps)
Video = Video.Spline36Resize(720,576)
Video = Video.DGHDRtoSDR(mode="pq", b=1.0)
Video = Video.ColorMatrix(source=0,dest=2)
Video = Video.ConvertToYV12()
AudioDub(Video, Audio)
FFmpeg (Atak version)
zscale=s=704x396,zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv,zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p,colormatrix=bt709:bt601
FFmpeg (Tebasuna version):
zscale=s=704x396,zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p,colormatrix=bt709:bt601
These parameters are easy to modify for HD output. Edit the "zscale" parameter for the desired size and remove the "colormatrix" parameter.
//EDIT//
I forgot to mention that the FFmpeg parameters are meant to be inserted in dmMediaConverter. If you want to use them in an existing FFmpeg commandline you need to add them as a video filter and enclose the parameters in double quotes. like:
-vf "parameter list"
Cheers
manolito
videoh
30th January 2020, 19:30
Thanks for the link to this old post, but such posts are not easy to find at Doom9. Neither me nor hello_hello found it, so it would be really nice if you could add this internal workflow to the readme... Search for DGHDRtoSDR and the thread for it appears within the first 10 results. How much hand-holding do you need? Nevertheless, to indulge you and others unable to execute simple searches, I'll add it to the user manual. ;)
manolito
30th January 2020, 19:46
:thanks:
hello_hello
30th January 2020, 22:18
When one is clueless it behooves one to do basic research, including reading the relevant threads for the tools:
https://forum.doom9.org/showthread.php?p=1847484#post1847484
If I'd gone to the trouble of hunting through the thread and what I needed to know wasn't there you'd be telling me to read the help file, which is where you'd expect to find all the relevant info. Not everyone posts at doom9. Is the information about colorimetry available in a thread in your forum too?
To me, due to a lack of anything in the help file to the contrary, it seemed perfectly reasonable to assume DGHDRtoSDR simply converts HDR to SDR and you'd be left with rec.2020. Maybe if the plugin was named DGHDRto709SDR.....
Anyway, it's sorted now and we know what to expect. Thanks for the plugin by the way. I'm sure I'll use it eventually, even if I don't have a need for it now. Although what do you use if you want to convert HDR range to SDR and not reduce the color gamut to rec709?
FranceBB
30th January 2020, 23:00
It's certainly something I could do. May I ask what source filter you using to deliver 4:2:2 and 4:4:4? A sample script would be helpful.
My indexer is simply FFMpegSource2 and my source files are generally either AppleProRes masterfiles or DNxHR masterfiles delivered directly by the production company that made the movie.
I can also provide a very short sample (few seconds) if you want but it has to be on a secured FTP provided that you will use it for test only and that you will never ever share it with anyone else. (Copyright is not a joke).
Richard1485
31st January 2020, 01:04
FFmpeg (Atak version)
zscale=s=704x396,zscale=tin=smpte2084:min=bt2020nc:pin=bt2020:rin=tv:t=smpte2084:m=bt2020nc:p=bt2020:r=tv,zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p,colormatrix=bt709:bt601
FFmpeg (Tebasuna version):
zscale=s=704x396,zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p,colormatrix=bt709:bt601
Is there a difference between Atak and Tebasuna's solutions? The outputs looked pretty similar to me, and I guessed that the difference between the two was that the settings that Atak spells out are (or have become) default settings that are implied in Tebasuna's example.
videoh
31st January 2020, 04:15
I can also provide a very short sample (few seconds) if you want but it has to be on a secured FTP provided that you will use it for test only and that you will never ever share it with anyone else. (Copyright is not a joke). PM sent. Thank you.
hello_hello
31st January 2020, 11:36
What method/program would anyone recommend if you want to convert HDR range to SDR and not reduce the color gamut to rec709? It looks like HDRTools can do it.
FranceBB,
I was looking at your LUT collection and while I have no idea how to use them yet (I've been meaning to work that out for a while) is there never a reason to convert HDR to SDR without changing the colorimetry?
richardpl
31st January 2020, 11:51
Is there a difference between Atak and Tebasuna's solutions? The outputs looked pretty similar to me, and I guessed that the difference between the two was that the settings that Atak spells out are (or have become) default settings that are implied in Tebasuna's example.
Stop using colormatrix filter - it is bad and evil. Instead use zscale options directly.
Richard1485
31st January 2020, 12:20
Stop using colormatrix filter - it is bad and evil. Instead use zscale options directly.
Thanks for your input, but I don't use colormatrix. That must be something that was tacked on to those examples, which I was only quoting. My question related to the difference in syntax.
manolito
31st January 2020, 15:54
Stop using colormatrix filter - it is bad and evil. Instead use zscale options directly.
The FFmpeg command lines I posted here:
https://forum.doom9.org/showthread.php?p=1897752#post1897752
use ColorMatrix for the final change from 709 to 601 for a very simple reason: Replacing 709 by 601 in the zscale parameters does not work, dozens of error messages. So you would have to tell me how to modify these parameters to get a bt601 output. BTW I would not be willing to pay money for this advice...
FranceBB
31st January 2020, 17:00
What method/program would anyone recommend if you want to convert HDR range to SDR and not reduce the color gamut to rec709? It looks like HDRTools can do it.
FranceBB,
I was looking at your LUT collection and while I have no idea how to use them yet (I've been meaning to work that out for a while) is there never a reason to convert HDR to SDR without changing the colorimetry?
Well, so basically you wanna go from BT2100 HDR PQ to BT2020nc SDR, is that right?
But... what for? I mean, if it's for TV compatibility, then it would make much more sense to go from PQ to HLG so that both SDR TVs and HDR ones will be able to play it without compromising the original HDR too much. If it's for FULL HD SDR TV compatibility, then they won't be able to interpret the new matrix anyway so it wouldn't make sense.
Anyway, I can definitely make a LUT from BT2100 PQ to BT2020 SDR and from BT2020nc HLG to BT2020 SDR.
As to how to use my matrices of linear transformation, it's pretty easy:
FFVideoSource("example.mxf")
ConvertBits(16)
ConvertToPlanarRGB()
Cube("C:\Programmi\AviSynth+\LUTs\example.cube", cpu=1, fullrange=false)
where "example.cube" is the matrix of linear transformation. Essentially a matrix of linear transformation is something that maps a point to another. I don't know whether you're familiar with linear algebra or not (I personally love it). If you are not familiar and you wanna have a visual intuition about what it, I strongly suggest you this series of videos made by Grant Sanderson: Link (https://www.youtube.com/watch?v=fNk_zzaMoSs&list=PLZHQObOWTQDPD3MizzM2xVFitgF8hE_ab) and check out "Linear Transformation". It's gonna be so much fun as it's extremely well animated. If you get very passionate about it there are real lectures made by Doctor Gilbert Strang (MIT).
EDIT: I made such a matrix: Link (https://forum.doom9.org/showthread.php?p=1897834#post1897834)
TheFluff
31st January 2020, 17:03
The FFmpeg command lines I posted here:
https://forum.doom9.org/showthread.php?p=1897752#post1897752
use ColorMatrix for the final change from 709 to 601 for a very simple reason: Replacing 709 by 601 in the zscale parameters does not work, dozens of error messages. So you would have to tell me how to modify these parameters to get a bt601 output. BTW I would not be willing to pay money for this advice...
That's because it's not called bt601, it's called bt470bg (PAL) or bt470m (NTSC).
See this thread (https://forum.doom9.org/showthread.php?t=170655) for some of the subtleties of analog SD TV (non-)standardization.
e: note that for color matrix there is no bt470m though.
e2: actually let me make a little table or something of the potentially relevant values.
For color primaries, there is
- bt709
- bt470m (old NTSC, I mean like ancient)
- bt470bg (equivalent to Rec.601 for PAL and SECAM)
- smpte170m and smpte240m (different metadata values but identical functionally; also equivalent to Rec.601 for NTSC)
For transfer characteristics ("gamma"), there is
- 601 and bt709 (different metadata values but functionally identical, note no "bt" before 601; you can also use smpte170m as an alias for 601)
- bt470bg (old PAL, assumed display gamma 2.8)
- bt470m (old NTSC, assumed display gamma 2.2)
For color matrix, there is only
- bt709
- bt470bg (equivalent to Rec.601 for both PAL, NTSC and SECAM)
So assuming you're targeting a PAL TV that is at least newer than fall of the Berlin Wall, you probably want primaries=bt470bg, transfer=601 and matrix=bt470bg.
The fact that colormatrix only touches the matrix, and PAL and NTSC happen to use identical values for the matrix in Rec601, is probably what has led to the somewhat confusing use of "601" as a generic name for all SDTV colorimetry even though it's ambiguous what it means for transfer and primaries.
manolito
1st February 2020, 01:00
Did some more tests with the FFmpeg command lines for HDR to SDR conversions. Still a little bit confused... :o
First of all I do not want to get into another dispute about using ColorMatrix. I did try using zscale instead of colormatrix, it did work in the end, but the result was indistinguishable from the colormatrix result.
What really bothers me is that the FFmpeg command lines I posted do work sometimes with good results, but for other source files I get results like this:
https://forum.doom9.org/showthread.php?p=1875073#post1875073
It does work nicely for the LG New York clip, but for the Sony Camping in Nature clip it did not work. To get a watchable result I had to change the tonemap algo from hable to clip or mobius. No way to make it work for hable or reinhard.
And both the clip and mobius methods result in very ugly colors. Quite unusable...
I first suspected that it had something to do with the FFmpeg versions I used, but after many tests with all kinds of different older versions I know that this is not true.
The clip properties of these two clips are very similar. Here is what MediaInfo has to say:
LG New York
=============
Video
ID : 1
Format : HEVC
Format/Info : High Efficiency Video Coding
Format_Commercial_IfAny : HDR10
Format-Profil : Main 10@L5@High
Codec-ID : V_MPEGH/ISO/HEVC
Dauer : 1 min 12s
Bitrate : 48,1 Mb/s
Breite : 3 840 Pixel
Höhe : 2 160 Pixel
Bildseitenverhältnis : 16:9
Modus der Bildwiederholungsrate : konstant
Bildwiederholungsrate : 25,000 FPS
ColorSpace : YUV
ChromaSubsampling/String : 4:2:0
BitDepth/String : 10 bits
Bits/(Pixel*Frame) : 0.232
Stream-Größe : 414 MiB (100%)
verwendete Encoder-Bibliothek : ATEME Titan KFE 3.7.3 (4.7.3.1003)
Default : Ja
Forced : Nein
colour_range : Limited
colour_primaries : BT.2020
transfer_characteristics : PQ
matrix_coefficients : BT.2020 non-constant
MasteringDisplay_ColorPrimaries : Display P3
MasteringDisplay_Luminance : min: 0.0500 cd/m2, max: 1200 cd/m2
Sony Camping in Nature
========================
Video
ID : 1
Format : HEVC
Format/Info : High Efficiency Video Coding
Format_Commercial_IfAny : HDR10
Format-Profil : Main 10@L5.1@High
Codec-ID : hvc1
Codec-ID/Info : High Efficiency Video Coding
Dauer : 2 min 7s
Bitrate : 75,6 Mb/s
maximale Bitrate : 123 Mb/s
Breite : 3 840 Pixel
Höhe : 2 160 Pixel
Bildseitenverhältnis : 16:9
Modus der Bildwiederholungsrate : konstant
Bildwiederholungsrate : 59,940 (60000/1001) FPS
ColorSpace : YUV
ChromaSubsampling/String : 4:2:0 (Type 2)
BitDepth/String : 10 bits
Bits/(Pixel*Frame) : 0.152
Stream-Größe : 1,12 GiB (100%)
Kodierungs-Datum : UTC 2016-02-03 07:59:49
Tagging-Datum : UTC 2016-02-03 08:01:32
colour_range : Limited
colour_primaries : BT.2020
transfer_characteristics : PQ
matrix_coefficients : BT.2020 non-constant
MasteringDisplay_ColorPrimaries : R: x=1.000000 y=1.000000, G: x=1.000000 y=1.000000, B: x=1.000000 y=1.000000, White point: x=1.000000 y=1.000000
MasteringDisplay_Luminance : min: 0.1000 cd/m2, max: 1 cd/m2
The only way I found to convert the Sony clip with FFmpeg with very good quality was to preencode it first to the final resolution using X264 lossless. The resulting file could be converted with hable tonemapping without any issues.
So I am still clueless why the original Sony clip could not be converted with hable tonemapping. There was no error message during the conversion, it was just that the result was borked.
Any ideas?
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.