1 (edited by Tereius 28-10-2014 20:10:15)

Topic: releasing AVS_ScriptEnvironment fails after loading svpflow dlls

Hi there,

I'm currently writing a small GUI for AviSynth especially to visualize the differences between native recorded and estimated frames. So I came across this wonderfull project which fits my needs perfectly.

Loading AviSynth scripts and receiving frames with my application works fine. But I have trouble releasing AviSynths ScriptEnvironment (avs_delete_script_environment(AVS_ScriptEnvironment *)). The debugger throws: "Exception (first Chance) 0xB0DA355A in minimal.exe: 0xC0000008: An invalid handle was specified". I tracked the problem down to the point where the SVPflow dlls (svpflow1.dll, svpflow2.dll) are loaded. Once both dlls are loaded the invocation of avs_delete_script_environment fails and the application crashes (other external avs filter (e.g ffms2.dll) don't fail). I wrote a minimal example that should reproduce this problem. Can someone give me some hints to solve this?

Some background infomation:
- I'm using Visual Studio Ultimate 2013, Windows 8.1 (64bit)
- replaced avisynth.dll in SysWOW64 folder with latest AviSynth2.5.8(SVP edition) dll
- using AviSynths C API
- linked against avisynth.lib
- svpflow_cpu.dll, svpflow_gpu.dll, svpflow1.dll, svpflow2.dll are in the same folder


#include "stdafx.h"
#include "avisynth_c.h"

#include <windows.h>
#include <stdio.h>

#define PATH_AVS_PLUGIN_SVPFLOW1  "C:\\Users\\Bjoern\\Desktop\\minimal\\minimal\\svpflow1.dll"
#define PATH_AVS_PLUGIN_SVPFLOW2  "C:\\Users\\Bjoern\\Desktop\\minimal\\minimal\\svpflow2.dll"

int _tmain(int argc, _TCHAR* argv[])
{

    typedef AVS_ScriptEnvironment*(_stdcall *avs_create_script_environment)(int);
    typedef void(_stdcall *avs_delete_script_environment)(AVS_ScriptEnvironment *);
    typedef AVS_Value(_stdcall *avs_invoke)(AVS_ScriptEnvironment *, const char *, AVS_Value, const char**);
    typedef void(_stdcall *avs_release_value)(AVS_Value);

    HMODULE dll;
    AVS_ScriptEnvironment *env;

    dll = LoadLibrary(L"avisynth.dll");
    if(!dll) {
        fprintf(stderr, "Cannot load avisynth.dll");
        return 1;
    }

    avs_create_script_environment p_create = (avs_create_script_environment) GetProcAddress(dll, "avs_create_script_environment");
    if(!p_create) {
        return 1;
    }

    env = p_create(AVISYNTH_INTERFACE_VERSION);
    if(env == NULL) {
        fprintf(stderr, "Cannot create CreateScriptEnvironment");
        return 1;
    }

    avs_invoke p_invoke = (avs_invoke) GetProcAddress(dll, "avs_invoke");
    if(!p_invoke) {
        return 1;
    }

    AVS_Value ret = p_invoke(env, "LoadPlugin", avs_new_value_string(PATH_AVS_PLUGIN_SVPFLOW1), NULL);
    if(avs_is_error(ret)) {
        fprintf(stderr, "%s", avs_as_error(ret));
        return 1;
    }

    ret = p_invoke(env, "LoadPlugin", avs_new_value_string(PATH_AVS_PLUGIN_SVPFLOW2), NULL);
    if(avs_is_error(ret)) {
        fprintf(stderr, "%s", avs_as_error(ret));
        return 1;
    }

    avs_release_value p_release = (avs_release_value) GetProcAddress(dll, "avs_release_value");
    if(!p_release) {
        return 1;
    }

    p_release(ret);

    avs_delete_script_environment p_delete_script_env = (avs_delete_script_environment) GetProcAddress(dll, "avs_delete_script_environment");
    if (!p_delete_script_env) {
        return 1;
    }

    p_delete_script_env(env); // IT FAILS HERE
    FreeLibrary(dll);

    return 0;
}

Re: releasing AVS_ScriptEnvironment fails after loading svpflow dlls

just getting the very same ... hmm, what is the word? ... coitus with "Avisynth+" project  big_smile
no one wants to clear this thing correctly

on the other hand if you'll run SVP, then ScriptEnviroment will be killed at each and every video seek
and it was never be a problem, AFAIK

...

you obviously using VC compiler - so why the "C API" ?

anyway, loading plugin just do nothing unless you'll invoke some filter

may be memory gets corrupted on "p_release(ret);" call as "LoadPlugin" actually doesn't return anything  hmm


- linked against avisynth.lib

what version? where you get this .lib?
keep in mind that 2.5.8 avisynth.h have plenty of stuff (including common classes destructors) defined in the header (and so they're compiled into plugins) and 2.6 doesn't

Re: releasing AVS_ScriptEnvironment fails after loading svpflow dlls

Chainik wrote:

you obviously using VC compiler - so why the "C API" ?

I want to exclude any problems that can be caused by different versions of VC compiler. I think the official AviSynth builds are compiled with VC6 or VC8 and I'm using VC12. Microsoft recommends using C interfaces, that are designed to have a stable ABI between compiler releases. But I also tried the c++ Interface which causes exactly the same problem.

Chainik wrote:

may be memory gets corrupted on "p_release(ret);" call as "LoadPlugin" actually doesn't return anything  hmm

avs_invoke has a return value (type AVS_Value) which must be released with avs_release_value (http://www.kevina.org/avisynth_c/api.html). The Variable ret actually holds a string saying: "svpflow1: part of SmoothVideo Project frame interpolation engine based on MVTools2 plugin".

Chainik wrote:

- linked against avisynth.lib

what version? where you get this .lib?
keep in mind that 2.5.8 avisynth.h have plenty of stuff (including common classes destructors) defined in the header (and so they're compiled into plugins) and 2.6 doesn't

You have to link against avisynth.lib if the c API is used. The lib is located in the installation folder of AviSynth if some ??? option is checked during installation process. I'm currently using version 2.5.8

Long story short. I have tryed any possesible combination of different AviSynth releases and their APIs. The ScriptEnviroment cannot be freed without a crash. Either env->DeleteScriptEnvironment() or avs_delete_script_environment(env) work after the svpflow dlls are loaded. The only possible solution to overcome this issue is to skip those calls and directly unload the AviSynth Module which should release all ressources. BUT that's pretty annoying because my application needs two ScriptEnviroments which are owned by two threads. If one thread resets its ScriptEnviroment the other thread will loose its Environment too. I hope there is some better solution. I'm not even sure if its a VC12 related problem or something else.