Log in

View Full Version : create and destroy a function instance at frame numbers


vcmohan
22nd June 2005, 03:46
I am trying to make a plugin for coloring a black and white video or recoloring a color video. I need to use a particular function with different set of parameters repeatedly a large number of times on a set of frames and also translate windows or change parameters from a range of frames to another range. Thus I find that a number of instances of function are created and remain even if the current frame number is not to be processed.
My plugin functions accept frame numbers to be filtered and so if the frame number is not in range for that particular instance of function, I just return it back in the GetFrame method. Since ApplyRange is a metafilter using it for every function (in my coloring scheme) I think will add not only to the complexity of scripting, but also to timing.

To make long story short my question is can a plugin function indicate to Avisynth in some way that its this instance has finished and can be destroyed.

Bidoche
22nd June 2005, 13:49
Can you explain more ?
I don't really understand what you mean here

mg262
22nd June 2005, 13:59
There's no guarantee that frames will be requested in order from the first to the last, and a given frame can be requested more than once... so I don't think there's a sense in which a given instance is 'finished'.

vcmohan
23rd June 2005, 03:54
Can you explain more ?
I don't really understand what you mean here
In a scene, there are some objects which are stationary over a range of frame numbers(say 0to 20) , some which move inside the frame and some which appear only in an yet different set of frame range (say 5 to 11). Also masks are to be created using different thresholds for different objects. While a very simple still scene with hardly any color variation took about 20 statements, a still with two balloons hopping took 33 statements. (see thread on recoloring at http://forum.doom9.org/showthread.php?t=93990). However an outdoor birthday party still photo (I use a frame of the scene as a still)with 6 to 8 persons, greenery, balloons, cake etc is taking upwards of 60 statements. In the still there is no frame range yet.. As the subjects will move by themselves and camera position also will change I need to have a frame range specifically for each object ( for creation of mask, for tracking it in each frame and for coloring) Thus I visualize a large number of statements calling for same MaskMaker but with different thresholds, an auxiliary modifying function, and a same color fill function but with different seed points and different colors).

Therefore at any time a very large number of instances of a function exist. Only a number of them operate in any frame and rest of its instances inactive ( just work as dummies). If I take an output of a few frames each time, may be I can remove some lines of script, but will make an already tedious scripting effort a little more complicated.
My question is can I destroy a particular instance of a filter by giving an instruction from within the filter function the moment I complete processing the range of frames for which it has been intended as it has become a dummy and is no longer required?

May be not practicable but another wish: can I some how Create_filter only when the start frame in the range appears.

Bidoche
23rd June 2005, 07:47
My question is can I destroy a particular instance of a filter by giving an instruction from within the filter function the moment I complete processing the range of frames for which it has been intended as it has become a dummy and is no longer required?Firstly, you can't.

Secondly, even if you could, how would you know it is no longer required ?
And don't tell me 'last frame was required', avs is non linear, who knows if the clip is not playing backwards...


Anyway why do you even want this in the first place ?

vcmohan
24th June 2005, 03:08
Thanks. I thought so, but was hoping against hope that such a thing might be possible atleast in cases where the processing goes linear . Its only rarely that a reverse motion is used and in a final run of the total script no start stop or skip back or front occurs. Now I will look into my script and functions to optimize to extant possible.

Guest
24th June 2005, 03:46
Instead of scripting, why don't you write this as a native filter, where you have dynamic object creation/destruction?

vcmohan
25th June 2005, 05:40
Instead of scripting, why don't you write this as a native filter, where you have dynamic object creation/destruction?
Well I am not that proficient in C++. But I still think that there can be a problem. Most likely this object creation and destroy has to be done in GetFrame method, as the parameters for the filters depend upon frame numbers. May be I check to see whether the current frame is within already created instances or requires a creation or deletion. I think thats the way to do it. But the filter then need to get all parameters at one go initially. As it is limited to 60 values may be I can get 6 to 10 instances in one script call. Further as each of these instances outputs a frame how can one output multiple frames and ensure that the appropriate output frame is input to the next filter? I think I will end up in multiple problems. But it looks even if the range of frames do not overlap, wherein the script this filter can be placed?

I have one more question. I see a lot of discussion about frame cache. Since it is considerably beyond my understanding I could not go through them. suppose I have a script like :
avisource(..)
a=filter1(.....)
filter2(last,.....)
filter3(last,....)
............
b=filter12(last,a,.....)
........
c=filter20(last,....)
........
filter24(last,b,c,......)

Does Avisynth keep the outputs a, b and c during the entire process of script or reprocesses the sequences to create b an c refered in filter24?
May be related to cache size but how can one find out about the efficiency or problems of the script ?

mg262
25th June 2005, 09:13
For a start, how about putting the params. in a separate text file and use

filter("params.txt")

?

... and read the data into a list of structures (e.g. using stl::list), with each entry corresponding to one range (i.e. one application of your original filter). Then when you're asked for a particular frame n, call MakeWritable and then loop through that list I just mentioned, applying the filter with the appropriate arguments for each entry where n lies in the range in question. So if n lies in the ranges of three of the entries in the list, you will call the relevant function three times on the input frame.

You can always make the filter store information about the last frame that it was asked for (including the number of that frame)... so you can optimise the filter to run quickly in the cases where frames are requested sequentially.

vcmohan
27th June 2005, 03:15
Thanks for the suggestion. I did not fully understand the scheme you suggested. for the following hypothetical script:
avisource(....)
filtera(....)
filterb(....)
myfilter(2,15,.....)
filterc(.....)
filterd(.....)
myfilter(4,8,....)
filtere(...)
filterf(.....)
myfilter(7,21,....)
filterg(.....)
filterf(....)
filtera(....)
myfilter(9,19,....)
.....
The numbers above are frame range. Now how do I know which instance I need to activate when output for frame 9 is called by final filter? There are 9 in the sequence above that fit.

mg262
29th June 2005, 12:23
Sorry -- I had assumed that the calls to your filter were consecutive. Let's step back... I assume that the problem is that each instance of your filter uses up quite a lot of resources so that you're worried about having them all running concurrently. How about having each filter have an active state and a deactivated state -- so when it switches from the active state to the deactivated state it gives the resources back (and vice versa). I'm not sure how clear that is so here's the pseudo-code fragment

//all members/member functions of the filter class
bool active;

void activate()
{
//allocate resources
active = true;
}

void deactivate()
{
//free resources
active = false;
}

... GetFrame(int n, ...)
{
if( n is outside the range affected by this filter)
{
if(active)
deactivate();
return child->GetFrame(n, ...);
}

// n is in the range affected by this filter, so...
if(!active)
activate();
// do the processing and return the result
}(You would still have multiple filter instances as in your example.)

If the frames are requested in order then the activation/deactivation will be fairly infrequent so it shouldn't slow things down? I'm not totally sure I'm following what you're asking for, so please prod if I'm on the wrong track.

vcmohan
30th June 2005, 03:22
Thanks.
Right now I just return the frame if it is out of range. Since I do not use any other resources there are multiple instances just lying about.

Another issue I raised in my earlier post is regarding optimum or efficient scripting.
If I have a script running like below:
avisource("....")
a=filter1()
.....
f=filterf(.....)
.......
n=filter(a,f,....)
...........
x=filterx(n,.....)
y=filter(n....)

filter(x,y,.....)

My question is does avisynth process twice filter n to begining for inputting to x and y to get to z or does it get n from its cache. If it gets from cache its ok, but if it has to reprocess n then it will slow down.

Can there be an instruction to Avisynth to keep a particular output in a cache? Even then I am not sure that it can be taken advantage of .

Bidoche
30th June 2005, 10:38
X -
\
Cache - - N
/
Y -

After it's the job of the Cache to cache efficiently

mg262
30th June 2005, 10:55
Since I do not use any other resources there are multiple instances just lying about.So does the large number of filters (filter instances) actually cause a visible problem? If not, (unless one of the devs says otherwise) I don't see that it is something you need to worry about?

Bidoche
30th June 2005, 16:21
Instances count doesn't matter, as long as it doesn't skyhigh.

Just compare the typical frame size (500K) with the size of your filter (If you don't keep buffers around, a few hundreds of bytes at most) ...

vcmohan
1st July 2005, 04:36
I have a problem. I am trying to color a black and white image where there are lot of subjects with overlapping grey values and edges not always good enough. So I use windowing to operate on each subject. Then I have different instances of mask maker for different parts of subject (hair, face, dress, body, legs shoes etc). So I am ending up with large number of instances. I tried this scheme with an image and found that after certain number of script statements (may be a total of various instances of different functions) I get an access violation message. I am sure that my function does not produce that violation. A statement when placed early in script works well and the same when placed at a very later stage gives access violation.

I also find that just a few statements prior to this access violation the output becomes unstable (erratic). I found that the window being displayed is incorrect in parts. Sometimes the clip itself is not correct. If I in virtualdub go past the range of my work and then reverse one frame at a time it comes out ok. After this even going forwards is ok.

I will analyse my statements for the exact spots where these occur and report back.

Ofcourse I have large number of instances and I found that itself is not creating any trouble. Possibly the number of individual new frames created or makewritable of the input frame is creating problem.

Bidoche
1st July 2005, 09:59
Can't you use a debug build to find more closely where the violiation occurs ?

vcmohan
2nd July 2005, 03:05
Possibly yes. But so far I have not used debug build as the very look of the panels are daunting and I never had a guide to use it. So I do debug in my own way, mostly using the ThrowError facility.

I could locate the access violation last evening and found the problem to be because I forgot Avisynth inserts last if a clip is missing, and in an default parameter computation (which I forgot to update in an earlier revision) which for that particular statement gave an erroneous value.

I also found that even if there were an upwards of 100 instances of an assortment of filters , beyond the frame range it hardly takes a quarter of second to go through 50 frames.

So My last post was made in haste and I regret it. The problem is not with Avisynth, but with my function.