Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
25th March 2021, 00:25 | #141 | Link |
Registered User
Join Date: Mar 2018
Posts: 447
|
Looks like there is no way to read the similarity metric back into a script variable which is how the current SSIM metric is handled. Perhaps this could be implemented by passing a (global?) variable name and GMSD / MDSI functions would assign that variable?
|
25th March 2021, 13:15 | #142 | Link | |
Registered User
Join Date: Jan 2016
Posts: 162
|
Quote:
For example, Code:
def output_frameprop( clip: vs.VideoNode, filename: str, prop_name: str ) -> vs.VideoNode: records = [] frames = clip.num_frames def output(n, f, clip=clip): records.append((n, f.props[prop_name])) nonlocal frames frames -= 1 if frames == 0: with open(filename, "w") as f: f.write(f"frameIdx {prop_name}\n") f.writelines( f"{idx:8} {value:{len(prop_name)}}\n" for idx, value in sorted(records)) return clip return core.std.FrameEval(clip, output, clip) clip = calculate_some_metric(clip) clip = output_frameprop(clip, "stats.txt", metric_name) |
|
25th March 2021, 16:12 | #143 | Link |
Registered User
Join Date: Dec 2005
Location: Germany
Posts: 1,795
|
@WolframRhodium I think he means the avisynth version. For VS we already have this scrpt here https://github.com/theChaosCoder/zop...er/zoptilib.py
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth VapourSynth Portable FATPACK || VapourSynth Database |
25th March 2021, 21:09 | #146 | Link | ||
Registered User
Join Date: Dec 2005
Location: Germany
Posts: 1,795
|
Quote:
https://github.com/Asd-g/AviSynthPlu...MDSI.avsi#L103 Quote:
They are read for show=true at the script bottom Code:
ScriptClip("""Subtitle("FrameMDSI: " + String(propGetFloat("_FrameMDSI")))"""
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth VapourSynth Portable FATPACK || VapourSynth Database |
||
28th March 2021, 01:17 | #147 | Link |
Registered User
Join Date: Mar 2018
Posts: 447
|
Thanks Chaos, I didn't notice that the metric can indeed be read from the frame properties. So here's an example script using GMSD:
Code:
TEST_FRAMES = 5 # how many frames are tested MIDDLE_FRAME = 50 # middle frame number RawSourcePlus("D:/optimizer/test/flower/flower_cif.yuv", width=352, height=288, pixel_type="I420") source=ColorYUV(levels="PC->TV") noisy=source.AddGrain(25, 0, 0, seed=1) #return noisy #denoised=noisy.FFT3DFilter(sigma=4, bt=4, bw=16, bh=16, ow=8, oh=8) # best settings by Fizick sigma = 400/100.0 # optimize sigma = _n_/100.0 | 100..800 | sigma bt = 4 # optimize bt = _n_ | -1..5 | blockTemporal blockSize = 32 # optimize blockSize = _n_ | 2..64 ; min:overlap 2 * | blockSize overlap = 16 # optimize overlap = _n_ | 0..32 ; max:blockSize 2 / | overlap denoised=noisy.FFT3DFilter(sigma=sigma, bt=bt, bw=blockSize, bh=blockSize, ow=overlap, oh=overlap) # cut out the part used in quality / speed evaluation source = source.Trim(MIDDLE_FRAME - TEST_FRAMES/2 + (TEST_FRAMES%2==0?1:0), MIDDLE_FRAME + TEST_FRAMES/2) denoised = denoised.Trim(MIDDLE_FRAME - TEST_FRAMES/2 + (TEST_FRAMES%2==0?1:0), MIDDLE_FRAME + TEST_FRAMES/2) last = denoised last = GMSD(source, denoised) global total = 0.0 global gmsd_total = 0.0 FrameEvaluate(last, """ global gmsd = propGetFloat("_PlaneGMSD") global gmsd = (gmsd == 0.0 ? 1.0 : gmsd) global gmsd_total = gmsd_total + gmsd """) # measure runtime, plugin writes the value to global avstimer variable global avstimer = 0.0 AvsTimer(frames=1, type=0, total=false, name="Optimizer") # per frame logging (gmsd, time) delimiter = "; " resultFile = "perFrameResults.txt" # output out1="gmsd: MIN(float)" out2="time: MIN(time) ms" file="perFrameResults.txt" WriteFile(resultFile, "current_frame", "delimiter", "gmsd", "delimiter", "avstimer") # write "stop" at the last frame to tell the optimizer that the script has finished frame_count = FrameCount() WriteFileIf(resultFile, "current_frame == frame_count-1", """ "stop " """, "gmsd_total", append=true) return last In this script GMSD gave indentical optimal values compared to SSIM except for the sigma which is 415 instead of 479. I didn't try MDSI yet. |
28th March 2021, 12:47 | #148 | Link |
Pig on the wing
Join Date: Mar 2002
Location: Finland
Posts: 5,718
|
Is there a way to utilize Avisynth+'s Prefetch to speed up calculation? I tested it briefly but there were problems probably related to writing to the file asynchronously.
__________________
And if the band you're in starts playing different tunes I'll see you on the dark side of the Moon... |
28th March 2021, 17:11 | #149 | Link | |
Registered User
Join Date: Mar 2018
Posts: 447
|
Quote:
Is it possible to force WriteFile to execute on one thread while the filters before it are multithreaded? The documentation states that you cannot set MT mode on script function calls, but would placing a MT_SERIALIZED plugin call just before WriteFile have that side effect? Or can you just say SetFilterMTMode("WriteFile", MT_SERIALIZED)? On the other hand, perhaps the WriteFile is already MT_SERIALIZED but the threads are writing into it in arbitrary order and the last line is not always last as it should be. In that case the per frame results should be written into a temporary thread-safe variable which would be written to file in correct order when all the frames are finished. It works like that in Vapoursynth using a map, but Avisynth doesn't have such a data structure so I'm not sure how to implement that. Perhaps a simple array would suffice as long as it's thread safe. |
|
28th March 2021, 18:04 | #150 | Link |
Pig on the wing
Join Date: Mar 2002
Location: Finland
Posts: 5,718
|
I'm not sure if WriteFile is internally marked as MT_SERIALIZED, but in general, it should already have a "correct" mode set. It is very much likely that the order of frames is very random since they finish at different times.
Setting both Prefetch(threads=1, frames=24) and Prefetch(threads=24, frames=1) give this error: java.lang.NumberFormatException: For input string: "1I don't know what 'delimiter' means.0.179144I don't know what 'delimiter' means.3150.284912" and the log file is full of these errors.
__________________
And if the band you're in starts playing different tunes I'll see you on the dark side of the Moon... |
29th March 2021, 02:55 | #151 | Link | |
Registered User
Join Date: Mar 2018
Posts: 447
|
Quote:
|
|
29th March 2021, 05:07 | #152 | Link | |
Pig on the wing
Join Date: Mar 2002
Location: Finland
Posts: 5,718
|
Quote:
The VS version is also not perfect in multithreading sense but it is somewhat faster.
__________________
And if the band you're in starts playing different tunes I'll see you on the dark side of the Moon... |
|
16th April 2021, 00:02 | #153 | Link |
Registered User
Join Date: Mar 2018
Posts: 447
|
Zopti v1.1.0 released
A new major release is here! Zopti now supports executing multiple scripts simultaneously which can lead to very nice performance improvement. This can be very useful when the script itself is not able to utilize all of your cores.
Here's the full release info:
Download link is at the first post. I will shortly post some data on the multithreading performance. |
16th April 2021, 00:49 | #154 | Link |
Registered User
Join Date: Mar 2018
Posts: 447
|
I tested the new -threads argument using the denoising tutorial script, this time using GMSD as the similarity metric and using 50 frames instead of 5. Here's the script:
Code:
import vapoursynth as vs from zoptilib import Zopti core = vs.core TEST_FRAMES = 50 # how many frames are tested MIDDLE_FRAME = 100 # middle frame number # read input video video = core.raws.Source(r'D:\optimizer\test\flower\flower_cif.yuv', 352, 288, src_fmt='I420') zopti = Zopti(r'results.txt', metrics=['gmsd', 'time']) # input color range is PC (full) video = video.std.SetFrameProp(prop="_ColorRange", intval=0) # add noise noisy = video.grain.Add(var=25, seed=3) #noisy.set_output() # remove noise sigma = 400/100 # optimize sigma = _n_/100 | 400..600 ; filter:x 5 % 0 == | sigma bt = 5 # optimize bt = _n_ | 3,5 | blockTemporal blockSize = 14 # optimize blockSize = _n_ | 6,12 ; min:overlap 2 * | blockSize overlap = 16 # optimize overlap = _n_ | 4..6 ; max:blockSize 2 / | overlap denoised = noisy.fft3dfilter.FFT3DFilter(sigma=sigma, bt=bt, bw=blockSize, bh=blockSize, ow=overlap, oh=overlap) # cut out the part used in quality / speed evaluation video = video[MIDDLE_FRAME - TEST_FRAMES//2 + (1 if (TEST_FRAMES%2==0) else 0) : MIDDLE_FRAME + TEST_FRAMES//2 + 1] denoised = denoised[MIDDLE_FRAME - TEST_FRAMES//2 + (1 if (TEST_FRAMES%2==0) else 0) : MIDDLE_FRAME + TEST_FRAMES//2 + 1] zopti.run(video, denoised) The script only has 246 valid parameter combinations to test so we can try all of them using Code:
zopti denoise_ex.vpy -alg exhaustive -threads 1 The best result is about 20 seconds using all 24 threads (on a Ryzen 3900X which has 12 cores / 24 threads). Another way to look at the scaling is to calculate how much faster we get the results when using -threads: Using 24 threads is 7,1 times as fast as using only one thread. Of course this is just one data point and I don't mean to imply that you can always get such a performance improvement. I would have liked to include more tests using more real-world usage scenarios (HD source etc) but my stock cooled processor cannot handle those for more than a few seconds, it becomes so hot that my PC shuts down. Comparing AviSynth and VapourSynth it looks like VS has the edge when using one or just a few threads, but the differences almost vanish when using 12 or more threads. The VS is also able to utilize more than 16 cores while with AVS the performance starts to degrade. The point where more threads are just slowing down is probably dependent on the specific script, I will have to run more tests on that. |
17th April 2021, 08:37 | #155 | Link |
Pig on the wing
Join Date: Mar 2002
Location: Finland
Posts: 5,718
|
With the new multithreading support, is it beneficial to increase the population size even with this kind of approach to optimizing the resizer params? A word of warning: VS uses a lot of memory for caching by default so it may be wise to lower the max_cache_size if you launch multiple instances
zopti "test.vpy" -alg mutation -iters dyn -dyniters 18 -dynphases 2 -pop 1 -runs 1 -mutcount 1 -mutamount 0.1 0.01 -initial script
__________________
And if the band you're in starts playing different tunes I'll see you on the dark side of the Moon... |
17th April 2021, 14:13 | #156 | Link | |
Registered User
Join Date: Mar 2018
Posts: 447
|
Quote:
Yes that's one downside of using -threads. It's process level multithreading and every VSPipe process will use as much memory as a single one would. So the amount of free memory might limit how many threads you can actually use even though CPU is still not maxed out. |
|
28th May 2021, 21:48 | #157 | Link |
Registered User
Join Date: Mar 2018
Posts: 447
|
Zopti v1.2.0 released
Time for a new update! This version has some major additions so I bumped the version to 1.2.0.
And here's what -vismode history looks like: The black thick line shows the best found value of the chosen parameter. The red diamonds indicate a point where a new best result has been found and this parameter's value was changed. The white diamonds indicate a new best result but this parameter's value remained the same. In the example optimization was finished and then restarted with different settings at around 190 000 iterations. The -timeout was needed when I started running MVTools2 tests with all the parameters and it turned out that some combinations took an enormous amount of time to finish (typical time was 5 seconds but some combinations took over 30 minutes...). Using a timeout of 60 seconds solved that problem. -continue is useful if you want to keep optimizing a result that is finished, you can try different settings. Also very handy when the optimization has been aborted by hardware failure or something like Windows update... you can just restart it using the same settings. This also makes it possible to run huge iteration counts little by little even if you need/want to use the computer for other things once in a while. Download link updated at first post. |
29th May 2021, 07:57 | #158 | Link |
Pig on the wing
Join Date: Mar 2002
Location: Finland
Posts: 5,718
|
Thank you for the new version It's always nice to see development even though the old product is running well.
One request though: would it be possible to remove the need for keeping the script that was used when running the optimization? I sometimes do many seasons of some TV series sequentially, and reuse the scripts since the properties are usually almost the same between the episodes from various seasons. Zopti doesn't like it when it cannot find the original script as I've already renamed it. I think writing the best result on the first line (to be able to see it right after opening the files in Notepad++ ) of the log file would do just fine.
__________________
And if the band you're in starts playing different tunes I'll see you on the dark side of the Moon... |
29th May 2021, 20:39 | #159 | Link | |||
Registered User
Join Date: Mar 2018
Posts: 447
|
Quote:
Quote:
Quote:
On the other hand if you just run -vismode none then the script should not be needed and the best results could be displayed. I'll have to get back to you on that. |
|||
1st June 2021, 22:49 | #160 | Link |
Registered User
Join Date: Dec 2005
Location: Germany
Posts: 1,795
|
Info: The latest VMAF release added PSNR-HVS and CIEDE2000 metrics.
__________________
AVSRepoGUI // VSRepoGUI - Package Manager for AviSynth // VapourSynth VapourSynth Portable FATPACK || VapourSynth Database |
Thread Tools | Search this Thread |
Display Modes | |
|
|