Log in

View Full Version : Bob_Comparator - or, "How to crush AVIsynth under the weight of my mighty script"


pbristow
21st June 2011, 15:12
This is not a serious request for anyone to put in diagnostic time on my problem - that would be silly! :) - but I present it for interest, as a case study of "work in progress with obvious problems" if you like, but I would also welcome any suggestions as to where to start diagnosing or working around the problem. (I have my own ideas, e.g. start by splitting the comparison stage from the generation of the test cases as two separate scripts, and proceed from there...)


Background:
-----------
I've been developing this script for over a couple of days now, and it's steadily grown more complex and demanding of CPU... although the memory requirement seems to have stayed reasonably small. Basically, it's a comparison testbed for different de-interlacers.

What the script does:
---------------------
It takes a 24fps progressive file, strips out alternate fields from successive frames, and weaves the result in to a 12fps interlaced clip. This clip is them passed to each of the de-interlacers under test, and the result (or rather a cropped and reduced section of it, to reduce CPU time and screen space requirements) is compared with the original (progressive) source for accuracy. Numerical measurement of difference from the reference is done via ScriptClip and MT_lutxy. The measured difference is averaged first per frame, then over time (121 frames, i.e. just over 5 seconds), and displayed on the output (updated every 11 frames) - This is achieved using TemporalSoften(radius=5) twice, with a SelectEvery(11,6) in between.

Finally, another comparison is done looking at how much change occurs between each frame of the output and the average of the ones before and after: This is checking for interlace flicker in the output and is again time-averaged of 121 frames.

The version of the script I've included here has 3 test active: Those for Bob, Yadif, and EEDI2 (basically, the simplest three cases). All the code is in place for testing various other deinterlacers (including combinations of TDeint with various interpolators), and the tests can be switched in or out simply by modifying the final StackHorizontal call.

The problem:
------------
Unfortunately, as the script has grown more complex, the number of times Virtualdub crashes just trying to open it has steadily increased, 'til it's now reached 100% (having just added the flicker check stage).



Crash details (as reported by VirtualDub):
------------------------------------------
VirtualDub has crashed. (etc.)

An out-of-bounds memory access (access violation) occurred in module 'mt_masktools-26'...
...reading address 11E72004.

(Same address quoted each time)


My Setup:
---------
VirtualDub 1.9.7
AVIsynth 2.5.8 MT
MaskTools v2.0a48
Haali media splitter
FFDShow decoder
Windows XP Pro (32 bit)
AMD Athlon II X3 425 (2.7GHz, three cores)
3GB ram (DDR2).
...and miscellaneous disk drives of various ages and capacities (mostly SATA). :)


(Script to follow in next post.)

pbristow
21st June 2011, 15:14
SetMemoryMax(128)
load_stdcall_plugin("C:\Program Files\AviSynth 2.5\C_plugins\yadif.dll")


DirectShowSource("Testfile.avi")
Crop(8*(width/64),0,-8*(width/64),0)
BilinearResize(8*(width/12),height)
blur(0.0, 0.6)
AssumeTFF
Original = Last


TestClip = SeparateFields.SelectEvery(4,1,2).Weave # 24 fields per second.
ReferenceClip = Original


Function ShowFour(a,b,c,d) {
StackVertical( StackHorizontal(a,b), StackHorizontal(c,d) )
}

Function Zoom2 (clip) {
clip
crop(width/4,height/4,width/2,height/2).PointResize(width,height)
}



#Return Original.subtitle( string( mt_polish(" (x - y) * (x - y)") ) )
function RMSdiff(a,b)
{
Calc = "X Y - X Y - * 64 / round"
global Lift = 20
Squarediff = mt_lutxy(a.ConvertToYV12, b.ConvertToYV12, yexpr=Calc, uexpr=Calc, vexpr=Calc)
#
SquarediffTempAv = Squarediff.BilinearResize(a.width/4,a.height/4).TemporalSoften(5,255,255).SelectEvery(11,6).TemporalSoften(5,255,255).PointResize(a.width,a.height/2).ChangeFPS(a)
ScriptClip( SquareDiffTempAv, """Last.Levels(0,2.0,255,Lift,235,coring=false).subtitle( "25-frame RMSDiff = " + string( 8*Sqrt(Last.AverageLuma), "%15.2f" ), y=50 )""" )
}


function ComparisonStack(clip "a", clip "b", clip "c")
{
# a is the test clip
# b is the reference to compare against (usually the original clip before whatever process you're testing)
# c is the clip to be displayed at the top, un-cropped and unmolested. By default, that's a copy of a,
# but sometimes you want to look at something else, e.g. the pre-filtered clip you used in mvtools, etc.
#

c = Default(c, a).crop(0,16,0,0) # Optional display clip c can be used display the PFC being fed to MVDN.
a2 = a.crop(0,16,0,0)
b2 = b.crop(0,16,0,0)
StackVertical ( c.ConvertToYUY2, \
Compare(a2.ConvertToYUY2,b2.ConvertToYUY2), \
RMSDiff(a2,b2).Subtitle("Error:").ConvertToYUY2, \
RMSDiff(a2,a2.DuplicateFrame(0)).Subtitle("Flicker:").ConvertToYUY2 )
}



SimpleBob = TestClip.Bob()
YadifBob = TestClip.Yadif(mode=1)
EEDI2Bob = TestClip.separatefields().eedi2(field=-2)
EEDI3Bob = TestClip.eedi3(field=-2)
NNEDI2Bob = TestClip.nnedi2(field=-2)
NNEDI3Bob = TestClip.nnedi3(field=-2)
TDBob = TestClip.TDeint(mode=1)
TDEEDI2Bob = TestClip.TDeint(mode=1, edeint=EEDI2Bob)
TDEEDI3Bob = TestClip.TDeint(mode=1, edeint=EEDI3Bob)
TDNNEDI2Bob = TestClip.TDeint(mode=1, edeint=NNEDI2Bob)
TDNNEDI3Bob = TestClip.TDeint(mode=1, edeint=NNEDI3Bob)

#Timing tests (one method at a time):
#Return SimpleBob.Subtitle("Simple Bob()").Trim(3,7202) # 7200 frames = 5 minutes
#Return YadifBob.Subtitle("Simple Bob()").Trim(3,7202)
#Return EEDI2Bob.Subtitle("EEDI2 Bob()").Trim(3,7202)


RC2 = ReferenceClip.Zoom2.ConvertToYUY2
SB2 = SimpleBob.Zoom2.ConvertToYUY2
YB2 = YadifBob.Zoom2.ConvertToYUY2
EEDI22 = EEDI2Bob.Zoom2.ConvertToYUY2
EEDI32 = EEDI3Bob.Zoom2.ConvertToYUY2
NNEDI22 = NNEDI2Bob.Zoom2.ConvertToYUY2
NNEDI32 = NNEDI3Bob.Zoom2.ConvertToYUY2
TD2 = TDBob.Zoom2.ConvertToYUY2
TDEEDI22 = TDEEDI2Bob.Zoom2.ConvertToYUY2
TDEEDI32 = TDEEDI3Bob.Zoom2.ConvertToYUY2
TDNNEDI22 = TDNNEDI2Bob.Zoom2.ConvertToYUY2
TDNNEDI32 = TDNNEDI3Bob.Zoom2.ConvertToYUY2
#Return ShowFour(YB2, RC2, Diff(YB2,RC2), Compare(YB2,RC2))

#Tsoft = SimpleBob.TemporalSoften(1,255,255,15,1)
#Blurred = SimpleBob.Blur(1.0)
#Mixed = Blurred.Merge(TSoft)
#SBMDG1_Ts = SimpleBob.MVDN(order=1,PFC=Tsoft).Zoom2.ConvertToYUY2
#SBMDG1_Mx = SimpleBob.MVDN(order=1,PFC=Mixed).Zoom2.ConvertToYUY2


#Timing tests (one method at a time):
#Return ComparisonStack(SB2,RC2).Subtitle("Simple Bob()").Trim(3,3002)

Return StackHorizontal( ComparisonStack(SB2,RC2).Subtitle("Simple Bob()") \
, ComparisonStack(YB2,RC2).Subtitle("YADIF Bob") \
, ComparisonStack(EEDI22,RC2).Subtitle("EEDI2 Bob)") \
).Trim(3,3002)


# , ComparisonStack(EEDI32,RC2).Subtitle("EEDI3 Bob)") \
# , ComparisonStack(NNEDI22,RC2).Subtitle("NNEDI3 Bob)") \
# , ComparisonStack(NNEDI32,RC2).Subtitle("NNEDI3 Bob)") \
#

# , ComparisonStack(TD2,RC2).Subtitle("TDeint Bob") \
# , ComparisonStack(TDEEDI22,RC2).Subtitle("TDeint(interp=EEDI2)") \
# , ComparisonStack(TDEEDI32,RC2).Subtitle("TDeint(interp=EEDI3)") \
# , ComparisonStack(TDNNEDI22,RC2).Subtitle("TDeint(interp=NNEDI2)") \
# , ComparisonStack(TDNNEDI32,RC2).Subtitle("TDeint(interp=NNEDI3)") \
#

pbristow
21st June 2011, 15:24
...And already I see one possible cause of trouble: Wrong version of MaskTools for my version of AviSynth! Better fix that as soon as I've made the tea...

um3k
21st June 2011, 19:04
Haha, yeah, I was about to point that one out for ya.

pbristow
21st June 2011, 20:58
Yep, changing that cured it. Got a complete run with results saved to disk, which took over 2 hours... during which time I was already refining the next version! :)
And realising that Blur(1.58,-1.0) makes a surprisingly "cheap" but effective detector for horizontal single-line features.

Didée
21st June 2011, 21:07
And realising that Blur(1.58,-1.0) makes a surprisingly "cheap" but effective detector for horizontal single-line features.
Heheh! You're about to enter the deeper circles of magic! :D

If I'm not mistaken, that one was the essential part of a blind-best-match fieldmatcher that Mug Funky scripted several years ago.