Log in

View Full Version : Runtime Recursion Assistance


mixt
12th April 2013, 05:48
So I captured some game footage in 1080i since that is the highest my capture device supported. As it turns out though movement only happens every full frame and not in every field, so by weaving I can produce a 1080p frame. Awesome. The only issue is then that the game doesn't keep track of keeping it all the same. For example given, 0a 0b 1a 1b and so on; the fields to be weaved might end up like this (0a 0b) 1a (1b 2a) (2b 3a). So I opted for use of the ConditionalFilter like so.
vid = DirectShowSource("D:\recording\Capture\vid.m2ts").AssumeTFF().SeparateFields().DoubleWeave()
vide = vid.SelectEven()
vido = vid.SelectOdd()
ConditionalFilter(vide, vido, vide, "IsCombed()", "equals", "true", show=true)
Which was close, but I got a lot of double true and double false results, so I needed something more in depth than just changing the threshold on IsCombed.
vid = DirectShowSource("D:\recording\Capture\vid.m2ts").AssumeTFF().SeparateFields().DoubleWeave()
global vide = vid.SelectEven()
global vido = vid.SelectOdd()
ConditionalFilter(vide, vido, vide, "CombedLess(vide, vido, 0)", "equals", "true", show=true)

function CombedLess(clip a, clip b, int pass)
{
global c = false #create test variables
global d = false
ScriptClip(a,"c = IsCombed(a,pass)") #is each frame combed?
ScriptClip(b,"d = IsCombed(b,pass)")
rv = ((c&&d)&&(pass<255)) ? CombedLess(a, b, pass+1) : c
return rv # if both are combed and the pass is in bounds, run again with higher threshold,
# else return bool of first clip combing
}
Not pretty and it abuses globals, but I don't mind for personal use. But this just returns false every single time, meaning that it is bottoming out and being caught by the pass limit (further evidenced by the whole thing crashing if I remove that). I'm thinking that means I'm using ScriptClip or IsCombed wrong within my function, probably in feeding it a whole clip instead of a frame, but I don't know how to fix that. Any suggestions?

Gavino
12th April 2013, 10:55
Write your function like this:
function CombedLess(clip a, clip b, int pass)
{
c = IsCombed(a,pass) # is current frame combed?
d = IsCombed(b,pass)
rv = ((c&&d)&&(pass<255)) ? CombedLess(a, b, pass+1) : c
return rv #if both are combed and the pass is in bounds, run again with higher threshold, else return bool of first clip combing
}
You will need to use GRunT, as the standard Avisynth runtime does not allow a runtime function (like IsCombed) to be called directly from a user function.

BTW vide and vido don't need to be global.

scharfis_brain
12th April 2013, 11:05
why don't you just use any of the field matcher filters out there?
examples are:
- decomb/telecide
- tfm/tdeint
- smartdecimate
these will also handle orphaned fields correctly.

mixt
12th April 2013, 23:17
Write your function like this:
function CombedLess(clip a, clip b, int pass)
{
c = IsCombed(a,pass) # is current frame combed?
d = IsCombed(b,pass)
rv = ((c&&d)&&(pass<255)) ? CombedLess(a, b, pass+1) : c
return rv #if both are combed and the pass is in bounds, run again with higher threshold, else return bool of first clip combing
}
You will need to use GRunT, as the standard Avisynth runtime does not allow a runtime function (like IsCombed) to be called directly from a user function.

BTW vide and vido don't need to be global.

I just attempted it like this and when loaded into VirtualDub it displays IsCombed cannot be used outside of the runtime environment. GRunT should have allowed that though though, as you said. Perhaps it is due to the recursion? Since it is then being called from the user function instead of from the ConditionalFilter
When I seek the error changes to say that the function call inside of ConditionalFilter does not recognize vido (and I assume vide) so I'll set those back to global for now, while I toy with it.

why don't you just use any of the field matcher filters out there?
examples are:
- decomb/telecide
- tfm/tdeint
- smartdecimate
these will also handle orphaned fields correctly.

I tried a couple (though I've already forgotten which ones) but they would frequently fail to match and resort to other deinterlacing methods such as Bob. (and for some reason a gradual audio desync was common). I'll try a few of those and see how it goes. I'm pretty new to deinterlacing so I wasn't really sure what to look for and that might have been the real issue in me using filters.

EDIT: SmartDecimate worked well. I might mess with my function more just for the learning of it, but the job's done so I'll take it. Thanks guys.

StainlessS
12th April 2013, 23:41
Not sure if this works correctly but it dont output an error.


vid = Avisource("D:\avs\TEST.avi").AssumeTFF().SeparateFields().DoubleWeave()
vide = vid.SelectEven()
vido = vid.SelectOdd()
#ConditionalFilter(vide, vido, vide, "IsCombed()", "equals", "true", show=true)
ConditionalFilter(vide, vido, vide, "CombedLess(vide, vido, 0,current_frame)", "equals", "true", show=true)

function CombedLess(clip a, clip b, int pass,int n)
{
current_frame=n
c = IsCombed(a,pass) # is current frame combed?
d = IsCombed(b,pass)
rv = ((c&&d)&&(pass<255)) ? CombedLess(a, b, pass+1,n) : c
return rv #if both are combed and the pass is in bounds, run again with higher threshold, else return bool of first clip combing
}

Gavino
13th April 2013, 00:11
I just attempted it like this and when loaded into VirtualDub it displays IsCombed cannot be used outside of the runtime environment. GRunT should have allowed that though though, as you said.
A quirk of GRunT (as yet undocumented) is that the name-overloaded filters will revert back to the standard Avisynth ones if the 'show' parameter is explicitly named. Try calling it like this:
GConditionalFilter(vide, vido, vide, "IsCombed()", "equals", "true", show=true)
or this:
ConditionalFilter(vide, vido, vide, "IsCombed()", "equals", "true", true)

StainlessS's solution should also work (even without GRunT installed) as it fools the run-time check by creating a local 'current_frame'.

mixt
13th April 2013, 00:19
That worked like a charm StainlessS. Odd syntax to me to indirectly set current_frame=current_frame, but I guess for the change in scope it is necessary. Told you it was probably a noob mistake somewhere.

You guys are great. I wrestle with this one for almost a week while registration here finished, and overnight you help me get it all sorted out.

EDIT: And after making sure it was the GConditionalFilter the use of GRunT also worked perfectly.