Log in

View Full Version : Slow performance with WriteFileIf in scene change script


johnmeyer
4th July 2010, 20:45
I have written several scene detection scripts in order to make it easier to cut and edit video captured from my VHS home video made twenty years ago. The scripts that use "Ydifference" work OK, but are easily fooled by someone walking in front of the camera. The scripts using Depan are also fooled. I then tried the "MSCDetection" function in MVTools2 and liked the accuracy much better. Also, using SetMTMode, I was able to get performance that is as good as my other scripts.

I optimized this script to make it run really fast (only processing even fields, for instance). Accuracy is not important, at least not compared to denoising, motion compensation, frame interpolation, etc. So, I did everything I could to speed up MVTools (blksize=16,search=0, etc.). When I tested it with ScriptClip (see the code below), I was able to get 180 fps performance on my computer.

Very nice.

However, when I comment out the ScriptClip statement (which is only used for debugging) and instead use the WriteFileIf to actually create the file with the scene change frame numbers, the script slows down to 90 fps, almost exactly half the speed.

So my question is this: why the performance hit? Both ScriptClip and WriteFileIf are conditionals, and they seem to be performing the same function. I can't imagine my hard drive is an issue, especially since there are often 1,000 frames between scene changes, and then when I do write to the hard drive, it is a trivial few characters of data.

--> Does anyone know why WriteFileIf is so slow, and is there anything I can do about it? <--

Just to be clear, when I remove the comment from the ScriptClip line and insert a comment in front of the WriteFileIf line, the script runs 2x faster.

Thanks.

Postscript: I forgot to mention that I open and run this in VirtualDub. I've played around with the VirtualDub Performance settings, and so far haven't been able to get any change. However, it is possible that this is a VirtualDub and not an AVISynth problem

Here's the code of my scene change script.

#Script to find scene changes
Loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools2.dll")

filename = "e:\scenes.txt"
BlockChangeThresh = 500 # Increase to reduce number of scenes detected
Num_blocks_changed = 130 # Increase to reduce number of scenes detected

setmtmode(5)
source=AVISource("e:\frameserver.avi").killaudio()
setmtmode(2,0)

source_fields = source.separatefields().selecteven().convertTOYV12(interlaced=false)
source_super = source_fields.MSuper(pel=2, sharp=0)

#Use really large blocksize to speed processing. Accuracy isn't important for this function
backward_vec = MAnalyse(source_super, isb = true, delta = 1, blksize=16, search=0)

SceneChange = MSCDetection (source_fields, backward_vec, thSCD1=BlockChangeThresh, thSCD2=Num_blocks_changed)

#Uncomment following line for troubleshooting. It puts the scene change threshold numbers on the screen.
#ScriptClip(source_fields, "Subtitle(String(AverageLuma(SceneChange ) ), align=5)")

#This line writes frame numbers to file. These can be imported into Vegas or other editor
WriteFileIf(source_fields, filename, "(AverageLuma(SceneChange)>30)" , "current_frame+1")

Gavino
4th July 2010, 21:33
--> Does anyone know why WriteFileIf is so slow, and is there anything I can do about it? <--
Setting flush=false will stop it opening and closing the file each time a line is written (default is flush=true).

Also, I'm not sure that either ScriptClip or WriteFile works properly under SetMTMode. Do you see the same results (relatively speaking) without SetMTMode?

johnmeyer
4th July 2010, 22:07
Setting flush=false will stop it opening and closing the file each time a line is written (default is flush=true).

Also, I'm not sure that either ScriptClip or WriteFile works properly under SetMTMode. Do you see the same results (relatively speaking) without SetMTMode?I completely missed the flush parameter. Thank you for telling me about it.

I just tried the script with flush=false, and unfortunately it didn't make any difference (it was still about 1/2 the speed).

I tried removing the SetMTMode statements, and was surprised that the script still ran relatively fast, almost as fast as with the SetMTMode command. I find this strange because I have always seen huge differences in MVTools2 scripts when I add the SetMTMode statements after debugging the script without them.

Without the SetMTMode statements, the fps reported during the "Run Video Analysis" pass in VirtualDub goes up and down quite a bit, from a low of about 80 fps up to about 110 fps. By contrast, with the SetMTMode statements included (i.e., the original script above), the fps is constant during the running of the script.

So, surprisingly (to me), the performance, measured by the time to complete the script, is not much worse without the SetMTMode command.

I did try putting a SetMTMode(5) command just before the WriteFileIf command, but that didn't make any difference.

Gavino
5th July 2010, 00:36
I just tried the script with flush=false, and unfortunately it didn't make any difference (it was still about 1/2 the speed).
I suppose it's not too surprising, if the write is only triggered every 1000 frames or so. It was worth a try.
I tried removing the SetMTMode statements, and was surprised that the script still ran relatively fast, almost as fast as with the SetMTMode command. I find this strange because I have always seen huge differences in MVTools2 scripts when I add the SetMTMode statements after debugging the script without them.
I am very familiar with the conditional environment, but I don't really understand how it interacts with SetMTMode, particularly how the current_frame variable is shared between threads. I've seen conflicting reports about whether it works at all.

When running without SetMTMode altogether, do you still see the same difference between ScriptClip and WriteFileIf?

johnmeyer
5th July 2010, 01:58
When running without SetMTMode altogether, do you still see the same difference between ScriptClip and WriteFileIf?
Interesting question. Here's the answer:
Normal SetMTMode
ScriptClip 62 168
WriteFileIf 62 92

I rounded the numbers a little because VirtualDub does not provide a constant fps. Also, I experimented again with the performance settings in VirtualDub to try to get the fps not only as high as possible, but also consistent. I assume that if the fps varies a lot, it indicates that there is a pipeline getting full somewhere and that may be causing problems.

I also tried to make this work using MT instead of SetMTMode, but I've never gotten MT to work in any of my scripts, and it didn't work here either.

Gavino
5th July 2010, 10:30
Normal SetMTMode
ScriptClip 62 168
WriteFileIf 62 92

So the difference appears to be related to SetMTMode in some way. Curious.

In principle, I would expect the ScriptClip version to be slower, not faster, since it is invoking Subtitle (a filter with a relatively high instantiation cost) on every frame.