View Full Version : Do you even need to copy to make an avisynth plugin?
ShinSan
30th September 2007, 04:54
Well, I was wondering about making a few "filters" for avisynth that actually have nothing to do with filtering. Kind-of a "null" filter, but I want to do things like processing other files in preparation for a filter (like generate an image file for use as an overlay). What's nice about avisynth is that it's a scripting language, and it could make things convenient if I want to pass the script to another person.
So far, from what I gathered from the SDK and the sample filter code, I haven't seen any complete sets of code that had anything less than a copy snippet. Is there a way to just bypass that completely?
stickboy
30th September 2007, 08:06
You can look at some of my plug-ins (http://www.avisynth.org/stickboy/), most of which don't do any image processing.
Leak
30th September 2007, 10:35
So far, from what I gathered from the SDK and the sample filter code, I haven't seen any complete sets of code that had anything less than a copy snippet. Is there a way to just bypass that completely?
You could do what you want to do when your plugin's constructor is called, then simply make GetFrame call the parent filter's GetFrame and pass the frame through. That has about as little overhead as possible...
np: Burnt Friedman - Chaos Breeds 1 (First Night Forever)
ShinSan
30th September 2007, 18:34
Yeah, I thought of just passing the source pointer out 10 mins after I made that forum post. Still, stickboy's examples will come in really handy for me.
IanB
30th September 2007, 23:30
The lowest overhead is to just return the input PClip in the creator proceedure (the routine you registered with AddFunction), this way no filter object is added to the graph.
To run code at the end of the script, you register an AtExit proceedure.
ShinSan
1st October 2007, 00:02
To run code at the end of the script, you register an AtExit proceedure.
You read my mind. I was actually wondering about that aspect.
ShinSan
1st October 2007, 04:55
Okay, I've got the basic filter to compile and work, but can someone show me an example on how to write an AtExit function? I tried searching the filter SDK and forum but couldn't find much.
IanB
1st October 2007, 15:36
From Avisynth.h typedef AVSValue (__cdecl *ApplyFunc)(AVSValue args, void* user_data, IScriptEnvironment* env);
virtual void __stdcall AddFunction(const char* name, const char* params, ApplyFunc apply, void* user_data) = 0;
...
typedef void (__cdecl *ShutdownFunc)(void* user_data, IScriptEnvironment* env);
virtual void __stdcall AtExit(ShutdownFunc function, void* user_data) = 0;Like when you register a creator ApplyFunc with env->AddFunction, you similarly register a ShutdownFunc with env->AtExit.
When IScriptEnvironment is deleted on script close the AtExit functions get run. When you register the func you can optionally provide some user data. When the function is finally called this data will be provided as the argument to the proceedure. Be carefull not to pass pointers to Avisynth manage objects, because they most likely will have been deleted before the AtExit functions are called.
// Declare a proceedure
void __cdecl AtExitProc(void* user_data, IScriptEnvironment* env) {
// Do stuff!
...
return;
}
...
env->AtExit(AtExitProc, 0); // Register shutdown proc for 'ron
...
ShinSan
1st October 2007, 17:13
Thanks. Got the function to work correctly but looks like it might not work in my case due to weird Win32API quirks. I have other ways around it though.
Ebobtron
1st October 2007, 17:29
weird Win32API quirks.
There are many, which are giving you fits.
??
ShinSan
3rd October 2007, 05:39
Well, basically I'm trying to rig a "filter" that will load fonts, but loads them so that they are gone on a reboot using AddFontResource. I put RemoveFontResource on the atexitproc, but I think what's happening is that when I close the file using virtualdub, the video is still kinda loaded and in the process of being closed when the filter closes, so I'll probably write a separate program to handle the font removal using something like a text file written to disc containing the font information. Main reason is that the primary Windows font directory can get clogged with font files and affect the OS.
It's designed to be used in conjunction with a filter like vsfilter.
One thing I think I'll do is to simplify the current filter since most of the functionality can probably be done with only those two functions. Right now the function is rigged so that it takes all of the fonts in a directory (except the adobe type1s) and loads them automatically.
ShinSan
3rd October 2007, 06:01
Here's what I have, as an attachment. I put in a bunch of MessageBox codes to help figure out return values. I took out the extra fluff code (the directory processing) to try to tackle the RemoveFontResource/AtExit problem first.
To be honest, having the font removed from the system on reboot (thanks to AddFontResource) is basically all I wanted to accomplish, but of course being able to automatically unload the font without the reboot would be nice icing on the cake.
IanB
25th November 2007, 11:36
/* LoadFont for avisynth
Created by Shin-san of Ishin Digital Anime Fansubbing
Special thanks to stickboy, Leak, and IanB of the doom9.org forums for the help
Special thanks to sh0dan for his simple sample script, which this file is based on
This code, if made public, is protected by the GPLv3, which can be found at
www.gnu.org. I'm too lazy to copy/paste it in here
Purpose: to make it so I can load a font into Windows and automatically unload it
after avisynth is done running
*/
#include <windows.h>
#include "avisynth.h"
void __cdecl UnLoadFont(void* user_data, IScriptEnvironment* env);
AVSValue __cdecl Create_LoadFont(AVSValue args, void* user_data, IScriptEnvironment* env) {
char *file = args[1].AsString("");
// and now load the font
if ( (AddFontResource( file )) > 0 )
{
MessageBox(NULL, "LOADED", file, MB_OK);
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
env->AtExit(UnLoadFont, strdup(file) );
}
else
{
env->ThrowError("LoadFont: Font load '%s' failed.", file);
}
return args[0];
}
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env)
{
env->AddFunction("LoadFont", "c[FONT]s", Create_LoadFont, 0);
return "'LoadFont' LoadFont plugin";
// A freeform name of the plugin.
}
void __cdecl UnLoadFont(void* user_data, IScriptEnvironment* env)
{
char *loadedFont = (char*)user_data;
if (loadedFont && *loadedFont)
{
if ( RemoveFontResource(loadedFont) > 0 )
{
MessageBox(NULL, "UNLOADED", loadedFont, MB_OK);
SendMessage(HWND_BROADCAST, WM_FONTCHANGE, 0, 0);
}
else
{
MessageBox(NULL, "NOT UNLOADED", loadedFont, MB_OK);
}
free(loadedFont);
}
else
{
MessageBox(NULL, "er...", loadedFont, MB_OK);
}
return;
}
Adub
25th November 2007, 11:59
Fansubbing?
IanB
25th November 2007, 13:22
Yes :p
Deleting code to make it even better :D :D :D
@Fizick,
If you nuke all the MessageBox crap it could make another reasonable example for your SDK pages.
Fizick
25th November 2007, 14:09
Done.
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.