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")
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")