View Full Version : How to do 3D Lut color correction (.3DL .Cube) with avisynth(+) ?
ErazorTT
7th August 2022, 19:22
I'm having a lut which when using ffmpeg produces the expected behaviour, but when using the cube function returns unexpected things.
The following image shows the result, on the right part there are these waves which are unexpected, and are also not there using ffmpeg.
https://i.postimg.cc/ykYZnHbn/v101-33-size.png (https://postimg.cc/ykYZnHbn)
However when using ffmpeg I'm getting this:
https://i.postimg.cc/tYSVMc0b/Grey-Ramp16bits-converted.png (https://postimg.cc/tYSVMc0b)
Here are all files I am using:
hlg_test.7z (https://cloud.rascanu.de/index.php/s/32eFwN5r3sDyBTy)
The command for ffmpeg is:
ffmpeg -i GreyRamp16bits.png -vf lut3d=lut_4000_3.0.cube -pix_fmt rgb48be GreyRamp16bits_converted.png
What is going on here, why the different results?
Reel.Deel
7th August 2022, 19:54
@ErazorTT
Does DGCube have the same problem? https://www.rationalqm.us/board/viewtopic.php?p=16092#p16092
poisondeathray
7th August 2022, 19:56
For reference, avs version , vpy version that it's based on , and Adobe get similar results
The difference is the default interpolation type for ffmpeg (tetrahedral) . Trilinear , pyramid, prism all produce the pattern to an extent
eg.
ffmpeg -i GreyRamp16bits.png -vf lut3d=lut_4000_3.0.cube:interp=trilinear -pix_fmt rgb48be GreyRamp16bits_converted_trilinear.png
tormento
8th August 2022, 11:50
Does DGCube have the same problem?
Is it working for you? What card? Drivers?
Reel.Deel
8th August 2022, 14:54
Is it working for you? What card? Drivers?
No, I am also getting access violation. I have not updated my drivers in a while so I was going to do that and see if it fixes the issue.
ErazorTT
8th August 2022, 16:38
For reference, avs version , vpy version that it's based on , and Adobe get similar results
The difference is the default interpolation type for ffmpeg (tetrahedral) . Trilinear , pyramid, prism all produce the pattern to an extent
eg.
ffmpeg -i GreyRamp16bits.png -vf lut3d=lut_4000_3.0.cube:interp=trilinear -pix_fmt rgb48be GreyRamp16bits_converted_trilinear.png
Oh that is a nice finding! So its the interpolation. Could this better interpolation be implemented into vscube (or DGCube for that matter)?
ErazorTT
8th August 2022, 16:50
@ErazorTT
Does DGCube have the same problem? https://www.rationalqm.us/board/viewtopic.php?p=16092#p16092
I just found that DGCube needs 65x65x65 sized LUTs, so I tried again with one of that size. And yes, DGCube behaves that same as vscube.
poisondeathray
8th August 2022, 17:46
Could this better interpolation be implemented into vscube (or DGCube for that matter)?
It's debatable if a certain interpolation is going to be "better" for all situations;
But having more options is always welcome
You can try submitting a feature request
https://github.com/sekrit-twc/timecube/issues
tormento
8th August 2022, 18:11
No, I am also getting access violation.
Generic size version has just been released.
tormento
10th August 2022, 16:07
Here is a new version supporting tetrahedral interpolation. It addresses ErazorTT's issue, as the artifacts do not occur with tetrahedral. Please read the new DGCube.txt file for details and be aware that the filter is now invoked as DGCube(). I'll add this to the timecube-derived Cube() filter as well. Also need to add Vapoursynth support to DGCube().
https://rationalqm.us/misc/DGCube.zip
tormento
19th August 2022, 12:40
Notice that in the latest version, no more avsresize is required and it got scorching fast.
ErazorTT
20th August 2022, 19:58
@tormento: Yup, this does now produce the intended results with these luts. Thanks!
tormento
20th August 2022, 22:48
Thanks!
Much better to thank the author. :)
Any bug report and testing is the most welcome.
kedautinh12
22nd August 2022, 14:50
https://rationalqm.us/misc/DGCube.zip
I wonder why don't DGCube have 2 ver x32 & x64
tormento
22nd August 2022, 17:37
I wonder why don't DGCube have 2 ver x32 & x64
'cause x86 is getting more and more useless, especially with 4k.
FranceBB
22nd August 2022, 18:05
Probably cause old x86 OS like my beloved XP don't really have drivers for modern NVIDIA GPUs so the DG plugins would have nowhere to run except for the old not so powerful NVIDIA GPUs... :(
I wish NVIDIA kept releasing drivers for XP x86 but it didn't happen, so nowadays I do most of my stuff via RDP from my XP to the remote Windows Server 2019 instance, especially after Tormento made me upgrade my stable Windows 10 Enterprise workstation to the unstable crap called Windows 11 Enterprise which one day upgraded itself only to end up blue screening in loop, thus making me lose every program installed.
tormento
22nd August 2022, 18:29
especially after Tormento made me upgrade my stable Windows 10 Enterprise workstation to the unstable crap called Windows 11 Enterprise which one day upgraded itself only to end up blue screening in loop, thus making me lose every program installed.
Oh, dear.
You use crappy hardware and you blame me. :D
Windows 11 Enterprise x64 here since day 1 (on Insider Channel too) and no major hiccups.
FranceBB
22nd August 2022, 18:35
Oh, dear.
You use crappy hardware
-> I'm broke, as simple as that xD
FranceBB
26th August 2022, 17:38
Hi there Donald,
currently it isn't possible to pick which kind of interpolation is used to produce the result in Cube() (I'm talking about the CPU version).
Would it be possible to introduce an option in Cube() like String Interpolation where it can have one of the following values Interpolation="Tricubic", Interpolation="Trilinear", Interpolation="Tetrahedral", where the default is Tetrahedral?
So I imagine the usage to be like:
Cube("myLUT.cube", fullrange=true, Interpolation="Tetrahedral")
The reason is that I'm currently dealing with a brand new BBC LUT for HLG to BT709 SDR.
I used to use the 8a, which performs clipping, but some majors want me to use the new 9c which works in Studio RGB (Limited TV Range) and preserves overshootings (so the BT709 will have out of range whites and blacks and it won't clip them).
The issue I have with it is that the interpolation Cube() is doing is different from the interpolation the major is using and they will therefore reject the result.
AVS Script:
LWLibavVideoSource("D:\4K_Ama\05_DI SERVIZIO - EBU UHD HDR COLOR BARS\EBU_HDR_COLOUR_BARS_2160p_v210.mov")
propClearAll()
#From 4:2:2 16bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:std-b67:2020:limited=>rgb:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)
#From HLG to BT709 with 16bit precision
Cube("A:\avdb\Server\encoder\encoder\Processors\avs_plugins\LUTs\9c_HLG_BT709_Type3_Display_DownMapping_SuperWhite_nocomp-v1_5.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV420 8bit planar Narrow Range with dithering
z_ConvertFormat(pixel_type="YUV420", colorspace_op="rgb:709:709:limited=>709:709:709:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)
Here's the result (Left interpolation done by Cube() - Right interpolation done by the major who's selling us the content):
https://i.imgur.com/hyky5sZ.png
Before you say "CUDA!" please note that our workflows are based on 100+ scalable VMs in the cloud that are shut down and only woken up when they need to perform a job and then they're shut down and they're CPU only, so we have no way to use CUDA other than on the legacy MAM on prem which will be discontinued soon-ish.
Thank you in advance,
Frank
kedautinh12
1st December 2022, 01:55
DGCube 22/09/30
https://rationalqm.us/misc/DGCube.zip
FranceBB
13th June 2023, 16:11
Hi Donald,
I've been trying DGCube() with a dual GPU configuration at work, however it only really seems to be using 1 GPU only.
Is there a way to make DGCube() use both GPUs?
Here's the script:
video=LWLibavVideoSource("A:\MEDIA\temp\Test.mxf")
FL_ORI=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=1)
FR_ORI=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=2)
CC_ORI=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=3)
LFE_ORI=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=4)
SL_ORI=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=5)
SR_ORI=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=6)
Left_ORI=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=7)
Right_ORI=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=8)
FL_ITA=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=9)
FR_ITA=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=10)
CC_ITA=LWLibavAudioSource("A:\MEDIA\temp\Testmxf", stream_index=11)
LFE_ITA=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=12)
SL_ITA=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=13)
SR_ITA=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=14)
Left_ITA=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=15)
Right_ITA=LWLibavAudioSource("A:\MEDIA\temp\Test.mxf", stream_index=16)
audio=MergeChannels(FL_ITA, FR_ITA, CC_ITA, LFE_ITA, SL_ITA, SR_ITA, Left_ITA, Right_ITA, FL_ORI, FR_ORI, CC_ORI, LFE_ORI, SL_ORI, SR_ORI, Left_ORI, Right_ORI)
AudioDub(video, audio)
propclearall()
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:std-b67:2020:limited=>rgb:std-b67:2020:full", resample_filter_uv="Spline64", dither_type="error_diffusion", use_props=0)
DGCube("HLG_to_BT709.cube", in="full", out="full", lut="full", interp="tetrahedral")
z_ConvertFormat(pixel_type="YUV422P10", colorspace_op="rgb:709:709:full=>709:709:709:limited", resample_filter_uv="Spline64", dither_type="error_diffusion", use_props=0)
however this is the result:
https://i.imgur.com/i2TWlcW.png
I know that I can get rid of z_ConvertFormat() on top and bottom and allow DGCube() to perform the YUV -> RGB -> YUV conversion to speed things up, however before I do that I wanna make sure that it's possible to use both GPUs at the same time.
poisondeathray
13th June 2023, 16:17
Is there a way to make DGCube() use both GPUs?
You can specify device # with DGCube
device: GPU device number to use. If device is 255 (default), then the GPU device will be automatically selected.
Untested, but maybe mp_pipeline to process 2 parallel processes (selecteven, selectodd), each with a different device #, then interleave(even,odd) . Or maybe you can do it without mp_pipeline, it might thread slower (or it might be faster)
poisondeathray
13th June 2023, 16:19
BTW teh donald does not post here anymore . You can post and ask in his forum too
tormento
2nd July 2023, 10:30
Added support to tethrahedral in VSCube.
kedautinh12
2nd July 2023, 17:01
DGCube 22/09/30
https://rationalqm.us/misc/DGCube.zip
But i still download old ver from here
FranceBB
2nd July 2023, 17:38
But i still download old ver from here
Not DGCube, VSCube.
As you can see from those commits here: https://github.com/sekrit-twc/timecube/commit/af682b6f7a5ad302bd59ab7e7a29312334be63ac the new tethrahedral interpolation version has been added, although it's not yet "official" 'cause it needs further testing.
Sekrit added it only as plain C code for debug reasons so that I could test it on Monday on my broadcast equipment.
If it works, he'll go on with writing the assembly / intrinsics to make use of AVX, AVX2, AVX512. After that, it will be time to update the old port with the new version, so AVSCube (i.e Cube() ).
If everything goes well, we'll have tetrahedral interpolation in Cube() in Avisynth along with VapourSynth.
Anyway the current plan for the week is:
- Test the current C only VapourSynth only implementation by Sekrit
- Report back if the results are par with what I expected on a Sony reference monitor + Tektronix Hardware Waveform Monitor
- Allow Sekrit to work on the SSE2, AVX, AVX2, AVX512 intrinsics / manually written assembly for VapourSynth
- Ask sekrit to merge the two projects (VSCube and AVSCube) so that they can coexist in the same repository so that next time they'll be updated at the same time
I'll keep you guys posted.
Bye,
Frank
FranceBB
4th July 2023, 09:28
In the meantime, in case people want to test, I've made a build with the latest changes from Sekrit (VapourSynth only, for now): vscube.zip (https://github.com/sekrit-twc/timecube/files/11946440/vscube.zip)
Inside the package you'll find the normal vscube_x86.dll and vscube_x64.dll compiled with v143 and of course the "special" v141_xp /Zc:threadSafeInit msvc compiled version called "_XP":
- vscube_x86.dll
- vscube_x64.dll
- vscube_XP_x86.dll
- vscube_XP_x64.dll
The idea is to test the new interpolation method with:
timecube.Cube(cube="Test.cube", fullrange=true, interp=1, cpu=0)
which is, hopefully, what I'm gonna do today.
tormento
4th July 2023, 10:47
I was chatting with FranceBB a few minutes ago and we noticed that NVEnc can apply 3D lut in tethraedral with hw acceleration.
I wrote a wake up call thread in development section, as an AVS plugin based on NVEnc would be awesome.
poisondeathray
4th July 2023, 14:59
In the meantime, in case people wants to test, I've made a build with the latest changes from Sekrit (VapourSynth only, for now): vscube.zip (https://github.com/sekrit-twc/timecube/files/11946440/vscube.zip)
Thanks.
I tried on ErazorTT's test in post 102.
The syntax is interp=<int>
0 Trilinear
1 Tetrahedral
Looks ok so far, Tetrahedral matches ffmpeg's output
tormento
4th July 2023, 19:02
Well. I did some tests applying SDR to HLG (1080p video) and PQ to HLG LUTs (2160p video). I tested with lossy compression as at the moment I don't have enough space to go HEVC lossless.
NVEncC (x64) 7.30 (r2572) by rigaya, Jun 24 2023 02:43:35 (VC 1929/Win)
OS Version Windows 11 x64 (25393) [UTF-8]
CPU Intel Core i7-2600K @ 3.40GHz [TB: 4.51GHz] (4C/8T)
GPU #0: NVIDIA GeForce GTX 1660 SUPER (1408 cores, 1830 MHz)[PCIe3x16][545.31]
NVENC / CUDA NVENC API 12.1, CUDA 12.2, schedule mode: auto
Input Buffers CUDA, 16 frames
Input Info AviSynth+ 3.7.3 r3996(yv12(16bit))->p010 [SSE2], 3840x2064, 24000/1001 fps
Width : 1920
Height : 1032
Frames : 5544
Time : 03:51.231
Framerate : 23.976023 (24000/1001)
Format : YUV420P8
NVEncC64.exe --cqp 18 --codec h265 --output-depth 10 --aq --aq-temporal --vpp-colorspace lut3d=D:\Programmi\Media\AviSynth+\cube\5a_BT709_HLG_UPCONVERT_DISPLAY_mode_nar_in_nar_out_nar_nocomp.cube,lut3d_interp=tetrahedral -i "N:\In\3_12 Avatar 2\avatar sdr to hlg_temp\avatar sdr to hlg.avs" -o "N:\In\3_12 Avatar 2\avatar sdr to hlg_temp\avatar sdr to hlg_out.h265"
encoded 5544 frames, 160.65 fps, 18601.23 kbps, 512.74 MB
Width : 3840
Height : 2064
Frames : 5544
Time : 03:51.231
Framerate : 23.976023 (24000/1001)
Format : YUV420P16
NVEncC64.exe --cqp 18 --codec h265 --output-depth 10 --aq --aq-temporal --vpp-colorspace lut3d=D:\Programmi\Media\AviSynth+\cube\1a_PQ1000_HLG_mode-nar_in-nar_out-nar_nocomp.cube,lut3d_interp=tetrahedral -i "N:\In\3_12 Avatar 2H\HDR10 to HLG_temp\HDR10 to HLG.avs" -o "N:\In\3_12 Avatar 2H\HDR10 to HLG_temp\HDR10 to HLG_out.h265"
encoded 5544 frames, 42.90 fps, 57277.81 kbps, 1578.86 MB
I haven't yet set the correct color spaces and ranges but it seems to work fine. I have yet to try to feed video directly to NVEnc, bypassing any frameserver.
So curious to see the numbers from modern cards.
FranceBB
4th July 2023, 20:14
it seems to work fine
Indeed, in your HLG sample converted from BT709 SDR with the NVEnc lut3d filter using tetrahedral interpolation and the 5a LUT the black was sitting at 0.0V and the white was correctly peaking at 0.52V as per HLG standard of 75% reference white.
https://i.imgur.com/42Gdvnc.png
It was peaking lower when you converted from PQ with the 1a LUT, but that's only because such a LUT assumes a source at 1000 nits, however your PQ version of Avatar 2 was made straight out of the DCI P3 XYZ MJPEG2000 4:4:4 12bit cinema master whose reference white is at 48 (so the actual PQ MaxCLL is actually much lower than what was specified in the metadata). This won't result in a wrong output, though, however it will be a slightly worse experience for those watching the BT2020 HLG version on a BT2020 SDR 100 nits display.
https://i.imgur.com/310Dzva.png
tormento
4th July 2023, 23:42
This won't result in a wrong output, though, however it will be a slightly worse experience for those watching the BT2020 HLG version on a BT2020 SDR 100 nits display.
Any way to "expand" somehow that lower nit value?
If there is no need any headroom for superwhites - simple ColorYUV() can be added as some gain to Y to reach the required white level at SDR.
tormento
5th July 2023, 09:05
If there is no need any headroom for superwhites - simple ColorYUV() can be added as some gain to Y to reach the required white level at SDR.
Please elaborate with some examples. How and how much should I apply?
For example using Videotek tool look at the white peaks level - add Y gain (ColorYUV gain_y >1) so white peaks reach 0.7V (nominal white SDR). Select scene with most powerful white peaks.
Or simply use master control monitor and adjust Y gain so that no whites reach clipping.
FranceBB
5th July 2023, 14:06
Also please keep in mind that such a thing is fine for SDR. If you're on HLG, you shouldn't exceed 0.52V for the white while you expand.
Compressing and expanding is the besting thing ever, though, so you could use HLG Tools (https://github.com/wswartzendruber/hlg-tools) to generate a specific LUT for that very MaxCLL + reference white. https://forum.doom9.org/showthread.php?t=182499
For Avatar 2, something like:
pq2hlg --max-cll 280 --ref-white 48 --size 64 avatar2.cube
should achieve a pretty decent result, but you can ask William and I'm sure he'll help you. ;)
May be already exist some PC software simulators of AUTO KNEE function of cameras ? So using HDR source user can get best SDR possible with good enough compressed superwhites as it possible with real hardware good quality SDR camera. Though it is not linear transform as LUT but in best case adaptive per-scene highlight compression engine.
So again 4K/(4K+) HDR footage may be treated as RAW source to master HD SDR footage using offline software tools. Realtime AUTO KNEE can not analyse full future scene and offline software can. So offline AUTO KNEE expected to be better it its robotic activity. And users will not be limited with static HDR to SDR LUT-based or static math-based transforms.
FranceBB
5th July 2023, 23:52
Though it is not linear transform as LUT but in best case adaptive per-scene highlight compression engine.
yep, we talked about this in 2021 and it is possible, but only with libplacebo I'm afraid as there's nothing else that provides dynamic scene-based tonemapping according to a tweakable threshold.
What I had in mind in 2021 was tonemapping on a scene by scene basis by using the HDR Compute Peak, the HDR Peak Decay Rate and the HDR Scene Threshold parameters.
Those three parameters aren't coming out of the blue, but rather they're what MPV is using already (and has been for years):
--hdr-compute-peak=<auto|yes|no>
Compute the HDR peak and frame average brightness per-frame instead of relying on tagged metadata. These values are averaged over local regions as well as over several frames to prevent the value from jittering around too much. This option basically gives you dynamic, per-scene tone mapping.
--hdr-peak-decay-rate=<1.0..1000.0>
The decay rate used for the HDR peak detection algorithm (default: 100.0). This is only relevant when --hdr-compute-peak is enabled. Higher values make the peak decay more slowly, leading to more stable values at the cost of more "eye adaptation"-like effects (although this is mitigated somewhat by --hdr-scene-threshold). A value of 1.0 (the lowest possible) disables all averaging, meaning each frame's value is used directly as measured, but doing this is not recommended for "noisy" sources since it may lead to excessive flicker. (In signal theory terms, this controls the time constant "tau" of an IIR low pass filter)
--hdr-scene-threshold-low=<0.0..100.0>, --hdr-scene-threshold-high=<0.0..100.0>
The lower and upper thresholds (in dB) for a brightness difference to be considered a scene change (default: 5.5 low, 10.0 high). This is only relevant when --hdr-compute-peak is enabled. Normally, small fluctuations in the frame brightness are compensated for by the peak averaging mechanism, but for large jumps in the brightness this can result in the frame remaining too bright or too dark for up to several seconds, depending on the value of --hdr-peak-decay-rate.
" These values are averaged over local regions as well as over several frames to prevent the value from jittering around too much. "
The words 'several frames' looks too scary. The cutscene duration may take > 10 seconds. It looks it is not full offline scene analysis but only some decode-ahead realtime playback engine. If decoding too much frames to make real full cutscene analysis takes too much RAM (in 4K and larger) - it can be simple 2-pass engine with collecting all peaks data from footage at 1st pass and making per-scene adjustment at second pass.
FranceBB
6th July 2023, 12:14
The words 'several frames' looks too scary. The cutscene duration may take > 10 seconds. It looks it is not full offline scene analysis but only some decode-ahead realtime playback engine.
Yeah... they have some kind of limited lookahead but they certainly don't go over the whole file at once.
If decoding too much frames to make real full cutscene analysis takes too much RAM (in 4K and larger) - it can be simple 2-pass engine with collecting all peaks data from footage at 1st pass and making per-scene adjustment at second pass.
That's a very good idea and it's close to what I'm already doing.
Even though I'm just applying a static LUT, when a provider doesn't send the MaxCLL value for a PQ content, I use a two step approach in which Avisynth goes through the whole file saving the info about the MaxCLL of each frame 'till the end, then my logic gets rid of outliers (and potential compression overshooting errors) and then gets the output to populate the MaxCLL value and apply the right LUT. For instance, if a content is 4322 nits, it will use the PQ_to_BT709_4322.cube so that 4322 nits will become 100.
Of course this is all just with a static LUT, but given that I'm already "wasting" time with a first pass + second pass, I wouldn't really mind if this led to a glorious scene-aware tonemapping.
I tried to talk about this to Jean Philippe back in the days, but he was pretty busy back then and he's still pretty busy right now, just like everyone else (me included, unfortunately :( ), so he didn't really have time to look at this, but ideally this is something that should be implemented in HDR Tools.
Anyway, even with the current static methods we have today, we're not getting terrible results, so we somehow managed to live 'till 2023 without dynamic scene-aware tonemapping and I can keep living without it, but yeah, it would be nice to have, one day, in the future. :)
FranceBB
7th July 2023, 08:56
Hi everyone,
as a little update, sekrit made a new commit here: https://github.com/sekrit-twc/timecube/commit/5f34d7a061b8898707594a5ef84dfd3e75216741
in which he committed the manually written intrinsics in assembly for SSE4.1, AVX2 and AVX512, so that the new tetrahedral interpolation method is no longer limited to the slow C++ code only.
I tested it on my Intel Xeon Gold 6238R and it seems to be working ok, but please test, 'cause the more feedback we can give him, the better. :)
Here's the new build I made with sekrit's latest changes: vscube_07072023.zip (https://github.com/sekrit-twc/timecube/files/11977404/vscube_07072023.zip)
just like before, inside the package you'll find the normal vscube_x86.dll and vscube_x64.dll compiled with v143 and of course the "special" v141_xp /Zc:threadSafeInit msvc compiled version called "_XP":
- vscube_x86.dll
- vscube_x64.dll
- vscube_XP_x86.dll
- vscube_XP_x64.dll
It's still VapourSynth only, for now, but you can see the development of the thread here (https://github.com/sekrit-twc/timecube/issues/8) and that sekrit is willing to incorporate the Avisynth version into the main repository as soon as someone (perhaps Donald, who also commented on the thread) commits the latest changes required. Anyway, looks like we're finally getting somewhere. :)
Please test and report back if you find any issues.
kedautinh12
7th July 2023, 09:38
Very pleasure if you port it to avs+ :D
FranceBB
7th July 2023, 12:25
Very pleasure if you port it to avs+ :D
If you're talking to Donald, I'm not sure he regularly checks here, so it might take a while before he sees your post; I was under the impression that he was willing to do it just like the other versions, though, but I'm not him, so I don't know what his intentions are.
If you're talking to me, instead, well, if and only if no one is willing to do it, then I'll try to do it myself ('cause I don't wanna have two people doing the same thing twice xD).
We'll see, but it would be better if everyone was here on Doom9 regularly, so that we didn't have to speculate :(
gonca
8th July 2023, 20:14
I believe he has a test version ready
FranceBB
8th July 2023, 22:04
I believe he has a test version ready
You're correct. Donald just released an Avisynth test version: Link (https://rationalqm.us/misc/AVSCube_test.rar)
I'll test it on Monday morning as soon as I get back to work and see if the results are consistent with the VapourSynth version.
The new syntax accepts:
interp: int, 0 = linear, 1 = tetrahedral
like in the VapourSynth version.
By the way, this is applied to a real life football content to go from UHD XAVC Intra Class 300 50p BT2020 HLG 1000 nits to an FULL HD XDCAM-50 25i BT709 SDR 100 nits:
#Indexing UHD 50p BT2020 HLG 1000 nits live feed
LWLibavVideoSource("Test_HLG.mxf")
#Screw frame properties
propclearall()
#From 4:2:2 10bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:std-b67:2020:limited=>rgb:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion",
use_props=0)
#From HLG to BT709 with 16bit precision
Cube("A:\LUTs\9c_HLG_BT709_Type3_Display_DownMapping_SuperWhite_nocomp-v1_5.cube", interp=1, fullrange=1)
#From RGB 16bit planar Narrow Range to YUV422 8bit planar Narrow Range with dithering
z_ConvertFormat(pixel_type="YUV422", colorspace_op="rgb:709:709:limited=>709:709:709:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)
#Downscaling to FULL HD
SinPowResizeMT(1920, 1080)
#Interlace to 25i
assumeTFF()
separatefields()
selectevery(4,0,3)
weave()
if tests go fine, I'll report back.
Speaking of which, I hope he'll release the source code given that I'll compile the x86 version as well to include it in FFAStrans (https://forum.doom9.org/showthread.php?t=176655) as I have to support both 64bit and 32bit users as always ;)
kedautinh12
9th July 2023, 00:15
Latest DGCube
https://www.rationalqm.us/misc/?C=M;O=D
FranceBB
11th July 2023, 17:01
Something doesn't feel right.
LWLibavVideoSource("K:\4K_Ama\05_DI SERVIZIO - EBU UHD HDR COLOR BARS\EBU_HDR_COLOUR_BARS_2160p_v210.mov")
propClearAll()
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:std-b67:2020:limited=>rgb:std-b67:2020:limited", resample_filter_uv="Spline64", dither_type="error_diffusion", use_props=0)
tetrahedral=Cube("B:\avdb\Server\encoder\encoder\Processors\avs_plugins\LUTs\9c_HLG_BT709_Type3_Display_DownMapping_SuperWhite_nocomp-v1_5.cube", interp=1, fullrange=1).VideoTek()
trilinear=Cube("B:\avdb\Server\encoder\encoder\Processors\avs_plugins\LUTs\9c_HLG_BT709_Type3_Display_DownMapping_SuperWhite_nocomp-v1_5.cube", interp=0, fullrange=1).VideoTek()
donald=DGCube("B:\avdb\Server\encoder\encoder\Processors\avs_plugins\LUTs\9c_HLG_BT709_Type3_Display_DownMapping_SuperWhite_nocomp-v1_5.cube", in="full", out="full", lut="full", interp="tetrahedral").VideoTek()
StackVertical(trilinear, tetrahedral, donald)
They produce three VERY different results.
https://user-images.githubusercontent.com/18946343/252718564-6cc33ab9-bffc-4dd7-8a57-a1636488c8b5.png
What I don't understand is why Cube() tetrahedral and DGCube() tetrahedral are so much different.
Souce: https://we.tl/t-xqG6XosULK
Cube_Tetrahedral: https://we.tl/t-GLjsVvJ6Ad
DGCube_Tetrahedral: https://we.tl/t-5L8KCVRfmg
Cube_Trilinear: https://we.tl/t-iBhR03kbFP
FranceBB
11th July 2023, 17:09
Also, DGCube with Tetrahedral is actually the one that gets it right.
In the Cube version, however, it looks like a bit of both versions is applied. You can see the ripples of the trilinear and also the smoothness of the tetrahedral. Why?
Cube Trilinear (rightly showing ripples):
https://user-images.githubusercontent.com/18946343/252724560-114173bd-d2a6-4c1f-9fe4-e7fe04cdc2af.png
DGCube Tetrahedral (no ripples, actually correct):
https://user-images.githubusercontent.com/18946343/252724797-2b7fda60-c6a9-44de-9875-063610838967.png
Cube Tetrahedral (something in-between, NOT correct):
https://user-images.githubusercontent.com/18946343/252724954-6e1a6f5e-d075-4089-94fa-19452abee4e9.png
Cube Tetrahedral is something in between...? O_O
poisondeathray
11th July 2023, 17:18
Do you get the same results with the vpy vscube version ?
FranceBB
11th July 2023, 18:42
@poisondeathray I found the culprit. It's the manually written assembly code for AVX2. I reported it back to both Donald and Sekrit.
The normal C++ code is actually correct.
https://user-images.githubusercontent.com/18946343/252745440-f84911cc-7ea4-43ff-be50-f807ac813d83.png
The SSE4.1 assembly code is also correct.
https://user-images.githubusercontent.com/18946343/252745542-dedb44eb-04da-42b2-9416-c5970c31690d.png
The AVX2 assembly code is wrong.
https://user-images.githubusercontent.com/18946343/252745656-13b452db-b2bf-48dc-afb7-36304615360a.png
The AVX512 assembly code is correct.
https://user-images.githubusercontent.com/18946343/252745744-c4833162-f814-4a6f-84ac-1640bc4ea382.png
So it looks like there's something wrong only in the AVX2 code.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.