Thread: Avisynth+
View Single Post
Old 14th December 2018, 10:15   #4327  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
David,
Some Stuff (SetVar and SetGlobalVar pretty much the same usage):-

http://avisynth.nl/index.php/Filter_...I#SetGlobalVar
http://avisynth.nl/index.php/Filter_...API#SaveString
https://forum.doom9.org/showthread.p...21#post1572321
https://forum.doom9.org/showthread.p...ar#post1843591


If setting some kind of var (Local or Global) from within eg GetFrame, then suggest that in Constructor, check for existence of the var, and if does not exist, create it with dummy value (using env->SaveString for the variable name, so you know for sure that the name already exists when in GetFrame), also, if eg var type is string and with a known max possible size, then create dummy max size string for it and also SaveString.
In GetFrame, can then assume that var name already exists (and saved with SaveString), and so can just set value in already allocated and saved buffer.

EDIT: If using preallocated buffer, then just write to that buffer, dont SetVar, assuming that you kept address of SaveString buffer,
otherwise get the used buffer via GetVar, and extract the pointer to the buffer from the AVSValue and write to that buffer.
Quote:
SaveString

virtual char* SaveString(const char* s, int length = -1);

This function copies its argument to a safe "permanent" location and returns a pointer to the new location. Each ScriptEnvironment instance has a buffer set aside for storing strings, which is expanded as needed. The strings are not deleted until the ScriptEnvironment instance goes away (when the script file is closed, usually). This is usually all the permanence that is needed, since all related filter instances will already be gone by then. The returned pointer is not const-qualified, and you're welcome to write to it, as long as you don't stray beyond the bounds of the string.
If just setting with string literals, can just save var name via SaveString,and set var with address of string literal (dont need saving),
string literals are at constant address and read only.

Saving Strings, related to SetVar;
https://forum.doom9.org/showthread.p...36#post1633936

EDIT:
ApparentFPS constructor
Code:
ApparentFPS::ApparentFPS(PClip _child,double _DupeThresh,double _FrameRate,int _Samples,double _ChromaWeight,
    const char*_Prefix,bool _Show,bool _Verbose,bool _Debug,
    int _Mode,int _Matrix,int _BlkW,int _BlkH,int _oLapX,int _oLapY,
    IScriptEnvironment* env) :
    GenericVideoFilter(_child),DupeThresh(_DupeThresh),FrameRate(_FrameRate),Samples(_Samples),
    ChromaWeight(_ChromaWeight),Prefix(_Prefix),Show(_Show),Verbose(_Verbose),Debug(_Debug),
    Mode(_Mode),Matrix(_Matrix),BlkW(_BlkW),BlkH(_BlkH),oLapX(_oLapX),oLapY(_oLapY) {
    # ifdef AVISYNTH_PLUGIN_25
        if(vi.IsPlanar() && vi.pixel_type != 0xA0000008) {
            // Here Planar but NOT YV12, If v2.5 Plugin Does NOT support ANY v2.6+ ColorSpaces
            env->ThrowError("ApparentFPS: ColorSpace unsupported in ApparentFPS v2.5\n");
        }
    # endif
    num_frames      = vi.num_frames;
    Dif             = 0.0;
    AppFPS          = 0.0;
    MaxAppFPS       = 0.0;
    MaxBelowDupeDif = 0.0;
    MinAboveDupeDif = 255.0;
    Unique          = 0;
    Valid           = 0;
    UniqMax         = 0;
    LftSpan         = 0;
    RgtSpan         = 0;
    Prev_n          = -666;
    int i;
    for(i=5;--i>=0;)    VarNames[i][0]='\0';
    if(*Prefix != '\0') {
        char *names[5]={"ApparentFPS","MaxApparentFPS","MaxBelowDupeDif","MinAboveDupeDif","CurrentDif"};
        int pfixlen=int(strlen(Prefix));
        if(pfixlen>128) pfixlen=128;
        for(i=5;--i>=0;) {
            char * p = VarNames[i];
            memcpy(p,Prefix,pfixlen);
            char *d=p+pfixlen;
            const char *np=names[i];
            for(;*d++=*np++;);          // strcat variable name part
            AVSValue var = GetVar(env,p);
            env->SetVar(var.Defined() ? p : env->SaveString(p),(i==3)?255.0:0.0); // Make sure name exists, init with dummy value
        }
    }
}
GetFrame
Code:
PVideoFrame __stdcall ApparentFPS::GetFrame(int n, IScriptEnvironment* env) {

 ...


    if(*Prefix != '\0') {
        env->SetVar(VarNames[0],AppFPS);
        env->SetVar(VarNames[1],MaxAppFPS);
        env->SetVar(VarNames[2],MaxBelowDupeDif);
        env->SetVar(VarNames[3],MinAboveDupeDif);
        env->SetVar(VarNames[4],Dif);
    }

 ...
}
EDIT: Take NOTE that GetVar() [by Gavino] is in the 3rd link.

EDIT: Again here:
Code:
AVSValue __cdecl GetVar(IScriptEnvironment* env, const char* name) {
    try {return env->GetVar(name);} catch (IScriptEnvironment::NotFound) {} return AVSValue();}
If you have any probs, post again. [EDIT: Perhaps ask a mod to move your post and this one to new thread]

EDIT:
Also AtExit function, maybe to release buffers if you allocate them for strings yourself.
http://avisynth.nl/index.php/Filter_SDK/Non-clip_sample
EDIT: Not sure, think you can forget AtExit above, I seem to remember that it is called AFTER plugins are destroyed, so may not work.
EDIT: Think maybe above wrong, plugins do still exist, its the filter graph that is already destroyed (otherwise there would be no point in the AtExit function if plugins already gone, basically dont count on any avisynth structures existing during call from AtExit).


EDIT:
Return constants rather than variables, simple really.
Code:
#include <windows.h>

#ifdef AVISYNTH_PLUGIN_25
    #include "avisynth25.h"
#else
    #include "avisynth.h"
#endif

AVSValue __cdecl Foo_Bilinear(AVSValue args, void* user_data, IScriptEnvironment* env) {
    return "12345678";  // Constant address read only, no need to SaveString
}

AVSValue __cdecl Foo_BiCubic(AVSValue args, void* user_data, IScriptEnvironment* env) {
    return "87654321";
}

AVSValue __cdecl Foo_PI(AVSValue args, void* user_data, IScriptEnvironment* env) {
    return 3.1415926f;
}

AVSValue __cdecl Foo_Life(AVSValue args, void* user_data, IScriptEnvironment* env) {
    return 42;
}

#ifdef AVISYNTH_PLUGIN_25
    extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
#else
    const AVS_Linkage *AVS_linkage = 0;
    extern "C" __declspec(dllexport) const char* __stdcall
            AvisynthPluginInit3(IScriptEnvironment* env, const AVS_Linkage* const vectors) {
    AVS_linkage = vectors;
#endif
    env->AddFunction("FOO_BILINEAR",    "", Foo_Bilinear, 0);
    env->AddFunction("FOO_BICUBIC",     "", Foo_BiCubic, 0);
    env->AddFunction("FOO_PI",  "",     "", Foo_PI, 0);
    env->AddFunction("FOO_Life",        "", Foo_Life, 0);
    return "`DHorman Presets' DHorman plugin";
}
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 19th December 2018 at 04:44.
StainlessS is offline