View Full Version : Help with writing Avisynth Plugins
blaze077
30th October 2016, 03:29
I am just starting to get into writing Avisynth plugins but got stuck right at the beginning in this guide (http://avisynth.nl/index.php/Avisynth_Plugin_Development_in_C).
Under the "Compiling Your First Plugin" section, it says:
Copy (C:\Program Files\ or other installation directory then:) AviSynth 2.5\Extras\avisynth.lib to demosaic\lib
However, there doesn't seem to be any such file anywhere in my Avisynth+ installation folder.
I am using Avisynth+ r2173.
qyot27
30th October 2016, 04:24
If you didn't choose to install the SDK when you installed AviSynth+, then those files won't be there.
And because it's gnawing at my brain like a parasite, the section of that guide that talks about licensing is false. The 2.6 (and Plus) C API does not and never has required plugins written with them be released under the GPL. You can use whatever license you like for the plugin, the exception is there in avisynth_c.h and was not removed at any point between 2.5 and 2.6 (unlike the C++ header, but even it had the exception restored when 2.6 Final was released).
blaze077
30th October 2016, 05:19
Will keep the licensing thing in mind.
As for the SDK, I just redid the installation with the FilterSDK option enabled and I still do not have an avisynth.lib file anywhere in the installation folder. I have the avisynth_c.h like before.
qyot27
30th October 2016, 06:14
Looks like Groucho2004 didn't include the dev files in the install package for that build.
To be fair, if you're looking at building the plugins, you might want to start by building AviSynth+ itself to get a feel for it*. And if you do that, the .lib files will get built.
A guide is in the AviSynth+ source:
https://github.com/AviSynth/AviSynthPlus/blob/MT/distrib/docs/english/source/avisynthdoc/contributing/compiling_avsplus.rst
The only thing that requires mentioning is that after cloning it, you'll want to checkout the MT branch to get the correct updates. Or you can do the checkout at the same time as the clone:
git clone -b MT git://github.com/AviSynth/AviSynthPlus.git
blaze077
30th October 2016, 06:17
Thank you. I will try that out tomorrow.
Groucho2004
30th October 2016, 10:42
Looks like Groucho2004 didn't include the dev files in the install package for that build.
What dev files? The AVS+ installer script only includes help files if "Filter SDK" is selected.
Edit: The "official" 2.6 Avisynth installer does offer the option to install the C-header and avisynth.lib.
qyot27
30th October 2016, 17:24
Actually yeah, now that I think of it, I don't think I'd ever tried installing the AviSynth+ SDK files from the InnoSetup-based installer. I must have been confusing it with the old installer.
Part of why it's not in the new installer is probably the stance that 'AviSynth+ should be supported in your program by using dynamic loading', and that doesn't need the *.lib files. For plugins that gets kind of hairy, though - not saying it can't be done, just that it's somewhat arcane (the FFMS2 C-plugin does it, but I haven't gotten it updated to use AviSynth+'s headers yet).
blaze077
31st October 2016, 22:58
I somehow managed to reach the Building Avisynth (https://github.com/AviSynth/AviSynthPlus/blob/MT/distrib/docs/english/source/avisynthdoc/contributing/compiling_avsplus.rst#building-avisynth) section of the guide through trial and error and whatever little knowledge I had. However, when I used the following command:
git clone git://github.com/AviSynth/AviSynthPlus.git && cd AviSynthPlus
it gave this message:
-bash: git: command not found
qyot27
1st November 2016, 01:31
With msys2 open:
pacman -S msys/git
blaze077
1st November 2016, 22:01
Thank you. That worked. Now I get the same error with cmake even though I have installed cmake and it has automatically been added to the Windows PATH directory:
-bash: cmake: command not found
qyot27
2nd November 2016, 01:18
I'm pretty sure the CMake installer's 'add to PATH' option puts the parent directory in the PATH, not the one we need. It needs to be C:\Program Files\CMake\bin (or C:\Program Files (x86)\CMake\bin if you're on 64-bit Windows) that's added to the PATH.
To check, run
echo %PATH%
from the regular Windows Command Prompt, or
echo $PATH
from inside msys2. Try to find either C:\Program Files\CMake\bin (Command Prompt) or /c/Program Files/CMake/bin (msys2) in the list of directories that show up. If it's *not* in there, then you'll have to either fix or add that directory to the PATH entry manually.
blaze077
2nd November 2016, 22:39
The directory "C:\Program Files (x86)\CMake\bin" is there in the Windows PATH. The echo %PATH% command in Windows Command Prompt returns all the directories in PATH whereas the msys echo $PATH gives me this:
/usr/local/bin:/usr/bin:/bin:/opt/bin:/c/Windows/System32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
qyot27
3rd November 2016, 00:15
Okay, I see what happened: https://github.com/msys2/msys2.github.io/issues/20
You need to make sure that msys2_shell.cmd has MSYS_TYPE_PATH set to 'inherit' (open it in Wordpad to check so that the Unix-style line feeds are interpreted correctly). But if I'm reading some of those cases right, when opening msys from the Visual Studio Command Prompt, it should be able to recognize that and inherit the %PATH% without the need to edit things.
blaze077
6th November 2016, 18:54
Sorry for the late reply. The MSYS_TYPE_PATH was set to 'inherit' already so in the end, I just added the cmake directory manually through the export PATH command. Now I'm stuck on the last part:
cp Output/AviSynth.dll Output/system/DevIL.dll Output/plugins/DirectShowSource.dll \
Output/plugins/ImageSeq.dll Output/plugins/Shibatch.dll Output/plugins/TimeStretch.dll \
Output/plugins/VDubFilter.dll ../$AVSDIRNAME/64bit
This gives me the error:
cp: target '..//64bit/dev' is not a directory
qyot27
6th November 2016, 19:15
You didn't set the AVSDIRNAME variable, or closed/reopened the terminal after you'd set it, or tried setting it when you were in the wrong directory. After cloning the git repo, cd into AviSynthPlus, set the AVSDIRNAME variable, back out of the AviSynthPlus directory, create the build and packaging directories, cd into the build directory, and then run the cmake configure and build commands. And after all that's finished, without closing the terminal at any point, then run the cp instructions to copy the .dlls into the packaging directory.
If the stuff actually built, you can find them in the Output/ directory and manually copy them around as you see fit.
FranceBB
6th November 2016, 19:54
Slightly off topic but still about "writing an avisynth plugin". I can generally use the avisynth scripting language in an .avs file or use C/C++, link the avisynth header and make a .dll. My question is: is there a way to handle certain tasks in C++, link the avisynth header AND use the avisynth scripting language for some other task INSIDE a C++ project?
StainlessS
6th November 2016, 20:04
Francebb, no chance.
Edit: you can use invoke() to call built in filters though, with args that would be familiar.
You can also call external plugs but have to handle errors if not installed.
Mobile
http://avisynth.nl/index.php/Filter_SDK/Env_Invoke
EDIT: Now seeing comments below, changing my reply from "No chance" to "Yes, Every Chance". :)
TheFluff
6th November 2016, 21:32
I'm pretty sure it's possible. You'll have to generate a script and write it to disk since you can't interact with the script interpreter directly, but once you've done that you can be your own host application and feed input/read output as you wish.
The question is why you want to do this, though. Any logic done in Avisynth script is usually easier done in almost any other language, and if you just want to build filter chains all you need to do is interact with the script environment directly by calling env->invoke() as StainlessS points out. The Avisynth video provider in Aegisub (https://github.com/Aegisub/Aegisub/blob/master/src/video_provider_avs.cpp#L214) is one example of how to create a "script" (read: filter chain) from a C++ application and use it to read video frames.
Gavino
6th November 2016, 23:50
You'll have to generate a script and write it to disk since you can't interact with the script interpreter directly
Yes you can, simply by using env->Invoke() to call the Eval() function on some script language text.
TheFluff
7th November 2016, 00:42
Oh right, well there you go then.
FranceBB
7th November 2016, 06:31
Got it! Thanks. :D
why you want to do this?
Luckily enough, if I'll have some free time, you'll find out in the avisynth usage section soon. Btw I'm very busy at work this very moment and every time I get back home I'm too tired to do pretty much anything other than replying to forums and scrolling Facebook...
StainlessS
7th November 2016, 15:49
I added below to my previous post
Now seeing comments below, changing my reply from "No chance" to "Yes, Every Chance".
Of course you can use Eval, what was I thinking.
I'de often thought that being able to call some kind of closedown script function would be useful, use of Eval completely escaped me.
http://avisynth.nl/index.php/Filter_SDK/Cplusplus_API#Invoke
http://avisynth.nl/index.php/Filter_SDK/Cplusplus_API#AtExit
However, anybody know if env->SaveString() of the string mem would be necessary, I think it probably would.
http://avisynth.nl/index.php/Filter_SDK/Cplusplus_API#SaveString
blaze077
7th November 2016, 17:15
I have the avisynth.lib file now. Thank you, qyot. :)
StainlessS
7th November 2016, 18:02
I'de often thought that being able to call some kind of closedown script function would be useful
Tried this, did not work, Looks like IScriptEnvironment is already closed, and fails with Access Violation.
#include <windows.h>
#include <stdio.h>
#include "Avisynth.h"
int __cdecl dprintf(char* fmt, ...) {
char printString[2048]="CallScriptFunctionAtCloseDown: ";
char *p=printString;
for(;*p++;);
--p; // @ null term
va_list argp;
va_start(argp, fmt);
vsprintf(p, fmt, argp);
va_end(argp);
for(;*p++;);
--p; // @ null term
if(printString == p || p[-1] != '\n') {
p[0]='\n'; // append n/l if not there already
p[1]='\0';
}
OutputDebugString(printString);
return p-printString; // strlen printString
}
void __cdecl myClosedown(void* user_data, IScriptEnvironment* env) {
const char *s =(char *)user_data;
if(s!=NULL && *s!='\0') {
AVSValue args[1]={s};
dprintf("AtExit::myClosedown(user_data) where user_data=\n'%s'",s);
dprintf("AtExit::myClosedown() Calling AtCloseDown()");
try {
env->Invoke("Eval", AVSValue(args,1)); // No return value
dprintf("Call to AtCloseDown SUCCEEDS");
} catch (IScriptEnvironment::NotFound) {
dprintf("Call to AtCloseDown FAILS");
}
} else {
dprintf("Error, user_data was %s",(s==NULL)?"NULL":"Empty String");
}
dprintf("AtExit::myClosedown() Exiting back to Avisynth");
}
static const char MyEvalString[]="AtCloseDown()";
AVSValue __cdecl Create_CallScriptFunctionAtCloseDown(AVSValue args, void*, IScriptEnvironment* env) {
dprintf("Create_CallScriptFunctionAtCloseDown: registering AtExit()");
// We are using fixed address string literal, dont need SaveString()
//myClosedown((void*)MyEvalString, env); // Test if myClosedown() works ok
env->AtExit(myClosedown, (void*)MyEvalString);
dprintf("Create_CallScriptFunctionAtCloseDown: registered OK, Returning to Avisynth");
return 0; // Implicit conversion to AVSValue
}
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
dprintf("AvisynthPluginInit2 Calling AddFunction()");
env->AddFunction("CallScriptFunctionAtCloseDown", "",Create_CallScriptFunctionAtCloseDown, 0);
dprintf("AvisynthPluginInit2 Returning to AviSynth");
return "'CallScriptFunctionAtCloseDown'";
}
where test.avs
Function AtCloseDown() {RT_DebugF("Inside the sctript function",name="AtCloseDown: ")}
CallScriptFunctionAtCloseDown()
Avisource("F:\v\StarWars.avi")
trim(10000,-1)
Produces this
# avisynth checks what plugins are available in Plugins dir
00000001 0.00000000 CallScriptFunctionAtCloseDown: AvisynthPluginInit2 Calling AddFunction()
00000002 0.00009849 CallScriptFunctionAtCloseDown: AvisynthPluginInit2 Returning to AviSynth
# some stuff from other plugins
00000003 0.14727053 RemoveDirt 0.9
00000004 0.36011204 SSETools 0.1
# Load plug for real
00000005 0.67881382 CallScriptFunctionAtCloseDown: AvisynthPluginInit2 Calling AddFunction()
00000006 0.67884332 CallScriptFunctionAtCloseDown: AvisynthPluginInit2 Returning to AviSynth
00000007 0.67888665 CallScriptFunctionAtCloseDown: Create_CallScriptFunctionAtCloseDown: registering AtExit()
00000008 0.67891932 CallScriptFunctionAtCloseDown: Create_CallScriptFunctionAtCloseDown: registered OK, Returning to Avisynth
# AtExit
00000009 2.25108886 CallScriptFunctionAtCloseDown: AtExit::myClosedown(user_data) where user_data=
00000010 2.25108886 'AtCloseDown()'
00000011 2.25113463 CallScriptFunctionAtCloseDown: AtExit::myClosedown() Calling AtCloseDown()
EDIT: Added line to show Eval string, in Blue
I guess you could probably do some closedown func in destructor of dummy pass-through filter at end of filter chain.
StainlessS
7th November 2016, 19:55
I guess you could probably do some closedown func in destructor of dummy pass-through filter at end of filter chain.
Nope, tried this.
#include <windows.h>
#include <stdio.h>
#include "Avisynth.h"
int __cdecl dprintf(char* fmt, ...) {
char printString[2048]="CallScriptFunctionOnDestruction: ";
char *p=printString;
for(;*p++;);
--p; // @ null term
va_list argp;
va_start(argp, fmt);
vsprintf(p, fmt, argp);
va_end(argp);
for(;*p++;);
--p; // @ null term
if(printString == p || p[-1] != '\n') {
p[0]='\n'; // append n/l if not there already
p[1]='\0';
}
OutputDebugString(printString);
return p-printString; // strlen printString
}
class CallScriptFunctionOnDestruction : public GenericVideoFilter {
private:
char * evalString;
IScriptEnvironment* env;
//
public:
CallScriptFunctionOnDestruction(PClip _child,char * _evalString,IScriptEnvironment* _env) :
GenericVideoFilter(_child),evalString(_evalString),env(_env) {
dprintf("Constructor tests EvalString");
AVSValue args[1]={evalString};
dprintf(" Evaluating '%s'",evalString);
try {
env->Invoke("Eval", AVSValue(args,1)); // No return value
dprintf(" Constructor Eval SUCCEEDS");
} catch (IScriptEnvironment::NotFound) {
dprintf(" Constructor Eval FAILS");
}
}
~CallScriptFunctionOnDestruction() {
if(evalString!=NULL) {
AVSValue args[1]={evalString};
dprintf("Evaluating '%s'",evalString);
try {
env->Invoke("Eval", AVSValue(args,1)); // No return value
dprintf("Eval SUCCEEDS");
} catch (IScriptEnvironment::NotFound) {
dprintf("Eval FAILS");
}
delete [] evalString;
evalString=NULL;
} else {
dprintf("evalString is NULL");
}
}
};
AVSValue __cdecl Create_CallScriptFunctionOnDestruction(AVSValue args, void*, IScriptEnvironment* env) {
dprintf("Create Enter");
PClip child=args[0].AsClip();
const char *s=args[1].AsString();
if(s=="") env->ThrowError("CallScriptFunctionOnDestruction: Need non empty Eval String");
int len=strlen(s);
char * evalString = new char[len+1];
strcpy(evalString,s);
dprintf("EvalString='%s'",evalString);
dprintf("Create Calling Constructor");
AVSValue ret = new CallScriptFunctionOnDestruction(child,evalString,env);
dprintf("Create Exit");
return ret;
}
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
dprintf("AvisynthPluginInit2 Enter");
env->AddFunction("CallScriptFunctionOnDestruction", "cs",Create_CallScriptFunctionOnDestruction, 0);
dprintf("AvisynthPluginInit2 Exit");
return "'CallScriptFunctionOnDestruction'";
}
Script
Function AtCloseDown(String "str") {
Str=Default(Str,"Hello")
RT_DebugF("Inside the script function Str='%s'",Str,name="AtCloseDown: ")
}
Avisource("F:\v\StarWars.avi")
Last=Last.CallScriptFunctionOnDestruction("""AtCloseDown("GoodBye")""")
trim(10000,-1)
Result
# Avisynth testing what plugs are available
00000001 0.00000000 CallScriptFunctionOnDestruction: AvisynthPluginInit2 Enter
00000002 0.00006399 CallScriptFunctionOnDestruction: AvisynthPluginInit2 Exit
# other plug stuff
00000003 0.14096585 RemoveDirt 0.9
00000004 0.32927427 SSETools 0.1
#load plug for real
00000005 0.72400969 CallScriptFunctionOnDestruction: AvisynthPluginInit2 Enter
00000006 0.72403854 CallScriptFunctionOnDestruction: AvisynthPluginInit2 Exit
00000007 0.72408146 CallScriptFunctionOnDestruction: Create Enter
00000008 0.72411495 CallScriptFunctionOnDestruction: EvalString='AtCloseDown("GoodBye")'
00000009 0.72414577 CallScriptFunctionOnDestruction: Create Calling Constructor
# constructor, testing if eval should work OK
00000010 0.72417861 CallScriptFunctionOnDestruction: Constructor tests EvalString
00000011 0.72420967 CallScriptFunctionOnDestruction: Evaluating 'AtCloseDown("GoodBye")'
00000012 0.72776389 AtCloseDown: Inside the script function Str='GoodBye'
00000013 0.72779864 CallScriptFunctionOnDestruction: Constructor Eval SUCCEEDS
00000014 0.72783029 CallScriptFunctionOnDestruction: Create Exit
# At Filter Destruction
00000015 28.66262436 CallScriptFunctionOnDestruction: Evaluating 'AtCloseDown("GoodBye")'
# Abnormal program termination, message.
Fails if CallScriptFunctionOnDestruction() dummy filter immediately after AviSource, or at end of chain, so looks like not really possible except maybe on last frame of last filter which is just a little bit too soon (as not yet completed).
EDIT: Maybe env has been trashed before destructor called (had to save copy for the destructor).
Gavino
8th November 2016, 00:11
However, anybody know if env->SaveString() of the string mem would be necessary, I think it probably would
SaveString() should not be necessary for the string passed into Eval().
The parser (which is called by Eval()) will itself call SaveString() for all relevant text fragments within the string (ie identifiers and string literals) that need to outlive the Eval() invocation.
Tried this [AtExit], did not work, Looks like IScriptEnvironment is already closed, and fails with Access Violation.
When the AtExit callback is executed, most of env has already been destroyed - the only thing remaining is the string table holding strings saved by SaveString(). Thus it is really only useful to do tidy-up of objects directly under the control of your own plugin.
Maybe env has been trashed before destructor called
Whether env still exists when a filter's destructor is called may depend on how Avisynth has been invoked. My reading of the VfW interface code (main.cpp) suggests that if Avisynth is invoked via VfW, env should still exist at that point (because the filter graph is destroyed before the script environment).
StainlessS
8th November 2016, 00:45
Most informative, many thanks big G.
EDIT: So are there any possibilities of any kind of Shutdown script function being called ?
[I'm guess'in NO, in the main it is not a problem, CallCmd() can eg delete files if required, which is really what I was thinking of].
Gavino
8th November 2016, 13:58
When the AtExit callback is executed, most of env has already been destroyed - the only thing remaining is the string table holding strings saved by SaveString().
Actually, I see that the AtExit handling was changed in v2.6 and now occurs slightly earlier than before. However, much of the environment has still been destroyed at that point (including the data about variables), making Eval() likely to fail.
So are there any possibilities of any kind of Shutdown script function being called ?
Can't think of anything reliable.
In your filter destructor experiment, how were you using Avisynth?
Did you try invoking it via VfW (eg through VDub, or even WMP)?
By my reckoning, it should have worked that way, although it's a bit of a hack (saving the env pointer inside a plugin is not recommended, I think IanB once said).
StainlessS
8th November 2016, 16:31
I had tried with VirtualDubMod and VirtualDubFilterMod and MPC-HC [EDIT: no, was actually MPlayer2.exe] , all failed.
(saving the env pointer inside a plugin is not recommended, I think IanB once said).
Yep, but only way it could be done as destructor is not provided with env.
CallCmd() will suffice I think.
Thanks G.
Gavino
8th November 2016, 18:48
Can't think of anything reliable.
I've just thought of one way of doing this - call CreateScriptEnvironment() to create a new environment of your own, in which you can do whatever you like. Of course, it will start off empty (apart from auto-loaded plugins), so you won't have access to anything created in the original environment.
In fact, you could create this "parallel" environment in your constructor and have it available throughout the lifetime of your filter! However, I can't think of anything you could usefully do with it that you couldn't do directly in C++.
blaze077
19th November 2016, 02:36
Is there a guide on compiling a plugin with Microsoft Visual Studio? I can't seem to configure a compiler for CodeBlocks. and hence moved to Visual Studio Professional 2013.
Also, is CodeBlocks considered deprecated? Because on the Avisynth+ Wiki, most of the plugins seemed to be compiled with "Microsoft Visual Studio C++ 20xx." Sorry if I am talking nonsense as I do not understand what a compiler truly is.
StainlessS
20th November 2016, 02:46
Perhaps take a peek here (I have not read much there so may not be that useful), was set up by JMac698, intent to create plugs via C interface
using Codeblocks, rather than CPP interface. http://avisynth.nl/index.php/Avisynth_Plugin_Development_in_C
Above is linked from the Sticky at top of Avisynth Development forum:- Humbly requested: Filter SDK / Easy filter sample
Also might find stuff of use in reading the other Sticky:- Compiling AviSynth.
Might also glean something of use from DavidHorman Sticky in VirtualDub forum ( [VirtualDub] Compiling VirtualDub with VC++ Express - how I did it):-
http://forum.doom9.org/showthread.php?t=152778
EDIT: People that use CodeBlocks are usually writing C plugins, CPP interface is a bit easier to master, IMHO.
EDIT: Dont know if I've already posted this in this thread, but if you do 'speak' C and not so much CPP, then this might also
be of use (Avisynth CPP Interface for C Programmers):-
http://forum.doom9.org/showthread.php?t=163082
blaze077
20th November 2016, 03:29
Thank you, I'll take a look at those links. I was following the CodeBlocks guide but encountered a problem in my installation. I asked a friend so he'll fix it for me tomorrow so I can continue on with CodeBlocks. I have no knowledge of programming besides Java and Avisynth(?) so I do not have much knowledge of C/CPP besides the tutorials I'm reading on.
StainlessS
20th November 2016, 03:53
Well if you know Java, then probably not so stiff a task (so far as I remember after reading half a very thin intro to Java some years back), not so very different to CPP.
I wish you the best of luck in your endeavor, there will be much to learn (but you are already half way there) and great satisfaction when achieved.
FranceBB
20th November 2016, 15:40
Is there a guide on compiling a plugin with Microsoft Visual Studio? I can't seem to configure a compiler for CodeBlocks. and hence moved to Visual Studio Professional 2013.
If you have visual studio installed, the Microsoft compiler will be automatically added to CodeBlock. Anyway, download MinGW and install it (it will ask you which components to install; choose GCC compiler). Once you have done that, you will be able to use GCC in CodeBlock as compiler. Of course, you are free to install old compilers like the Borderlands one as well, but GCC will probably work for the 90% of the things you have to compile. ;)
Groucho2004
20th November 2016, 17:25
GCC will probably work for the 90% of the things you have to compile. ;)
He specifically asked about compiling Avisynth plugins (most of which are CPP type). I pointed this out to you before, GCC cannot compile Avisynth CPP plugins.
qyot27
21st November 2016, 00:01
He specifically asked about compiling Avisynth plugins (most of which are CPP type). I pointed this out to you before, GCC cannot compile Avisynth CPP plugins.
The guide mentioned by/in the OP was for developing C plugins. Granted, I think there's a few more important subjects (like the actual way that a compilation process is supposed to be structured to get a proper result, whether that's a Makefile or however a Visual Studio Project gets set up to handle this) that the OP may want to look at and get familiar with before attempting to write a plugin.
The GCC situation is slightly more complicated/convoluted now, since the AviSynth+ core can be built with GCC now*, and ostensibly that could mean C++ plugins updated with any needed g++ compliance might work with that kind of special build...but it places restrictions on the build environment that cause GCC-built programs to not work with MSVC-built AviSynth+, and probably vice-versa.
*and it works as far as Version() (and maybe AviSource, since that's built with the core; I didn't test that) goes, but getting deeper into the [external or not] C++ plugins would definitely make the inverse of this issue come back and bite the user: a GCC-built AviSynth+ will not be able to load MSVC-built plugins.
parbruek
1st January 2019, 16:55
So is there actually any tutorial for making a filter for Avisynth in C, rather than in C++?
Because I followed the guide (http://avisynth.nl/index.php/Avisynth_Plugin_Development_in_C) and (not surprisingly) it didn't work. Even the file for demosaic is a .cpp, in which case codeblocks shouldn't be used to compile it for avisynth. I mean - the dll compiled fine, but unsurprisingly I got the error:
...AviSynth+/plugins/demosaic.dll' cannot be used as a plugin for Avisynth.
Or does anyone have examples of compilable C filters which could be used as examples in lieu of demosaic?
Wilbert
2nd January 2019, 21:50
So is there actually any tutorial for making a filter for Avisynth in C, rather than in C++?
Because I followed the guide (http://avisynth.nl/index.php/Avisynth_Plugin_Development_in_C) and (not surprisingly) it didn't work. Even the file for demosaic is a .cpp, in which case codeblocks shouldn't be used to compile it for avisynth. I mean - the dll compiled fine, but unsurprisingly I got the error:
Or does anyone have examples of compilable C filters which could be used as examples in lieu of demosaic?
Some examples can be found here: http://avisynth.nl/index.php/Filter_SDK (Yes i still need to fix the memory leaks ...). See e.g.
http://avisynth.nl/index.php/Filter_SDK/CMerge
http://avisynth.nl/index.php/Filter_SDK/CInvertNeg
http://avisynth.nl/index.php/Filter_SDK/C_API
and compiling AviSynth plugins that use the C api using MS VC++ 2010:
http://avisynth.nl/index.php/Filter_SDK/Compiling_instructions#Compiling_AviSynth_plugins_or_console_applications_step_by_step_instructions_.28for_MS_VC.2B.2B_2010_Express_and_Professional_Edition.29
TheFluff
7th January 2019, 16:52
So is there actually any tutorial for making a filter for Avisynth in C, rather than in C++?
Because I followed the guide (http://avisynth.nl/index.php/Avisynth_Plugin_Development_in_C) and (not surprisingly) it didn't work. Even the file for demosaic is a .cpp, in which case codeblocks shouldn't be used to compile it for avisynth. I mean - the dll compiled fine, but unsurprisingly I got the error:
Or does anyone have examples of compilable C filters which could be used as examples in lieu of demosaic?
If you are on Windows, there is absolutely no reason to use anything other than Visual Studio in the year 2019, regardless of whether you're developing in C or in C++. It's by far the best IDE out there, the free version does everything you need, and it compiles C99 just fine these days. Don't muck around with mingw and gcc unless you know exactly what you're doing and why.
StainlessS
8th January 2019, 06:35
Here a CPP conversion of the tutorial C Demosaic() filter, re-named DemosaicCPP() and assigned v1.00.
Includes v2.58, avs/+ v2.60 x86 and x64 dll's + source + original C source + full VS2008 Project files.
Requires VS 2008 CPP runtimes.
EDIT: Below link will be permanently available.
http://www.mediafire.com/file/3d5c0ir7e3ig3uw/DemosaicCPP_25%2626_x86_x64_dll_v1.00_20190108.zip
#LoadPlugin(".\DemosaicCPP_25.dll") # Standard v2.58 CPP plugin, can go in Plugins dir
#LoadPlugin(".\DemosaicCPP_x86.dll") # Standard Avs/+ v2.60 CPP plugin, can go in Plugins dir
#LoadPlugin(".\DemosaicCPP_x64.dll") # Avs+ x64 CPP plugin, can go in Plugins dir
ImageSource(".\image.jpg")
ConvertToYUY2()
#ConvertToYV12()
# Avs/+ v2.60
#ConvertToY8()
#ConvertToYV16()
#ConvertToYV24()
#ConvertToYV411()
/*
Plugin parameters:
------------------
DemosaicCPP(clip c,String "Mosaic"="Bayer",String "Method"="bilinear",Int "xoffset"=0,Int "yoffset"=0)
clip clip: input clip, can be YUY2, or 8 bit Planar
string mosaic (default: "Bayer"): the color filter array arrangement. Currently only "Bayer" is supported.
string method (default: "bilinear"): interpolation method: "bilinear" or "nearest"
int xoffset (default: 0): color filter array x offset value.
int yoffset (default: 0): color filter array y offset value.
Output: RGB32 color image
*/
#DemosaicCPP(xoffset = 1, yoffset = 0, method = "bilinear")
DemosaicCPP(xoffset = 1, yoffset = 0, method = "nearest")
# EDIT: Just to tweak color a bit
RGBAdjust(r=1.0, g=1.1, b=1.8, a=1.0, rb=0.0, gb=0.0, bb=0.0, ab=0.0, rg=1.00, gg=1.00, bg=1.00, ag=1.00, analyze=false)
Input Image
https://i.postimg.cc/HJtcbqVf/image.jpg (https://postimg.cc/HJtcbqVf)
Result image
https://i.postimg.cc/zbXL7xh3/Image-Result.jpg (https://postimg.cc/zbXL7xh3)
TheFluff
8th January 2019, 09:49
Have you considered upgrading Visual Studio to a version that's less than ten years old? VS2013 and newer can compile C99!
StainlessS
8th January 2019, 12:39
Have you considered upgrading Visual Studio to a version that's less than ten years old?
@Faceless & Accursed, [ :) ] [EDIT: Apparently Faithless & Accursed, but I likes my version better]
I did try VS2010, IDE felt way too rickety for me, went back to VS2008. [and intellisense kept failing on me in 2010]
Might down 2017 one day, got links, just have not bothered yet.
(53GB scared me a bit shitless, guess thats what happens when you tick everything).
EDIT: 2017, You can download selected items offline as time permits, or partial/whole lot net install.
EDIT:
VS2013 and newer can compile C99!
Maybe one day I might have some reason to care about that, but not today.
@parbruek
The CPP interface is considerably less hassle than the C interface, once you figure out how it works (easier than figuring out the C interface).
Updated (in zip) recently:- Avisynth CPP Interface for C Programmers. - 03 Jan 2019
https://forum.doom9.org/showthread.php?t=163082
Once you have your CPP interface template, you can for the most part just fill in the plugin specific CPP parts (easy), and then continue everything else in C code. [me does it all of the time]
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.