View Full Version : Correct way to target multiple Avisynth versions
TurboPascal7
22nd July 2013, 00:17
What is the correct/recommended way to target multiple versions (2.58, 2.6a3, 2.6a4) of Avisynth in a plugin if it needs to support as many planar colorspaces as possible (yv24, yv12, y8 etc.).
As I understand there are currently over 9k different versions Avisynth.h around each with some hackery added. Which one should be used?
If possible I would prefer not to use "separate plugins for different versions" (like masktools) approach.
Thanks.
StainlessS
22nd July 2013, 00:41
Do not use/target v2.6a3, not supported any more.
Use version 3 Avisynth.h for 2.5 and Version 5 for v2.6, version 4 header does NOT exist.
You can get both current headers from any of the 25&26 plugin zips in my sig, eg the ClipBlend zip.
v2.6 plugins cannot not be loaded in 2.58, v2.5 plugins work just fine in v2.6 although 2.6 colorspaces will be incorrectly identified as YV12
and filters will not process properly.
How I do it in ClipBlend plug (EDIT: although cannot guarantee that it is "correct way"):-
/*
Compiling for both Avisynth v2.58 & v2.6 ProjectName under VS6, where ProjectName is the base name of the plugin.
Create an additional project ProjectName26 and copy the
project files into ProjectName folder. Add headers and source files to v2.6 project.
You should have "avisynth25.h" in the ProjectName Header Files and
"avisynth26.h" in the ProjectName26 Header Files.
For the v2.58 project, add preprocessor definition to :-
Menu/Project/Settings/All Configuration/C/C++, AVISYNTH_PLUGIN_25
*/
// Load header
#ifdef AVISYNTH_PLUGIN_25
#include "avisynth25.h" // Version 3 for Avisynth 2.5
#else
#include "avisynth26.h" // Version 5 for Avisynth 2.6a4
#endif
// In constructor
# ifdef AVISYNTH_PLUGIN_25
if(vi.IsPlanar() && vi.pixel_type != 0xA0000008) { // Planar but NOT YV12, ie Avisynth v2.6+ ColorSpace
// Here Planar but NOT YV12, v2.5 Plugin Does NOT support ANY v2.6+ ColorSpaces
env->ThrowError("ClipBlend: ColorSpace unsupported in ClipBlend v2.5\n");
}
# endif
// Plugin init
#ifdef AVISYNTH_PLUGIN_25
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
#else
/* New 2.6 requirement!!! */
// Declare and initialise server pointers static storage.
const AVS_Linkage *AVS_linkage = 0;
/* New 2.6 requirement!!! */
// DLL entry point called from LoadPlugin() to setup a user plugin.
extern "C" __declspec(dllexport) const char* __stdcall
AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
/* New 2.6 requirment!!! */
// Save the server pointers.
AVS_linkage = vectors;
#endif
env->AddFunction("ClipBlend", "c[delay]i", Create_ClipBlend, 0);
return "`ClipBlend' ClipBlend plugin";
// A freeform name of the plugin.
}
If possible I would prefer not to use "separate plugins ...
You have no choice, if you want to support v2.5, it will not load v2.6 plugins. If you want to support v2.6
colorspace, then you need a v2.6 plugin, no alternative.
(EDIT: Only exception is that 2.5 plugin could process Y8 (under avisynth v2.6) when established that RowSizeU/V is zero
ie no chroma, it is the chroma that is problematic).
Good luck.
EDIT: You might find these of interest too:-
http://forum.doom9.org/showthread.php?p=1617236#post1617236
http://forum.doom9.org/showthread.php?p=1580772#post1580772
Chikuzen
22nd July 2013, 06:12
I think that most recommended way is just drop support of 2.5.
qyot27
22nd July 2013, 10:23
FFMS2's C plugin has been capable of handling both 2.5 and 2.6 in a single .dll since r511:
http://code.google.com/p/ffmpegsource/source/detail?r=511
(I believe the changes introduced into avisynth_c.h have actually been added to the CVS version, just with some organizational differences)
Might provide a reference for how to do it, although I dunno if that kind of trickery is permissible with the standard plugin interface.
StainlessS
22nd July 2013, 12:25
I think that most recommended way is just drop support of 2.5.
That certainly is the easiest way.
The C plugin interface could provide a way of supplying only one plugin, but it is also less easy to use and you would
(I think) have to delve more into interpreting meaning of vi.pixel_type bits, any changes in Avisynth in that respect
would mean more work.
dunno if that kind of trickery is permissible with the standard plugin interface
Since about release of v2.6a4 v5 Avisynth.h, changes make it impossible to load v2.6 standard C++ plugin into
v2.5 avisynth, it would need to be a v2.5 plug with v3 avisynth.h, and you would have to handle all the extra colorspaces
and bit flags yourself in a C++ interface plugin, and cope with future changes when and where the occur.
I prefer my previously suggested method, although it is very tempting to just forget that v2.58 exists.
EDIT: If I am wrong and you do not have to handle all extra colorspaces and bit flags yourself in a C interface
plugin, then perhaps someone can advise on how this is achieved.
I dont actually like C style plugins, I like the autoload functionality of the CPP plugs.
cretindesalpes
28th July 2013, 20:16
I wrote a terrible hack (as usual), but it seems to work so far. I added the constants and functions from interface version 5 to an avisynth.h v3. Some functions from the SDK like GetRowSize() or GetHeight() cannot be safely called anymore because they make assumptions on the chroma planes. I had to write a little wrapper on the plug-in side to handle correctly all the colorspaces with the help of GetPlaneXXXSubsampling(). I think frame creation for source filters won’t work for the same reasons, but I’m not sure if there is a workaround.
Mystery Keeper
5th August 2013, 12:29
This is how I handled it in TempLinearApproximate. (https://bitbucket.org/mystery_keeper/templinearapproximate/src/f6dfb358836202635b831c5529e78257719c8473/main.cpp?at=master)
Would that cause any problems?
StainlessS
5th August 2013, 14:48
Just posting MysteryKeeper link contents:
#if __cplusplus <= 199711L
#define nullptr NULL
#endif
#include "TempLinearApproximate.h"
const AVS_Linkage * AVS_linkage = nullptr;
AVSValue __cdecl Create_TempLinearApproximate(AVSValue args, void* user_data,
IScriptEnvironment* env)
{
return new TempLinearApproximate(
args[0].AsClip() // child
, (unsigned int)args[1].AsInt(TLA_DEFAULT_RADIUS) // radius
, (unsigned char)args[2].AsInt(TLA_DEFAULT_PLANE) // plane
, args[3].AsBool(false)
, args[4].AsBool(false)
, env);
};
extern "C" __declspec(dllexport) const char * __stdcall AvisynthPluginInit3(
IScriptEnvironment* env, const AVS_Linkage* const vectors)
{
AVS_linkage = vectors;
env->AddFunction("TempLinearApproximate",
"c[radius]i[plane]i[inLsb]b[outLsb]b",
Create_TempLinearApproximate, nullptr);
return "Temporal linear approximation filter";
}
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(
IScriptEnvironment* env)
{
env->AddFunction("TempLinearApproximate",
"c[radius]i[plane]i[inLsb]b[outLsb]b",
Create_TempLinearApproximate, nullptr);
return "Temporal linear approximation filter";
};
you use both v2.5 (AvisynthPluginInit2) and v2.6 (AvisynthPluginInit3) funcs, which I think might undo the reason
for the change in ~jan13 version 5 Avisynth.h, which inhibits v2.6 plugin being used in v2.58 avisynth.
Has it been tested under Avisynth v2.58 ?
EDIT: Dont think it can work, "AVS_linkage = vectors;" not initialized under v2.58
StainlessS
5th August 2013, 15:59
Mystery Keeper,
I have compiled (with small change) as given and I get an Access Violation under v2.58 (OK under v2.6a4), due I think to previously posted
AVS_Linkage = vectors; not set, and baked code none existent in v2.6 header.
here reason for small change to source, errors in VS6.
TempLinearApproximate.cpp
d:\templinearapproximate\templinearapproximate.h(37) : error C2258: illegal pure syntax, must be '= 0'
d:\templinearapproximate\templinearapproximate.h(37) : error C2252: 'Y_FLAG' : pure specifier can only be specified for functions
d:\templinearapproximate\templinearapproximate.h(38) : error C2258: illegal pure syntax, must be '= 0'
d:\templinearapproximate\templinearapproximate.h(38) : error C2252: 'U_FLAG' : pure specifier can only be specified for functions
d:\templinearapproximate\templinearapproximate.h(39) : error C2258: illegal pure syntax, must be '= 0'
d:\templinearapproximate\templinearapproximate.h(39) : error C2252: 'V_FLAG' : pure specifier can only be specified for functions
changed TempLinearApproximate.h: (EDIT: defined private: in class)
static const unsigned char Y_FLAG = 1;
static const unsigned char U_FLAG = 2;
static const unsigned char V_FLAG = 4;
changed to private:
enum {
Y_FLAG=1,
U_FLAG=2,
V_FLAG=4
};
similar errors compiling other source files when header included.
Guess it depends if you want to be able to compile in older version compiler or not.
TempLinearApproximate constructor, there does not seem to be a check on whether height / 2 is legal for colorspace,
when inLsb=true, outLsb=false.
in_height HMOD should be 2*(in_height_Y / in_height_U), {will fail without sensible error message, something like "an error occurred"}
(take care for Y8)
else if(m_inLsb == true && m_outLsb == false)
{
vi.height /= 2;
}
EDITED:
Mystery Keeper
7th August 2013, 19:59
Thank you. I'll look into it better when I have time.
Why use VS6 at all though? There are free versions of newer VS that not only follow the standard better, but also went far in terms of optimization.
StainlessS
7th August 2013, 20:51
Why use VS6 at all though ?
Compiler compatability (eg your source dont work in VS6/TK3/VS2002/VS2003 and maybe Vs2005).
Perhaps due to default optimization settings but I've found VS2008/2010 to be slower than VS6/TK3/VS2005 (at least for some things).
EDIT: Generally (but not always), 2005 faster than TK3,faster than VS6 (sometimes other way around especially in hand optimized code).
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.