View Full Version : z.lib resizers for AviSynth+
Stephen R. Savage
29th October 2016, 21:23
z_ConvertFormat(
clip clip,
int "width",
int "height",
str "pixel_type",
str "colorspace_op",
str "chromaloc_op",
bool "interlaced",
float "src_left",
float "src_top",
float "src_width",
float "src_height",
str "resample_filter",
float "filter_param_a",
float "filter_param_b",
str "resample_filter_uv",
float "filter_param_a_uv",
float "filter_param_b_uv",
str "dither_type")
width: output width in pixels
height: output height in pixels
pixel_type: output pixel type ("YV12", "YUV420P16", etc.)
colorspace_op: colorspace operation description
Format is
"matS[:transS[:primS[:rangeS]]]=>matD[:transD[:primD[:rangeD]]]"
Example JPEG to MPEG: "170m:709:709:f=>709:709:709:l"
chromaloc_op: chroma location operation description
Format is "[locS]=>[locD]"
Example JPEG to MPEG2: "center=>left"
interlaced: whether to use interlaced mode (default: false)
resample_filter: resampling mode
filter_param_a: first parameter to resampler
filter_param_b: second parameter to resampler
Example Bicubic (Mitchell-Netravali):
resample_filter="bicubic", filter_param_a=0.333, filter_param_b=0.333
Example 4-tap Lanczos: resample_filter="lanczos", filter_param_a=4
resample_filter_uv: resampling mode for chroma
filter_param_a_uv: first parameter to chroma resampler
filter_param_b_uv: second parameter to chroma resampler
dither_type: dithering type
See VapourSynth documentation for valid string constants.
Also has all the AviSynth resizers, but with "z_" prefix.
Download: r2 (https://www.sendspace.com/file/h4lmxg)
Reel.Deel
30th October 2016, 14:43
Thanks twc, are you planning on adding support for colorspace and bit depth conversions?
pinterf
4th November 2016, 10:44
Thanks, I will look try it later it when I have time, just looked at the source.
A remark: Planar RGB plane order is PLANAR_G, PLANAR_B, PLANAR_R
Question: AVS+ default alignment is 32. Is the 64 byte alignment is a requirement for zimg?
wonkey_monkey
6th November 2016, 01:20
Just curious, but what does "z.lib" refer to in this context? It's too close to zlib to Google for it...
Reel.Deel
6th November 2016, 01:46
Just curious, but what does "z.lib" refer to in this context? It's too close to zlib to Google for it...
See here: https://github.com/sekrit-twc/zimg#zlib
TheFluff
6th November 2016, 02:02
I'm pretty sure he named it that just to be obnoxious. It's what he does.
filler56789
6th November 2016, 03:04
I'm pretty sure he named it that just to be obnoxious. It's what he does.
lol LoL LOL
http://forum.videohelp.com/attachments/37296-1465229588/003.jpeg http://forum.videohelp.com/attachments/37295-1465229580/002.jpeg http://forum.videohelp.com/attachments/37302-1465229635/009.jpeg
MysteryX
6th November 2016, 08:37
Does this provide 16-bit support for AviSynth+?
Sparktank
15th December 2017, 11:39
Any updates on this?
Sparktank
29th December 2017, 09:23
Is there any update needed?
I wouldn't know if it needs updating or not, so I was asking.
Sparktank
14th January 2018, 21:04
Does any of this have to do with Zimg?
Zimg is getting a lot of updates.
And the documentation for this is lazy. I find things better looking at source code.
ZIMG is getting a lot of updates. This isn't getting anything.
https://github.com/sekrit-twc/zimg
Would it be better to ask Pinterf to make a port? Or even cretindesalpes?
Open source is nice. But only for those who know what it means.
Why is ZIMG getting more updates than this very small port?
The doc really says nothing. I only learn from looking at the source code and guessing.
Does the AVS+ port mean nothing?
I'll stick to Dither_tools until AVS+ really improves on these functions.
TheFluff
14th January 2018, 21:20
It's an Avisynth plugin that uses the zimg resizers, yes, but since nobody seemed interested in it I doubt it'll ever get updated again. Just use the Vapoursynth version instead; there's no reason to use Avisynth anymore since the new avsproxy plugin (https://forum.doom9.org/showthread.php?t=175141) lets you load even ancient no-source 32-bit Avisynth plugins in a 64-bit Vapoursynth process, or run Avisynth scripts if that's a thing you need.
real.finder
16th January 2018, 02:39
It's an Avisynth plugin that uses the zimg resizers, yes, but since nobody seemed interested in it I doubt it'll ever get updated again. Just use the Vapoursynth version instead; there's no reason to use Avisynth anymore since the new avsproxy plugin (https://forum.doom9.org/showthread.php?t=175141) lets you load even ancient no-source 32-bit Avisynth plugins in a 64-bit Vapoursynth process, or run Avisynth scripts if that's a thing you need.
what is the difference between avsproxy and MP_Pipeline?
edcrfv94
16th January 2018, 14:33
what is the difference between avsproxy and MP_Pipeline?
MP_Pipeline can not export clip to VapourSynth and pass it back.
Stephen R. Savage
27th January 2018, 23:41
Since it came up in the main AviSynth+ thread, I updated the first post with a new build. It has an updated version of z.lib.
pinterf
28th January 2018, 18:51
Since it came up in the main AviSynth+ thread, I updated the first post with a new build. It has an updated version of z.lib.
Speedwise much better on my i7-7770. I guess it's really not much time is spent in resizers in complex scripts but I definitely like the art of optimization.
pinterf
31st January 2018, 10:57
Something strange happens.
When resizing vertically performance suddenly drops at delta=256.
Using avsresize r1b, x64, Intel i7-7700, current dev avs+ x64
w = 1920
h = 1920
BlankClip(width=w, height=h, length=8000, pixel_type = "YUV444P8")
#z_Spline64Resize(w,h+255) # 192.5 fps
z_Spline64Resize(w,h+256) #30 fps
Stephen R. Savage
31st January 2018, 17:48
You managed to find an obscure bug in z.lib. I updated first post with a new build (z.lib 2.7.3).
videoh
19th March 2018, 16:35
These conversions seem extremely slow compared to the Vapoursynth core equivalents. Really, it is too slow to be usable. Here is the script:
dgsource("THE GREAT WALL.dgi",fulldepth=true)
z_ConvertFormat(pixel_type="RGBPS",colorspace_op="2020ncl:st2084:2020:l=>rgb:linear:2020:l", dither_type="none")
#tonemap()
z_ConvertFormat(pixel_type="YUV420P16",colorspace_op="rgb:linear:2020:l=>709:709:709:l",dither_type="ordered")
prefetch(8)
For a typical clip, this takes 45 seconds while the corresponding Vapoursynth script takes 13 seconds.
Is there any way to speed things up or do we have to declare Avisynth+ dead for things like this?
MAGA (Make Avisynth Great Again)
pinterf
19th March 2018, 16:53
These conversions seem extremely slow compared to the Vapoursynth core equivalents. Really, it is too slow to be usable. Here is the script:
dgsource("THE GREAT WALL.dgi",fulldepth=true)
z_ConvertFormat(pixel_type="RGBPS",colorspace_op="2020ncl:st2084:2020:l=>rgb:linear:2020:l", dither_type="none")
#tonemap()
z_ConvertFormat(pixel_type="YUV420P16",colorspace_op="rgb:linear:2020:l=>709:709:709:l",dither_type="ordered")
prefetch(8)
For a typical clip, this takes 45 seconds while the corresponding Vapoursynth script takes 13 seconds.
Is there any way to speed things up or do we have to declare Avisynth+ dead for things like this?
MAGA (Make Avisynth Great Again)
The functions - I think - are not autoregistering their MT modes for Avs+. Try using SetFilterMTMode avs+ function, probably they are MT_NICE_FILTER compatible but at least good for MT_MULTI_INSTANCE.
videoh
19th March 2018, 17:31
Thanks for your reply.
MT_NICE_FILTER crashes, and MT_MULTI_INSTANCE is as slow as not declaring the mode.
videoh
20th March 2018, 15:38
zimg is used in Vapoursynth so we can't blame this on zimg. Is it just the case that Avisynth+ multithreading is terminally deficient? Or is there some heavy penalty for not having the resizing in the core? Or both? If anyone cares about Avisynth+ there will have to be an answer and resolution.
pinterf
20th March 2018, 16:37
Try eliminating dgsource for speed tests.
videoh
20th March 2018, 16:50
Huh? The same DGSource() executable is used for both Avisynth+ and Vapoursynth testing.
Vapoursynth: 13 seconds
Avisynth+ with z.lib: 45 seconds
pinterf
20th March 2018, 17:20
I was asking you for benchmarks w/o dgsource (e.g. using a BlankClip instead) because Avisynth+ runs source filters in MT_SERIALIZED mode.
I don't know how it works in VapourSynth but that can be a difference, which could be eliminated by omitting source filter.
When a source filter would benefit from a specific MT mode, you have to set it for that specific filter manually. It would show then that DgSource with MT_SERIALIZED mode is bottleneck or not.
videoh
20th March 2018, 17:27
DGSource runs fine in MT_MULTI_INSTANCE but it makes no difference. I'll try with blank clip.
DJATOM
20th March 2018, 17:31
DGSource is actually handled as source filter inside VS's avisynth wrapper: https://github.com/vapoursynth/vapoursynth/blob/master/src/avisynth/avisynth_compat.cpp#L378, so it should not be a bottleneck for tests.
videoh
20th March 2018, 17:53
With BlankClip (specifying 10000 frames at 1000 fps and playing in VirtualDub2, just the format conversions):
Vapoursynth 14 sec
Avisynth+ 22 sec
The difference is not as large but is still quite significant. So there is a pure penalty in the conversions and another penalty in the handling of the source filter.
Setting DGSource MT_NICE_FILTER or MT_MULTI_INSTANCE makes no difference (DGSource is actually thread safe and CUVID supports multiple instances). So why does Vapoursynth apparently not suffer these penalties while Avisynth+ does? I tried a large value in SetMemoryMax() but again it made no difference.
Don't get me wrong; I've been a stalwart supporter of Avisynth(+) since year 2000 and have greatly appreciated your efforts along with everyone else. I just want to be able to continue using it in the UHD world.
MAGA (Make Avisynth Great Again)
jpsdr
20th March 2018, 18:02
Are the speed test results from playing the same avs script in Avs+ and Vapoursynth, or, is it the avs script using z.lib vs Vapoursynth using internal conversion ?
If it's the second case, one possible explaination would be that the conversion is just faster in Vapoursynth than z.lib.
You're not alone thinking z.lib conversion is slow, also here (https://forum.doom9.org/showthread.php?t=175279).
videoh
20th March 2018, 18:19
Interesting, thanks for that confirmation.
It's the second case, of course. But avsresize (z.lib) is basically just a wrapper around zimg, and zimg is used by Vapoursynth. The difference I guess is in invoking it in the core versus an external filter. Hopefully pinterf can shed some light on things for us. zimg could be added to the Avisynth+ core. Things take time, it's not a surprise.
Myrsloik
20th March 2018, 20:03
Interesting, thanks for that confirmation.
It's the second case, of course. But avsresize (z.lib) is basically just a wrapper around zimg, and zimg is used by Vapoursynth. The difference I guess is in invoking it in the core versus an external filter. Hopefully pinterf can shed some light on things for us. zimg could be added to the Avisynth+ core. Things take time, it's not a surprise.
Nope, no "core" magic there. It's just an internal plugin and nothing more. No secrets.
videoh
20th March 2018, 20:23
Seems that Avisynth has reached end of life, but what do I know?
jpsdr
20th March 2018, 21:23
Is the actual build of z.lib up to date with the zimg version ? Does Vapoursynth and this z.lib use the same zimg version ?
videoh
20th March 2018, 21:35
I rebuilt avsresize with the the latest version of zimg:
https://github.com/sekrit-twc/zimg
poisondeathray
20th March 2018, 22:53
Were those observations based on your rebuilt avsresize, or "avsresize-r1c" provided in the 1st post ? or same results ?
real.finder
20th March 2018, 23:15
Seems that Avisynth has reached end of life, but what do I know?
you say that just because one filter run faster in vs?! there are another cases that avs is faster like https://github.com/Khanattila/KNLMeansCL/wiki/Benchmark
I think there are something in avsresize dll that case that slowness
gonca
20th March 2018, 23:52
Apart from the fact that the benchmark is for 1080p, and not 4K as is being discussed, it actually shows that vpy can handle formats, channels and precisions that avs can't
videoh
21st March 2018, 02:35
Were those observations based on your rebuilt avsresize, or "avsresize-r1c" provided in the 1st post ? or same results ? Results are the same for both.
poisondeathray
21st March 2018, 07:00
How about avsmeter diagnostics ? changing prefetch values ? - check memory / cpu usage etc... is "prefetch(8)" the "best" number in that situation ? Personally I like the auto threading of vpy better.
Can you double check some other measurement tools? maybe vspipe to ffmpeg, vs. avs to ffmpeg for example .
I'll try to compare some other operations in avs vs. vpy tomorrow for z.lib/zimg , if sekrit-twc / s.savage doesn't post by then
pinterf
21st March 2018, 09:25
With BlankClip (specifying 10000 frames at 1000 fps and playing in VirtualDub2, just the format conversions):
Vapoursynth 14 sec
Avisynth+ 22 sec
The difference is not as large but is still quite significant. So there is a pure penalty in the conversions and another penalty in the handling of the source filter.
Setting DGSource MT_NICE_FILTER or MT_MULTI_INSTANCE makes no difference (DGSource is actually thread safe and CUVID supports multiple instances). So why does Vapoursynth apparently not suffer these penalties while Avisynth+ does? I tried a large value in SetMemoryMax() but again it made no difference.
Don't get me wrong; I've been a stalwart supporter of Avisynth(+) since year 2000 and have greatly appreciated your efforts along with everyone else. I just want to be able to continue using it in the UHD world.
MAGA (Make Avisynth Great Again)
Thanks, the difference is still big, worth investigating when I have time.
videoh
21st March 2018, 10:29
No comment on the source filter handling penalty? That appears more serious than the avsresize slowness.
videoh
21st March 2018, 12:46
How about avsmeter diagnostics ? Can't work with Vapoursynth, so comparison would not be possible.
changing prefetch values ? - check memory / cpu usage etc... is "prefetch(8)" the "best" number in that situation ? Personally I like the auto threading of vpy better. Prefetch 4 or 8 made no difference. Anyway, if users are forced to tweak things like this then it is just braindead, IMHO.
Can you double check some other measurement tools? maybe vspipe to ffmpeg, vs. avs to ffmpeg for example . Never used those and don't see the relevance.
videoh
21st March 2018, 12:59
I want to demonstrate the source filter handling penalty of Avisynth+. Recall that the same DGSource executable is used by both Vapoursynth and Avisynth+. Here are the two scripts:
Vapoursynth:
import vapoursynth as vs
core = vs.get_core()
core.avs.LoadPlugin(path="D:/Don/Programming/C++/DGDecNV/DGDecodeNV/x64/release/DGDecodeNV.dll")
video = core.avs.DGSource('THE GREAT WALL.dgi',fulldepth=True)
video=core.std.AssumeFPS(video,fpsnum=1000, fpsden=1)
video.set_output()
Avisynth+:
loadplugin("d:\don\Programming\C++\dgdecnv\DGDecodeNV\x64\release\dgdecodenv.dll")
SetFilterMTMode("DGSource", MT_MULTI_INSTANCE)
dgsource("THE GREAT WALL.dgi",fulldepth=true)
assumefps(1000.0)
prefetch(8)
Results playing in VirtualDub2:
Vapoursynth: 6 seconds
Avisynth+: 12 seconds
If I remove the prefetch then Avisynth+ finishes in 7 seconds. But that will disable multithreading for anything else in the script.
This together with the inefficient conversions makes Avisynth+ unusable for me. I remind of the overall result for the simple process of tonemapping a UHD stream:
Vapoursynth: 13 seconds
Avisynth+ with avsresize: 45 seconds
Which one do you think a sensible person would use?
TheFluff
21st March 2018, 16:55
As much as I approve of demonstrating the superiority of Vapoursynth, I really don't think setting a source filter to MT_MULTI_INSTANCE is a good idea. MT_SERIALIZED forces everything upstream of the filter to be synchronous and single threaded, but source filters have no upstream so it doesn't matter. VS source filters tend to be serial in nature too.
Stephen R. Savage
21st March 2018, 16:56
It is because the avsresize was never tested with gamma function operations. It is missing this statement from the VS z.lib filter that enables certain speed-ups:
vsresize.cpp:L683: m_params.allow_approximate_gamma = 1;
videoh
21st March 2018, 16:59
As much as I approve of demonstrating the superiority of Vapoursynth, I really don't think setting a source filter to MT_MULTI_INSTANCE is a good idea. MT_SERIALIZED forces everything upstream of the filter to be synchronous and single threaded, but source filters have no upstream so it doesn't matter. VS source filters tend to be serial in nature too. I'm sure you're right, but the setting doesn't seem to have any effect at all. I'm not familiar with Vapoursynth internals. ;)
poisondeathray
21st March 2018, 17:01
You would expect prefetch(2) should be faster in that script
For the src filter threading issue, it did not affect the old avisynth(-) mt (at least no reports as bad as this) - what is different about the threading model here in avisynth(+) ?
videoh
21st March 2018, 17:01
It is because the avsresize was never tested with gamma function operations. It is missing this statement from the VS z.lib filter that enables certain speed-ups:
vsresize.cpp:L683: m_params.allow_approximate_gamma = 1;
Thanks, I will try adding that. Of course, that may remove one penalty but not the source filter penalty.
videoh
21st March 2018, 17:14
It is because the avsresize was never tested with gamma function operations. It is missing this statement from the VS z.lib filter that enables certain speed-ups:
vsresize.cpp:L683: m_params.allow_approximate_gamma = 1;
Bravo Stephen! With that change, avsresize performance is the same as Vapoursynth. Will you release an update with this change?
Now let's try to figure out the second issue.
poisondeathray
21st March 2018, 17:23
For the src filter issue - it doesn't appear to be a GPU latency /transfer issue, because avs+ prefetch(4) incurs no significant penalty with dss/dss2 cuvid
videoh
21st March 2018, 17:24
You would expect prefetch(2) should be faster in that script
For the src filter threading issue, it did not affect the old avisynth(-) mt (at least no reports as bad as this) - what is different about the threading model here in avisynth(+) ? I ran the entire HDR->SDR process again with the avsresize fix. Here is the script:
loadplugin("d:\don\Programming\C++\dgdecnv\DGDecodeNV\x64\release\dgdecodenv.dll")
loadplugin("D:\Don\Programming\C++\Avisynth filters\ToneMap float\x64\release\tonemap.dll")
loadplugin("D:\Don\Programming\C++\avsresize-r1c\x64\release\avsresize.dll")
SetFilterMTMode("z_ConvertFormat", MT_MULTI_INSTANCE)
dgsource("THE GREAT WALL.dgi",fulldepth=true)
z_ConvertFormat(pixel_type="RGBPS",colorspace_op="2020ncl:st2084:2020:l=>rgb:linear:2020:l", dither_type="none")
tonemap()
z_ConvertFormat(pixel_type="YV12",colorspace_op="rgb:linear:2020:l=>709:709:709:l",dither_type="ordered")
prefetch(2)
The overall performance is now the same as Vapoursynth!
The prefetch number didn't affect the timing but value 2 made things smooth and 8 made it go in stops and starts.
So, hey, Avisynth+ lives on. :eek: but :)
videoh
21st March 2018, 17:32
I'll release an Avisynth+ port of Phillip Blucas's tonemap filter within a few days (with some performance improvements). Then there will be a full HDR->SDR solution for Avisynth+.
It's close to being realtime for UHD (22fps on my machine) when playing in VirtualDub2. It would be nice if we could squeeze a little more performance out of zimg (or port equivalent conversions to CUDA).
Sharc
21st March 2018, 17:38
so, hey, avisynth+ lives on. :eek: But :)
oh happy day :)
TheFluff
21st March 2018, 17:49
Setting the source filter to MT_MULTI_INSTANCE with prefetch(2) is functionally much like doing something like
src1 = dgsource("file.dgi")
src2 = dgsource("file.dgi")
interleave(src1.selecteven(), src2.selectodd())
So if you have too many instances you'll start trashing the disk because you'll have many threads reading from the same file. Depending on the filter chain, it may or may not be beneficial to do this. You'll get as many instances as you have threads whether you want to or not. On the other hand if the source filter is MT_SERIALIZED there'll only be one instance of it and it'll only process one frame request at a time, but other filters that are requesting frames from it may run in parallel in various ways. The requesting thread will always block and wait for the request to complete though because that's just how the API is designed.
In VS, all Avisynth filters are always run single threaded and in a single instance, but VS attempts to fit them into its nonblocking frame request framework as well as it can, and it will also automatically attempt to request frames from source filters linearly in order. I'd expect it to run most source filters slightly faster than Avs+ would with MT_SERIALIZED.
I wrote a very long and boring attempt to explain the differences between the concurrency models here (https://forum.doom9.org/showthread.php?t=174437) a while ago.
videoh
21st March 2018, 18:01
Thanks for that explanation. I tried to read your link some time ago, but I fell asleep. :p
Is there anything to be gained by making a Vapoursynth-native version of DGSource()?
TheFluff
21st March 2018, 18:14
For a source filter I don’t think there’s anything significant to gain performance-wise, no. Not sure about how complete the VS compatibility layer is in terms of various exotic colorspaces and/or bitdepths though.
DJATOM
21st March 2018, 18:16
Thanks for that explanation. I tried to read your link some time ago, but I fell asleep. :p
Is there anything to be gained by making a Vapoursynth-native version of DGSource()?
Yes. Autoloading is great!
videoh
21st March 2018, 18:17
For a source filter I don’t think there’s anything significant to gain performance-wise, no. Not sure about how complete the VS compatibility layer is in terms of various exotic colorspaces and/or bitdepths though. Thank you. All I need is YUV420P016 and that is covered now.
videoh
21st March 2018, 18:17
Yes. Autoloading is great! Alrighty then, I'll do it. Actually I already have it from a while ago, just have to add a few fixes that flowed under the bridge since then.
videoh
21st March 2018, 22:04
Please give the script that plays that fast for UHD content (3840x2160 16-bit). Just to be clear, I am talking about playing the script in VitualDub2.
Will you release a fixed avsresize so I don't have to include one? Thanks.
pinterf
22nd March 2018, 09:56
Thanks. Now it's fast!
But now it seems that probably the VS integration would be better (compiler optimization?), surely it's not an MT issue, even the single-threaded case is slower a bit.
Provided my two scripts are comparable, please note if it's not the case.
(Win10, i7-7700)
Avs+ r2636
Avsmeter64: 264 fps (was: 41fps with r1c)
Avsmeter64: (thread=1, no prefetch): 90 fps
VapourSynth r43
VSEdit r18 Benchmark: 217 fps
VSEdit r18 Benchmark: (threads=1): 83 fps
VirtualDub2 r41462 (Direct Stream Copy, switched off input/output preview):
avs+: 172 fps (37fps with r1c)
vs r43: 150 fps
Passing a YUV420P16 clip to Virtualdub2 runs through a P016 conversion - both at VapourSynth and Avisynth+ -, and possibly VDub2 makes further copy/conversions which are extra overhead.
I was using this script to find the slowness before your r1d patch:
BlankClip(10000,1920,1080,"YUV420P8")
z_ConvertFormat(resample_filter="bicubic", pixel_type="RGBPS",colorspace_op="709:709:709:l=>rgb:linear:2020:l", dither_type="none") # r1c: slooooow, r1d: faaast
z_ConvertFormat(resample_filter="bicubic", pixel_type="YUV420P16",colorspace_op="rgb:linear:2020:l=>709:709:709:l",dither_type="ordered")
prefetch(4)
import vapoursynth as vs
core = vs.get_core(threads=4)
clip = core.std.BlankClip(width=1920, height=1080, length=10000, color=[0, 128, 128], format=vs.YUV420P8)
clip = core.resize.Bicubic(clip=clip, format=vs.RGBS, matrix_s="rgb", transfer_s="linear", primaries_s="2020", matrix_in_s="709", transfer_in_s="709", primaries_in_s="709", dither_type="none")
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P16, matrix_in_s="rgb", transfer_in_s="linear", primaries_in_s="2020", matrix_s="709", transfer_s="709", primaries_s="709", dither_type="ordered")
clip.set_output()
jpsdr
22nd March 2018, 10:04
What is the difference between
z_ConvertFormat(pixel_type="RGBPS",colorspace_op="2020ncl:st2084:2020:l=>rgb:linear:2020:l", dither_type="none")
and the BT.2020 convert implemented in avs+ ?
Is it related to the formula in REC-BT.2100 page 4 and 5 ?
Or is it something found only in SMTPE 2084 ?
TheFluff
22nd March 2018, 11:36
What is the difference between
z_ConvertFormat(pixel_type="RGBPS",colorspace_op="2020ncl:st2084:2020:l=>rgb:linear:2020:l", dither_type="none")
and the BT.2020 convert implemented in avs+ ?
Is it related to the formula in REC-BT.2100 page 4 and 5 ?
Or is it something found only in SMTPE 2084 ?
I dunno, does Avs+ even have linear RGB builtin? As far as I know the builtin Avs+ BT2020 conversion doesn't touch the gamma at all. The conversion you quoted is SMPTE 2084 to linear, and the zimg ST2084 transfer functions are in zimg/colorspace/gamma.cpp line 228 and onwards (https://github.com/sekrit-twc/zimg/blob/master/src/zimg/colorspace/gamma.cpp#L228).
zimg does support HLG too, but under the name ARIB B67, see zimg/colorspace/gamma.cpp line 154 and on (https://github.com/sekrit-twc/zimg/blob/master/src/zimg/colorspace/gamma.cpp#L154).
videoh
22nd March 2018, 13:37
I updated the first post with a new build. Thank you!
videoh
22nd March 2018, 13:41
Passing a YUV420P16 clip to Virtualdub2 runs through a P016 conversion I thought those two were the same thing. DGSource() delivers CS_YUV420P16. Why would there need to be any conversion?
pinterf
22nd March 2018, 13:46
I thought those two were the same thing. DGSource() delivers CS_YUV420P16. Why would there need to be any conversion?
P016 is a semi-packed format which is needed for passing a YUV420P16 clip.
https://msdn.microsoft.com/en-us/library/windows/desktop/bb970578(v=vs.85).aspx
Similarly Y416 is used for passing a YUV444P16 clip through the VfW interface, VirtualDub is using.
videoh
22nd March 2018, 13:57
I see, thank you. If there are spurious conversions inside Avisynth+ or Windows due to VfW maybe that is another reason to prefer Vapoursynth and native Vapoursynth filters. It seems insane to me to convert to an intermediate semi-packed format.
And thank you for your test results. Hopefully, Myrsloik will comment on your performance numbers.
pinterf
22nd March 2018, 14:21
As at 8 bits, 10-16 bit formats are also negotiated through the Vfw interface, here (https://github.com/pinterf/AviSynthPlus/blob/MT/avs_core/core/main.cpp#L1047). For YUV420P16 the fourcc code P016 is reported, this is what VirtualDub2 understands. This format is semi-packed one, Y "plane" is followed immediately wih UVUVUVUV.. data, so that pitch is the same as of the Y data. For YUV422P10 the P210 is used, but you have 2 more choices, such as V210 and Y3[10][10] fourcc codes. These other options can be set thought Avisynth+ OPT_xxx variables (http://avisynth.nl/index.php/Internal_functions#Global_Options), which should appear at the beginning of the scripts.
EDIT: this conversion is done once in the outputting stage, because VirtualDub2 works through VfW. The same interface and method is used by VapourSynth
TheFluff
22nd March 2018, 14:45
Yeah, for VfW you need the packing unfortunately. VS also uses P016 for YUV420P16 when outputting through the VfW interface. If you're outputting through e.g. vspipe though, you can output whatever format you want.
Myrsloik
22nd March 2018, 14:47
Yeah, for VfW you need the packing unfortunately. VS also uses P016 for YUV422P16 when outputting through the VfW interface. If you're outputting through e.g. vspipe though, you can output whatever format you want.
You shouldn't be using vfw, it's <current year>. It mostly exists for convenience, previews and backward compatibility. You're sacrificing a lot of threading by using vfw, do the right thing and use vspipe. Or avspipe or whatever...
videoh
22nd March 2018, 15:14
Questions for Myrsloik:
1) I have made a version of DGDecodeNV that supports both native Avisynth and native Vapoursynth. Will we have to remove DGSource from your avscompat layer, or will Vapoursynth see the native version and use it even if the avscompat layer still has DGSource given as a source filter?
2) Any comment on pinterf's benchmarking showing Vapoursynth a bit slower?
TheFluff
22nd March 2018, 15:28
It doesn't need to be removed, you can have (and use) both. VS plugins get their own namespaces so the same function name can exist in several different plugins that are loaded at the same time. That is, you can have both core.avs.DGSource() and core.dg.DGSource() in the same script, no problem. The AVS compat stuff is only used when loading plugins with core.avs.LoadPlugin.
You can't have two functions with the same name in the same plugin namespace though, so IIRC if you load an Avisynth plugin that uses overloaded functions (exports the same function more than once but with different argument signatures) in VS, the compat layer will de-conflict by renaming the functions, so you get e.g. func(), func_2(), func_3() etc.
Myrsloik
22nd March 2018, 15:56
Question for Myrsloik: I have made a version of DGDecodeNV that supports both native Avisynth and native Vapoursynth. Will we have to remove DGSource from your avscompat layer, or will Vapoursynth see the native version and use it even if the avscompat layer still has DGSource given as a source filter?
Don't forget to mark the filter as fmUnordered and have the flag nfMakeLinear set. Will you export frametype information as well?
poisondeathray
22nd March 2018, 16:11
2) Any comment on pinterf's benchmarking showing Vapoursynth a bit slower?
One difference might be blankclip . It's much faster in avisynth. Like 100x faster with 0% cpu usage , no overhead. You can set the length to 1000000 and it will finish instantaneously with blankclip only.
Myrsloik
22nd March 2018, 16:14
One difference might be blankclip . It's much faster in avisynth. Like 100x faster with 0% cpu usage , no overhead. You can set the length to 1000000 and it will finish instantaneously with blankclip only.
Add keep=1 as an argument to vs blankclip to speed it up a lot. If you don't it creates a new frame every getframe call to avoid extreme memory bloat in some corner cases. Most people never notice the difference anyway until the benchmarks come out...
videoh
22nd March 2018, 16:21
How do I "mark the filter as fmUnordered and have the flag nfMakeLinear set"?
Thank you.
Myrsloik
22nd March 2018, 16:26
How do I "mark the filter as fmUnordered and have the flag nfMakeLinear set"?
Thank you.
You'll have a line with createfilter that looks something like this:
vsapi->createFilter(in, out, "DGSomething", init, getframe, free, fmUnordered, nfMakeLinear, data, core);
poisondeathray
22nd March 2018, 16:27
Add keep=1 as an argument to vs blankclip to speed it up a lot. If you don't it creates a new frame every getframe call to avoid extreme memory bloat in some corner cases. Most people never notice the difference anyway until the benchmarks come out...
Yes, I tried that (I actually read the docs this time :) ) . You still don't get "ludicrous" speed
I think it might have to do with avsmeter64. If you send avs to a "real" encoding application , ffmpeg , vdub, x264, etc... you don't get those "instant" speeds when outputting null
This is why I suggested looking at other testing methodologies earlier - there are discrepancies between the methods and numbers, sometimes large
I like ffmpeg since it accepts both avs and vspipe. There still is a discrepancy with blankclip between avs and vpy . Avs is about 20% faster
pinterf
22nd March 2018, 16:30
Add keep=1 as an argument to vs blankclip to speed it up a lot. If you don't it creates a new frame every getframe call to avoid extreme memory bloat in some corner cases. Most people never notice the difference anyway until the benchmarks come out...
Thanks, in this case keep=1 has practically no effect.
Myrsloik
22nd March 2018, 16:31
Yes, I tried that (I actually read the docs this time :) ) . You still don't get "ludicrous" speed
I think it might have to do with avsmeter64. If you send avs to a "real" encoding application , ffmpeg , vdub, x264, etc... you don't get those "instant" speeds when outputting null
This is why I suggested looking at other testing methodologies earlier - there are discrepancies between the methods and numbers, sometimes large
I like ffmpeg since it accepts both avs and vspipe. There still is a discrepancy with blankclip between avs and vpy . Avs is about 20% faster
I sure hope you benchmarked this way:
vspipe script.vpy .
And at ludicrous speeds you basically end up benchmarking very irrelevant things, like the number of calls used for writing to stdout and nothing else.
poisondeathray
22nd March 2018, 16:35
I sure hope you benchmarked this way:
vspipe script.vpy .
And at ludicrous speeds you basically end up benchmarking very irrelevant things, like the number of calls used for writing to stdout and nothing else.
Exactly! You want to measure the pipe speed before an actual encoding application . Because that is how it would be used in real usage scenario. IMO , that is more useful information
vspipe --y4m script.vpy - | ffmpeg -f yuv4mpegpipe -i - -an -f null NUL
ffmpeg -i script.avs -an -f null NUL
videoh
22nd March 2018, 16:46
You'll have a line with createfilter that looks something like this:
vsapi->createFilter(in, out, "DGSomething", init, getframe, free, fmUnordered, nfMakeLinear, data, core); Thank you. nfMakeLinear is undefined. Do I need more recent headers?
Yes, I will export frame info.
Do I still need to do this:
muldivRational(&VI[0].fpsDen, &VI[0].fpsNum, 1, 1);
Myrsloik
22nd March 2018, 16:58
You need newer headers and you still need to do that
videoh
22nd March 2018, 17:04
Thanks. Working now.
videoh
22nd March 2018, 20:41
What is the Vapoursynth equivalent of:
env->SetVar(env->Sprintf("%s", "FFPICT_TYPE"), static_cast<int>(ctype));
Myrsloik
22nd March 2018, 20:46
What is the Vapoursynth equivalent of:
env->SetVar(env->Sprintf("%s", "FFPICT_TYPE"), static_cast<int>(ctype));
If the picture type is a single char you'd do something like this:
VSMap *Props = vsapi->getFramePropsRW(Dst);
vsapi->propSetData(Props, "_PictType", &Frame->PictType, 1, paReplace);
Note that many properties have standard names and types. See this part of ffms2 (https://github.com/FFMS/ffms2/blob/master/src/vapoursynth/vapoursource.cpp#L172) for hints.
videoh
22nd March 2018, 20:54
Thanks.
Myrsloik
22nd March 2018, 21:00
No properties are required but a list of what you should call some things if you do attach them is here (http://www.vapoursynth.com/doc/apireference.html#reserved-frame-properties). For example all the colorpsace stuff gets used by format conversions automatically then.
You're free to make up your own properties too as long as they don't start with _.
videoh
22nd March 2018, 22:53
Nice. Just what the doctor ordered.
poisondeathray
4th April 2018, 19:31
The discrepancy with BlankClip you observed comes from the fact that, one uses direct file input while the other uses pipe. If you use ffmpeg -i test.avs -an -f null NUL you do see faster fps. But if you use avs2pipemod64 -y4mp test.avs | ffmpeg -f yuv4mpegpipe -i - -an -f null NUL you will see the same (or very close) fps compared to vpy. I don't know if pipe does cause that large overhead or it's the limitation of ffmpeg itself.
It is what we currently use. If there is overhead, than means if you use ffmpeg to encode, that overhead is currently incurred in real practice too - i.e it reflects reality. If you were to encode, say using libx264, it would be marginally slower because of that penalty
But I would like to compare "apples to apples" someday. It is a dream. Maybe with this :)
https://forum.doom9.org/showpost.php?p=1838296&postcount=10
maybe quote it before it might disappear
poisondeathray
6th April 2018, 15:46
So, the penalty of pipe only has a significant impact when the script itself is quite fast. Otherwise in practical complex scripts, together with real encoding, it could be considered negligible.
Thanks for the testing!
It's just 1 test so far, but 4.5% faster is still significant. But when coupled with actual encoding (-c:v something), you'd expect that difference to drop more
TheLastOfUs
11th August 2018, 12:45
Doesn't work for me. Constantly still says no such function z_ConvertFormat. I put it under plugins+ in AviSynth+ Prog Files x86 :/
Using FFMS2 for a 4K mkv...what am I doing wrong?
Groucho2004
11th August 2018, 13:05
Doesn't work for me. Constantly still says no such function z_ConvertFormat. I put it under plugins+ in AviSynth+ Prog Files x86 :/
Using FFMS2 for a 4K mkv...what am I doing wrong?
Run "AVSMeter avsinfo" (or "AVSMeter64 avsinfo") and let us know if that produces any errors.
It's quite possible that you don't have the required runtimes installed.
TheLastOfUs
12th August 2018, 07:29
Run "AVSMeter avsinfo" (or "AVSMeter64 avsinfo") and let us know if that produces any errors.
It's quite possible that you don't have the required runtimes installed.
AVSMeter just crashes, assuming its flipping out because that function doesn't exist apparently.
AviSynth+ 0.1 (r1576, x86) (2.6.0.5)
Script error: There is no function named 'z_ConvertFormat'.
(C:\Users\Desktop\AVSMeter281\New File (1).avs, line 2)
Groucho2004
12th August 2018, 08:07
AVSMeter just crashes, assuming its flipping out because that function doesn't exist apparently.
AviSynth+ 0.1 (r1576, x86) (2.6.0.5)
Script error: There is no function named 'z_ConvertFormat'.
(C:\Users\Desktop\AVSMeter281\New File (1).avs, line 2)
1. Update AVS+ to the most recent version (https://github.com/pinterf/AviSynthPlus/releases)
2. Read my last post again - The command line should be "AVSMeter avsinfo"
TheLastOfUs
12th August 2018, 08:53
Ok doing so now!
TheLastOfUs
12th August 2018, 08:56
Didn't even REALIZE there's a most recent fork. I always just went to AviSynth+ website lol
TheLastOfUs
12th August 2018, 08:59
1. Update AVS+ to the most recent version (https://github.com/pinterf/AviSynthPlus/releases)
2. Read my last post again - The command line should be "AVSMeter avsinfo"
Updating worked. Thank you kindly!
I love avsmeter. It's amazing for diagnosis. I'm surprised I'm JUST now finding out about your tool!
TheLastOfUs
12th August 2018, 09:02
sOLVED!
TheLastOfUs
12th August 2018, 09:11
Remove!
real.finder
30th March 2020, 22:14
I asked here https://forum.doom9.org/showpost.php?p=1905691&postcount=69
z_ConvertFormat(colorspace_op="470bg:470bg:470bg:limited=>709:709:709:limited",dither_type="ordered")
give dark output, is this normal or it bug?
poisondeathray
30th March 2020, 23:12
I asked here https://forum.doom9.org/showpost.php?p=1905691&postcount=69
z_ConvertFormat(colorspace_op="470bg:470bg:470bg:limited=>709:709:709:limited",dither_type="ordered")
give dark output, is this normal or it bug?
Expected result
The original colormatrix() only changes the matrix, nothing else.
You are are telling avsresize to change matrix, transfer and primaries
real.finder
30th March 2020, 23:19
Expected result
The original colormatrix() only changes the matrix, nothing else.
You are are telling avsresize to change matrix, transfer and primaries
so z_ConvertFormat should be better, right?
but it's not as fast as colormatrix, is it because colormatrix only change matrix?
poisondeathray
30th March 2020, 23:26
so z_ConvertFormat should be better, right?
"better" in what way?
For HD/SD , the standard of practice is actually to only change matrix . (Not for UHD). For matrix, 470bg and 170m have the same value (SD, 601) . 709 does not
Transfer function value is the same for 601/709 .
Primaries are slightly different between 601/709 .
The list is in the h265 document . Table E4.
But you check with other programs, resolve, premiere , dozens of others, only matrix is ever adjusted. The colors will be slightly shifted in media players, other programs, hardware, displays, AV equipment if you adjust for the primaries - even though it's technically more correct
but it's not as fast as colormatrix, is it because colormatrix only change matrix?
I don't know why one is faster
Quality wise colormatrix can produce more pronounced banding artifacts under some conditions. It's more visible in cartoons and anime .
real.finder
8th April 2020, 02:13
"better" in what way?
For HD/SD , the standard of practice is actually to only change matrix . (Not for UHD). For matrix, 470bg and 170m have the same value (SD, 601) . 709 does not
Transfer function value is the same for 601/709 .
Primaries are slightly different between 601/709 .
The list is in the h265 document . Table E4.
But you check with other programs, resolve, premiere , dozens of others, only matrix is ever adjusted. The colors will be slightly shifted in media players, other programs, hardware, displays, AV equipment if you adjust for the primaries - even though it's technically more correct
I don't know why one is faster
Quality wise colormatrix can produce more pronounced banding artifacts under some conditions. It's more visible in cartoons and anime .
I mean better for HD <-> SD convert
also I know colormatrix can produce more pronounced banding artifacts since it 8bit
I did post another time there https://forum.doom9.org/showthread.php?p=1905976#post1905976
z_ConvertFormat(colorspace_op="470bg:601:170m:limited=>709:709:709:limited",dither_type="ordered")
seems fine but aside from matrix how one know for sure the color info in DVD? or if I cap from VHS
and aside from that, can we have update for avsresize? https://forum.doom9.org/showthread.php?p=1906749#post1906749
and since the documentation is kinda shortened, is avsresize has all Dither_resize16/fmtconv features like kernel inversion mode and additional Kernels?
poisondeathray
8th April 2020, 02:46
also I know colormatrix can produce more pronounced banding artifacts since it 8bit
It's not just an 8bit thing; there are some weird noise patterns enhanced by colormatrix on some anime. If you check by disable dithering and use 8bit with zimg, it's still more pronounced with colormatrix . Haven't seen the issue on live action content , it's probably hidden by natural noise and grain
z_ConvertFormat(colorspace_op="470bg:601:170m:limited=>709:709:709:limited",dither_type="ordered")
seems fine but aside from matrix how one know for sure the color info in DVD? or if I cap from VHS
No way to know for sure.
If you assume the colors are correct on the DVD in the first place, you're asking the wrong question. You should be asking what method is your viewing hardware or software using to convert back to RGB for display ? ie. is it using something like ConvertToRGB24(matrix="rec709") ? Because that accounts for matrix only . If you adjust for primaries the colors will be shifted for the HD version when viewing on that hardware or software
I would only adjust matrix, unless you knew primaries were adjusted and the SD image is wrong in the first place
I would always use full=>full . I thought it was a no-op limited=>limited, but it makes a difference on the brightest
and darkest pixels if you look closely . Detectable with metrics too
and aside from that, can we have update for avsresize? https://forum.doom9.org/showthread.php?p=1906749#post1906749
I would like update too, but I don't know how to compile it
and since the documentation is kinda shortened, is avsresize has all Dither_resize16/fmtconv features like kernel inversion mode and additional Kernels?
No ; and available kernels are only the common ones and they are listed in the readme
pinterf
8th April 2020, 07:44
zimg integration is on my roadmap but not in the very near future
StvG
8th April 2020, 08:32
Here update (https://cloud.owncube.com/s/DjHxaH7YdEieY3s) (zimg@5896a26). Added few things (cpu_type, nominal_luminance, approximate_gamma, alpha plane). Check readme for more info.
MeteorRain
8th April 2020, 09:17
seems fine but aside from matrix how one know for sure the color info in DVD? or if I cap from VHS
Some DVD mastering company can't even resize the image correctly (like SAR and over scan stuff). Some staff probably don't even have the skills that we have. God knows how they converted the colors.:sly:
pinterf
8th April 2020, 12:14
Here update (https://cloud.owncube.com/s/DjHxaH7YdEieY3s) (zimg@5896a26). Added few things (cpu_type, nominal_luminance, approximate_gamma, alpha plane). Check readme for more info.
Thanks. Do you have a github link (also for addgrain stuff), it's hard to follow the changes (and to give you the proper credits on a re-use).
poisondeathray
8th April 2020, 15:25
Here update (https://cloud.owncube.com/s/DjHxaH7YdEieY3s) (zimg@5896a26). Added few things (cpu_type, nominal_luminance, approximate_gamma, alpha plane). Check readme for more info.
thanks for the update
Reel.Deel
8th April 2020, 17:06
Here update (https://cloud.owncube.com/s/DjHxaH7YdEieY3s) (zimg@5896a26). Added few things (cpu_type, nominal_luminance, approximate_gamma, alpha plane). Check readme for more info.
Thank you for the update StvG!
Not long ago I added documentation to the wiki: http://avisynth.nl/index.php/Avsresize
I'll will update the documentation with the things that were added.
I see that compatibility aliases "gauss", "lanczos4", "blackman", "sinc" were removed. And also z_BlackmanResize(), z_GaussResize(), z_SincResize() are gone. I know these essentially did nothing since they are just aliases, will they be gone forever?
Stereodude
8th April 2020, 17:32
Thank you for the update StvG!
Not long ago I added documentation to the wiki: http://avisynth.nl/index.php/Avsresize
I'll will update the documentation with the things that were added.
I see that compatibility aliases "gauss", "lanczos4", "blackman", "sinc" were removed. And also z_BlackmanResize(), z_GaussResize(), z_SincResize() are gone. I know these essentially did nothing since they are just aliases, will they be gone forever?
It would be nice if you could list the terminology of all the allowed color formats in the wiki or if the plug-in aligned its accepted naming with Avisynth+'s terms. It will not accept some of the names used by AVIsynth+ (http://avisynth.nl/index.php/Avisynthplus_color_formats).
Like using RGBP8 gives you a bad pixel type error. It looks like it wants RGBP, not RGBP8.
StainlessS
8th April 2020, 21:45
The affected ones look to all have entries in the Remarks column. [ RGBP vs RGBP8, on wiki:- http://avisynth.nl/index.php/Avisynthplus_color_formats ]
Oops, wrong link, FIXED.
StvG
9th April 2020, 08:29
Thanks. Do you have a github link (also for addgrain stuff), it's hard to follow the changes (and to give you the proper credits on a re-use).
Sorry, I don't have any github links.
Thank you for the update StvG!
Not long ago I added documentation to the wiki: http://avisynth.nl/index.php/Avsresize
I'll will update the documentation with the things that were added.
I see that compatibility aliases "gauss", "lanczos4", "blackman", "sinc" were removed. And also z_BlackmanResize(), z_GaussResize(), z_SincResize() are gone. I know these essentially did nothing since they are just aliases, will they be gone forever?
IMO, yes, they are gone "forever" unless zimg adds support for them. For example I had a version compiled without spline64 too (spline64 was spline32 alias) but when zimg added spline64 (https://github.com/sekrit-twc/zimg/commit/6ffe4b162f7e71dbd13428bc3e9542ac17646e44), I added back spline64.
Btw on the wiki page chromaloc_op "top_left" is missing.
FranceBB
9th April 2020, 10:22
Some staff probably don't even have the skills that we have. God knows how they converted the colors.:sly:
You mean morons who don't know how to do these things?
They do it via hardware, mostly.
The reason? They have little to no clue about what they're doing as they're just operators that someone put there and they don't know how to code or use pseudo-scripting softwares like Avisynth, BUT they strictly follow a procedure that someone not too incompetent put in place several years ago back when there was no software at all.
It generally involves a play port (like the Omneon ones), a resizing hardware converter (Evertz and similar), a Softel/Cavena for subtitles and either a DVD itself or a Rec Port.
They generally put the colorbars, then the file, then black at the end, then they route the signal from the playback port to the converter and from the converter to the Softel or Cavena which "plays" the subtitles according to the timecode read from the SDI port and it places it in the inactive lines of the stream while playing and from there to either the DVD itself or to a Rec Port which records the file that is going to be mastered to the DVD.
Stone age at its best as it could be easily done in a fraction of the time with Avisynth or literally anything that isn't from decades ago, but I've seen it with my eyes and years ago I was one of the people who had to do it this way (i.e I was forced to do it this way) because of "sacred procedures"... -.-
Reel.Deel
9th April 2020, 15:47
IMO, yes, they are gone "forever" unless zimg adds support for them. For example I had a version compiled without spline64 too (spline64 was spline32 alias) but when zimg added spline64 (https://github.com/sekrit-twc/zimg/commit/6ffe4b162f7e71dbd13428bc3e9542ac17646e44), I added back spline64.
Btw on the wiki page chromaloc_op "top_left" is missing.
I've updated the wiki to match these changes and added chromaloc_op "top_left" :thanks:
Reel.Deel
22nd April 2020, 18:46
It would be nice if you could list the terminology of all the allowed color formats in the wiki or if the plug-in aligned its accepted naming with Avisynth+'s terms. It will not accept some of the names used by AVIsynth+ (http://avisynth.nl/index.php/Avisynthplus_color_formats).
Like using RGBP8 gives you a bad pixel type error. It looks like it wants RGBP, not RGBP8.
Done: http://avisynth.nl/index.php/Avsresize#z_ConvertFormat
-----
@StvG
Any thoughts on adding YUV420P8, YUVA420P8, YUV422P8, YUVA42AP8, YUV444P8, YUVA444P8, RGBP8, RGBAP8 aliases?
StvG
23rd April 2020, 21:45
Here r1e (https://cloud.owncube.com/s/a2Jg7j4ojEKkYoD):
- zimg@8815111;
- added pixel type RGBP8, RGBAP8, YUV444, YUV444P8, YUVA444P8, YUV422, YUV422P8, YUVA422P8, YUV420, YUV420P8 , YUVA420P8, YUV411, YUV411P8;
- added version.
Reel.Deel
27th April 2020, 08:11
:thanks: StvG
I updated the wiki accordingly.
Losko
12th August 2020, 22:00
Added a few tiny fixes, and now I can run avsresize filer as a dynamic library libavsresize.so with avs+ 3.6.1-git natively on my debian box.
I checked resize and color space conversion, everything seems to be fine.
how to build:
g++ -Wall -Wextra -O2 -std=c++17 -fPIC -c -o avsresize.o avsresize.cpp
g++ -s -shared -o libavsresize.so avsresize.o -lzimg
===============================================================================
--- avsresize.orig.cpp 2020-04-23 19:48:21.000000000 +0200
+++ avsresize.cpp 2020-08-11 21:22:33.716137465 +0200
@@ -9,7 +9,22 @@
#include <regex>
#include <string>
#include <malloc.h>
+#ifdef _WIN32
#include "avisynth.h"
+#else
+#include <avisynth/avisynth.h>
+#define _aligned_free free
+#define __int64 int64_t
+/* gnu libc offers the equivalent 'aligned_alloc' BUT requested 'size'
+ has to be a multiple of 'alignment' - in case it isn't, I'll set
+ a different size, rounding up the value */
+#define _aligned_malloc(s,a) ( \
+ (s%a)? \
+ aligned_alloc(a,(s/a+1)*a) \
+ : \
+ aligned_alloc(a,s) \
+ )
+#endif
#include "zimg++.hpp"
namespace {
StvG
26th August 2020, 15:59
avsresize_r1f (https://cloud.owncube.com/s/XCLyRtnysGXY92c) - added @Losko patch, zimg v3.0.1, added support for frame properties.
hello_hello
26th August 2020, 17:05
Thank you!
kedautinh12
26th August 2020, 18:17
Thanks
real.finder
2nd October 2020, 18:44
avsresize_r1f (https://cloud.owncube.com/s/XCLyRtnysGXY92c) - added @Losko patch, zimg v3.0.1, added support for frame properties.
pinterf said that frame properties are just copyied not really used https://github.com/AviSynth/AviSynthPlus/issues/189#issuecomment-701993847
StvG
3rd October 2020, 07:49
pinterf said that frame properties are just copyied not really used https://github.com/AviSynth/AviSynthPlus/issues/189#issuecomment-701993847
I didn't mention anything specific than a general support (copying of frame properties).
avsresize_r1g (https://cloud.owncube.com/s/rqiwDJT7dncATgr) - added parameter prefer_props; read and set _ChromaLocation, _ColorRange, _Matrix, _Transfer, _Primaries frame properties; added chromaloc_op parameters - bottom_left and bottom.
For more info check the included README.md.
real.finder
6th October 2020, 18:27
I didn't mention anything specific than a general support (copying of frame properties).
avsresize_r1g (https://cloud.owncube.com/s/rqiwDJT7dncATgr) - added parameter prefer_props; read and set _ChromaLocation, _ColorRange, _Matrix, _Transfer, _Primaries frame properties; added chromaloc_op parameters - bottom_left and bottom.
For more info check the included README.md.
thanks, and I think there are no source call support frame properties yet, even ffms2 (it still use old global) except https://github.com/Asd-g/RawSource_2.6x/commit/13a0fd8119bc74f92b126bda6653af08a4ccb7d3
real.finder
8th October 2020, 08:31
can we have "auto" in colorspace_op input and "same" in output?
colorspace_op="auto:auto:auto:auto=>same:same:same:f"
the "auto" see if there are frame properties first and if there are no frame properties for the parameter it will use presupposed value based on video informations like resolution and fps
and "same" will use the input value
pinterf
9th October 2020, 10:41
I didn't mention anything specific than a general support (copying of frame properties).
avsresize_r1g (https://cloud.owncube.com/s/rqiwDJT7dncATgr) - added parameter prefer_props; read and set _ChromaLocation, _ColorRange, _Matrix, _Transfer, _Primaries frame properties; added chromaloc_op parameters - bottom_left and bottom.
For more info check the included README.md.
Great news, thanks!
StvG
13th October 2020, 18:57
can we have "auto" in colorspace_op input and "same" in output?
colorspace_op="auto:auto:auto:auto=>same:same:same:f"
the "auto" see if there are frame properties first and if there are no frame properties for the parameter it will use presupposed value based on video informations like resolution and fps
and "same" will use the input value
"auto" is unnecessary. Any source value with "same" destination would lead to no conversion.
real.finder
14th October 2020, 01:48
but "auto" make things easier for user
StvG
14th October 2020, 18:39
avsresize_r2 (https://cloud.owncube.com/s/jfDf8rERkxEFTqW) - added keyword 'same' for destination matrix, transfer, primaries, range, chromaloc_op.
When it's used the source value (argument or frame property) is used for destination too.
real.finder
15th October 2020, 03:15
avsresize_r2 (https://cloud.owncube.com/s/jfDf8rERkxEFTqW) - added keyword 'same' for destination matrix, transfer, primaries, range, chromaloc_op.
When it's used the source value (argument or frame property) is used for destination too.
thanks, so since auto not added, I think prefer_props need to be set to true so user can set something like this
colorspace_op="709:709:709=>709:709:709", prefer_props=true
and since prefer_props=true the it will use the frame properties and ignore the input 709:709:709=>
right?
StvG
15th October 2020, 05:32
Sorry for avsresize_r2. I was negligent.
avsresize_r3 (https://cloud.owncube.com/s/f6rQEcCLA95jZMN): - removed parameter prefer_props;
- added keyword "auto" for source matrix, transfer, primaries, range. When it's used the corresponding input frame properties are used, if such frame properties don't exist either an error is raised or default matrix and color range are used;
- added keyword "auto" for source chromaloc_op. When it's used the corresponding input frame property is used, if such frame property doesn't exist default chromaloc is used.
If colorspace_op is not defined and there are frame properties, they are used for default source values.
If colorspace_op is not defined and there are no frame properties or they are not supported, default values are used as before (there are default values for matrix, range and chromaloc).
If colorspace_op is defined and you want to use the frame property for a source value, use "auto".
If colorspace_op is defined and you use "auto" without frame property, the default value for that argument will be used if exist.
If you use "auto" for argument with frame property that has value of 2 (unspec) and use anything different than "same" for destination, error will be raised.
If you use "auto=>same" for matrix/transfer/primaries with frame property 2 (unspec) and you want to make colorspace conversion, error will be raised. For example:#transfer property has value of 2
#primaries 709 (1)
#input yv12
z_convertformat(pixel_type="rgbp", colorspace_op="auto:auto:709=>rgb:same:470bg") # error raised
#z_convertformat(pixel_type="rgbp", colorspace_op="auto:709:709=>rgb:709:470bg") # ok
#z_convertformat(pixel_type="rgbp", colorspace_op="auto:709:auto=>rgb:same:470bg") # ok
#z_ConvertFormat(colorspace_op="auto:auto=>same:470bg") # error
#z_ConvertFormat(colorspace_op="auto:auto:auto:auto=>same:same:same:f") # ok
real.finder
15th October 2020, 07:18
thanks! the changes seems ok, and I will test and see
zambelli
15th October 2020, 09:06
I was thinking it would be helpful to simplify the current list of enum values for matrix/transfer/primaries by indicating in the documentation that certain standards actually use the same matrix/transfer/primaries values.
For example:
Matrix coefficients: "470bg", "170m" and "601" use identical coefficients (and "fcc" isn't too far off either)
Matrix coefficients: "2020ncl", "2020cl" and "2020" use identical coefficients
Transfer characteristics: "709", "601", "2020_10", "2020_12" and "2020" use the same transfer function
Transfer characteristics: In order to match FFmpeg Zscale values it'd be nice to add "170m" as alias for "601"
Color primaries: "170m" and "240m" use identical primaries (also, it's strange that the standard is called "240m" here but called "240" under matrix coefficients)
Color primaries: "709" and "470bg" aren't identical, but they are VERY close, which is useful to know when dealing with PAL video
The reason I mention it is because it's easy for someone to lose a lot of time sweating over the details of whether an old video capture is ST 170M or BT.601, only to realize after many hours of research that they're essentially the same thing. :)
real.finder
15th October 2020, 12:13
StvG, what about interlaced parameter and frame properties?
StvG
18th October 2020, 10:11
@zambelli, I will add comments.
@real.finder, currently video with frame property _FieldBased = 1/2 is processed but it shouldn't be. I'll change that later.
mp3dom
18th October 2020, 16:59
Just asking, but does R3 works fine for everyone? I'm converting a 1920x1080 4:2:2 10bit clip from 709 to 601 and I get a system exception (without any additional infos) on x64 while on x86 Vdub2 crash and close without any warning. The same script works with R1g.
zambelli
18th October 2020, 20:58
@zambelli, I will add comments.
Thanks!
One more documentation suggestion: I think the current definition of nominal_luminance could also benefit from some clarification. It says, "Nominal peak luminance in cd/m^2 when converting HDR content to RGB Linear". However, I don't think HDR conversion is the only scenario in which this parameter can be used. To the best of my understanding, what nominal_luminance really does is determine the scale of conversion between linear and non-linear transfer functions. It defines which luminance value (in cd/m^2) in a non-linear colorspace should be mapped to 1.0 in the floating point linear RGB colorspace, regardless of whether one is converting to or from linear RGB. For example, if I am converting from HLG ("std-b67") to linear RGB and want to capture the full BT.2100 HLG range (0-1000 nits) in 0.0-1.0 linear RGB, I'd set the nominal_luminance value to 1000. Does that sound right, or is my own understanding of the parameter incorrect?
Thank you for bringing this great plugin to AviSynth - it's much appreciated!
real.finder
21st October 2020, 16:51
Just asking, but does R3 works fine for everyone? I'm converting a 1920x1080 4:2:2 10bit clip from 709 to 601 and I get a system exception (without any additional infos) on x64 while on x86 Vdub2 crash and close without any warning. The same script works with R1g.
maybe it's better to post a simple script with colorbars that show the problem
mp3dom
21st October 2020, 22:57
maybe it's better to post a simple script with colorbars that show the problem
ColorBars(width=1920,height=1080,pixel_type="yuv422p10")
z_ConvertFormat(720,480,colorspace_op="709:709:709:limited=>170m:601:170m:limited",resample_filter="bicubic")
This made VDub2 crash without any warning/advice, at least here.
StvG
22nd October 2020, 04:08
avsresize_r4 (https://cloud.owncube.com/s/ScA6xEADaHLiAFd): - fixed crashing when avs+ doesn't support frame properties;
- set _SARNum and _SARDen properties;
- read the input frame property _ChromaLocation if available;
- do not process clips with frame property _FiledBased > 0.
zambelli
22nd October 2020, 07:47
avsresize_r4 (https://cloud.owncube.com/s/ScA6xEADaHLiAFd): - fixed crashing when avs+ doesn't support frame properties;
- set _SARNum and _SARDen properties;
- read the input frame property _ChromaLocation if available;
- do not process clips with frame property _FiledBased > 0.
Thanks for the update - the new build no longer crashes VDub.
I've run into another unrelated bug though. It looks like it's been there going back to at least version r1g.
The output of z_ConvertFormat() is different depending on whether the input is integer or floating point.
Example:
ColorBars()
v1 = ConvertToPlanarRGB().ConvertBits(32).ConvertToYUV444(matrix="Rec601").z_ConvertFormat(pixel_type="RGBP8", colorspace_op="470bg:470bg:470bg:l=>rgb:709:709:f")
v2 = ConvertToPlanarRGB().ConvertBits(16).ConvertToYUV444(matrix="Rec601").z_ConvertFormat(pixel_type="RGBP8", colorspace_op="470bg:470bg:470bg:l=>rgb:709:709:f")
Interleave(v1, v2)
StvG
22nd October 2020, 14:43
zimg expects full range when input is YUV float or RGB.
In your example "ColorBars().ConvertToPlanarRGB()" returns RGB in limited range so after "ConvertToYUV444(matrix="Rec601")" you have limited range but zimg expects full range.
The following give you identical output: ColorBars()
#v1 = ConvertToPlanarRGB().z_ConvertFormat(pixel_type="rgbps", colorspace_op="auto:auto:auto:l=>same:same:same:f").ConvertToYUV444(matrix="Rec601").z_ConvertFormat(pixel_type="RGBP8", colorspace_op="470bg:470bg:470bg=>rgb:709:709") # also same output
v1 = ConvertToPlanarRGB().ConvertBits(32, fulls=false, fulld=true).ConvertToYUV444(matrix="Rec601").z_ConvertFormat(pixel_type="RGBP8", colorspace_op="470bg:470bg:470bg=>rgb:709:709")
v2 = ConvertToPlanarRGB().ConvertBits(16).ConvertToYUV444(matrix="Rec601").z_ConvertFormat(pixel_type="RGBP8", colorspace_op="470bg:470bg:470bg=>rgb:709:709")
Interleave(v1, v2)
zambelli
26th October 2020, 11:30
zimg expects full range when input is YUV float or RGB.
Are you saying that when input to zimg is floating point YUV and the input range is indicated as "limited", zimg assumes that black is Y=0.0 and white is Y=1.0?
Shouldn't "limited" range imply that black is Y=0.06 and white is Y=0.92?
When RGBP8 0-255 is converted to RGBPS using Avisynth's internal ConvertBits(32), I am making the assumption that 0 gets mapped to 0.0 and 255 gets mapped to 1.0.
When RGBPS gets converted to YUV444PS using internal ConvertToYUV444(matrix="Rec601"), I am making the assumption that RGB 0.0 gets mapped to Y=16.0/255.0, and RGB 1.0 gets mapped to Y=235.0/255.0 since the matrix indicates RGB full --> YUV limited.
Am I making the wrong assumptions there?
real.finder
26th October 2020, 15:45
Are you saying that when input to zimg is floating point YUV and the input range is indicated as "limited", zimg assumes that black is Y=0.0 and white is Y=1.0?
Shouldn't "limited" range imply that black is Y=0.06 and white is Y=0.92?
When RGBP8 0-255 is converted to RGBPS using Avisynth's internal ConvertBits(32), I am making the assumption that 0 gets mapped to 0.0 and 255 gets mapped to 1.0.
When RGBPS gets converted to YUV444PS using internal ConvertToYUV444(matrix="Rec601"), I am making the assumption that RGB 0.0 gets mapped to Y=16.0/255.0, and RGB 1.0 gets mapped to Y=235.0/255.0 since the matrix indicates RGB full --> YUV limited.
Am I making the wrong assumptions there?
https://github.com/sekrit-twc/zimg/issues/134
zambelli
27th October 2020, 09:04
https://github.com/sekrit-twc/zimg/issues/134
Huh. Interesting. Is the last comment in that thread correct - is AVS+ converting incorrectly?
So when an 8-bit limited range signal is converted to YUV4xxPS with zimg, does that mean 16 maps to Y=-0.07 and 235 maps to Y=1.09?
real.finder
27th October 2020, 14:05
Huh. Interesting. Is the last comment in that thread correct - is AVS+ converting incorrectly?
So when an 8-bit limited range signal is converted to YUV4xxPS with zimg, does that mean 16 maps to Y=-0.07 and 235 maps to Y=1.09?
I don't think it's incorrect, float can be any thing, I don't see problem using 0.06..0.92 but it will not stay as it after using some filters since float don't clamp anyway
anyway, pinterf seems plan about do something about this using frame properties
so for now, you can use z_ConvertFormat if you convert to float permanently, and avs one if you do it temporarily (mean int -> float -> int)
So when an 8-bit limited range signal is converted to YUV4xxPS with zimg, does that mean 16 maps to Y=-0.07 and 235 maps to Y=1.09?
don't know, but you can try it (even if it hard since avsp don't show the real value of the pixel, so you must find some work around)
TheFluff
28th October 2020, 14:56
Are you saying that when input to zimg is floating point YUV and the input range is indicated as "limited", zimg assumes that black is Y=0.0 and white is Y=1.0?
zimg always assumes that float input is in the range 0.0-1.0 regardless of whether you tell it that the input is limited range or not, and I believe likewise always converts float output into that range. This is because "limited range" makes no sense for float, or perhaps more accurately it's always limited range. Limited range means using a pair of arbitrarily chosen values to represent black and white instead of using the minimum and maximum values of the storage format (e.g. 8-bit integer, 16-bit integer, 32-bit float), but with float it makes no sense to use the minimum and maximum representable values of the storage format as black and white because then you get different numerical precision in different parts of the range, so we use the arbitrary convention 0.0-1.0 instead. There is no point in choosing a different arbitrary convention.
zambelli
29th October 2020, 06:09
zimg always assumes that float input is in the range 0.0-1.0 regardless of whether you tell it that the input is limited range or not, and I believe likewise always converts float output into that range. [...] There is no point in choosing a different arbitrary convention.
I'm OK with that, it makes sense now, but I'm surprised that Avisynth might not be aligned with that same convention.
I'm still curious: what happens to superblack and superwhite values from a limited Y integer range when it's converted to float? Do they end up mapping to <0 and >1?
pinterf
29th October 2020, 09:10
I'm OK with that, it makes sense now, but I'm surprised that Avisynth might not be aligned with that same convention.
I'm still curious: what happens to superblack and superwhite values from a limited Y integer range when it's converted to float? Do they end up mapping to <0 and >1?
Yes, they are mapped then outside the 0..1 range.
At the time I was developing the high bit depth additions I was not aware of any conventions. I suppose this convention was not even a strong one. And it had two phases, even putting the float UV chroma range to zero center was an extra project for me years ago, mainly because I wanted it to be compatible with zimg (and VS). And because it is a reasonable convention. Now it needs a third step: handle 32 bit float format uniformly across avs+ core and plugins. With additions attention to the implemented auto-conversions in Expr and masktools lut.
hello_hello
29th October 2020, 14:17
To clarify....
z_ConvertFormat(720,480,colorspace_op="709:709:709:limited=>170m:601:170m:limited")
If the source is some flavour of YUV and the input to z_ConvertFormat is 32 bit float, should "limited" be changed to "full", or is the specified range ignored for float?
StvG
29th October 2020, 21:04
... and I believe likewise always converts float output into that range.
If input is float and output is float - color_range source/destination doesn't have effect; range is always assumed full.
If input is int and output is float - color_range source set to full keeps the values same and returns x/255 (8-bit) within 0..1 range; color_range source set to limited expands the range limited to full; color_range destination doesn't have effect.
If input is float (full range) and output is int - color_range source doesn't have effect; color_range destination set to limited does full to limited; color_range destination set to full keeps the full range.
To clarify....
z_ConvertFormat(720,480,colorspace_op="709:709:709:limited=>170m:601:170m:limited")
If the source is some flavour of YUV and the input to z_ConvertFormat is 32 bit float, should "limited" be changed to "full", or is the specified range ignored for float?
Using the same value for source and destination means no conversion. It doesn't matter if you use limited for source and destination or full for source and destination, or omit color_range at all.
StvG
30th October 2020, 11:12
avsresize_r5 (https://cloud.owncube.com/s/Zq6iPjyYGcTLAT8): use chromaloc frame property (when available) for the legacy resizers.
kedautinh12
15th May 2021, 14:42
I seen zimg have new ver
https://github.com/sekrit-twc/zimg/blob/master/ChangeLog
avsresize_r6 (https://cloud.owncube.com/s/KfAcEpqkMPSdagr): - registered as MT_NICE_FILTER;
- read frame properties from every frame (previously only from the first frame);
- zimg@8d0b839.
kedautinh12
30th May 2021, 15:55
Thanks
If anyone downloaded avsresize_r6, download it again (fixed regression: approximate_gamma (r5 is ok)).
tormento
31st May 2021, 09:46
If anyone downloaded avsresize_r6, download it again (fixed regression: approximate_gamma (r5 is ok)).
Unable to download.
Il server non è stato in grado di completare la tua richiesta.
Se ciò si verifca nuovamente, invia i seguenti dettagli tecnici all'amministratore del server.
Ulteriori dettagli sono disponibili nel log del server.
Dettagli tecnici
Indirizzo remoto: 84.221.196.138
ID richiesta: WXU1VipibSaEEFhe3TpD
Edit: now it works.
FranceBB
21st June 2021, 16:47
It was working, I updated Avisynth on my production server to 3.7.0, now it's throwing this error:
https://i.imgur.com/UxWQT6G.png
Why?
Edit: Tested on Avisynth 3.7.1 Beta 6, same result, same error.
Edit 2: I'm temporarily using ConverttoYUV422(matrix="PC2020") as a workaround. Technically, it should leave the levels untouched from the Studio RGB...
StvG
23rd June 2021, 02:12
avsresize_r7 (https://ppp.woelkli.com/s/8ZoEqE7o3GFfREc) (pass: hIaK6dSB69uK): fixed frame properties reading.
kedautinh12
23rd June 2021, 03:09
Thanks
FranceBB
23rd June 2021, 06:42
I updated but now I get: RGB Color family cannot have YUV matrix coefficients
https://i.imgur.com/ije1YiC.png
if I remove the last conversion and leave it as RGB it works:
https://i.imgur.com/1isEVxY.png
Version: Avisynth 3.7.1 Beta 6 x64
OS: Windows 10 Enterprise x64
StvG
23rd June 2021, 07:23
Check the last line from the first screenshot: pixel_type=rgb but destination matrix 2020 (yuv).
Dogway
23rd June 2021, 08:44
Check the last line from the first screenshot: pixel_type=rgb but destination matrix 2020 (yuv).
This is one of the many reasons why I started Transforms Pack, no-sense limitations and restrictions in avsresize. YUV 2020 can be converted to RGB 2020, it's even a standard conversion (CL and NCL).
FranceBB
23rd June 2021, 09:15
Check the last line from the first screenshot: pixel_type=rgb but destination matrix 2020 (yuv).
Daaaamn, this is why I shouldn't test things at 6.42 in the morning before having my breakfast...
Version 7 works like a charm now, thanks! ;)
I'm rolling it on all my production server. :D
Now I've got a few MJPEG2000 12bit PQ masterfiles to encode in HLG eheheheh
StvG
29th June 2021, 09:28
avsresize_r8 (https://ppp.woelkli.com/s/nCNwep672C4CzYs) (pass: Zz299Qct9i4P): changed MT mode to MT_MULTI_INSTANCE.
kedautinh12
29th June 2021, 10:31
Thanks
Audionut
30th June 2021, 14:05
Hi, I'm seeing an issues with levels that begun in r7.
This is what the frames should look like.
And this is the output of ComparisonGen.avsi after updating to r7.
Still same issue in r8.
StvG
30th June 2021, 18:01
avsresize_r9 (https://ppp.woelkli.com/s/GMieecQBi2wrMnp) (pass: au7cG6ztmrW4): do not use the same color range for the destination when frame property available and source/destination color family is different;
- set the correct color range frame property value for destination YUV 32-bit.
kedautinh12
1st July 2021, 03:05
thanks
FranceBB
1st July 2021, 12:31
Thanks for the update!
Time to test and then replace it in our production servers. :)
Boulder
23rd July 2021, 12:18
Out of interest, should the value for nominal_luminance be adjusted based on source metadata (=maximum content light level) in case of HDR?
StvG
24th July 2021, 02:31
Out of interest, should the value for nominal_luminance be adjusted based on source metadata (=maximum content light level) in case of HDR?
Check the first two comments from this issue (https://github.com/sekrit-twc/zimg/issues/73).
Ideally you want to set it to the frame peak luminance.
Boulder
24th July 2021, 08:57
Check the first two comments from this issue (https://github.com/sekrit-twc/zimg/issues/73).
Ideally you want to set it to the frame peak luminance.
Thanks, looks like it's not worth it and best just to leave it at the default if unknown. There probably is no tool to find the value by scanning the whole video.
Dogway
24th July 2021, 16:27
@Boulder: runtime yplanemax maybe? Maybe do a first pass analysis.
FranceBB
26th July 2021, 20:00
Thanks, looks like it's not worth it and best just to leave it at the default if unknown. There probably is no tool to find the value by scanning the whole video.
PQStat (https://github.com/wswartzendruber/hlg-tools/tree/main/pqstat) (written by William Swartzendruber, who is also a user of this forum) can do it for you: it's free, open source and written in Rust.
It will scan the whole video and report the right values in nits.
Please note, though, that if you're not scanning a lossless masterfile made of 12bit tiff but rather a consumer relatively low bitrate HEVC .ts file from a broadcasting channel or a consumer UHD-BD HEVC .m2ts file (which also has a low bitrate compared to the master), there are gonna be compression overshooting (i.e outliers) which might affect the overall detection.
(Just as a reference, a ProRes 4K mezzanine file, which is NOT lossless, has 1 Gbit/s as bitrate and it's still losing quality and potentially creating overshooting, so those ARE DEFINITELY GONNA HAPPEN in a "low bitrate" H.265 HEVC file...)
Boulder
26th July 2021, 20:36
PQStat (https://github.com/wswartzendruber/hlg-tools/tree/main/pqstat) (written by William Swartzendruber, who is also a user of this forum) can do it for you: it's free, open source and written in Rust.
It will scan the whole video and report the right values in nits.
Please note, though, that if you're not scanning a lossless masterfile made of 12bit tiff but rather a consumer relatively low bitrate HEVC .ts file from a broadcasting channel or a consumer UHD-BD HEVC .m2ts file (which also has a low bitrate compared to the master), there are gonna be compression overshooting (i.e outliers) which might affect the overall detection.
(Just as a reference, a ProRes 4K mezzanine file, which is NOT lossless, has 1 Gbit/s as bitrate and it's still losing quality and potentially creating overshooting, so those ARE DEFINITELY GONNA HAPPEN in a "low bitrate" H.265 HEVC file...)
Thanks, I'll check that one out.
Wouldn't it actually be better to use the value, overshooting or not, since it's from the source that the decoder gets anyway?
FranceBB
27th July 2021, 10:31
Wouldn't it actually be better to use the value, overshooting or not, since it's from the source that the decoder gets anyway?
Well no.
Simply put: whenever you have a file and it has a waveform and it has a certain set of values and you re-encode it with some kind of compression, those values might not be respected.
What happens is this kind of overshooting, but here's the thing: the overshoot is an outlier.
Simply put: let's suppose that you're looking for the peak brightness in nits in a PQ file and the official metadata say it's 2500 nits. You analyze the file and you find out it's actually 2842 nits. At this point, you set the conversion to respect that and everything looks dark, way darker than it should have been. Why? Easy: the 2842 pixel was indeed the peak, but it was an outlier, which means that although the average was like closer to the right value, every now and then there are few overshoots occurred due to the compression and those will be much higher than the real value. Of course, if you take into account a simple average, what you're gonna get is a skewed result as the outliers are gonna affect the final value of the average brightness, so what you need is to avoid to take those outliers into account, however it would be hard to write a logic around that 'cause you would have to decide how far away a pixel has to go to be considered an outlier, which can be tough. Luckily for us, the standard deviation comes in rescue:
https://www.gstatic.com/education/formulas2/355397047/en/population_standard_deviation.svg
which tells us how much a set of values is disperse/various.
Anyway, we're digressing.
The point is that if you do end up using PQStat or similar tools on compressed files, you're gonna have to take the results with a pinch of salt, so always remember to look at the waveform and to trust your eyes as well. :)
Small size over and undershoots can be removed with low-pass filtering or blurring. Like gauss-blur with enough radius. And the medium and large size details levels can be analyzed for min/max/average .
StvG
12th August 2021, 22:01
avsresize_r10 (https://ppp.woelkli.com/s/iw6jdxokxfBsdWX) (pass: 7fgQwBn9zreN): do not set matrix frame property when source matrix frame property is undef and color family is not changed;
- zimg@bf73dbe.
FranceBB
13th August 2021, 12:53
Thanks for the new build and most importantly thanks for making the plugin in the first place.
I wouldn't have been able to encode some Studio RGB 12bit PQ masterfiles by reliably applying my non-public LUTs without messing up with the levels without this one.
You saved me in a certain sense. ;)
StvG
18th November 2021, 01:35
avsresize_r11 (https://ppp.woelkli.com/s/Pndi2kQnJz6AiLB) (pass: 2bzWmpDAZbk8): added parameter use_props (whether to read and set frame properties);
- zimg 3.0.3.
Boulder
18th November 2021, 06:26
Thank you for the new version :)
Would it be possible to add an option to use properties from a different clip than the source for the colorspace_op (and maybe chromaloc_op)? My use case is a simple "original clip" -> "convert to linear RGB and downscale" -> "convert back to original colorspace".
DTL
18th November 2021, 08:27
use case is a simple "original clip" -> "convert to linear RGB and downscale" -> "convert back to original colorspace".'
If you use typical chroma subsampled input and output to this 'simple' - it is really very complex. Because chroma subsampling introduce distortions that can not be completely fixed in 'linear processing'. To better fix the both luma and chroma distortions of nonlinear systems the 'non-linear' that is content-adaptive processing required. Also to build the better processing the standartization of chroma antialiasing filter in display device required (or standartization of other display subsampled-decompressor if it finally going out of 'linear processing' at all).
So the playing 'simple' games around chroma-loc and 'going to linear' that is not perfectly possible from chroma-subsampled ugly old lossy compression still not allow to get best possible results. The distortions raises with saturation of colours and sharpness of colour transients.
So if the developer of z.lib reads here - may be try to add some content-adaptive non-linear resizer methods too to this library of functions.
FranceBB
18th November 2021, 22:55
avsresize_r11 (https://ppp.woelkli.com/s/Pndi2kQnJz6AiLB) (pass: 2bzWmpDAZbk8): added parameter use_props (whether to read and set frame properties);
- zimg 3.0.3.
It's always nice to see developers beginning to use the new Avisynth+ 3.7.1 frame properties. Well done and thanks! :)
StvG
19th November 2021, 07:37
Thank you for the new version :)
Would it be possible to add an option to use properties from a different clip than the source for the colorspace_op (and maybe chromaloc_op)? My use case is a simple "original clip" -> "convert to linear RGB and downscale" -> "convert back to original colorspace".
Can you elaborate why would you use different frame properties than ones of the source clip?
It's always nice to see developers beginning to use the new Avisynth+ 3.7.1 frame properties. Well done and thanks! :)
After r3 frame properties are always read and set when the avs+ version supports them.
When every option of colorspace_op is specified (matrix, transfer, primaries, range) and different than "auto", use_props=false can be used for higher fps.
But now I'm seeing that use_props=false doesn't pass frame properties (removes the frame properties). Another version is needed to fix that.
Boulder
19th November 2021, 08:34
Can you elaborate why would you use different frame properties than ones of the source clip?
In that phase, the source clip is in RGB. It's basically YUV420P16 (BT709 or BT2020) -> linear RGB, downscale -> YUV420P16 (original format) -> feed to x265 for encoding.
StvG
19th November 2021, 09:22
In that phase, the source clip is in RGB. It's basically YUV420P16 (BT709 or BT2020) -> linear RGB, downscale -> YUV420P16 (original format) -> feed to x265 for encoding.
You want to use the frame properties of "YUV420P16 (BT709 or BT2020)" as target matrix/transfer/primaries... when doing "linear RGB, downscale -> YUV420P16" ?
Boulder
19th November 2021, 09:33
You want to use the frame properties of "YUV420P16 (BT709 or BT2020)" as target matrix/transfer/primaries... when doing "linear RGB, downscale -> YUV420P16" ?
Yes, that's the idea.
StvG
21st November 2021, 11:06
avsresize_r12 (https://ppp.woelkli.com/s/dTceZSPdLf4YDjQ) (pass: oPrkZ7IH132A): changed use_props type from bool to int.
use_props (default -1) - whether to read and set frame properties:
-1: If frame properties are supported - if every option of colorspace_op and chromaloc_op are specified and different than "auto", 0, otherwise 1.
If frame properties are not supported - 0.
0: If frame properties are supported - only set frame properties.
1: Read and set frame properties.
2: Save properties of the source clip as frame properties: z_ChromaLocation, z_ColorRange, z_Matrix, z_Transfer, z_Primaries.
Every option of colorspace_op and chromaloc_op must be specified and different than "auto".
3: Save properties of the source clip as frame properties: z_ChromaLocation, z_ColorRange, z_Matrix, z_Transfer, z_Primaries.
Frame properties _ChromaLocation, _ColorRange, _Matrix, _Transfer, _Primaries must exist.
Frame properties _Matrix, _Transfer, _Primaries must have values different than 2 (unspec).
4: Use z_xxx frame properties as target values.
z_xxx frame propeties are removed after the colorspace conversion.
use_props=0 is faster than use_props=1
use_props=2 is faster than use_props=3
Example use_props=2 and use_props=4
z_ConvertFormat(pixel_type="rgbp", colorspace_op="709:709:709:l=>rgb:linear:709:f", chromaloc_op="left=>left", use_props=2)
z_ConvertFormat(pixel_type="yv12", use_props=4) # convert rgb to yuv with the yuv initial properties
Example use_props=3 and use_props=4
z_ConvertFormat(pixel_type="rgbp", colorspace_op="709:709=>rgb:linear", use_props=3)
z_ConvertFormat(pixel_type="yv12", use_props=4) # convert rgb to yuv with the yuv initial properties
FranceBB
22nd November 2021, 10:29
Well, looks like it works! :D
#Indexing the HDR10 PQ BT2100 4:2:2 10bit planar source
video=FFVideoSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov")
ch1=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=1)
ch2=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=2)
ch3=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=3)
ch4=FFAudioSource("\\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=4)
ch5=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=5)
ch6=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=6)
ch7=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=7)
ch8=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=8)
ch9=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=9)
ch10=FFAudioSource("\\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=10)
ch11=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=11)
ch12=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=12)
ch13=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=13)
ch14=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=14)
ch15=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=15)
ch16=FFAudioSource("\\mibcisilonsc\avisynth\Scambio\FILM\Harry Potter and The Chamber of Secrets\HARRYPOTTERANDTHECHAMBEROFSECRETS_FEA_HDR_REC2020PQ_444F_PR444_2160P23-20211024145222.mov", track=16)
audio=MergeChannels(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16)
AudioDub(video, audio)
#From 4:2:2 10bit to 4:2:2 16bit planar
ConvertBits(16)
#From 4:2:2 16bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#From PQ to HLG with 16bit precision
Cube("\\mibcisilonsc\avisynth\Server\encoder\encoder\Processors\avs_plugins\LUTs\WarnerBros_PQToHLG_MaxCLL_2508.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV422 10bit planar Narrow Range with dithering
z_ConvertFormat(pixel_type="YUV422P10", colorspace_op="rgb:std-b67:2020:limited=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#Clipping
Limiter(min_luma=64, max_luma=940, min_chroma=64, max_chroma=960)
Prefetch(8)
correctly reports std-b67 which stands for arib-std-b67 which is HLG in the frame properties! :D
https://i.imgur.com/tjBEizV.png
ErazorTT
7th January 2022, 01:12
I would like to report that the dithering methods ordered, random, error_diffusion of the z_ConvertFormat function return slightly different averaged values.
So when having big single color patches like in test patterns, the averages over all pixels are slightly different for the methods.
I admit that the difference is small (9 in the full range of 0-32768 which equals 0.07 for the range of 0-255). But still for 16 bit clips this would be measurable.
I put all the screenshots in the folder and also the saved pictures from the clip, which can be opened an checked:
https://drive.google.com/drive/folders/1kbs9ndCz4cI_NLx5Z1dX_gpi_aJVCEpn?usp=sharing
If this is expected, then which method is nearer to the true average?
kedautinh12
7th January 2022, 03:00
I would like to report that the dithering methods ordered, random, error_diffusion of the z_ConvertFormat function return slightly different averaged values.
So when having big single color patches like in test patterns, the averages over all pixels are slightly different for the methods.
I admit that the difference is small (9 in the full range of 0-32768 which equals 0.07 for the range of 0-255). But still for 16 bit clips this would be measurable.
I put all the screenshots in the folder and also the saved pictures from the clip, which can be opened an checked:
https://drive.google.com/drive/folders/1kbs9ndCz4cI_NLx5Z1dX_gpi_aJVCEpn?usp=sharing
If this is expected, then which method is nearer to the true average?
I think it's faster than convertbits. Maybe can replace convertbits in TemporalDegrain2???
StvG
8th January 2022, 01:12
I would like to report that the dithering methods ordered, random, error_diffusion of the z_ConvertFormat function return slightly different averaged values.
So when having big single color patches like in test patterns, the averages over all pixels are slightly different for the methods.
I admit that the difference is small (9 in the full range of 0-32768 which equals 0.07 for the range of 0-255). But still for 16 bit clips this would be measurable.
I put all the screenshots in the folder and also the saved pictures from the clip, which can be opened an checked:
https://drive.google.com/drive/folders/1kbs9ndCz4cI_NLx5Z1dX_gpi_aJVCEpn?usp=sharing
If this is expected, then which method is nearer to the true average?
It's expected. About the choice of the dither algorithm - you can check this thread (https://forum.doom9.org/showthread.php?t=172266).
For info:
- colorspace_op conversions are done in float and then dither to the target bit depth (if different than float);
- resize operations are done in 16-bit (if source/target are not float) and then dither to the target bit depth (if target lower than source and lower than 16/32-bit).
ErazorTT
10th January 2022, 01:21
I think it's faster than convertbits. Maybe can replace convertbits in TemporalDegrain2???
Really? I’ve never benchmarked that. I would assume that both are orders of magnitudes faster than anything TemporalDegrain2 is doing.
tormento
11th January 2022, 10:56
Really? I’ve never benchmarked that. I would assume that both are orders of magnitudes faster than anything TemporalDegrain2 is doing.
fmtc_bitdepth works really fine too.
Boulder
25th January 2022, 06:08
It's expected. About the choice of the dither algorithm - you can check this thread (https://forum.doom9.org/showthread.php?t=172266).
For info:
- colorspace_op conversions are done in float and then dither to the target bit depth (if different than float);
- resize operations are done in 16-bit (if source/target are not float) and then dither to the target bit depth (if target lower than source and lower than 16/32-bit).
If the process chain is denoise -> downscale -> deband, is it better to leave dithering out of the downscaling phase, since debanding also does some sort of dithering (f.ex. f3kdb)?
StvG
25th January 2022, 23:31
If the process chain is denoise -> downscale -> deband, is it better to leave dithering out of the downscaling phase, since debanding also does some sort of dithering (f.ex. f3kdb)?
It depends. If your source is 10-bit (it will be valid for any bit depth < 16-bit):
a) if denoise in source bit depth (10-bit), downscale w/o bit depth change (10-bit->16-bit->10-bit - how internally avsresize will scale), deband w/o bit depth change (assume f3kdb: 10->16-bit->10-bit - how internally f3kdb will deband)
b) convert to 16-bit, denoise, downscale, deband, convert to source bit depth (10-bit)
For a) it's better to apply dither after the downscaling.
For b) 16-bit->10-bit is done only once at the end - dither.
If the speed penalty of b) isn't the bottleneck, it should be always the preferred option imo.
Boulder
26th January 2022, 06:05
It depends. If your source is 10-bit (it will be valid for any bit depth < 16-bit):
a) if denoise in source bit depth (10-bit), downscale w/o bit depth change (10-bit->16-bit->10-bit - how internally avsresize will scale), deband w/o bit depth change (assume f3kdb: 10->16-bit->10-bit - how internally f3kdb will deband)
b) convert to 16-bit, denoise, downscale, deband, convert to source bit depth (10-bit)
For a) it's better to apply dither after the downscaling.
For b) 16-bit->10-bit is done only once at the end - dither.
If the speed penalty of b) isn't the bottleneck, it should be always the preferred option imo.
For 8- or 10-bit sources, I do the denoising part in 16 bits. Then that is fed to the downscaling part, where it's converted to linear RGBPS, downscaled and converted to YUV420P16. Then debanding without any bitdepth change, fed to the encoder (x265) as 16-bit and the internal dithering is enabled to get the final 10-bit output. So based on your answer, I think it's best that dithering is disabled wherever possible and allow it only at the encoder phase.
By the way, what is the difference between converting the format and resizing in the same z_ConvertFormat call and doing it in two different calls (resizing first, then converting to the final format)? I tested it yesterday and there seems to be a rather noticable performance drop if you use two calls.
FranceBB
26th January 2022, 10:20
[...] fed to the encoder (x265) as 16-bit and the internal dithering is enabled to get the final 10-bit output.
I do exactly the same.
No matter if the source is 8bit, 10bit or 12bit planar, I always bring everything to 16bit planar, filter everything out and feed the encoder with the 16bit input.
My outputs are always 10bit, so x264 will dither it down using the Sierra-2-4A algorithm, while x265 will use... something else.
Speaking of which, what will x265 use with --dither? I mean, which algorithm?
I know we've been having this conversation before but I forgot xD
Reel.Deel
26th January 2022, 10:51
I try to do everything in one go (if possible). Sometimes doing 2 steps can be detrimental. For example, I saw this script in another thread:
LWLibavVideoSource("video.uhd.rmx.mkv",cachefile="video.lwi",format="YUV420P16",decoder="hevc_qsv",prefer_hw=2) # hw
# (avsresize.dll)
z_Spline36Resize(1920,1080) # FHD
# Converting format (avsresize.dll)
z_ConvertFormat(pixel_type="RGBP16",colorspace_op="2020:st2084:2020:l=>rgb:st2084:2020:f",dither_type="none")
# Apply LUT (vscube.dll) input full / output full HLG
Cube("hlg-tools65.cube",fullrange=true) # max-cll 1000
# Converting format (avsresize.dll)
z_ConvertFormat(pixel_type="YUV420P16",colorspace_op="rgb:std-b67:2020:f=>2020ncl:std-b67:2020:l",dither_type="error_diffusion")
The source is 4k and it's getting resized down to 1920x1080 YUV420 and then converted to RGB16. Here the chroma is going from 1920x1080 down to 960x540 and then scaled back up to 1080p when converted to RGB. Sure, after applying the LUT it is converted back to YUV420 and the chroma size is back again down to 960x540. Most wont even be able to tell the difference but it still does unnecessary processing. source.z_ConvertFormat(1920,1080, pixel_type="RGBP16",...) would be higher fidelity. At least that is how dither works when you resize and change format at the same time. In this scenario you can even go from UHD YUV4:2:0 down to FHD YUV4:4:4 without even resizing the chroma planes. Provided that the luma channel gets independently resized with src_left=-0.50, src_top=-0.50 to account for the chroma placement shift (top left in this case, assuming source is uhd bluray). After that, merge the luma with the original chroma planes, convert to RGB and proceed :).
Edit: re-reading the last few post, seems my comment is somewhat not related to the discussion. But, I'll leave it here since it's still relevant to the thread. I should be asleep lol.
Boulder
26th January 2022, 11:35
I do exactly the same.
No matter if the source is 8bit, 10bit or 12bit planar, I always bring everything to 16bit planar, filter everything out and feed the encoder with the 16bit input.
My outputs are always 10bit, so x264 will dither it down using the Sierra-2-4A algorithm, while x265 will use... something else.
Speaking of which, what will x265 use with --dither? I mean, which algorithm?
I know we've been having this conversation before but I forgot xD
From api.cpp: "The dithering algorithm is based on Sierra-2-4A error diffusion." It's probably identical to x264, why re-invent the wheel since they ported other stuff as well.
StvG
27th January 2022, 01:51
By the way, what is the difference between converting the format and resizing in the same z_ConvertFormat call and doing it in two different calls (resizing first, then converting to the final format)? I tested it yesterday and there seems to be a rather noticable performance drop if you use two calls.
If you mean something like this:z_ConvertFormat(pixel_type="rgbps", colorspace_op="709:709:709:l=>rgb:linear:709:f", chromaloc_op="left=>left")
z_BicubicResize(x, y)
z_ConvertFormat(pixel_type="yuv420p16", colorspace_op="rgb:linear:709:f=>709:709:709:l", chromaloc_op="left=>left")
z_ConvertFormat(pixel_type="rgbps", colorspace_op="709:709:709:l=>rgb:linear:709:f", chromaloc_op="left=>left")
z_ConvertFormat(x, y, pixel_type="yuv420p16", colorspace_op="rgb:linear:709:f=>709:709:709:l", chromaloc_op="left=>left")
These variants give identical results. The first one have some overhead that could have some penalty for the final speed. My quick test shows ~7% difference. If frame properties are involved I would say there is no speed difference.
StvG
15th April 2022, 04:52
avsresize_r13 (https://ppp.woelkli.com/s/F478Yf3WQkRtXqW) (pass: f0MNKlTxVxl5):
- zimg@dd4c4df;
- use_props= -1: If frame properties are supported - if every option of colorspace_op and chromaloc_op (for src/dst colorspace with subsampling w/h > 0) are specified and different than "auto", 0, otherwise 1.
FranceBB
15th April 2022, 08:29
ffms2_6ad7738 (https://ppp.woelkli.com/s/NMk6MyD6LZR7nYH) (pass: u7Uezbh3fTHM):
- ffms2@90975ec;
- ffmpeg n5.1@1764a6887b;
- zlib 1.2.12;
- dav1d 1.0.0;
- AviSynth: set Dolby Vision RPU data in frame props.
Thanks, works perfectly on Windows 11 x64 and Windows Server 2019 x64. :)
FFMpegSource2("\\mibctvan000.avid.mi.bc.sky.it\Ingest\MEDIA\temp\test_PCM_DolbyE_PCM_PCM.mxf", atrack=-1)
propClearAll()
#From 4:2:0 16bit planar Narrow Range to RGB Planar 16bit Full Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="709:709:709:limited=>rgb:709:709:full", dither_type="error_diffusion")
#From BT709 SDR to BT2020 HDR HLG with 16bit precision
Cube("C:\Program Files (x86)\AviSynth+\LUTs\5a_BT709_HLG_UPCONVERT_DISPLAY_mode-nar_in-nar_out-nar_nocomp.cube", fullrange=true)
#From RGB 16bit planar Full Range to YUV422 10bit planar Narrow Range with dithering
z_ConvertFormat(pixel_type="YUV422P10", colorspace_op="rgb:std-b67:2020:full=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
to deliver a cool nice 75% ref white HLG output. :)
https://i.imgur.com/Sj1hJ3A.png
Cheers,
Frank
Boulder
18th April 2022, 15:44
Using props=4 causes an access violation on my system. Tested with this:
z_ConvertFormat(pixel_type="RGBPS", chromaloc_op="auto=>same", colorspace_op="auto:auto:auto:auto=>rgb:linear:same:full", approximate_gamma=true, cpu_type="AVX2", use_props=3)
z_ConvertFormat(pixel_type="YUV420P16", chromaloc_op="auto=>same", resample_filter="Bicubic", resample_filter_uv="Bicubic", filter_param_a=0, filter_param_b=0.6, width=960, height=720, cpu_type="AVX2", dither_type="none", approximate_gamma=true, use_props=4)
StvG
19th April 2022, 06:00
avsresize_r14 (https://ppp.woelkli.com/s/bD6xpSyDgdZjW9a) (pass: QOvyNpMf5TyF) - fixed regression (r12) when reading frame properties (use_props=3/4).
Boulder
19th April 2022, 07:10
avsresize_r14 (https://ppp.woelkli.com/s/bD6xpSyDgdZjW9a) (pass: QOvyNpMf5TyF) - fixed regression (r12) when reading frame properties (use_props=3/4).
Still the same problem with this one.
StvG
19th April 2022, 12:25
Still the same problem with this one.
Download again the r14. You will see error that chromaloc_op (colospace_op too) must be not specified when use_props=4.
Boulder
19th April 2022, 14:40
Download again the r14. You will see error that chromaloc_op (colospace_op too) must be not specified when use_props=4.
Thanks, works now :)
Stephen R. Savage
6th July 2022, 01:26
Released r2:
Update to z.lib 3.0
Enable 64-byte alignment
Support real Spline64Resize
Support alpha-aware resizing
Implement multi-threading
kedautinh12
6th July 2022, 04:44
Hmm, 2 version?
FranceBB
6th July 2022, 13:12
What do you mean by "real" Spline64Resize?
Reel.Deel
6th July 2022, 14:34
What do you mean by "real" Spline64Resize?
Up until 2 years ago or so, Spline64Resize was just an alias for Spline32Resize. z.lib added the spline64 filter in v2.9.3.
tormento
6th July 2022, 14:41
Hmm, 2 version?
First number major buiid, second number minor release? :confused:
Reel.Deel
6th July 2022, 15:18
First number major buiid, second number minor release? :confused:
Stephen R. Savage is the original author of avsresize (and z.lib). He released the first version of avsresize (r1) back in 2016 and then some periodic updates. The last update was r1d in March of 2018. StvG then continued updating the plugin ever since, up to r14 now.
kedautinh12
6th July 2022, 16:07
Stephen R. Savage is the original author of avsresize (and z.lib). He released the first version of avsresize (r1) back in 2016 and then some periodic updates. The last update was r1d in March of 2018. StvG then continued updating the plugin ever since, up to r14 now.
And r2 is continued update of r14??
TomArrow
2nd August 2022, 17:03
I've a quick question about z_ConvertFormat. Does it write any usually not visible metadata to the clip that a software like ffmpeg can use? A friend reported that in conjunction with ffmpeg, using this filter (just doing a straight conversion to the same color space) can result in changes to the output file in terms of metadata, transfer characteristic specifically.
Of course this doesn't have to be a bad thing per se, but it would be good to know.
FranceBB
2nd August 2022, 18:56
I think it does make use of frame properties, so if you're using a recent version of Avisynth and a frame properties enabled build of ffmpeg, it will read them.
This is just an example:
#Indexing ProRes HQ 4:2:2 23,976p 10bit planar HDR PQ source
video=LWLibavVideoSource("KFH00862.mov")
ch1=LWLibavAudioSource("KFH00862.mov", stream_index=1)
ch2=LWLibavAudioSource("KFH00862.mov", stream_index=2)
ch3=LWLibavAudioSource("KFH00862.mov", stream_index=3)
ch4=LWLibavAudioSource("KFH00862.mov", stream_index=4)
ch5=LWLibavAudioSource("KFH00862.mov", stream_index=5)
ch6=LWLibavAudioSource("KFH00862.mov", stream_index=6)
ch7=LWLibavAudioSource("KFH00862.mov", stream_index=7)
ch8=LWLibavAudioSource("KFH00862.mov", stream_index=8)
ch9=LWLibavAudioSource("KFH00862.mov", stream_index=9)
ch10=LWLibavAudioSource("KFH00862.mov", stream_index=10)
ch11=LWLibavAudioSource("KFH00862.mov", stream_index=11)
ch12=LWLibavAudioSource("KFH00862.mov", stream_index=12)
ch13=LWLibavAudioSource("KFH00862.mov", stream_index=13)
ch14=LWLibavAudioSource("KFH00862.mov", stream_index=14)
ch15=LWLibavAudioSource("KFH00862.mov", stream_index=15)
ch16=LWLibavAudioSource("KFH00862.mov", stream_index=16)
audio=MergeChannels(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16)
AudioDub(video, audio)
#From 4:2:2 10bit to 4:2:2 16bit planar
ConvertBits(16)
#From 4:2:2 16bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:2020:2020:limited=>rgb:2020:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#From PQ to HLG with 16bit precision
Cube("WarnerBros_PQToHLG_MaxCLL_2752.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV422 16bit planar Narrow Range
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:2020:2020:limited=>2020:2020:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#Filling the right frame properties with HLG
propset("_Transfer", 18)
#Speed-up + pitch adjustment
ResampleAudio(48000)
AssumeFPS(25, 1, false)
TimeStretch(tempo=100.0*25.0/(24000.0/1001.0))
ResampleAudio(48000)
#Clipping
Limiter(min_luma=4096, max_luma=60160, min_chroma=4096, max_chroma=60160)
as you can see here I'm populating the transfer characteristics value with the right one, in fact this is the important bit:
#Filling the right frame properties with HLG
propset("_Transfer", 18)
which will set the arib-std-b67 transfer, so HLG, so that when FFMpeg is gonna read the script with -i "AVS Script.avs" it will read them correctly.
If you wanna be absolutely sure that frame properties are set correctly, you can check them with AVSPmod and eventually populate them accordingly yourself, otherwise you can always use propClearAll() right after indexing and everything will be business as usual (I generally prefer the latter).
StvG
3rd August 2022, 09:14
It's probably better that a moderator to move posts from #109 (https://forum.doom9.org/showthread.php?p=1906771#post1906771) to #213 (https://forum.doom9.org/showthread.php?p=1967712#post1967712) (including) in a separate thread to avoid confusions between the two builds.
At the moment the main diff between the builds(r2 (https://forum.doom9.org/showthread.php?p=1971316#post1971316) and r14 (https://forum.doom9.org/showthread.php?p=1967682#post1967682)):
- how alpha plane is treated: r2 - ZIMG_ALPHA_STRAIGHT; r14 - ZIMG_ALPHA_PREMULTIPLIED
- r14 has additional pixel types aliases - RGBP8, RGBAP8, YUV444, YUV444P8, YUVA444P8, YUV422, YUV422P8, YUVA422P8, YUV420, YUV420P8 , YUVA420P8, YUV411, YUV411P8
- r14 has additional chroma locations - TOP_LEFT, TOP, BOTTOM_LEFT, BOTTOM
- r2 has additional chroma location alias - dv (LEFT)
- r2 has additional resample aliases - gauss (BICUBIC), lanczos4 (LANCZOS), blackman (LANCZOS), sinc (LANCZOS), z_BlackmanResize (LANCZOS), z_GaussResize (BICUBIC), z_SincResize (LANCZOS)
- r14 has additional args: cpu_type, nominal_luminance, approximate_gamma, use_props
- r14 has support for frame properties
- r14 has additional args for the compatibility wrappers (z_xxResize) - chromaloc_op, dither
Btw r2 still has the parsing bug when colospace_op values with dash are used - for example std-b67/st431-2...
DTL
3rd August 2022, 09:56
As the jpsdr post at https://forum.doom9.org/showthread.php?p=1970987#post1970987 -
I don't know what the others plugins output, neither what they expect in input. "linear", but wich one ? scene linear light and scaled by camera exposure or displayed linear ?
Can the z.lib switch between different 'linear' conversions from HDR formats ?
Following tests at https://forum.doom9.org/showthread.php?p=1970995#post1970995 shows that the OOTF on/off at the process of conversion system transfer to 'linear' looks like make the main difference. The difference is not great and may be too few persons now make processing in linear to detect this difference at real footage.
StvG
4th August 2022, 13:32
As the jpsdr post at https://forum.doom9.org/showthread.php?p=1970987#post1970987 -
I don't know what the others plugins output, neither what they expect in input. "linear", but wich one ? scene linear light and scaled by camera exposure or displayed linear ?
Can the z.lib switch between different 'linear' conversions from HDR formats ?
Following tests at https://forum.doom9.org/showthread.php?p=1970995#post1970995 shows that the OOTF on/off at the process of conversion system transfer to 'linear' looks like make the main difference. The difference is not great and may be too few persons now make processing in linear to detect this difference at real footage.
zimg itself can switch between scene-referred and display-referred case (here (https://github.com/sekrit-twc/zimg/blob/797024c67be7ffd959da381adf7b0164029ef3e5/src/zimg/colorspace/gamma.cpp#L342-L353)) but this option is not api exposed so the avs/vs plugin is using only the display-referred one.
DTL
4th August 2022, 14:32
Can the OOTF stage be simulated as some AVS scripting after 'first stage conversion to linear' with zimg-AVS plugin ? To get 'scene-referred' too if required ?
"but this option is not api exposed"
May be it can be feature-request and API supplement and finally go into next plugin version ?
So for sources 'conditioned' in 'scene-linear light' it can be used as a one-step conversion from HDR transfer encoded form into linear for scaling or other processing.
TomArrow
4th August 2022, 23:23
I think it does make use of frame properties, so if you're using a recent version of Avisynth and a frame properties enabled build of ffmpeg, it will read them.
This is just an example:
#Indexing ProRes HQ 4:2:2 23,976p 10bit planar HDR PQ source
video=LWLibavVideoSource("KFH00862.mov")
ch1=LWLibavAudioSource("KFH00862.mov", stream_index=1)
ch2=LWLibavAudioSource("KFH00862.mov", stream_index=2)
ch3=LWLibavAudioSource("KFH00862.mov", stream_index=3)
ch4=LWLibavAudioSource("KFH00862.mov", stream_index=4)
ch5=LWLibavAudioSource("KFH00862.mov", stream_index=5)
ch6=LWLibavAudioSource("KFH00862.mov", stream_index=6)
ch7=LWLibavAudioSource("KFH00862.mov", stream_index=7)
ch8=LWLibavAudioSource("KFH00862.mov", stream_index=8)
ch9=LWLibavAudioSource("KFH00862.mov", stream_index=9)
ch10=LWLibavAudioSource("KFH00862.mov", stream_index=10)
ch11=LWLibavAudioSource("KFH00862.mov", stream_index=11)
ch12=LWLibavAudioSource("KFH00862.mov", stream_index=12)
ch13=LWLibavAudioSource("KFH00862.mov", stream_index=13)
ch14=LWLibavAudioSource("KFH00862.mov", stream_index=14)
ch15=LWLibavAudioSource("KFH00862.mov", stream_index=15)
ch16=LWLibavAudioSource("KFH00862.mov", stream_index=16)
audio=MergeChannels(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16)
AudioDub(video, audio)
#From 4:2:2 10bit to 4:2:2 16bit planar
ConvertBits(16)
#From 4:2:2 16bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:2020:2020:limited=>rgb:2020:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#From PQ to HLG with 16bit precision
Cube("WarnerBros_PQToHLG_MaxCLL_2752.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV422 16bit planar Narrow Range
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:2020:2020:limited=>2020:2020:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
#Filling the right frame properties with HLG
propset("_Transfer", 18)
#Speed-up + pitch adjustment
ResampleAudio(48000)
AssumeFPS(25, 1, false)
TimeStretch(tempo=100.0*25.0/(24000.0/1001.0))
ResampleAudio(48000)
#Clipping
Limiter(min_luma=4096, max_luma=60160, min_chroma=4096, max_chroma=60160)
as you can see here I'm populating the transfer characteristics value with the right one, in fact this is the important bit:
#Filling the right frame properties with HLG
propset("_Transfer", 18)
which will set the arib-std-b67 transfer, so HLG, so that when FFMpeg is gonna read the script with -i "AVS Script.avs" it will read them correctly.
If you wanna be absolutely sure that frame properties are set correctly, you can check them with AVSPmod and eventually populate them accordingly yourself, otherwise you can always use propClearAll() right after indexing and everything will be business as usual (I generally prefer the latter).
Thanks! That could explain it.
StvG
5th August 2022, 19:39
avsresize_r15 (https://ppp.woelkli.com/s/QN4X5AjsKcbAnTj) (pass: gjFnhBCshVL3):
- relaxed restrictions for use_props=0;
- added scene_referred parameter (default false).
... otherwise you can always use propClearAll() right after indexing and everything will be business as usual (I generally prefer the latter).
If you don't want the source frame properties to be read use "use_props=0". The performance would be better than propClearAll() and checking for source frame properties.
Can the OOTF stage be simulated as some AVS scripting after 'first stage conversion to linear' with zimg-AVS plugin ? To get 'scene-referred' too if required ?
"but this option is not api exposed"
May be it can be feature-request and API supplement and finally go into next plugin version ?
So for sources 'conditioned' in 'scene-linear light' it can be used as a one-step conversion from HDR transfer encoded form into linear for scaling or other processing.
Try the new scene_referred parameter.
DTL
5th August 2022, 21:57
Try the new scene_referred parameter.
It finally work about as expected https://forum.doom9.org/showthread.php?p=1972723#post1972723 but looks the float RGB values are very different for each plugin and require deep correction with 'magic numbers' like about 3.0 gain for one plugin and 0.157 for avsresize. But finally it can convert 10bit HLG YUV codevalues into rec709 via RGB-linear-float path with 'exact' precision in 8bit R'G'B' output. And the intermediate values forming transient looks about good too.
FranceBB
6th August 2022, 16:22
If you don't want the source frame properties to be read use "use_props=0". The performance would be better than propClearAll() and checking for source frame properties.
Gotcha, will do! :)
#From 4:2:2 16bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:2020:2020:limited=>rgb:2020:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)
#From PQ to HLG with 16bit precision
Cube("\\myserver.local\avdb\Server\encoder\encoder\Processors\avs_plugins\LUTs\WarnerBros_PQToHLG_MaxCLL_2752.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV422 16bit planar Narrow Range
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:2020:2020:limited=>2020:2020:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)
#Filling the right frame properties with HLG
propset("_Transfer", 18)
StvG
6th August 2022, 18:58
Gotcha, will do! :)
#From 4:2:2 16bit planar Narrow Range to RGB Planar 16bit Narrow Range
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:2020:2020:limited=>rgb:2020:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)
#From PQ to HLG with 16bit precision
Cube("\\myserver.local\avdb\Server\encoder\encoder\Processors\avs_plugins\LUTs\WarnerBros_PQToHLG_MaxCLL_2752.cube", fullrange=true)
#From RGB 16bit planar Narrow Range to YUV422 16bit planar Narrow Range
z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:2020:2020:limited=>2020:2020:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0)
#Filling the right frame properties with HLG
propset("_Transfer", 18)
The last line propset("_Transfer", 18) can be omitted by using z_ConvertFormat(pixel_type="YUV422P16", colorspace_op="rgb:std-b67:2020:limited=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion", use_props=0).
FranceBB
8th August 2022, 12:45
Thanks, I have updated my scripts! :)
I have another question, though.
I have a BT601 SD 25i TFF source that I want to convert to BT709 but I want to leave interlacing alone.
Of course I could just bob, use z_ConvertFormat() and then separatefields() etc, but I'd like to avoid that.
I noticed that in z_ConvertFormat() there's "interlaced" as a parameter that can be either true or false, however if I set it to "true", it says "Interlaced operation not supported":
video=FFVideoSource("G:\txmaster\sd\PRM7_0247234_SD_Remuxed_v2.mxf")
ch1=FFAudioSource("G:\txmaster\sd\PRM7_0247234_SD_Remuxed_v2.mxf", track=1)
ch2=FFAudioSource("G:\txmaster\sd\PRM7_0247234_SD_Remuxed_v2.mxf", track=2)
audio=MergeChannels(ch1, ch2)
AudioDub(video, audio)
propclearall()
z_ConvertFormat(colorspace_op="470bg:470bg:470bg:limited=>709:709:709:limited", pixel_type="YUV422P10", resample_filter="lanczos", dither_type="error_diffusion", interlaced=true, use_props=0)
https://i.imgur.com/vqBbPjF.png
why?
this works but I'd like to avoid it:
video=FFVideoSource("G:\txmaster\sd\PRM7_0247234_SD_Remuxed_v2.mxf")
ch1=FFAudioSource("G:\txmaster\sd\PRM7_0247234_SD_Remuxed_v2.mxf", track=1)
ch2=FFAudioSource("G:\txmaster\sd\PRM7_0247234_SD_Remuxed_v2.mxf", track=2)
audio=MergeChannels(ch1, ch2)
AudioDub(video, audio)
propclearall()
Bob()
z_ConvertFormat(colorspace_op="470bg:470bg:470bg:limited=>709:709:709:limited", pixel_type="YUV422P10", resample_filter="lanczos", dither_type="error_diffusion", interlaced=false, use_props=0)
assumeTFF()
separatefields()
selectevery(4,0,3)
weave()
https://i.imgur.com/o8F77C0.png
StvG
9th August 2022, 00:34
The support for interlaced video isn't added. Btw why propclearall() when you have use_props=0?
FranceBB
9th August 2022, 05:48
I see...
Will it ever be added?
As to propclearall (), if I don't use it, even if avsresize won't use them with use_props=0, it won't nuke them, so they would still be there which is even worse 'cause at that point they would just be wrong and not updated.
EDIT: Actually, you're right, use_props=0 make it not read them but still set them, so they're gonna be correct, my bad. ;)
StvG
10th August 2022, 01:52
avsresize_r16 (https://ppp.woelkli.com/s/dMg9tfxFHRsQjaC) (pass: ZrDjU0BAGRha):
- improved use_props=-1;
- throw error when use_props=0 and _FieldBased/_Field > 0;
- added support for interlaced clips: when interlaced=true, always use_props=0.
FranceBB
10th August 2022, 08:19
What a lovely morning present.
Yesterday Donald gifted the community with a CUDA porting of Cube(), today you introduced interlaced = true support in avsresize.
I wonder what's gonna be next... :D
kedautinh12
10th August 2022, 13:47
What a lovely morning present.
Yesterday Donald gifted the community with a CUDA porting of Cube(), today you introduced interlaced = true support in avsresize.
I wonder what's gonna be next... :D
Thanks for info of CUDA ver of cube but where's the link?
tormento
10th August 2022, 15:04
Thanks for info of CUDA ver of cube but where's the link?
Here (https://www.rationalqm.us/board/viewtopic.php?f=14&t=1180)
FranceBB
10th August 2022, 15:35
ehehehe, you know, Tormento is my drug-deal--- ehm I mean DLL dealer too! Especially for GPU-related stuff eheheheh
StvG
13th August 2022, 17:12
avsresize_r17 (https://ppp.woelkli.com/s/q7RYetopF5ayjFq) (pass: OPtHxyD16GmI): use_props=-1 improved a bit more.
StvG
14th August 2022, 20:15
avsresize_r18 (https://ppp.woelkli.com/s/GecgF4CDQrjmKse) (pass: MzYJG3B0mt0M): fixed output frame properties when use_props=0 and colorspace_op/chromaloc_op not specified.
FranceBB
14th August 2022, 20:31
Thank you.
Tomorrow is bank holiday in Italy and this whole week I'm gonna be off, so I'll test it next week. :)
kedautinh12
15th August 2022, 00:23
Thank you.
Tomorrow is bank holiday in Italy and this whole week I'm gonna be off, so I'll test it next week. :)
I think you're French cause your name :D
guest
15th August 2022, 05:02
I think you're French cause your name :D
Wait, what, he said Italy !!! :confused:
kedautinh12
15th August 2022, 05:03
Wait, what, he said Italy !!! :confused:
That i was thought cause "France"BB :D
FranceBB
15th August 2022, 08:20
That's a common mistake eheheheh
FranceBB actually refers to my name "Francesco" and the first letter of my surname "Bucciantini".
Unfortunately, in 1999 when I had my first computer with Windows 98SE with a puny monocore, 40 GB Pata Hard Drive and 64MB of RAM and I started registering on forums across the web (mostly football related) the username "FranceB" was already taken, so... FranceBB was born. XD
So... Yep, I'm not French, I'm Italian and I also passed the British citizenship test in 2017 which makes me almost British. :P
StvG
18th August 2022, 01:14
avsresize_r19 (https://ppp.woelkli.com/s/48afszmo6k2ZaGd) (pass: wJCnTcLxAQT9):
- fixed the behavior when missing frame property;
- the matrix between yuv<->grey isn't silently changed anymore.
guest
19th August 2022, 08:02
What a lovely morning present.
Yesterday Donald gifted the community with a CUDA porting of Cube(), today you introduced interlaced = true support in avsresize.
I wonder what's gonna be next... :D
What needs to be done to this script, to use Donald's DGCube...
LoadPlugin("%AVISYNTHPLUGINS%\avscube\vscube.dll")
video=ConvertBits(video, 16)
video=ConvertToPlanarRGB(video)
video=Cube(video, "%AVISYNTHPLUGINS%\3D LUTs\6500.CUBE", cpu=2, fullrange=true)
video=Converttoyuv420(video)
I have tried a few "obvious" things, but couldn't get it to work.
TIA
kedautinh12
19th August 2022, 09:12
What needs to be done to this script, to use Donald's DGCube...
LoadPlugin("%AVISYNTHPLUGINS%\avscube\vscube.dll")
video=ConvertBits(video, 16)
video=ConvertToPlanarRGB(video)
video=Cube(video, "%AVISYNTHPLUGINS%\3D LUTs\6500.CUBE", cpu=2, fullrange=true)
video=Converttoyuv420(video)
I have tried a few "obvious" things, but couldn't get it to work.
TIA
Your scripts used for Cube-CPU not DGCube
guest
19th August 2022, 10:25
Your scripts used for Cube-CPU not DGCube
I am aware, that is why I have asked the question, as I can't find a definitive usable script.
There are some examples here :-
https://rationalqm.us/board/viewtopic.php?f=14&t=1180&hilit=DGCube&start=75
tormento
19th August 2022, 12:36
What needs to be done to this script, to use Donald's DGCube...
I am sometimes lazy but you could at least read the DG thread and the included txt file. :rolleyes:
guest
19th August 2022, 13:01
I am sometimes lazy but you could at least read the DG thread and the included txt file. :rolleyes:
I am sometimes lazy too, and I have actually read both, but it still didn't really make too much sense to me...sorry.
Examples:
Apply 3D LUT to clip obtained from BlankClip:
loadplugin("...\dgcube.dll")
blankclip(pixel_type="RGBP16",color=$ff0000)
DGCube("...\test.cube")
converttoyuv420()
Apply 3D LUT to HDR10 PQ clip obtained from DGSource():
loadplugin("...\dgdecodenv.dll")
loadplugin("...\avsresize.dll")
loadplugin("...\dgcube.dll")
dgsource("THE GREAT WALL.dgi")
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:full", resample_filter_uv="spline64", dither_type="error_diffusion")
DGCube("PQ_to_BT709_slope.cube", fullrange=true, interp="tetrahedral")
z_ConvertFormat(pixel_type="YUV422P10", colorspace_op="rgb:std-b67:2020:full=>2020:std-b67:2020:limited", resample_filter_uv="spline64", dither_type="error_diffusion")
I was hoping that someone might provide some helpful info.
What's "BlankClip" ??
tormento
19th August 2022, 18:06
I am sometimes lazy too
Now DGCube doesn't need AVSResize anymore. Just use
loadplugin("...\dgdecodenv.dll")
loadplugin("...\dgcube.dll")
dgsource("THE GREAT WALL.dgi")
DGCube("PQ_to_BT709_slope.cube", fullrange=false)
and you will have just to dither bitdepth down according to your chosen encoder (8 or 10 bit) or just leave as it is and the encoder will to its best.
guest
20th August 2022, 02:16
Now DGCube doesn't need AVSResize anymore. Just use
loadplugin("...\dgdecodenv.dll")
loadplugin("...\dgcube.dll")
dgsource("THE GREAT WALL.dgi")
DGCube("PQ_to_BT709_slope.cube", fullrange=false)
and you will have just to dither bitdepth down according to your chosen encoder (8 or 10 bit) or just leave as it is and the encoder will to its best.
Thankyou so much tormento..
However, it still doesn't work for me in RipBot264, when "testing" with AVSMeter, it doesn't Start...
Having said that, do I need to use a dgsource ".dgi" for this work ??
'Cause I don't use that.
Cheers
DTL
20th August 2022, 11:59
Wiki http://avisynth.nl/index.php/DGCube
lists first input argument as standard AVS clip - nothing any special (only limited to possible formats list) -
clip =
Input clip; the filter receives and delivers either RGBP16 or YUV420P16 color space.
So it should work with any AVS clip of the specified format. Not only loaded by dgsource() from .dgi file.
" it still doesn't work for me in RipBot264, when "testing" with AVSMeter, it doesn't Start..."
May be input format not as required. Try to add conversion before - like
ConvertBits(16)
ConvertToYUV420()
guest
20th August 2022, 13:20
Wiki http://avisynth.nl/index.php/DGCube
lists first input argument as standard AVS clip - nothing any special (only limited to possible formats list) -
clip =
Input clip; the filter receives and delivers either RGBP16 or YUV420P16 color space.
So it should work with any AVS clip of the specified format. Not only loaded by dgsource() from .dgi file.
" it still doesn't work for me in RipBot264, when "testing" with AVSMeter, it doesn't Start..."
May be input format not as required. Try to add conversion before - like
ConvertBits(16)
ConvertToYUV420()
Interesting that you suggest the conversions, 'cause in my first post about this
https://forum.doom9.org/showthread.php?p=1973391#post1973391
The avscube script has those calls.
So it might need a combination of that & the DGCube script that tormento suggested.
EDIT:
Maybe this :-
LoadPlugin("%AVISYNTHPLUGINS%\dgdecodenv\dgdecodenv.dll")
LoadPlugin("%AVISYNTHPLUGINS%\dgcube\dgcube.dll")
video=ConvertBits(video, 16)
video=ConvertToPlanarRGB(video)
video=Cube(video, "%AVISYNTHPLUGINS%\3D LUTs\6500.CUBE", fullrange=false)
video=Converttoyuv420(video)
DTL
20th August 2022, 13:26
If your source is not higher 4:2:0 sampling - it may be no reason to convert to RGBP16 to make LUT processing if plugin accept YUV420P16 (though it may be created inside plugin). So the YUV420P16 suggested as using less RAM and may be less distortive.
Script in that post uses conversion to RGBP16 before LUT.
So the script to try:
loadplugin("...\dgcube.dll")
__any_source_load__
ConvertBits(16)
ConvertToYUV420()
DGCube("PQ_to_BT709_slope.cube", fullrange=false)
Convert* are sort of fail-safe processing so if format is not as required it perform conversion or pass-through. So no need to remove if your source already in YUV420P16.
guest
20th August 2022, 13:46
If your source is not higher 4:2:0 sampling - it may be no reason to convert to RGBP16 to make LUT processing if plugin accept YUV420P16 (though it may be created inside plugin). So the YUV420P16 suggested as using less RAM and may be less distortive.
Script in that post uses conversion to RGBP16 before LUT.
So the script to try:
loadplugin("...\dgcube.dll")
__any_source_load__
ConvertBits(16)
ConvertToYUV420()
DGCube("PQ_to_BT709_slope.cube", fullrange=false)
Convert* are sort of fail-safe processing so if format is not as required it perform conversion or pass-through. So no need to remove if your source already in YUV420P16.
Thanks DTL, I have changed my script (has to slightly different for RipBot264, and will test it tomorrow, and will report back :)
EDIT:- OK, I'm not having any success with this, so I will stick with the avscube option, that works for me. Thanks for your help :)
frank
16th September 2022, 12:09
Latest dgCube (2022.09.02) has changed params:
# Apply LUT (dgcube.dll) input full / output full RGBP16
dgCube("1000nit.cube",in="full",out="full",lut="full",interp="tetrahedral")
TomArrow
23rd October 2022, 08:09
avsresize_r15 (https://ppp.woelkli.com/s/QN4X5AjsKcbAnTj) (pass: gjFnhBCshVL3):
- relaxed restrictions for use_props=0;
- added scene_referred parameter (default false).
If you don't want the source frame properties to be read use "use_props=0". The performance would be better than propClearAll() and checking for source frame properties.
Try the new scene_referred parameter.
Hi, could you please explain how this was achieved? I am trying to compile the code myself while referencing zimg but it's telling me that it's trying to write scene_referred into zimg_graph_builder_params but that doesn't exist there. Did you simply add the parameter to the struct and then copied it over in import_graph_params()?
TomArrow
23rd October 2022, 12:50
Btw, I made a fork of this plugin with added ProPhotoRGB support if anyone's interested: https://github.com/TomArrow/avsresize
Needed that for a project of mine. Just use "prophoto" for transfer and/or primaries.
(The AVX512 stuff is untested)
FranceBB
23rd October 2022, 14:09
Thanks Tom, I'm sure StvG will eventually merge the changes. :)
Speaking of which, StvG, any chance to see the project on GitHub with builds there instead of ppp.woelkli.com links + password?
p.s I noticed that both x64 and x86 have been compiled through the avsresize.sln with v143, I'll try to compile them with v141_xp too next week 'cause current x86 builds don't work on XP
kedautinh12
23rd October 2022, 14:31
Thanks Tom, I'm sure StvG will eventually merge the changes. :)
Speaking of which, StvG, any chance to see the project on GitHub with builds there instead of ppp.woelkli.com links + password?
p.s I noticed that both x64 and x86 have been compiled through the avsresize.sln with v143, I'll try to compile them with v141_xp too next week 'cause current x86 builds don't work on XP
I don't know if it's belong to StvG
https://github.com/sekrit-twc/zimg
StvG
23rd October 2022, 20:18
Hi, could you please explain how this was achieved? I am trying to compile the code myself while referencing zimg but it's telling me that it's trying to write scene_referred into zimg_graph_builder_params but that doesn't exist there. Did you simply add the parameter to the struct and then copied it over in import_graph_params()?
Hi, here is the patch (https://pastebin.com/raw/199xgB7y) for zimg that I'm using. I will included it in the next versions.
Edit: the patch is for zimg branch v3.0.
Speaking of which, StvG, any chance to see the project on GitHub with builds there instead of ppp.woelkli.com links + password?
I'm sorry, at the moment I don't have intention to create a github repo. Anyone is free to upload it. Btw here there is one mirror (https://github.com/realfinder/avsresize-mirror)
I don't know if it's belong to StvG
https://github.com/sekrit-twc/zimg
No, it's not mine.
TomArrow
23rd October 2022, 21:02
Hi, here is the patch (https://pastebin.com/raw/199xgB7y) for zimg that I'm using. I will included it in the next versions.
Edit: the patch is for zimg branch v3.0.
Cool, thanks! That's pretty much the same thing I added to make it work. Glad I'm sane. I personally just used the newest version of zimg and had no issues. Or is there any specific reason to use 3.0?
StvG
23rd October 2022, 23:38
Cool, thanks! That's pretty much the same thing I added to make it work. Glad I'm sane. I personally just used the newest version of zimg and had no issues. Or is there any specific reason to use 3.0?
No specific reason for 3.0. I'm using the branch used for the latest release.
Dogway
28th November 2022, 16:19
I think I found a bug, correct me if I did something wrong:
YUV420P16 source
CCTF("1886",true) # to linear
z_ConvertFormat(2560,1120,pixel_type="RGBP16",colorspace_op ="709:linear:709:auto=>rgb:srgb:170m:l")
Basically the problem is going from YUV linear to RGB non-linear regardless of other settings.
EDIT: Also seems to happen with YUV420P16 as target.
StvG
29th November 2022, 07:27
I think I found a bug, correct me if I did something wrong:
YUV420P16 source
CCTF("1886",true) # to linear
z_ConvertFormat(2560,1120,pixel_type="RGBP16",colorspace_op ="709:linear:709:auto=>rgb:srgb:170m:l")
Basically the problem is going from YUV linear to RGB non-linear regardless of other settings.
EDIT: Also seems to happen with YUV420P16 as target.
What if you use:
YUV420P16 source
z_ConvertFormat(colorspace_op="auto:709=>same:linear")
z_ConvertFormat(2560,1120,pixel_type="RGBP16",colorspace_op ="709:linear:709:auto=>rgb:srgb:170m:l")
Dogway
29th November 2022, 13:09
An error dialog with:
Error requesting frame 184
no path between colorspaces
I'm using r19
StvG
29th November 2022, 15:11
An error dialog with:
Error requesting frame 184
no path between colorspaces
I'm using r19
It seems _Matrix is unspecified (2). Try:
YUV420P16 source
z_ConvertFormat(colorspace_op="709:709=>709:linear") # change to the correct matrix if needed
z_ConvertFormat(2560,1120,pixel_type="RGBP16",colorspace_op ="709:linear:709:auto=>rgb:srgb:170m:l")
Dogway
29th November 2022, 15:15
Thanks, yes it worked. So matrix has to be explicitly defined, because it didn't work with "auto" either.
StvG
29th November 2022, 19:40
Thanks, yes it worked. So matrix has to be explicitly defined, because it didn't work with "auto" either.
Here (https://forum.doom9.org/showthread.php?p=1925849#post1925849) is the info about the keywords "auto"/"same". That info is in the avs wiki too (http://avisynth.nl/index.php/Avsresize#Frame_Properties).
StvG
30th November 2022, 04:18
YUV420P16 source
z_ConvertFormat(colorspace_op="auto:709=>same:linear")
@Dogway, the above is a short cut of
YUV420P16 source
z_ConvertFormat(pixel_type="rgbps", colorspace_op="auto:709=>rgb:linear")
z_ConvertFormat(pixel_type="yuv420p16", colorspace_op="rgb=>same")
There is colorspace conversion that's the reason for the error (from the wiki "If you use "auto=>same" for matrix/transfer/primaries with frame property 2 (unspec) and you want to make colorspace conversion, error will be raised.").
Dogway
30th November 2022, 17:22
Thanks for the note, I was reporting a possible bug I found while debugging TransformsPack.
I myself don't use avsresize as it doesn't feel intuitive to me despite being super-fast.
tormento
9th December 2022, 11:00
Guys, where can I find the sources for avsresize r19?
There could be a good chance for it to be ported to CUDA.
kedautinh12
9th December 2022, 11:37
Guys, where can I find the sources for avsresize r19?
There could be a good chance for it to be ported to CUDA.
You can port to CUDA??
tormento
9th December 2022, 14:23
You can port to CUDA??
Not me, someone who lurks in forum shadow. :p
kedautinh12
9th December 2022, 14:24
Not me, someone who lurks in forum shadow. :p
Ok, waiting for StvG share source code :D
Reel.Deel
9th December 2022, 17:45
Guys, where can I find the sources for avsresize r19?
There could be a good chance for it to be ported to CUDA.
DG has seen the source (see your own post in that thread on Oct 10, 2022). Regardless, the source code for avsresize is included in the 7z file with every release. And here is the zimg repo: https://github.com/sekrit-twc/zimg
FranceBB
9th December 2022, 17:54
DG has seen the source (see your own post in that thread on Oct 10, 2022).
Yeah, but he also said that perhaps Sherman is able to port it to CUDA by himself for him, which would be absolutely welcomed.
I mean, when you encode a UHD at only 6fps on a 56c/112th pure CPU AVX512 Intel Xeon monster, burning a whole amazonian forest in electricity bills while you have an NVIDIA Quadro P5000 sitting idle (if it wasn't for the OpenCl acceleration of x264), you start wondering your life choices. :P
Julek
9th December 2022, 19:36
zimg is so fast on CPU (at least in vapoursynth) that I see no reason to use GPU resizer, it is more useful to leave it free for heavy denoise/eedi/nnedi.
kedautinh12
10th December 2022, 02:21
zimg is so fast on CPU (at least in vapoursynth) that I see no reason to use GPU resizer, it is more useful to leave it free for heavy denoise/eedi/nnedi.
eedi2 had cuda ver :D
https://github.com/kedaitinh12/VapourSynth-EEDI2CUDA/releases
tormento
10th December 2022, 11:28
zimg is so fast on CPU (at least in vapoursynth) that I see no reason to use GPU resizer,
Perhaps on newer systems. Not everybody has a brand new Sapphire Rapids processor :).
kedautinh12
10th December 2022, 11:47
Perhaps on newer systems. Not everybody has a brand new Sapphire Rapids processor :).
Don't need. With AMD r3 series and above, intel 8th and above. it's very fast
tormento
10th December 2022, 12:12
Don't need. In AMD r3 series and above, intel 8th and above. it's very fast
It was figurative.
StvG
30th January 2023, 08:37
avsresize_r20 (https://ppp.woelkli.com/s/cMwJgP83ebywkzj) (pass: iFmc8FTt1DsT):
- not read "_FieldBased" frame prop when use_props=0;
- added ProPhotoRGB (TomArrow).
FranceBB
30th January 2023, 11:44
Thanks for the new release, I'll test it when I get back to the office on February the 2nd! ;)
StvG
15th February 2023, 03:04
avsresize_r21 (https://ppp.woelkli.com/s/CrsC8rQmwNdApEg) (pass: 0RHxLfJy1t0C):
- throw error if IsFieldBased()=true and interlaced=false/use_props=1;
- resizer wrappers: added parameter interlaced;
- changed behavior of interlaced=true - previously it force use_props=0; now it doesn't have effect when use_props=1.
FranceBB
15th February 2023, 12:23
Ah, ok.
Upgrading now again, thanks. :)
StvG
15th February 2023, 18:37
Just to point out if it's not obvious already - after r19 you can process interlaced content without interlaced=true when use_props=0 and _FieldBased > 0 which will lead to wrong outputs. Before r20 there will be error raised that clip must be frame-based because frame prop was checked. Now (>= r20) when use_props=0, none frame prop is read. Be careful.
Again info about use_props=-1 (default value):
i. Auto use_props=0
1. Source and destination colorspace are same (source and destination are yuv/y, source and destination are rgb)
- colorspace_op is undefined and chromaloc_op is undefined or chromaloc_op src is not auto (chromaloc_op="left=>left")
2. colorspace_op is defined and every src value is not auto (x:x:x:x=>y:y:y:y), and chromaloc_op is undefined or chromaloc_op src is not auto (chromaloc_op="left=>left")
ii. Every other case - auto use_props=1
You can force to read frame props by set use_props=1, or force to not read frame prop by set use_prop=0.
FranceBB
15th February 2023, 20:47
Yep, that's good to know and that's exactly what a user would want: use_props=0 should avoid reading any property in any case and therefore speed things up.
By the way, I am beginning to slowly try frame properties for things I don't encode manually and go through automation.
Luckily, in my case, I should be ok 'cause indexers are reading frame_properties and if there are none, they're assumed and populated by my ClipPropertyParser() for all the automated supply chains in FFAStrans, so in theory it shouldn't matter, but yeah, thanks for the heads up. ;)
I'll come up with a report of how things went tomorrow.
EDIT: So far so good
https://i.imgur.com/k2IZ2vm.png
ErazorTT
27th March 2023, 19:32
Would it be possible to include the 2.6 gamma to the possible transfer function which is used in st431-2 and st432-1?
StvG
1st April 2023, 23:06
Can you ask the zimg author (https://github.com/sekrit-twc/zimg). If he wouldn't add it, I can take a look.
FranceBB
4th July 2023, 14:09
Hi there guys,
I tried to compile avsresize.dll using v141_xp:
https://i.imgur.com/ITRMv7E.png
https://i.imgur.com/GppJrWd.png
the build completed fine
https://i.imgur.com/EmdFgzm.png
and the produced dll shows no issues in Dependency Walker:
https://i.imgur.com/JO5MZ0Z.png
however it just won't work in Avisynth.
Is it because it's zlib being actually incompatible with XP even though it's not erroring during compilation?
Test build (link valid for 7 days only): https://we.tl/t-ZcUDEqFsZp
real.finder
4th July 2023, 15:16
seems _FieldBased frame property is not used to check whether the source is interlaced or not (I also tried with use_props=1 when convert from yv12 to yv24 but it kinda broken)
also can we have independent chroma subsampling parameter? for let say convert anything to 4:4:4 regardless of bitdepth to do some filtering then back to 4:2:0 or whatever original subsampling with another z_ConvertFormat() call and this is easy z_ConvertFormat(pixel_type=PixelType(orig))
seems _FieldBased frame property is not used to check whether the source is interlaced or not (I also tried with use_props=1 when convert from yv12 to yv24 but it kinda broken)
also can we have independent chroma subsampling parameter? for let say convert anything to 4:4:4 regardless of bitdepth to do some filtering then back to 4:2:0 or whatever original subsampling with another z_ConvertFormat() call and this is easy z_ConvertFormat(pixel_type=PixelType(orig))
About _FieldBased - did you read this post (https://forum.doom9.org/showthread.php?p=1983022#post1983022)?
I'm not sure what you exactly ask about "independent chroma subsampling parameter". Can you elaborate?
real.finder
5th July 2023, 06:25
About _FieldBased - did you read this post (https://forum.doom9.org/showthread.php?p=1983022#post1983022)?
didn't read it but still with use_props=1 seems not work (avspmod will show error about not frame base)
I'm not sure what you exactly ask about "independent chroma subsampling parameter". Can you elaborate?
like adding new parameter called chroma_subsampling (or any short name) that accept "444" or "422" and so as string or as int so (-1=same as input) and this will be default or (0=444) (1=422) and so on, and this parameter will be ignored if user set pixel_type
didn't read it but still with use_props=1 seems not work (avspmod will show error about not frame base)
Colorbars(pixel_type="yv12")
propset("_FieldBased", 1)
z_ConvertFormat(pixel_type="yv24", use_props=1)
Above code throw error - frame property is read.
Using use_props=0 doesn't throw error - frame property is not read.
real.finder
5th July 2023, 12:33
Colorbars(pixel_type="yv12")
propset("_FieldBased", 1)
z_ConvertFormat(pixel_type="yv24", use_props=1)
Above code throw error - frame property is read.
Using use_props=0 doesn't throw error - frame property is not read.
yes but with use_props=0 will treat the yv12 as progressive when convert it to yv24 which will cause chroma Field Blending
yes but with use_props=0 will treat the yv12 as progressive when convert it to yv24 which will cause chroma Field Blending
use_props=0 doesn't read frame properties. You have to take care if the video is interlaced or not. If the video is interlaced use interlaced=true.
If you want the frame properties to be read (including _FieldBased) use use_props=1.
real.finder
5th July 2023, 14:46
use_props=0 doesn't read frame properties. You have to take care if the video is interlaced or not. If the video is interlaced use interlaced=true.
If you want the frame properties to be read (including _FieldBased) use use_props=1.
I know but the problem is with use_props=1 it not same as interlaced=true
avspmod error
https://i.postimg.cc/qMxDzPgQ/Untitled.png (https://postimages.org/)
with interlaced=true it work fine but I need to put it inside avsi function that work with interlaced and progressive and since we got frame properties in avs+ we should rely on them especially if we have a source that got mixed interlaced and progressive frames/sections
avsresize_r22 (https://ppp.woelkli.com/s/jYrxm4eLWAgRCjW) (pass: m6UEtJm68sPV):
- interlaced now works with use_props=1 too.
If interlaced is not specified, frame property "_FieldBased" is read to enable/disable the interlaced mode.
If interlaced is specified, "_FieldBased" doesn't have effect.
- zimg v3.0.5.
real.finder
7th July 2023, 19:11
avsresize_r22 (https://ppp.woelkli.com/s/jYrxm4eLWAgRCjW) (pass: m6UEtJm68sPV):
- interlaced now works with use_props=1 too.
If interlaced is not specified, frame property "_FieldBased" is read to enable/disable the interlaced mode.
If interlaced is specified, "_FieldBased" doesn't have effect.
- zimg v3.0.5.
thank you, I will test it as soon as possible
edit: everything seems ok, what about chroma subsampling parameter? https://forum.doom9.org/showthread.php?p=1989150#post1989150
thank you, I will test it as soon as possible
edit: everything seems ok, what about chroma subsampling parameter? https://forum.doom9.org/showthread.php?p=1989150#post1989150
What's the difference between z_ConvertFormat(pixel_type="yuv444p16") and z_ConvertFormat(chroma_subsampling="444") (assuming YUV420P16 input)?
real.finder
8th July 2023, 13:12
What's the difference between z_ConvertFormat(pixel_type="yuv444p16") and z_ConvertFormat(chroma_subsampling="444") (assuming YUV420P16 input)?
with YUV420P16 case both are same but with yv12 (8bit YUV420) z_ConvertFormat(pixel_type="yuv444p16") will convert it from 8 bit to 16 bit and 4:4:4 while z_ConvertFormat(chroma_subsampling="444") will only convert it to 4:4:4 (it will be yv24)
edit: maybe it also worth adding bit_bepth parameter too
and both chroma_subsampling and bit_bepth will be ignored when pixel_type is used
with YUV420P16 case both are same but with yv12 (8bit YUV420) z_ConvertFormat(pixel_type="yuv444p16") will convert it from 8 bit to 16 bit and 4:4:4 while z_ConvertFormat(chroma_subsampling="444") will only convert it to 4:4:4 (it will be yv24)
edit: maybe it also worth adding bit_bepth parameter too
and both chroma_subsampling and bit_bepth will be ignored when pixel_type is used
z_ConvertFormat(pixel_type="yuv444p" + (ComponentSize() == 4 ? "s" : String(BitsPerComponent())))
Is the above code too complicated?
Don't get me wrong. There are already a lot of parameters that making the usage a bit complicated at first look. Adding more parameters with actions that are already covered is unnecessary further complication imo.
real.finder
9th July 2023, 10:41
if the problem that it got lot of parameters, then can we got pixel_type to accept things like "444" (or "yuv444*") or "Y" (without any number or "Y*") and same with bitbepth (like *P16)
avsresize_r23 (https://ppp.woelkli.com/s/jYrxm4eLWAgRCjW) (pass: m6UEtJm68sPV):
- Added parameter bit_depth: output bit depth. It doesn't have effect if pixel_type is defined;
- Added parameter chroma_subsampling: output chroma subsampling. It doesn't have effect if pixel_type is defined;
- zimg v3.0.5.
real.finder
9th July 2023, 18:05
avsresize_r23 (https://ppp.woelkli.com/s/jYrxm4eLWAgRCjW) (pass: m6UEtJm68sPV):
- Added parameter bit_depth: output bit depth. It doesn't effect if pixel_type is defined;
- Added parameter chroma_subsampling: output chroma subsampling. It doesn't effect if pixel_type is defined;
- zimg v3.0.5.
thanks! both work fine
FranceBB
9th July 2023, 19:43
- Added parameter bit_depth: output bit depth. It doesn't effect if pixel_type is defined;
- Added parameter chroma_subsampling: output chroma subsampling. It doesn't effect if pixel_type is defined;
- zimg v3.0.5.
So, as long as I specify the pixel_type, everything stays the same as in the last version if I don't specify the two new parameters, right?
StvG
10th July 2023, 02:31
So, as long as I specify the pixel_type, everything stays the same as in the last version if I don't specify the two new parameters, right?
Yes, if you specify pixel_type the two new parameters are ignored even if they are specified too.
FranceBB
10th July 2023, 05:25
Perfect, so it won't break any of my supply chains. :)
Well, I'm suffering from insomnia due to the heatwave (I'm currently in Milan, Italy and not in the UK unfortunately) and the fan is just blowing hot air on me, which is useless...
So... I might just get up, take a shower, have breakfast, go to the office (where I actually have AC) and update all my servers xD
joearmstrong
30th July 2023, 07:50
I'm not sure if I'm using chromaloc_op correctly. I haven't used it so far.
I want to convert HDR PQ to SDR:
Example 1:
z_ConvertFormat(pixel_type="RGBP16", colorspace_op="2020ncl:st2084:2020:limited=>rgb:st2084:2020:full", chromaloc_op="top_left=>top_left", dither_type="none")
Cube("D:\5-NBCU_PQ2SDR_DL_Adobe_v1.cube", interp=1, fullrange=1)
z_ConvertFormat(pixel_type="YV12", colorspace_op="rgb:709:709:full=>709:709:709:limited", chromaloc_op="top_left=>left", dither_type="ordered")
Example 2:
z_ConvertFormat(pixel_type="YUV444P16",colorspace_op="2020ncl:st2084:2020:l=>2020ncl:st2084:2020:l",chromaloc_op="top_left=>top_left",dither_type="none")
ConvertYUVtoXYZ(Color=0,HDRMode=0,OOTF=false,OutputMode=2)
ConverXYZ_BT2446_C_HDRtoSDR(PQMode=true,Lhdr=50000.0,Lsdr=100.0,pColor=0,pct_ref=0.6,pct_ip=0.6,pct_wp=1.0,pct_sdr_skin=1.0,pct_hdr_skin=0.44)
ConvertXYZtoYUV(Color=2,pColor=0,OOTF=false)
z_ConvertFormat(pixel_type="YV12",colorspace_op="709:709:709:l=>709:709:709:l",chromaloc_op="top_left=>left",dither_type="ordered")
I think the change to "left" (mpeg2), which is the standard for Rec709, should be placed at the end of the scripts ?
FranceBB
30th July 2023, 11:04
It should, in theory, be fine.
When you upscale the chroma to RGB, you're essentially going to the same resolution for both luma and chroma and, just like with 4:4:4, the chroma location loses its meaning.
When you're downscaling the chroma to go back to 4:2:0, however, it actually matters, but given that by default it assumes that you want the classic 4:2:0 (i.e left) and not type 2 (i.e top left), it will automatically get it right even if you don't specify it ;)
joearmstrong
30th July 2023, 11:46
Thanks for your answer and explanation, FranceBB.
StvG
1st October 2023, 20:11
The source code is uploaded here (https://codeberg.org/StvG/avsresize).
Builds are here (https://codeberg.org/StvG/avsresize/releases).
tormento
2nd October 2023, 11:12
Builds are here.
Thank you :)
hello_hello
26th February 2024, 17:22
I'm think I'm starting to seriously dislike frame properties. Nothing specific to AVSResize. Just generally.
AVSResize appears to have the same problem VapourSynth's resizers did previously (https://forum.doom9.org/showthread.php?t=185080), in that it doesn't take it's own cropping into account when calculating a new sample aspect ratio. I'm using AVSResize r23.
Thanks.
ColorBars.KillAudio().ConvertToYV12() # 640x480 (4:3)
propSet("_SARNum", 1).propSet("_SARDen", 1)
z_ConvertFormat(720,576)
# propGetAny("_SARNum") = 16
# propGetAny("_SARDen") = 15
ColorBars.KillAudio().ConvertToYV12() # 640x480 (4:3)
propSet("_SARNum", 1).propSet("_SARDen", 1)
z_ConvertFormat(720,576, src_left=240, src_top=0, src_width=400, src_height=480)
# propGetAny("_SARNum") = 16
# propGetAny("_SARDen") = 15
FranceBB
26th February 2024, 18:56
I'm think I'm starting to seriously dislike frame properties.
Amen.
I've been saying this for months, Tormento knows that 'cause I've been complaining to him for months when I had to implement them in all my workflows!
Life was easier when we only had clip properties.
Eventually, what I ended up doing in all my Avisynth workflow is:
1) propclearall() to nuke everything
2) do the stuff as I always did
3) propset() to re-populate everything correctly at the end
which is a big pain anyway... :(
hello_hello
26th February 2024, 20:05
FranceBB, "starting to" was probably a bit of an under-statement. :)
It might be handy for resizers that support reading and writing a frame properties SAR to have a specific option for keeping the original SAR or even changing it. Sometimes you want to resize an image and keep the resized aspect ratio on playback instead of the player undoing the resizing, as would happen if the SAR is honored from Avisynth script through to encoder, which I assume is the ultimate goal. It'd probably be easier to do via a resizer argument rather than having to fiddle with frame properties. A DAR argument might even be a better as people tend to think in terms of a DAR rather than a SAR (I definitely do) and it'd be easy for the resizer to convert it to a SAR for frame properties. I can only dream....
StvG
28th February 2024, 04:34
avsresize r24 (https://codeberg.org/StvG/avsresize/releases):
- Added ST.428-1 (gamma 2.6) transfer function.
- Fixed SAR calculation when internal crop is used.
- zimg a0fac0f.
Would it be possible to include the 2.6 gamma to the possible transfer function which is used in st431-2 and st432-1?
Added in r24 as "st428". Related (https://github.com/sekrit-twc/zimg/issues/192).
I'm think I'm starting to seriously dislike frame properties. Nothing specific to AVSResize. Just generally.
AVSResize appears to have the same problem VapourSynth's resizers did previously (https://forum.doom9.org/showthread.php?t=185080), in that it doesn't take it's own cropping into account when calculating a new sample aspect ratio. I'm using AVSResize r23.
Thanks.
ColorBars.KillAudio().ConvertToYV12() # 640x480 (4:3)
propSet("_SARNum", 1).propSet("_SARDen", 1)
z_ConvertFormat(720,576)
# propGetAny("_SARNum") = 16
# propGetAny("_SARDen") = 15
ColorBars.KillAudio().ConvertToYV12() # 640x480 (4:3)
propSet("_SARNum", 1).propSet("_SARDen", 1)
z_ConvertFormat(720,576, src_left=240, src_top=0, src_width=400, src_height=480)
# propGetAny("_SARNum") = 16
# propGetAny("_SARDen") = 15
Fixed in r24.
hello_hello
28th February 2024, 22:02
Fixed in r24.
Thank you.
Another one....
AVSResize is changing the ColorRange frame property from full to limited for 32 bit YUV. Would it be correct to assume it shouldn't?
ColorBars.KillAudio().ConvertToYV24().ConvertBits(32)
propset("_ColorRange", 0)
z_ConvertFormat(960,720)
# propGetAny("_ColorRange") = 1
The same thing happens when you use colorspace_op without specifying a coior range
z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")
And when using two instances of z_ConvertFormat to convert to RGB and back.
z_ConvertFormat(colorspace_op="170m:601:170m=>rgb:linear:170m", pixel_type="RGBPS")
z_ConvertFormat(colorspace_op="rgb:linear:170m=>470bg:601:470bg", pixel_type="YUV420PS")
Cheers.
StvG
29th February 2024, 05:07
avsresize r25 (https://codeberg.org/StvG/avsresize/releases):
- Fixed exported _ColorRange properties.
- zimg a0fac0f.
Thank you.
Another one....
AVSResize is changing the ColorRange frame property from full to limited for 32 bit YUV. Would it be correct to assume it shouldn't?
ColorBars.KillAudio().ConvertToYV24().ConvertBits(32)
propset("_ColorRange", 0)
z_ConvertFormat(960,720)
# propGetAny("_ColorRange") = 1
The same thing happens when you use colorspace_op without specifying a coior range
z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")
And when using two instances of z_ConvertFormat to convert to RGB and back.
z_ConvertFormat(colorspace_op="170m:601:170m=>rgb:linear:170m", pixel_type="RGBPS")
z_ConvertFormat(colorspace_op="rgb:linear:170m=>470bg:601:470bg", pixel_type="YUV420PS")
Cheers.
The first case (z_ConvertFormat(960,720)) is fixed in r25.
The last two cases always should give full color range property. It's fixed in r25.
hello_hello
1st March 2024, 01:23
Thanks again!
ErazorTT
5th March 2024, 01:29
Unrelated to the current new versions, is there something off for 2020->709?
Taking this red ramp as an input:
https://i.postimg.cc/WhY8pzLc/red-ramp-input.png (https://postimg.cc/WhY8pzLc)
And applying:
z_ConvertFormat(colorspace_op="rgb:2020:2020:full=>rgb:709:709:full")
results in:
https://i.postimg.cc/nXskXxpj/red-ramp-2020-to-709.png (https://postimg.cc/nXskXxpj)
Comparing to my expectation and with the calibrated display modes BT.2020 and BT.709 on my display, the position marked (look at the full image) appears too abrupt and too magenta. Could there be something off somewhere in the matrices?
my expectation would have been this:
https://i.postimg.cc/Hrft5NkS/red-ramp-expectation.png (https://postimg.cc/Hrft5NkS)
poisondeathray
5th March 2024, 03:39
Unrelated to the current new versions, is there something off for 2020->709?
Taking this red ramp as an input...
It seems off . There are large jumps at lower values in the green channel .
Compare the result to FMTC, which is smooth and the increments are even
fmtc_transfer(transs="2020", transd="linear")
fmtc_primaries(prims="2020", primd="709")
fmtc_transfer(transs="linear", transd="709")
For avsresize - I tried linearizing first, also maxcpu setting. Also same result in vapoursynth
StvG
5th March 2024, 04:52
Yes, it's zimg bug.
The github (https://github.com/sekrit-twc/zimg) repo is abandoned and the new bitbucket (https://bitbucket.org/the-sekrit-twc/zimg/src/master/) repo doesn't have enabled the "Issues" sections. If someone has contact with the author (irc, discord) can report this. Also it can be reported on the VS repo/forum (I guess the VS people can reach him since zimg is the default VS resize/colorspace function).
Balling
16th March 2024, 21:33
"Comparing to my expectation and with the calibrated display modes BT.2020 and BT.709 on my display, the position marked (look at the full image) appears too abrupt and too magenta. Could there be something off somewhere in the matrices?"
Mmmm... "Note that "z" is not a color management system and should not be used to perform drastic contrast or gamut reduction, such as BT.2020 to BT.709."
Same command ffmpeg -i red-ramp-inputbt2020.png -vf zscale=rin=full:r=full:tin=2020_12:t=2020_12:pin=2020:p=709:d=none dwedstrange1.png
Balling
16th March 2024, 21:42
" Taking this red ramp as an input:"
That ramp is sRGB, rendering intent Perceptual. This is lossless data (-f md5 - prints c9910d9f1c4dcf3698ba025a268facf4), but tagged as 2020 primaries, 2.4 gamma. Here you go (I must say windows is closer to what zimg does in sdr mode, in HDR not even close): https://i.postimg.cc/1zWB2gMn/red-ramp-inputbt2020.png
DTL
16th March 2024, 22:14
Unrelated to the current new versions, is there something off for 2020->709?
Taking this red ramp as an input:
https://i.postimg.cc/WhY8pzLc/red-ramp-input.png (https://postimg.cc/WhY8pzLc)
And applying:
z_ConvertFormat(colorspace_op="rgb:2020:2020:full=>rgb:709:709:full")
Any 'simple' shrink-conversion of wider domain to narrower is unlikely possible with significant clipping or other issues. Maybe original designer of wide->narrow valid convert path assume user prepare valid colour gamut and levels range first (in 2020 primaries and 2020 transfer) and only as next step apply conversion. Maybe avsresize do not doing any 'shrinking' at all at attempt to to 'downconversion'. It looks not covered in the documentation ? HDR to SDR and WCG to SCG conversions may be performed at least in 3 different ways:
1. Range crop (extract SDR and SCG from HDR and WCG). Any out of range values are clipped to max valid values.
2. Full range map (compress full HDR and WCG into SDR and SCG).
3. Some unlimited ways of 'tonemap'.
So it possibly only low-distorted way: rgb:709:709:full=>rgb:2020:2020:full=>rgb:709:709:full (using 32bit float samples to escape of quantization noise as best as possible).
If feed out-of-range 2020 primaries and transfer to conversion to 709 - the result maybe undefined.
Also freeware HDR<->SDR conversion libraries may have some set of 'magic variables' to tweak the conversion like float "nominal_luminance", bool "approximate_gamma", bool "use_props", bool "scene_referred".
ErazorTT
20th March 2024, 02:12
"Note that "z" is not a color management system and should not be used to perform drastic contrast or gamut reduction, such as BT.2020 to BT.709."
Any 'simple' shrink-conversion of wider domain to narrower is unlikely possible with significant clipping or other issues. Maybe original designer of wide->narrow valid convert path assume user prepare valid colour gamut and levels range first (in 2020 primaries and 2020 transfer) and only as next step apply conversion. Maybe avsresize do not doing any 'shrinking' at all at attempt to to 'downconversion'.
I don't know what you guys are talking about. There is a very well defined conversion from any color space to any other, by going through XYZ. This of course involves clipping but if nothing else is specified by the user this should be the default. And no, z_ConvertFormat does not try to do any perceptual conversion, that is clear from the clipping it produces.
For the discussed case, the conversion from (linear) 2020 RGB to XYZ is given by:
X = 0.636958048 * rl + 0.144616904 * gl + 0.168880975 * bl;
Y = 0.262700212 * rl + 0.677998072 * gl + 0.059301716 * bl;
Z = 0.000000000 * rl + 0.028072693 * gl + 1.060985058 * bl;
And the conversion from XYZ to (linear) 709 RGB is given by:
rl = 3.240969944 * X - 1.537383176 * Y - 0.4986107602 * Z;
gl = -0.9692436371 * X + 1.875967501 * Y + 0.04155505794 * Z;
bl = 0.05563007901 * X - 0.2039769588 * Y + 1.056971515 * Z;
The clipping than happens by clamping:
rl = min(max(rl,0),1);
gl = min(max(gl,0),1);
bl = min(max(bl,0),1);
This will produce my "expectation image" from the "input image". z_ConvertFormat reproduces this for all colored ramps apart from the red ramp, thus there is something wrong.
(PS: that is exactly what Rep. ITU-R BT.2407-0 describes in section 2, on pages 1 and 2. And of course what I haven’t shown here is going back and forth from gamma to linear, but thats also streightforward.)
ErazorTT
20th March 2024, 02:52
That ramp is sRGB, rendering intent Perceptual. This is lossless data, but tagged as 2020 primaries, 2.4 gamma.
How do you come to that conclusion? By looking at the tags of the image file? That is completely irrelevant, first of all that is just a screenshot, second the input can be interpreted however necessary.
My actual input was not that image but a script creating the ramp which I then fed to z_ConvertFormat.
ErazorTT
20th March 2024, 10:49
Ok I think found the issue. Actually I looked further into it because of Balling's and DTL's comments.
The point is that the conversion by z_ConvertFormat is done display-referred, while I did it scene-referred. Display-referred is probably the "more correct".
So the conversion by z_ConvertFormat is actually fine!
This obviously means that fmtc_transfer converts scene-referred.
Scene-referred means that the transfer function used is that shown in item 1.2 from the tabel on page 3 of Rec. ITU-R BT.709-6. Display-referred means that the transfer function used is the one from Rec. ITU-R BT.1886 page 3.
DTL
20th March 2024, 14:20
Documentation http://avisynth.nl/index.php/Avsresize says
bool scene_referred = false
Whether to use scene-referred transfer function (default false).
Is setting to true produce expected result ?
"Display-referred is probably the "more correct"."
Linear scene light expected to be close to reality and fixed for source (image data). And displays may be different. If you make a chain of conversions and some uses display linear and some scene linear - the result will be more distorted.
It may be same idea as about spatial spectrum shaping - it is better to do in scene linear light.
ErazorTT
20th March 2024, 16:34
bool scene_referred = false
Whether to use scene-referred transfer function (default false).
Ah, it's good to know that it can do both. Yes, so this reproduces what I initially expected. I am now not sure which conversion to prefere but it seems that display-referred is the one I need.
Balling
4th April 2024, 21:22
Ok I think found the issue. Actually I looked further into it because of Balling's and DTL's comments.
The point is that the conversion by z_ConvertFormat is done display-referred, while I did it scene-referred. Display-referred is probably the "more correct".
So the conversion by z_ConvertFormat is actually fine!
This obviously means that fmtc_transfer converts scene-referred.
Scene-referred means that the transfer function used is that shown in item 1.2 from the tabel on page 3 of Rec. ITU-R BT.709-6. Display-referred means that the transfer function used is the one from Rec. ITU-R BT.1886 page 3.
It is more complex. If we have PQ it is only display referred, as OETF is inverse of EOTF. With BT.709 and BT.2020 — both SDR specs — it is not thay simple. The change of primaries must happen ON LINEAR LIGHT using 2.0 gamma, not 2.2 or 2.4. Then you can apply 2.4.
hello_hello
25th July 2024, 23:55
Another one....
AVSResize is changing the ColorRange frame property from full to limited for 32 bit YUV. Would it be correct to assume it shouldn't?
ColorBars.KillAudio().ConvertToYV24().ConvertBits(32)
propset("_ColorRange", 0)
z_ConvertFormat(960,720)
# propGetAny("_ColorRange") = 1
The same thing happens when you use colorspace_op without specifying a coior range
z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")
And when using two instances of z_ConvertFormat to convert to RGB and back.
z_ConvertFormat(colorspace_op="170m:601:170m=>rgb:linear:170m", pixel_type="RGBPS")
z_ConvertFormat(colorspace_op="rgb:linear:170m=>470bg:601:470bg", pixel_type="YUV420PS")
StvG,
While trying to get my head around the assumptions ConvertBits() makes regarding color range for 32 bit YUV when there's no ColorRange in frame properties (you answered my question in that thread), I started to worry that changing the way AVSResize handles YUV float might have been a mistake.
I'd been under the impression that 32 bit YUV was always full range, and from what I can tell that was true originally but it's no longer the case. Without a frame property to tell it otherwise ConvertBits() assumes all YUV is limited range, including float, so would it be better for consistency if AVSResize did the same?
AVSResize is also currently writing full range to frame properties for any 32 bit color space conversion even when limited is specified. For example:
z_ConvertFormat(colorspace_op="170m:601:170m:l=>470bg:601:470bg:l")
Cheers.
StvG
26th July 2024, 07:43
StvG,
While trying to get my head around the assumptions ConvertBits() makes regarding color range for 32 bit YUV when there's no ColorRange in frame properties (you answered my question in that thread), I started to worry that changing the way AVSResize handles YUV float might have been a mistake.
I'd been under the impression that 32 bit YUV was always full range, and from what I can tell that was true originally but it's no longer the case. Without a frame property to tell it otherwise ConvertBits() assumes all YUV is limited range, including float, so would it be better for consistency if AVSResize did the same?
I don't think so. In this thread there was a discussion (https://forum.doom9.org/showthread.php?p=1926448#post1926448) already about this (read the linked post and the next posts, btw I see you replied too at that time).
AVSResize is also currently writing full range to frame properties for any 32 bit color space conversion even when limited is specified. For example:
z_ConvertFormat(colorspace_op="170m:601:170m:l=>470bg:601:470bg:l")Cheers.
Because zimg always assumes 32-bit float in full range and l=>l doesn't perform range conversion.
hello_hello
9th October 2024, 06:00
I was initially stacking videos to check the frame properties were correct after conversion with a function, but I noticed some color oddities with AVSResize when converting between rec.2020 and rec.709.
Would it be safe to assume from the result that approximate_gamma=true (the default) is a bad idea? The difference seems to be the most noticeable for the primary colors. The source is a rec.709 blank clip converted to rec.2020 with HDRTools (so the primaries are rec.2020) and then converted back to rec.709.
z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>rgb:linear:xyz:full", pixel_type="RGBP16")
z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P8")
https://i.imgur.com/56LbtCC.png
z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>rgb:linear:xyz:full", pixel_type="RGBP16", approximate_gamma=false)
z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P8", approximate_gamma=false)
https://i.imgur.com/1p9Nx2d.png
DTL
9th October 2024, 07:24
It is good to pick RGB levels (or YUV if the conversion in that colour space) and post source code values for Red patch and all output code values of different tools used. Typical sources of errors - levels range treatment (in float more frequently) and scene/display referred linear. So you can try first RGB only colour space and limited (narrow) range only and look for scene/display switches in the tools used and test different options combinations. Also for best possible matching between different tools - may be helpful https://forum.doom9.org/showthread.php?p=1972733#post1972733
StvG
19th October 2024, 06:51
I was initially stacking videos to check the frame properties were correct after conversion with a function, but I noticed some color oddities with AVSResize when converting between rec.2020 and rec.709.
Would it be safe to assume from the result that approximate_gamma=true (the default) is a bad idea? The difference seems to be the most noticeable for the primary colors. The source is a rec.709 blank clip converted to rec.2020 with HDRTools (so the primaries are rec.2020) and then converted back to rec.709.
z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>rgb:linear:xyz:full", pixel_type="RGBP16")
z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P8")
https://imgur.com/56LbtCC.png
z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>rgb:linear:xyz:full", pixel_type="RGBP16", approximate_gamma=false)
z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P8", approximate_gamma=false)
https://imgur.com/1p9Nx2d.png
Can you share a test script and a sample if there is?
tormento
19th October 2024, 16:22
I am scratching my head.
From Avsresize (http://avisynth.nl/index.php/Avsresize#Changing_Colorimetry) page:
SD NTSC Rec. 601 to HD Rec. 709
z_ConvertFormat(colorspace_op="470bg:601:170m:full=>709:709:709:full")
SD PAL Rec. 601 to HD Rec. 709
z_ConvertFormat(colorspace_op="470bg:601:470bg:full=>709:709:709:full")
Rec. 709 SDR to Rec. 2020 SDR
z_ConvertFormat(colorspace_op="709:709:709:full=>2020:2020:2020:full")
And so on.
Why it requires full when it's actually limited?
FranceBB
19th October 2024, 18:42
Probably to preserve overshootings (i.e highlights over 0.7V) which shouldn't be there in the first place.
It won't do anything bad to the input signal anyway other than changing the frame properties in terms of metadata.
Anyway, I tried without specifying anything and it worked just fine and the same goes for limited to limited as long as you don't have anything exceeding 0.7V.
#Matrix Conversion BT601 PAL to BT709
z_ConvertFormat(colorspace_op="470bg:601:470bg=>709:709:709")
#Matrix Conversion BT709 to BT601 PAL
z_ConvertFormat(colorspace_op="709:709:709=>470bg:601:470bg")
#Matrix Conversion BT709 to BT2020
z_ConvertFormat(colorspace_op="709:709:709:limited=>2020:2020:2020:limited")
#Matrix Conversion BT2020 to BT709
z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>709:709:709:limited")
#Matrix Conversion BT2020 to BT601 PAL
z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>470bg:601:470bg:limited")
DTL
20th October 2024, 22:50
I am scratching my head.
Why it requires full when it's actually limited?
full->full may mean 'no change of range mapping'. Though if calculation is somehow depend on range mapping it can cause distortions - so better to test also limited->limited.
hello_hello
21st October 2024, 13:48
Can you share a test script and a sample if there is?
I was just using a blank clip and changing the color (of the blank clip).
It's probably not technically correct as the blank clip wouldn't have 2020 primaries (I assume) but it does illustrate the difference.
clip = BlankClip(color=color_red).ConvertToYUV420(matrix="rec2020").Spline36Resize(240,240)
clip = clip.ConvertBits(10)
SourceBits = BitsPerComponent(clip)
Bits = (SourceBits == 32) ? 32 : 16
RGBType = "RGBP" + ((SourceBits == 32) ? "S" : "16")
YUVType = "YUV420P" + ((SourceBits == 32) ? "S" : "16")
clipA = clip.HistoTop().Subtitle("BlankClip", size=20)
clipB = clip.ConvertBits(Bits)\
.z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>rgb:linear:xyz:full", pixel_type=RGBType)\
.z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type=YUVType)\
.ConvertBits(SourceBits).HistoTop().Subtitle("AVSResize (ag=true)", size=20)
clipC = clip.ConvertBits(Bits)\
.z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>rgb:linear:xyz:full", pixel_type=RGBType, approximate_gamma=false)\
.z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type=YUVType, approximate_gamma=false)\
.ConvertBits(SourceBits).HistoTop().Subtitle("AVSResize (ag=false)", size=20)
clipD = clip\
.fmtc_bitdepth(Bits)\
.fmtc_resample(css="444")\
.fmtc_matrix(mat="2020", fulls=false, fulld=true, bits=Bits)\
.fmtc_transfer(transs="1886", transd="Linear")\
.fmtc_primaries(prims="2020", primd="709")\
.fmtc_transfer(transs="Linear", transd="1886")\
.fmtc_matrix(mat="709", fulls=true, fulld=false, bits=Bits)\
.fmtc_resample(css="420")\
.fmtc_bitdepth(SourceBits)\
.HistoTop().Subtitle("FMTConv", size=20)
clipE = clip\
.ConvertBits(16)\
.ConvertToYUV444()\
.ConvertYUVtoXYZ(Color=1, fullrange=false)\
.ConvertXYZtoYUV(Color=2, PColor=1, fullrange=false)\
.ConvertToYUV420()\
.ConvertBits(SourceBits)\
.HistoTop().Subtitle("HDRTools", size=20)
StackHorizontal(clipA, clipB, clipC, clipD, clipE)
function HistoTop(clip Source) {
Try{ FTurnRight(Source).Histogram().FTurnLeft() }Catch(err){ TurnRight(Source).Histogram().TurnLeft() } }
https://i.imgur.com/L02pGs2.png
clip = BlankClip(color=color_lime).ConvertToYUV420(matrix="rec2020").Spline36Resize(240,240)
https://i.imgur.com/PEB9RmO.png
DTL
21st October 2024, 16:28
scene_referred=true or false change anything ?
Also look at comment: https://forum.doom9.org/showthread.php?p=1972755#post1972755
About the 'magic' amplitude correction:
- fmtconv - after rgb_lin=fmtc_transfer(rgb_lin,transs="hlg",transd="linear", sceneref=true) the ouput is within range [0,~1]. After applying RGBAdjust values of 0.5, the output becomes within range [0, ~0.5].
- avsresize after rgb_lin=z_convertformat(yuv444,pixel_type="rgbps", colorspace_op="2020ncl:std-b67:2020:l=>rgb:linear:2020:l", scene_referred=true) the output is within range [0, ~3.188]. After applying RGBAdjust values of 0.157, the output becomes within range [0, ~0.5].
Different tools may use different scaling in 'linear'. So may you need to use RGBAdjust() to tweak RGB linear code values somehow. Try to look into code values after each operation.
poisondeathray
21st October 2024, 16:41
What plugins/versions ? I'm getting different results with that script just copy/pasted
avs+ r4066
avsresize r25
fmtconv r30
hdrtools 1.0.5
https://i.postimg.cc/L8xMH2FT/hello-hello.png
hello_hello
21st October 2024, 22:25
DTL & poisondeathray,
thanks for the info. I probably won't get a chance to play around again until late today or tomorrow.
What plugins/versions ? I'm getting different results with that script just copy/pasted
avs+ r4066
avsresize r25
fmtconv r30
hdrtools 1.0.5
https://i.postimg.cc/L8xMH2FT/hello-hello.png
I'm using the same versions of everything except Avisynth+ (r4073 (https://gitlab.com/uvz/AviSynthPlus-Builds))
hello_hello
22nd October 2024, 08:20
I was just using a blank clip and changing the color (of the blank clip).
It's probably not technically correct as the blank clip wouldn't have 2020 primaries (I assume) but it does illustrate the difference.
Well it looks like it was my fault. Kind of.....
I think it's the first time I've come across a plugin behaving differently running in Wine than in Windows, but when I ran the script again in VirtualBox/Windows 11 it was fine.
https://i.imgur.com/nsoivwQ.png
I went back to Avisynth+ 3.7.3 (official release) and nothing changed, so I doubt it's an Avisynth problem.
So it appears approximating gamma in Wine is a bad idea. Anyone know why that'd be? I'm not running the latest version of Wine, so out of curiosity I might install some flavor of Linux in VirtualBox later and install the latest Wine to see if it works properly. I don't want to update Wine on my main OS just yet.
poisondeathray
22nd October 2024, 14:40
So it appears approximating gamma in Wine is a bad idea. Anyone know why that'd be? I'm not running the latest version of Wine, so out of curiosity I might install some flavor of Linux in VirtualBox later and install the latest Wine to see if it works properly. I don't want to update Wine on my main OS just yet.
Maybe some issues with SIMD / AVX2 ? Apparently some Wine releases had some issues . You can try SetMaxCPU and work your way down the list to help debug
hello_hello
22nd October 2024, 15:39
Maybe some issues with SIMD / AVX2 ? Apparently some Wine releases had some issues . You can try SetMaxCPU and work your way down the list to help debug
It's all over with anything less than sse4.1, running in both Windows and Wine. Unfortunately though, limiting the CPU capabilities didn't make any difference to the approximate gamma problem.
SetMaxCPU("ssse3")
https://i.imgur.com/xzHSqd1.png
poisondeathray
22nd October 2024, 15:47
It's all over with anything less than sse4.1, running in both Windows and Wine.
I get same results in windows that I did before, with sse3 or otherwise
hello_hello
22nd October 2024, 17:55
I get same results in windows that I did before, with sse3 or otherwise
Well the plot thickens. Maybe there's something the z.lib resizers don't like about my AMD 7900X CPU and VirtualBox is pretending it's a different one, or something.....
Native Linux VapourSynth (MX Linux)
https://i.imgur.com/sV0S64Z.png
Windows VapourSynth running in VirtualBox (Windows 11)
https://i.imgur.com/6xshfuJ.png
import vapoursynth as vs
core = vs.core
import CropResize as cr
import RGBColor as rgb
import HistoTop as ht
clip = core.std.BlankClip(format=vs.YUV420P10)
clip = core.std.BlankClip(clip, color=rgb.RGBColor(clip, 'red', matrix=1))
clip = core.resize.Spline36(clip, 240,240)
clipA = ht.HistoTop(core.resize.Bicubic(clip, format=vs.YUV420P8)).text.Text("BlankClip")
clipB = core.resize.Bicubic(clip, matrix_in_s="2020cl", transfer_in_s="2020_10", primaries_in_s="2020", \
range_in_s="limited", matrix_s="rgb", transfer_s="linear", primaries_s="xyz", range_s="full", format=vs.RGB48)
clipB = core.resize.Bicubic(clipB, matrix_in_s="rgb", transfer_in_s="linear", primaries_in_s="xyz", \
range_in_s="full", matrix_s="709", transfer_s="709", primaries_s="709", range_s="limited", format=vs.YUV420P16)
clipB = ht.HistoTop(core.resize.Bicubic(clipB, format=vs.YUV420P8)).text.Text("VapourSynth (ag=true)")
clipC = core.resize.Bicubic(clip, matrix_in_s="2020cl", transfer_in_s="2020_10", primaries_in_s="2020", \
range_in_s="limited", matrix_s="rgb", transfer_s="linear", primaries_s="xyz", range_s="full", format=vs.RGB48, \
approximate_gamma=False)
clipC = core.resize.Bicubic(clipC, matrix_in_s="rgb", transfer_in_s="linear", primaries_in_s="xyz", \
range_in_s="full", matrix_s="709", transfer_s="709", primaries_s="709", range_s="limited", format=vs.YUV420P16, \
approximate_gamma=False)
clipC = ht.HistoTop(core.resize.Bicubic(clipC, format=vs.YUV420P8)).text.Text("VapourSynth (ag=false)")
clipD = cr.CropResize(clip, 0,0, ColorConvert="FC", ColorMode="2020-709")
clipD = ht.HistoTop(core.resize.Bicubic(clipD, format=vs.YUV420P8)).text.Text("FMTConv")
clip = core.std.StackHorizontal([clipA, clipB, clipC, clipD])
clip.set_output()
poisondeathray
22nd October 2024, 18:32
No idea. You can also try testing core.std.SetMaxCPU("blah") for the vpy version . Both the vapoursynth core.resize and avsresize also have "cpu_type" parameters too to control for zimg/z.lib specifically instead of globally for the script
hello_hello
22nd October 2024, 19:15
I'm not sure what values VapourSynth accepts for cpu_type (the Resizer documentation doesn't specify) so I tried the values listed in the AVSResize docs. Anything above "avx512f" on the list produces an error:
vapoursynth.Error: Resize error: bad value: cpu_type
Values from "avx512f" down fix the problem, with the exception of "avx_e".
I haven't tested the Windows version of VapourSynth yet, only Linux, but I tested AVSResize running in Wine, and once again setting the correct cpu_type fixes the problem. CPU types such as "avx512_snc" that produce an error in VapourSynth don't do so for AVSResize though. Instead the output simply goes back to what it was originally (incorrect).
For some reason the cpu_type argument only seems to be needed when converting from RGB to YUV.
AVSResize
clipB = clip.ConvertBits(Bits)\
.z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>rgb:linear:xyz:full", pixel_type=RGBType)\
.z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type=YUVType, cpu_type="avx512f")
VapourSynth
clipB = core.resize.Bicubic(clip, matrix_in_s="2020cl", transfer_in_s="2020_10", primaries_in_s="2020", \
range_in_s="limited", matrix_s="rgb", transfer_s="linear", primaries_s="xyz", range_s="full", format=vs.RGB48)
clipB = core.resize.Bicubic(clipB, matrix_in_s="rgb", transfer_in_s="linear", primaries_in_s="xyz", \
range_in_s="full", matrix_s="709", transfer_s="709", primaries_s="709", range_s="limited", format=vs.YUV420P16, cpu_type="avx512f")
https://i.imgur.com/NFMSPqL.png
For the record, the color's probably a tad different compared to the screenshot in my previous post as I think I used matrix=9 instead of matrix=1 when creating the blank clip this time.
clip = core.std.BlankClip(clip, color=rgb.RGBColor(clip, 'red', matrix=9))
_Al_
22nd October 2024, 22:05
On windows 10, using vapoursynth R62, (it seams R62 version resize does not have approximate_gamma argument yet, so no ClipC,
using this script (no dependent modules, except histogram and fmtConv):
import vapoursynth as vs
from vapoursynth import core
def histo_top(clip, subtitle):
if not hasattr(core, 'hist'):
raise AttributeError('vapoursynth histogram plugin is not loaded, nhttps://github.com/dubhater/vapoursynth-histogram')
clip = core.resize.Bicubic(clip, format=vs.YUV420P8)
clip = clip.std.Transpose().std.FlipHorizontal() # turn right
clip = core.hist.Classic(clip).std.Transpose().std.FlipVertical() # turn left
return clip.text.Text(subtitle)
clip = core.std.BlankClip(color=(255, 0, 0))
clip = core.resize.Bicubic(clip, width=240, height=240, format=vs.YUV420P10, matrix_s="709")
clipA = histo_top(clip, subtitle="BlankClip")
clipB = core.resize.Bicubic(clip, matrix_in_s="2020cl", transfer_in_s="2020_10", primaries_in_s="2020",
range_in_s="limited", matrix_s="rgb", transfer_s="linear", primaries_s="xyz", range_s="full", format=vs.RGB48)
clipB = core.resize.Bicubic(clipB, matrix_in_s="rgb", transfer_in_s="linear", primaries_in_s="xyz",
range_in_s="full", matrix_s="709", transfer_s="709", primaries_s="709", range_s="limited", format=vs.YUV420P16)
clipB = histo_top(clipB, subtitle="ag=default(true?)")
# clipC = core.resize.Bicubic(clip, matrix_in_s="2020cl", transfer_in_s="2020_10", primaries_in_s="2020",
# range_in_s="limited", matrix_s="rgb", transfer_s="linear", primaries_s="xyz", range_s="full", format=vs.RGB48,
# approximate_gamma=False)
# clipC = core.resize.Bicubic(clipC, matrix_in_s="rgb", transfer_in_s="linear", primaries_in_s="xyz",
# range_in_s="full", matrix_s="709", transfer_s="709", primaries_s="709", range_s="limited", format=vs.YUV420P16,
# approximate_gamma=False)
# clipC = histo_top(clipC, subtitle="VapourSynth (ag=false)")
if not hasattr(core, 'fmtc'):
raise AttributeError('FMTConv plugin is not loaded, https://github.com/EleonoreMizo/fmtconv/releases')
clipD = core.fmtc.resample(clip, css="444")
clipD = core.fmtc.matrix(clipD, mat="2020", fulls=False, fulld=True)
clipD = core.fmtc.transfer(clipD, transs="1886", transd="Linear")
clipD = core.fmtc.primaries(clipD, prims="2020", primd="709")
clipD = core.fmtc.transfer(clipD, transs="Linear", transd="1886")
clipD = core.fmtc.matrix(clipD, mat="709", fulls=True, fulld=False)
clipD = core.fmtc.resample(clipD, css="420")
clipD = histo_top(clipD, subtitle="FMTConv")
clip = core.std.StackHorizontal([clipA, clipB, clipD])
clip.set_output()
https://imgur.com/a/VlWs4nZ
Jamaika
22nd October 2024, 22:39
I've been compiling various projects for a long time.
Does ffmpeg + avisynth + avsresize make sense? Or is this creation a piece of junk? I won't deny that it's hard to compile under Windows and I had to correct errors.
https://www.sendspace.com/file/9ar08u
tormento
23rd October 2024, 18:02
There is a strange bug that I can't really understand.
I was playing with some resize scripts and one arose to my mind. Something like:
SetMemoryMax()
SetCacheMode(0)
SetFilterMTMode("DEFAULT_MT_MODE", 2)
LoadPlugin("D:\Eseguibili\Media\DGDecNV\DGDecodeNV.dll")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\DehaloAlpha\Dehalo_alpha.avsi")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\Dither\mt_xxpand_multi.avsi")
Import("D:\Eseguibili\Media\StaxRip\Apps\Plugins\AVS\FineDehalo\FineDehalo.avsi")
DGSource("M:\In\Shangri-La frontier vol 1-4 ~931p BDJP\1-01.dgi", dn_enable=3, dn_strength=0.04, dn_cstrength=0.02, dn_quality="best")
AiUpscale(Factor=1, CResample="KrigBilateral", Mode="LineArt", OutDepth=16)
Spline64ResizeMT(1656,932,threads=1)
FineDehalo(rx=2.0, ry=2.0, thmi=80, thma=128, thlimi=50, thlima=100, darkstr=0.6, brightstr=1.0, showmask=0, contra=0.0, excl=true)
libplacebo_Deband(iterations=5,temporal=false)
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion")
Prefetch(2,6)
The idea was to upscale the chroma to 444 before resizing.
It ended with a grey line at the bottom of the screen (zoom the image)
https://i.ibb.co/Ytc3RSZ/Shangri-La01.png (https://ibb.co/30p7rbz)
i.e. no chroma information.
I have commented every single line and arrived to a very simple scripts, such as
Source()
z_ConvertFormat(pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion")
And I had the very same result.
I tried to debug the error.
At first, I saw that changing the last line to
fmtc_resample(css="420",kernel="spline64")
works perfectly.
Later, I changed the last line to
z_ConvertFormat(pixel_type="YUV420P10")
and the grey line disappeared too.
Eventually, I have noticed that the other z.lib resamplers, such as Lanczos, doesn't show the same issue.
What's wrong with Spline64 in z.lib? Why does it work with fmtc_resample?
poisondeathray
24th October 2024, 02:01
Source()
z_ConvertFormat(pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion")
And I had the very same result.
The following looks ok to me, no grey line . How about you ?
ColorbarsHD(1920,1080)
ConvertToYV12()
FlipVertical()
z_ConvertFormat(pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion")
If you have problem , post avs+ version, avsresize version
Or can you provide a source/script combination that can produce the problem
FranceBB
24th October 2024, 10:23
Oh crap.
Well, there's a good news and a bad news.
The "bad news" is that I can reproduce the issue.
The "good news" is that you stumbled upon a bug in the AVX assembly code that none of my production servers at work use.
To make it appear more obvious I used the following code:
source=ColorBars(500, 960, pixel_type="YV16").Crop(0, 0, -0, -940)
z_ConvertFormat(source, pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx")
avx=last
z_ConvertFormat(source, pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx2")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx2")
avx2=last
StackHorizontal(avx, avx2)
Here you can see how the output produced by the AVX assembly code (left) has the issue, while the one produced by AVX2 (right) doesn't:
https://i.imgur.com/zppCvjo.png
I also tried all the other assemblies and luckily enough the issue was present only in the AVX code path.
This is the full test with plain C++, AVX, AVX2, AVX512:
source=ColorBars(500, 960, pixel_type="YV16").Crop(0, 0, -0, -940)
z_ConvertFormat(source, pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="none")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="none")
Subtitle("C++")
cpp=last
z_ConvertFormat(source, pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx")
Subtitle("AVX")
avx=last
z_ConvertFormat(source, pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx2")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx2")
Subtitle("AVX2")
avx2=last
z_ConvertFormat(source, pixel_type="YUV444P16", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx512f")
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion", cpu_type="avx512f")
Subtitle("AVX512")
avx512=last
StackVertical(cpp, avx, avx2, avx512)
https://i.imgur.com/HaPcZNH.png
I opened a bug in the sekrit's zimg repository here: https://github.com/sekrit-twc/zimg/issues/209
FranceBB
25th October 2024, 15:17
Sekrit fixed it.
Turns out, it was used by AVX only capable CPUs but it was actually part of the SSE2 code path.
Anyway this is the commit with the fix https://github.com/sekrit-twc/zimg/commit/034b7cf5339e576080e61fd53f566387687ff4d6
Full SSE2 assembly code by Sekrit https://github.com/sekrit-twc/zimg/blob/master/src/zimg/resize/x86/resize_impl_sse2.cpp
To test Sekrit's fix, I grabbed the StvG's avsresize source code from here https://codeberg.org/StvG/avsresize and I linked against the zimg master, the graphedit master and the Avisynth master (the Ferenc & Stephen repository) and compiled a debug build.
Link (avsresize r25 + Spline64 SSE2 bugfix x64 MSVC): https://github.com/user-attachments/files/17523207/avsresize.zip
Sekrit's fix works. :)
https://i.imgur.com/nbOjC4F.png
Now we just need StvG to build a new version of avsresize using this new version of zimg and release avsresize r26. ;)
Please do not use my debug build for anything other than testing. Wait for StvG to release the final version.
tormento
25th October 2024, 23:27
Link (avsresize r25 + Spline64 SSE2 bugfix x64 MSVC)
Getting
Script error: There is no function named 'z_ConvertFormat'.
for
z_ConvertFormat(pixel_type="YUV420P10", resample_filter_uv="Spline64", dither_type="error_diffusion")
FranceBB
26th October 2024, 00:07
You're missing the Microsoft C++ Redistributable.
You can install them one by one from the Microsoft website or get the unofficial AIO (all in one) package from here https://github.com/abbodi1406/vcredist/releases/
tormento
26th October 2024, 18:47
You're missing the Microsoft C++ Redistributable.
You linked the debug dlls not the standard ones.
StvG
27th October 2024, 15:14
avsresize_r25a (https://codeberg.org/StvG/avsresize/releases):
- zimg 2aed91a
@hello_hello, you can also try this build (https://files.catbox.moe/2e14q0.7z) if the other r25a build still give you different output in Wine.
Jamaika
27th October 2024, 16:07
plugins/libzimg/zimg++.hpp:333:8: warning: extra tokens at end of '#endif' directive [-Wendif-labels]
333 | #endif ZIMG_GRAPHENGINE_API // ZIMG_GRAPHENGINE_API
| ^~~~~~~~~~~~~~~~~~~~
plugins/avsresize.cpp:1067:27: error: 'ZIMG_TRANSFER_PROPHOTORGB' was not declared in this scope
1067 | { "prophoto", ZIMG_TRANSFER_PROPHOTORGB},
| ^~~~~~~~~~~~~~~~~~~~~~~~~
plugins/avsresize.cpp:1085:25: error: 'ZIMG_PRIMARIES_PROPHOTO' was not declared in this scope
1085 | { "prophoto", ZIMG_PRIMARIES_PROPHOTO },
| ^~~~~~~~~~~~~~~~~~~~~~~
plugins/avsresize.cpp: In function 'AVSValue {anonymous}::create_resize(AVSValue, void*, IScriptEnvironment*)':
plugins/avsresize.cpp:1472:29: error: 'struct zimgxx::zfilter_graph_builder_params' has no member named 'scene_referred'
1472 | params.graph_params.scene_referred = args[22].AsBool(false);
| ^~~~~~~~~~~~~~
StvG
27th October 2024, 17:25
plugins/libzimg/zimg++.hpp:333:8: warning: extra tokens at end of '#endif' directive [-Wendif-labels]
333 | #endif ZIMG_GRAPHENGINE_API // ZIMG_GRAPHENGINE_API
| ^~~~~~~~~~~~~~~~~~~~
plugins/avsresize.cpp:1067:27: error: 'ZIMG_TRANSFER_PROPHOTORGB' was not declared in this scope
1067 | { "prophoto", ZIMG_TRANSFER_PROPHOTORGB},
| ^~~~~~~~~~~~~~~~~~~~~~~~~
plugins/avsresize.cpp:1085:25: error: 'ZIMG_PRIMARIES_PROPHOTO' was not declared in this scope
1085 | { "prophoto", ZIMG_PRIMARIES_PROPHOTO },
| ^~~~~~~~~~~~~~~~~~~~~~~
plugins/avsresize.cpp: In function 'AVSValue {anonymous}::create_resize(AVSValue, void*, IScriptEnvironment*)':
plugins/avsresize.cpp:1472:29: error: 'struct zimgxx::zfilter_graph_builder_params' has no member named 'scene_referred'
1472 | params.graph_params.scene_referred = args[22].AsBool(false);
| ^~~~~~~~~~~~~~
There is zimg.patch in the release archive.
FranceBB
28th October 2024, 15:59
avsresize_r25a (https://codeberg.org/StvG/avsresize/releases):
- zimg 2aed91a
Thank you for the official build! :D
I can confirm that the issue is solved.
https://i.imgur.com/irYBS2B.png
hello_hello
2nd November 2024, 09:51
avsresize_r25a (https://codeberg.org/StvG/avsresize/releases):
- zimg 2aed91a
@hello_hello, you can also try this build (https://files.catbox.moe/2e14q0.7z) if the other r25a build still give you different output in Wine.
Thanks. I tried them both but the result is still the same. I need to use the cpu_type argument for the RGB to YUV part of the conversion to get the expected result when approximate_gamma is true.
z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type=YUV420P16, cpu_type="avx512f")
It doesn't seem to be a Wine issue as such though, as the behavior is the same for the native Linux flavor of VapourSynth and it's resizers. Possibly something to do with my AMD 7900X CPU??
Cheers.
FranceBB
4th November 2024, 14:36
Hey hello_hello, I'm trying to reproduce this on Windows Server 2019 Standard x64 running on an Intel Xeon Gold 6238R which supports AVX512 natively.
Unfortunately (or should I say "fortunately" in this case) I can't reproduce as the C++, AVX, AVX2 and AVX512 conversions all produce identical results.
source=ColorBars(500, 960, pixel_type="YUV444P16").Crop(0, 0, -0, -940).ConvertYUVtoXYZ().ConverttoPlanarRGB()
z_ConvertFormat(source, colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P16", cpu_type="none")
Subtitle("C++")
cpp=last
z_ConvertFormat(source, colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P16", cpu_type="avx")
Subtitle("AVX")
avx=last
z_ConvertFormat(source, colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P16", cpu_type="avx2")
Subtitle("AVX2")
avx2=last
z_ConvertFormat(source, colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P16", cpu_type="avx512f")
Subtitle("AVX512")
avx512=last
StackVertical(cpp, avx, avx2, avx512)
https://i.imgur.com/2lOESqu.png
In other words, it doesn't seem to be an issue within avsresize, at least not in the Avisynth version running on bare metal hardware.
hello_hello
4th November 2024, 17:22
Hey hello_hello, I'm trying to reproduce this on Windows Server 2019 Standard x64 running on an Intel Xeon Gold 6238R which supports AVX512 natively.
Unfortunately (or should I say "fortunately" in this case) I can't reproduce as the C++, AVX, AVX2 and AVX512 conversions all produce identical results.
If it's a CPU related issue it looks like it's an AMD one. Or an AMD/Linux one. The same problem exists for both AVSResize running in Wine and the native Linux VapourSynth resizers.
If Avisynth and/or VapourSynth are running on Windows 11 in VirtualBox there's no issue with approximate_gamma=true. I don't know much about emulation but apparently VirtualBox pretends Windows is running on an Intel chipset, although Device Manager correctly identifies the AMD Ryzen 9 7900x CPU. I haven't tried adding cpu_type to z_ConvertFormat running on Windows though as it's not needed and I rarely run anything in Windows/VirtualBox anyway.
As a side note I was reading a review regarding the newer AMD CPUs and SMT (hyperthreading). It mentioned disabling SMT can sometimes improve performance a little for specific workloads, so I thought I'd try it. The Avisynth script I used for testing included some fairly slow denoising and I was encoding with x264, all running in Wine. I wasn't expecting much of a change, but disabling SMT increased encoding speed by roughly 30% (~25 fps to ~33fps), CPU usage increased from 50-60% to 90%, and the CPU also ran about 7 degrees cooler with SMT disabled. I ran the test twice for each, obviously rebooting in between to disable/enable SMT. Maybe that's a Wine or Linux issue too. I haven't run the test again with the native Linux Vapoursynth and x264 to see if the result is similar, but I probably will sometime soon, just out of curiosity.
StvG
4th November 2024, 22:28
@hello_hello, you can report to zimg.
Emulgator
4th November 2024, 22:43
Maybe just one codepath, and maybe compiler dependent, so dependent on build version ?
IIRC qyot27 found such dependency on another occasion.
takla
5th November 2024, 23:41
As a side note I was reading a review regarding the newer AMD CPUs and SMT (hyperthreading). It mentioned disabling SMT can sometimes improve performance a little for specific workloads, so I thought I'd try it. The Avisynth script I used for testing included some fairly slow denoising and I was encoding with x264, all running in Wine. I wasn't expecting much of a change, but disabling SMT increased encoding speed by roughly 30% (~25 fps to ~33fps), CPU usage increased from 50-60% to 90%, and the CPU also ran about 7 degrees cooler with SMT disabled. I ran the test twice for each, obviously rebooting in between to disable/enable SMT. Maybe that's a Wine or Linux issue too. I haven't run the test again with the native Linux Vapoursynth and x264 to see if the result is similar, but I probably will sometime soon, just out of curiosity.
If your CPU wasn't thermal or power throttling SMT=Off shouldn't get more fps.
hello_hello
6th November 2024, 17:51
@hello_hello, you can report to zimg.
Done. https://github.com/sekrit-twc/zimg/issues/211
hello_hello
17th November 2024, 21:09
According to the response to my question here (https://github.com/sekrit-twc/zimg/issues/211#issuecomment-2463684750), there's no need to use an intermediate RGB clip when converting color with AVSResize (at least for standard matrix/primaries conversions). Therefore converting from rec.2020 to rec.709 this way isn't necessary:
z_ConvertFormat(colorspace_op="2020:2020:2020:limited=>rgb:linear:xyz:full", pixel_type="RGBP16")
z_ConvertFormat(colorspace_op="rgb:linear:xyz:full=>709:709:709:limited", pixel_type="YUV420P16")
And it's okay to do it like this:
z_ConvertFormat(colorspace_op="2020:2020:2020=>709:709:709", pixel_type="YUV420P16")
Is that correct?? I feel like it shouldn't be after using the first method for so long.
StvG
19th November 2024, 13:04
This way is also worse if the intermediate RGB is 16-bit and not float. If the intermediate RGB is float (RGBPS), then both methods has identical output - your choice which to use (I always use the one line method).
hello_hello
20th November 2024, 17:17
Thanks!
hello_hello
8th December 2024, 05:48
StvG,
I know I asked about 32 bit float handling a while ago, but I'm still not 100% sure how to correctly convert to float and back.
For an 8 bit limited range clip, the frame property becomes full range if I do this:
ConvertBits(32)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8)
ConvertBits can change the frame property back to limited range though, and the result is exactly the same:
ConvertBits(32)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8, fulls=false, fulld=false)
However as you previously said zimg assumes 32-bit float is full range, I'm wondering if I should do it like this. According to Compare() the output isn't the same, but in my head at least, it seems to be the technically correct method. Would that assumption be correct?
Cheers.
ConvertBits(32, fulls=false, fulld=true)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8, fulls=true, fulld=false)
DTL
8th December 2024, 12:57
If all used equations are not dependent on the range mapping - the frame properties range mapping hints do nothing in float samples format processing. So if the result is the same - you can pass any range mapping to float processing. But you need to check the before and after range mapping to be equal. Some plugins may depend on the black (and all other levels position/mapping).
So if you send narrow-float (shifted black) to convert and use narrow-float to narrow-integer convert back it will work. Many plugins may assume float always uses black mapped to 0.0f and nominal white mapped to 1.0f. (Also zero UV to 0.0f). But some may use any other like 0..max_int mapped to 0.0f..max_int_as_float.
"For an 8 bit limited range clip, the frame property becomes full range if I do this:
ConvertBits(32)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8)"
You use 3 filters in a chain - first you can start to look where your range mapping property switched from narrow/limited to full. Maybe after the first ConvertBits(32) filter.
hello_hello
8th December 2024, 15:26
You use 3 filters in a chain - first you can start to look where your range mapping property switched from narrow/limited to full. Maybe after the first ConvertBits(32) filter.
It's definitely z_ConvertFormat writing "full" to frame properties. Avisynth's ConvertBits is happy for float to be either full or limited range.
I hunted around some more and I'm pretty sure for my example above, converting limited range integer to full range float before z_ConvertFormat is the correct way to do it, as zimg always assumes float is full range (either that or let zimg do the conversion).
https://github.com/sekrit-twc/zimg/issues/134
https://forum.doom9.org/showthread.php?p=1927024#post1927024
I think the same applies to FMTConv. The help file doesn't specifically say float is full range, but it does say the fulls and fulld arguments have no meaning for float data.
These produce the same result (8 bit limited range input):
A = ConvertBits(32, fulls=false, fulld=true)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8, fulls=true, fulld=false)
B = z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg", bit_depth=32)\
.ConvertBits(8, fulls=true, fulld=false)
Compare(A,B)
The output here is very close, but not exactly the same. Maybe a rounding difference when converted back to 8 bit?
A = ConvertBits(32, fulls=false, fulld=true)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8, fulls=true, fulld=false)
B = z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg", bit_depth=32)\
.z_ConvertFormat(bit_depth=8)
Compare(A,B)
tormento
8th December 2024, 22:43
I think the same applies to FMTConv
I deeply encourage you to use FMTconv when dithering down, instead of AVS+ implicits or z_img, at least for its wider dithering choices and resilience of some of them (i.e. 8) to codec encoding.
StvG
9th December 2024, 01:15
StvG,
I know I asked about 32 bit float handling a while ago, but I'm still not 100% sure how to correctly convert to float and back.
For an 8 bit limited range clip, the frame property becomes full range if I do this:
ConvertBits(32)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8)
ConvertBits can change the frame property back to limited range though, and the result is exactly the same:
ConvertBits(32)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8, fulls=false, fulld=false)
However as you previously said zimg assumes 32-bit float is full range, I'm wondering if I should do it like this. According to Compare() the output isn't the same, but in my head at least, it seems to be the technically correct method. Would that assumption be correct?
Cheers.
ConvertBits(32, fulls=false, fulld=true)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8, fulls=true, fulld=false)
The latest example is the correct one.
If you will use z_ConvertFormat in already converted 32-bit environment you have to be sure that the range is [0,1] (full) before the z_ConvertFormat call.
The output here is very close, but not exactly the same. Maybe a rounding difference when converted back to 8 bit?
A = ConvertBits(32, fulls=false, fulld=true)\
.z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg")\
.ConvertBits(8, fulls=true, fulld=false)
B = z_ConvertFormat(colorspace_op="170m:601:170m=>470bg:601:470bg", bit_depth=32)\
.z_ConvertFormat(bit_depth=8)
Compare(A,B)
Yes, the difference is due to rounding diff.
hello_hello
23rd March 2025, 02:04
Is it expected behavior for AVSResize to flip the image when pixel shifting rather than duplicate the edge pixels?
I realize these aren't exactly examples of real world pixel shifting, but it wasn't what I expected so I thought I'd ask.
Using a 640x480 source:
Spline36Resize(640,480,0,0,680,520)
https://i.ibb.co/35g1x3dL/A.png
z_Spline36Resize(640,480,0,0,680,520)
https://i.ibb.co/Q7DbBnwv/B.png
Spline36Resize(640,480,-40,0,640,520)
https://i.ibb.co/TD6NqNvN/C.png
z_Spline36Resize(640,480,-40,0,640,520)
https://i.ibb.co/HppPqS0z/D.png
StvG
23rd March 2025, 06:58
Is it expected behavior for AVSResize to flip the image when pixel shifting rather than duplicate the edge pixels?
Yes, this is the zimg behavior.
StvG
31st August 2025, 03:11
New version: avsresize r26 (https://codeberg.org/StvG/avsresize/releases).
Jamaika
31st August 2025, 05:09
I don't know why it doesn't work in C++17. Too modern, remains old.
plugins/avsresize/avsresize.cpp:1390:82: error: no matching function for call to 'std::basic_string_view<char>::basic_string_view(const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&, const __gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> >&)'
1390 | const std::string_view dst_matrix(match[5].first, match[5].second);
| ^
StvG
31st August 2025, 12:32
I don't know why it doesn't work in C++17. Too modern, remains old.
C++20 is required.
tormento
1st September 2025, 10:24
C++20 is required.
I hope not to annoy you with the request that I am making to many developers.
When you have time, could you try a Intel compiler build?
StvG
1st September 2025, 17:38
I hope not to annoy you with the request that I am making to many developers.
When you have time, could you try a Intel compiler build?
Release files:
- x64 binary is compiled with Intel C++ Compiler 2025.
- x86 binary is compiled with clang-cl.
Here you can download x64 binaries compiled with MSVC and clang-cl (https://files.catbox.moe/tgjh5o.7z), if you want to benchmark the different binaries.
tormento
1st September 2025, 19:36
Release files:
- x64 binary is compiled with Intel C++ Compiler 2025.
- x86 binary is compiled with clang-cl.
Here you can download x64 binaries compiled with MSVC and clang-cl, if you want to benchmark the different binaries.
Sorry but I can't understand.
You write Intel + clang and then the files are MSVC + clang.
You mean that the x64 release file is ICC already?
StvG
1st September 2025, 19:54
Sorry but I can't understand.
You write Intel + clang and then the files are MSVC + clang.
You mean that the x64 release file is ICC already?
Release is avsresize_26.7z. When you extract it - there are x64 (64-bit) and x86 (32-bit) binaries. Binary file means "avsresize.dll".
x64 binary - avsresize.dll (64-bit) is compiled with Intel C++ Compiler 2025 (icx, not icc because icc is the signature of the old Intel C++ Compilers).
x86 binary - avsresize.dll (32-bit) is compiled with clang-cl because the Intel C++ Compilers supports only 64-bit.
The additional files I shared in my previous post are only 64-bit - when you extract the archive, you will see two folders "avsresize_r26_cl" (compiled with MSVC) and "avsresize_r26_clang" (compiled with clang-cl).
I hope it's clear now.
tormento
1st September 2025, 20:42
I hope it's clear now.
It happens something really strange with your builds.
Usually, for my old CPU (i7-2600k w/AVX only), the speed order is:
ICX > MSVC > CLANG > GCC
but with your plugin and a madeup script
ColorBarsHD(3840, 2160)
z_ConvertFormat(chromaloc_op="top_left=>left",pixel_type="RGBP16", colorspace_op="2020:st2084:2020:limited=>rgb:st2084:2020:full", resample_filter_uv="Spline64", dither_type="error_diffusion", use_props=0)
z_ConvertFormat(pixel_type="yuv444ps", colorspace_op="rgb:std-b67:2020:full=>2020:std-b67:2020:limited", resample_filter_uv="Spline64", dither_type="error_diffusion", use_props=0)
z_ConvertFormat(resample_filter="spline64",dither_type="error_diffusion",pixel_type="YUV420P10")
Prefetch(4)
I have
clang 6.904 fps
ICX 5.603 fps
MSVC 5.722 fps
and it's really unusual. :eek:
StvG
2nd September 2025, 14:56
It's unsual for you but it doesn't mean something is wrong. You should understand that the compilers aren't static. Even the same compiler with same settings but different version can produce binaries with different performance (speed and memory).
From my quick tests both icx and clang-cl are on par.
tormento
4th September 2025, 12:20
From my quick tests both icx and clang-cl are on par.
Thank you for your time and effort ;)
Sharc
15th September 2025, 08:10
It's still r21.7 in the Avisynth wiki......
StvG
19th August 2026, 06:38
New version: avsresize r27 (https://codeberg.org/StvG/avsresize/releases).
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.