Reel.Deel
27th June 2016, 14:12
I recently started working on some of the documentation for AviSynth+. I'm creating this thread to discuss a few things that will eventually end up in the documentation.
My plans for the documentation are:
Go over all the internal filters and syntax pages and update the information to match the AviSynth wiki. And also make the formatting consistent.
Document the new plugin autoloading features.
Document the multithreading features.
Document the extended GScript syntax.
Document any other features, changes from classic AviSynth, and other small things.
Even if all that is done, there's still a lots of pages that will need to be updated or at least gone over. The wiki has had quite a few updates in recent times, unfortunately, most of those updates don't make it to the bulletin docs.
Reel.Deel
27th June 2016, 14:13
Below is some questions I have regarding plugin loading and the new autoloading features. Here's what I have so far (https://s33.postimg.org/mdibub8rx/plugins.png?dl=0) and here's the .rst file (https://www.refheap.com/0bf8c2e51091fc747ac023988). If there's anything wrong, anything I missed, or even a better way to write something please let me know. :)
1)
Okay, so how do multiple plugin directories interact with plugin autoloading?
As a recap, here is how it used to work in the official Avisynth:
- Look for the string HKEY_CURRENT_USER/Software/Avisynth/PluginDir2_5 in the registry. If it exists, load plugins from the path specified there and stop.
- If the above string didn't exist, look in HKEY_LOCAL_MACHINE/Software/Avisynth/PluginDir2_5. Try to load plugins from the path specified there.
- Done.
First thing to note, is that classic Avisynth only ever searches for plugins in one single directory. It only knows two directories (both specified in the registry), and it only tries the second path if there is no entry for the first one.
Avisynth+'s autoloader has a list of autoload directories. It iterates over all those directories and tries to load all plugins from each. But (and a big but!) it will not load a plugin from a directory if another plugin with the same basename is already loaded. The basename of a plugin is simply its file name without the extension.
The expected use case is that you can now overlay a new plugin directory on top of another one. Avisynth+ then would load all plugins from the first folder, then load only those plugins from the second that weren't loaded from the first, then those from the third that weren't loaded from the first or second and so on. For example, let's say your usual plugin folder has a lot of plugins you normally use. But at one time you have a small number of updated plugins that you only want to use from a few scripts, but you do not yet want to replace your existing plugins globally. Then you'd just add a new plugin overlay folder, with only the new plugins in it, and that's it. All scripts that specify the new folder will autoload all plugins from your usual one, except for the new plugins, which would get loaded from the new folder. All your other scripts will still use your old plugins.
My next post will tell you how to add and remove autoload folders.
By default, Avisynth+'s autoload folder list has four paths in it, in this order:
- PluginDir+ in Software/Avisynth in HKEY_CURRENT_USER
- PluginDir+ in Software/Avisynth in HKEY_LOCAL_MACHINE
- PluginDir2_5 in Software/Avisynth in HKEY_CURRENT_USER
- PluginDir2_5 in Software/Avisynth in HKEY_LOCAL_MACHINE
This means, if there are ever plugins which will only work with Avs+ but not with classic Avs, you can put them into one of the "PluginDir+" folders. Avisynth+ will then use the classic plugins from the normal Avisynth, but if there are versions of some plugins written for Avisynth+, it will use them instead, and the classic avisynth.dll will still not be bothered with them. This is all without you having to lift a finger (except for adding the "PluginDir+" values to the registry once, until we have an installer). So to summarize all this, you have the ability to define a plugin autoload folder in the registry which will only be used by Avs+, but not by Avs, in addition to your classic plugins.
However, another new functionality offered by Avisynth+, is that now you can also specify autoload paths in the scripts. There are two functions for this:
- AddAutoloadDir(string path, bool toFront): this will add a new autoload folder. The string parameter is obligatory, it is the folder path where to load from. The second boolean parameter is optional, and if true (default), it will add the path to the front/beginning of the autoloader's list, which means it will be searched earlier than the rest. If it is false, the path will get added to the end of the list, so it will get searched last (unless you again add another one to the end).
- ClearAutoloadDirs(): This will clear all the paths from the autoloader's list. Note that it is NOT a reset to the default state. ClearAutoloadDirs() will clear all folders, so if you don't add new ones after that, you have disabled the autoload functionality. This is, BTW, also a way to disable autoloading for a particular script in Avisynth+.
Here's an important note: You can only call these functions if no plugin has been autoloaded yet. Autoloading happens if the first unknown function is looked up. This means you can only call AddAutoloadDir or ClearAutoloadDirs if you have only made calls to built-in functions up to that point in the script. I suggest you start your scripts with these calls to avoid any problems.
There is only one thing left to discuss: Are there any special directories you can reference from your script? You bet there are :)
- SCRIPTDIR is the folder of the most current script. It is the path of the imported script if your script calls import()
- MAINSCRIPTDIR is the folder of your main script, the one where execution started
- PROGRAMDIR is the folder of the executable running the current script
- USER_PLUS_PLUGINS is the string stored in PluginDir+ in Software/Avisynth in HKEY_CURRENT_USER
- MACHINE_PLUS_PLUGINS is the string stored in PluginDir+ in Software/Avisynth in HKEY_LOCAL_MACHINE
- USER_CLASSIC_PLUGINS is the string stored in PluginDir2_5 in Software/Avisynth in HKEY_CURRENT_USER
- MACHINE_CLASSIC_PLUGINS is the string stored in PluginDir2_5 in Software/Avisynth in HKEY_LOCAL_MACHINE
... all these special constants are case-sensitive for now.
Examples
- If you want plugins to be autoloaded from the script's "autoload" directory too, you'd write:
AddAutoloadDir("MAINSCRIPTDIR/autoload")
- If you want plugins to be autoloaded from the script's "autoload" directory, only from there and nowhere else, you'd write:
ClearAutoloadDirs()
AddAutoloadDir("MAINSCRIPTDIR/autoload")
- If you wanted to manually recreate the default state of the autoloading folder list, you'd write:
ClearAutoloadDirs()
AddAutoloadDir("USER_PLUS_PLUGINS", false)
AddAutoloadDir("MACHINE_PLUS_PLUGINS", false)
AddAutoloadDir("USER_CLASSIC_PLUGINS", false)
AddAutoloadDir("MACHINE_CLASSIC_PLUGINS", false)
This was written before there was a 64-bit build and before the new installer was made. I know most of it is still current but I would like to know what has changed due to the installer and 64-bit.
2)
Avs+ autoloads plugins if any of the following happens:
- AutoloadPlugins() is called
- LoadPlugin() is called
- A yet unknown (non-internal) function is called
avs_function_exists does not find the external source filter in this case because none of the above happened. So MasterNobody's patch is the right thing to do.
How about having env->FunctionExists() (which is called by avs_function_exists) autoload plugins if a yet unknown function name is passed? Then it is transparent to client applications.
Hmm, I didn't like the idea at first, but thinking about it some more, it does make sense. The fact that FunctionExists() never autoloads while a function call can do it means that it is possible to call functions for which FunctionExists() returned false. That is not only inconsistent, but it can be argued it is a bug.
On the other hand, the reason I'm not perfectly satisfied with FunctionExists() autoloading is because FunctionExists() has the semantics of a getter function. It is pretty unexpected that it changes the internal state greatly (even if we are talking about non-observable state). I have to conclude though that this rather ideological argument is outweighed by the proposed solution's practical relevance.
So I guess I will correct this in Avisynth+ after all.
Does this affect anything that was written in 1?
3)
- If you want plugins to be autoloaded from the script's "autoload" directory, only from there and nowhere else, you'd write:
ClearAutoloadDirs()
AddAutoloadDir("MAINSCRIPTDIR/autoload")
In what contexts do MAINSCRIPTDIR and the other 'special' names get replaced with the corresponding folders?
In all strings, or only when used in the argument to AddAutoloadDir?
Only in AddAutoloadDir(), and even there, only if they are at the very beginning of the string. These get replaced to absolute folder paths, so if they are not at the beginning of the string, replacing them would only result in an invalid path (e.g. you'd end up with "c:" in the middle of your path).
Don't quite understand this, is there an example?
4)
both Avs and Avs+ already query interface versions. They try to load the 2.6 interface from a plugin first, and if that is not supported, they try to load the 2.5 interface. Avs+ also tries to load the C interface if both of the previous ones fail. In the future, the C interface should probably be prioritized over 2.5.
I'm changing the loading order in my next public build. Meaning that the new order will be 2.6 -> C -> 2.5.
As I said before, I'm gonna change Avisynth+ to try the C interface of a plugin before the 2.5 interface anyway.
Just to to confirm, In AviSynth+ the C interface is prioritized over 2.5, correct? Yes, see here https://github.com/AviSynth/AviSynthPlus/commit/0afe5314c03aa433447d873af2a7d82d34df4177, found the answer myself. :)
5)
- LoadVFAPIPlugin() is out of order for now. I'm not planning on removing it, I just need some info how to correct it.
Is this still true? No one really uses it anymore but I'd like to add a note if it's still out of commission.
6)
Groucho2004 reported that 2.0 C-plugins are not supported in AviSynth+ (http://forum.doom9.org/showthread.php?p=1769658#post1769658). Is this by design or is it something that will be fixed? Luckily there's not that many 2.0 C-plugins (http://forum.doom9.org/showthread.php?p=1764025#post1764025), and the ones that do exist are kinda old.
7)
If a plugin DLL cannot be loaded, a human-readable error from Windows is also displayed, giving the user a clue what is wrong.
Is there a predefined list of these errors?
ultim
2nd July 2016, 19:40
1)
This was written before there was a 64-bit build and before the new installer was made. I know most of it is still current but I would like to know what has changed due to the installer and 64-bit.
No, those don't have any effects on what was written. The installer never affects the scripting semantics, and in general 64-bits also does not (only in the rarest and subtlest occasions).
The only difference since what was written here, is when an automatic load of plugins happens (see answer below in 2), but this change has nothing to do with 64-bits or the installer.
2)
Does this affect anything that was written in 1?
Yes it does. In 1 it was stated that automatic loading happens when an unknown function is called. New cases has been added since then, and as of today, the cases when plugins are autoloaded are:
- AutoloadPlugins() is called
- LoadPlugin() is called
- FunctionExists() is called and the queried function was not found
- A yet unknown (non-internal) function is called
3)
Don't quite understand this, is there an example?
It means that the new variables described in 1 are only expanded if they are found in a call to AddAutoloadDir(), and only if they are at the beginning of the directory string. Examples:
- Subtitle("MAINSCRIPTDIR") will simply output "MAINSCRIPTDIR", and not the intended directory, because it is was not supplied as a parameter to AddAutoloadDir().
- AddAutoloadDir("c:/MAINSCRIPTDIR") will also not work, because even though AddAutoloadDir() was used, "MAINSCRIPTDIR" was not at the beginning of the path.
- AddAutoloadDir("MAINSCRIPTDIR/somedir") will work correctly.
4)
Just to to confirm, In AviSynth+ the C interface is prioritized over 2.5, correct? Yes, see here https://github.com/AviSynth/AviSynthPlus/commit/0afe5314c03aa433447d873af2a7d82d34df4177, found the answer myself. :)
Yep. And just to underline, the compatibility with 2.5 is only for really-really old plugins which cannot be recompiled. At some point I might even remove it (with prior notice ofc). New or even recompiled plugins should not use it.
5)
Is this still true? No one really uses it anymore but I'd like to add a note if it's still out of commission.
It is still out cold. I have no interest in it bringing it back. If anybody wants to see it resurrected, a turn-key patch will be accepted.
6)
Groucho2004 reported that 2.0 C-plugins are not supported in AviSynth+ (http://forum.doom9.org/showthread.php?p=1769658#post1769658). Is this by design or is it something that will be fixed? Luckily there's not that many 2.0 C-plugins (http://forum.doom9.org/showthread.php?p=1764025#post1764025), and the ones that do exist are kinda old.
By design. At that time when developing the new plugin loading, I wasn't aware of the older 2.0 C interface, so it wasn't really a conscious decision. But now I also don't see any motivation in supporting it.
7)
Is there a predefined list of these errors?
The full list of codes, including english messages, can be found at https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx .
Of course only a subset will be relevant for DLL loading. The text messages are returned by Windows, so they can be localized if you have a non-english OS.
So, while technically "yes", the practical and short answer is "no". The advantage though of course is that there is a user-friendly (kind-of) message for every possible error condition.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.