Log in

View Full Version : Any way to force AviSynth to ignore the cache?


stickboy
27th June 2004, 21:28
To test some of the frame reordering filters I've written (DeleteFrames, DeleteEvery, InterleaveEvery, RemapFrames, Shuffle, etc.), I've basically been doing things like:
logFile = "output.log"
expectedLogFile = "output.good.log"

BlankClip(pixel_type="yuy2", length=100)
WriteFile(logFile, "current_frame", append=false)
DeleteEvery(9, 2, 3)

ScanClip()
Assert(CompareFiles(logFile, expectedLogFile),
\ "FAILED: unexpected results")ScanClip is a trivial plug-in function that tries to request every frame in the clip:static AVSValue __cdecl ScanClip(AVSValue args, void* /* userDataP */,
IScriptEnvironment* envP)
{
PClip& clip = args[0].AsClip();

const int numFrames = clip->GetVideoInfo().num_frames;
for (int i = 0; i < numFrames; ++i)
{
(void) clip->GetFrame(i, envP);
}
return args[0];
}and CompareFiles, not surprisingly, is another simple plug-in function that compares the contents of two files.

The test script requests all frames from the clip, which in turn causes WriteFile to output the corresponding frame numbers from the original clip. It then checks the output against expected values.

This normally works great for making automated tests that verify correctness. However, if the same frame from the original clip is requested multiple times (e.g. frames are duplicated with FreezeFrame or RemapFrames), the cache causes a problem: WriteFile doesn't receive the GetFrame call again, so it writes the frame number only the first time a particular frame is requested.

To summarize, if I have something such as:
BlankClip(pixel_type="yuy2", length=10)
WriteFile("foo.log", "current_frame", append=false)
FreezeFrame(2, 5, 0)
ScanClip()then the output is going to be:0
1
6
7
8
9but I want:0
1
0
0
0
0
6
7
8
9Does anyone have any ideas how I can work around this?

Thanks.

Bidoche
27th June 2004, 22:49
make your own build of avisynth with a modified Cache class

stickboy
28th June 2004, 00:46
Hmm... well, that works, but I'd rather not swap around different avisynth.dll's.

It did, however, get me on track to an alternative, uglier method: I have a plug-in export function that allows a script to directly set cache hints:static AVSValue __cdecl SetCacheHints(AVSValue args, void* /* userDataP */,
IScriptEnvironment* envP)
{
PClip& clip = args[0].AsClip();
int hintsType = args[1].AsInt();
int radius = args[2].AsInt();
clip->SetCacheHints(hintsType, radius);

// do NOT return the clip; otherwise AviSynth will add a new Cache
// filter automatically
return AVSValue();
}then I can modify my script to:
BlankClip(pixel_type="yuy2", length=10)
WriteFile("foo.log", "current_frame", append=false)
SetCacheHints(0, 0)
FreezeFrame(2, 5, 0)
ScanClip()and I get the results I want.

Ugh.

Bidoche
28th June 2004, 19:08
You won't.
SetCachehints' Cache will get in the way.

stickboy
29th June 2004, 05:19
Hmm? But I've tried it, and it works! :confused:

AviSynth adds a Cache only when a function returns a Clip, right?

kassandro
29th June 2004, 06:55
Though Bidoche is definitely the expert on this subject, you are very likely right here, stickboy. Avisynth simply can't allocate a cache here, because Avisynth has similar functions which return scalars through AVSValue. At least it should be checked. It would be a very trick. Zero cost filters like SelectEven should never get cached. That precious memory should be preserved for better use and with your simple function SetCacheHints one could achieve just this.

Bidoche
30th June 2004, 10:20
Seems I read too fast :p
I was totally in the "it's a filter too so its Cache will...", so I didn't notice the comment about not returning PClip.


Nice trick, actually.
It helps working around a 2.x defect.

stickboy
4th July 2004, 04:24
If anyone is interested in playing around with SetCacheHints, I've posted a plug-in with it:
http://www.avisynth.org/stickboy/TestHarness.zip

The plug-in includes a number of other functions (e.g. ScanClip and CompareFiles), but they're probably not of any interest to most people.

enterprise
9th July 2004, 21:29
Hi,

Your plugin is very interesting! but i don't know how can I use it. I´m trying to use it with CALL plugin from Nic.
I want to play an AVI and to call an external command in a specific frame but i want also that when I play again the file, the command would trigger again.

this is the script I am using:

LoadPlugin("plugins\call_25.dll")
LoadPlugin("plugins\TestHarness.dll")
version()
SetCacheHints(0,0)

Call("c:\beeper.exe)

But when I playvack AVI again CALL command is not executed.

Could you help me?

stickboy
10th July 2004, 05:38
As I mentioned in response to your other post (http://forum.doom9.org/showthread.php?s=&threadid=46506&perpage=20&pagenumber=3#post522103), it doesn't have anything to do with the cache. Call isn't really a filter; it gets run when the script is loaded, not when frames are requested.

FrameEvaluate probably would do what you want.

Edit:
Okay, yeah, I suppose you'll need to call FrameEvaluate and to disable its cache with SetCacheHints.

Edit #2:
Okay, I don't know what I'm talking about. My understanding of Call was totally wrong.

enterprise
10th July 2004, 08:26
Thanks again!

Could you post a small example about how I can use FrameEvaluate with Call command.

Thansk in advance!

stickboy
10th July 2004, 09:10
Sorry, you're right. Call indeed is a regular filter that responds to frame-requests. (I guess I haven't used Call in quite awhile.)

I'm not sure why Call doesn't rerun the program, even with SetCacheHints. Maybe Call maintains its own internal cache; I'll take a glance at the source code.

stickboy
10th July 2004, 09:19
Okay, I looked at Call's source code, and it looks like it does internally check to make sure it runs the specified program only once per frame. (Normally this is good, because otherwise it could be really annoying for most usage cases.)

Anyhow, the FrameEvaluate workaround I suggested earlier does seem to work:Version()
FrameEvaluate("""(current_frame == 50)
? Call("c:\beeper.exe", "-2")
: NOP()""")
SetCacheHints(0, 0)
last

enterprise
10th July 2004, 14:56
Many Many Thanks!

It works perfectly!