Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Development

Reply
 
Thread Tools Search this Thread Display Modes
Old 7th December 2013, 21:53   #201  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 408
Long Live SimpleSample

Because I first failed with compiling SimpleSample 1.7 for AviSynth 2.6 and then found the credentials spread at various locations, I post a package of the sources and a test script here.

I also reworked SimpleSample 1.8 a bit. Since the 2nd clip was only overlayed in YUY2 colorspace and I saw no checks that it has the same colorspace at all, I removed that special code and made the behaviour same in all colorspaces. Also, I imported most of the enhancements of the Wiki version but kept the comments, tidied it up (I prefer descriptive comments above the code - please don't argue about that) and corrected some bugs. Also added a list of parameter types as a reference, Debug output example and a bool parameter to switch to in-place processing like the Wiki version.

So, for developer newbies like me it hopefully serves as a first step to have something that compiles and executes. And some essential things like colorspace, debug output, parameter list are shown too - .

Caution: only for V2.6
Attached Files
File Type: zip SimpleSample18.zip (16.1 KB, 138 views)
martin53 is offline   Reply With Quote
Old 11th June 2016, 13:19   #202  |  Link
jmac698
Registered User
 
Join Date: Jan 2006
Posts: 1,869
I wanted to rewrite my plugin development guide , http://avisynth.nl/index.php/Avisynt...velopment_in_C for Avisynth API 2.6 and C++, but I do not have the rights to create new pages. Apparently I need to find one of these people to do it:
SilverbackNet, Tepples‏‎, Vcmohan, Violao.

I also note that http://avisynth.nl uses MediaWiki 1.18 from 2011, and it is recommended to update to at least version 1.23. It seems I have no hope of getting colour syntax support.

Edit: Now I see that SimpleSample has been updated for Avisynth 2.6 API, by an unknown contributor (marked as Admin). Also thanks @martin53 for your contribution.

Last edited by jmac698; 11th June 2016 at 13:27.
jmac698 is offline   Reply With Quote
Old 11th June 2016, 14:51   #203  |  Link
raffriff42
Retried Guesser
 
raffriff42's Avatar
 
Join Date: Jun 2012
Posts: 1,371
Send a PM to Wilbert. He will give you the exalted power of page creation, if you know the secret handshake.
http://forum.doom9.org/private.php?do=newpm&u=2705

Oblig. Monty Python:
https://www.youtube.com/watch?v=ddM7kJ9xQfA
raffriff42 is offline   Reply With Quote
Old 11th June 2016, 17:33   #204  |  Link
jmac698
Registered User
 
Join Date: Jan 2006
Posts: 1,869
Done. Thanks. I'd like to attempt to create a plugin with vs2015, include instructions, and test it with avs2.6 x86/x64, avs+, and vs, and write up my tutorial.

I also want to write a general pixel class so you don't need to write code for each colour space; yes this will be slow, but it's fine for me for testing.
jmac698 is offline   Reply With Quote
Old 12th June 2016, 14:40   #205  |  Link
MysteryX
Soul Architect
 
MysteryX's Avatar
 
Join Date: Apr 2014
Posts: 2,560
In terms of tutorial, we really don't care about the speed. All we care about is understanding how the various formats work! It took me a while to sort that out.

Those who want performance should seek an ASM tutorial which is a whole other ball-game.
MysteryX is offline   Reply With Quote
Old 12th June 2016, 16:04   #206  |  Link
MysteryX
Soul Architect
 
MysteryX's Avatar
 
Join Date: Apr 2014
Posts: 2,560
With my code, after changing the code structure, I have an issue with a serious memory leak.

Visual Leak Detector for Visual Studio is crashing when trying to profile AviSynth.

The CRT Library, however, works

To get it to detail the location of the memory leaks, I had to add this code into the top of the files I want to profile. Adding it into a generic header file causes conflicts with AviSynth.h preventing compilation.

Code:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif  // _DEBUG
I think that information would be useful for others!

What happened when I ran the tool? A WHOLE LIST of memory leaks showed up!! 14 after displaying a single frame. I double-click on it and it bring me to the line where it was allocated.

If you never ran such a tool on your own code, you might get a surprise.

Edit: it wasn't that bad; but when adding "_CrtDumpMemoryLeaks();" into my destructor, there are additional releases happening afterwards that are being marked as a leak. I don't know of a proper way of doing memory leak detection. I tried adding "_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );" at the beginning and that didn't work. Input from experts would be welcomed, and perhaps there could be information about this in the development guides.

Last edited by MysteryX; 12th June 2016 at 16:48.
MysteryX is offline   Reply With Quote
Old 26th June 2016, 15:40   #207  |  Link
slavanap
Registered User
 
slavanap's Avatar
 
Join Date: May 2011
Location: Moscow, Russia
Posts: 124
I think, this example may be quite useful for people who starting implementing their own plugins. Unfortunately, it has some heavy (for beginners) WinAPI code, and its PVideoFrame wrapper supports only RGB32 input but everything is structured. And I love calling other AviSynth functions via AvsCall template function (like this, for example).

To build this project you need to have CMake and Visual Studio installed (I use MSVS 2015). After you installed them, run configure.bat in project root folder, and then open generated VS solution in __build/ folder. And you need to check out project repository with "recursive" parameter set. I use Git in conjunction with TortoiseGit for development with Git version control system.

P.S. Don't forget to keep my LICENSE file in your binaries distribution, if you use my code. Project has very nonrestrictive MIT license.

Last edited by slavanap; 26th June 2016 at 15:54.
slavanap is offline   Reply With Quote
Old 26th June 2016, 15:48   #208  |  Link
slavanap
Registered User
 
slavanap's Avatar
 
Join Date: May 2011
Location: Moscow, Russia
Posts: 124
Quote:
Originally Posted by martin53 View Post
Because I first failed with compiling SimpleSample 1.7 for AviSynth 2.6 and then found the credentials spread at various locations, I post a package of the sources and a test script here.
Does your example considers VideoInfo::IsBFF() value ?
slavanap is offline   Reply With Quote
Old 26th June 2016, 19:56   #209  |  Link
TurboPascal7
Registered User
 
TurboPascal7's Avatar
 
Join Date: Jan 2010
Posts: 270
That is one ridiculously overcomplicated "easy filter sample".
__________________
Me on GitHub | AviSynth+ - the (dead) future of AviSynth
TurboPascal7 is offline   Reply With Quote
Old 5th August 2016, 12:22   #210  |  Link
jpsdr
Registered User
 
Join Date: Oct 2002
Location: France
Posts: 2,637
If you want to use in a plugin one (or several) core avisynth filter. Is using env->Invoke (like done in nnedi3) the only way, or is there any other way by any chance (also if you want to use core filter/function inside getframe) ?
If yes, a link to an exemple will be very appreciated.

Last edited by jpsdr; 5th August 2016 at 12:46.
jpsdr is offline   Reply With Quote
Old 5th August 2016, 13:09   #211  |  Link
Chikuzen
typo lover
 
Chikuzen's Avatar
 
Join Date: May 2009
Posts: 601
Quote:
Originally Posted by jpsdr View Post
is there any other way by any chance (also if you want to use core filter/function inside getframe) ?
If yes, a link to an exemple will be very appreciated.
no.
You have to implement same function yourself (or copy those code from avs source repo).
__________________
my repositories
Chikuzen is offline   Reply With Quote
Old 5th August 2016, 14:14   #212  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Quote:
Originally Posted by jpsdr View Post
If you want to use in a plugin one (or several) core avisynth filter. Is using env->Invoke (like done in nnedi3) the only way, or is there any other way by any chance (also if you want to use core filter/function inside getframe) ?
If yes, a link to an exemple will be very appreciated.
You might get a better answer if you tell exactly what you want to do (Invoke aint so difficult).

Here filter create function that uses Subtitle on some clips and hands the PClips to the constructor, thereafter used in GetFrame.

Code:
AVSValue __cdecl SCSC::Create(AVSValue &args,int mode,const char *myName, IScriptEnvironment* env) {
    DPRINTF("%sCREATE IN",myName)

    PClip   dclip   = args[0].AsClip();                 // Detection Clip, No Default
    PClip   MotionC = args[1].AsClip();                 // Motion Clip, No Default
    PClip   StartC  = args[2].AsClip();                 // Start Clip, No Default
    PClip   EndC    = args[3].AsClip();                 // End Clip, No Default

    const VideoInfo &Motion_vi  = MotionC->GetVideoInfo();
    const VideoInfo &dclip_vi   = dclip->GetVideoInfo();
    const VideoInfo &Start_vi   = StartC->GetVideoInfo();
    const VideoInfo &End_vi     = EndC->GetVideoInfo();

    double  dPd     = args[4].AsFloat(45.0);
    double  dCor    = args[5].AsFloat(0.55f);

    double  dFact   = args[6].AsFloat(1.5);
    double  dMin    = args[7].AsFloat(2.0);
    int     dMinLen = args[8].AsInt(6);
    double  dCW     = args[9].AsFloat(0.333333f);
    double  dCorHi  = args[10].AsFloat(0.75);

    int     x       = args[11].AsInt(0);
    int     y       = args[12].AsInt(0);
    int     w       = args[13].AsInt(0);
    int     h       = args[14].AsInt(0);
    bool    altscan = args[15].AsBool(false);
    int     CDf     = args[16].AsInt(-1);
    double  CTh     = args[17].AsFloat(15.0f);
    bool    ChromaI = args[18].AsBool(false);
    int     Matrix  = args[19].AsInt(dclip_vi.width > 1100 || dclip_vi.height > 600 ? 3 : 2);
    const char *    Override = args[20].AsString("");
    const char *    Project = args[21].AsString("");

    const int       oFla = args[22].AsInt(9);

    bool    Show         = args[23].AsBool(true);
    bool    Verbose      = args[24].AsBool(true);
    bool    Ver          = args[25].AsBool(true);
    bool    ForceProcess = args[26].AsBool(false);


    #ifdef AVISYNTH_PLUGIN_25
        if(Motion_vi.IsPlanar()) {
            if(Motion_vi.pixel_type!=0xA0000008) {  // YV12
                env->ThrowError("%sMotion clip ColorSpace unsupported in v2.5 dll\n",myName);
            }
        }
        if(dclip_vi.IsPlanar()) {
            if(dclip_vi.pixel_type!=0xA0000008 &&   // YV12
                dclip_vi.pixel_type!=0xE0000000)    // Y8
            {
                env->ThrowError("%sdClip clip ColorSpace unsupported in v2.5 dll\n",myName);
            }
        }
    # endif

    if(Motion_vi.width==0 || Motion_vi.num_frames==0)   env->ThrowError("%sMotion Clip has no video",myName);
    if(dclip_vi.width==0  || dclip_vi.num_frames==0)    env->ThrowError("%sdClip has no video",myName);
    if(Start_vi.width==0  || Start_vi.num_frames==0)    env->ThrowError("%sStart clip has no video",myName);
    if(End_vi.width==0    || End_vi.num_frames==0)      env->ThrowError("%sEnd clip has no video",myName);
    if(!Motion_vi.IsSameColorspace(Start_vi))           env->ThrowError("%sDissimilar Start Colorspace",myName);
    if(Motion_vi.width != Start_vi.width)               env->ThrowError("%sStart clip Dissimilar Width",myName);
    if(Motion_vi.height!= Start_vi.height)              env->ThrowError("%sStart clip Dissimilar Height",myName);
    if(!Motion_vi.IsSameColorspace(End_vi))             env->ThrowError("%sDissimilar End Colorspace",myName);
    if(Motion_vi.width != End_vi.width)                 env->ThrowError("%sEnd clip Dissimilar Width",myName);
    if(Motion_vi.height != End_vi.height)               env->ThrowError("%sEnd clip Dissimilar Height",myName);

    if(mode==0) {
        if(Motion_vi.num_frames != dclip_vi.num_frames)     env->ThrowError("%sdclip & Motion FrameCount Mismatch",myName);
    } else {
        if(Motion_vi.num_frames*3 != dclip_vi.num_frames)   env->ThrowError("%sdClip FrameCount Must be 3x Motion Framecount",myName);
    }

    if(dPd <0.0f || dPd>100.0f)     env->ThrowError("%s0.0 <= dPd <= 100.0(%f)",myName,dPd);
    if(dCor<0.0f || dCor>1.0f)      env->ThrowError("%s0.0 <= dCor <= 1.0(%f)",myName,dCor);

    if(dFact<1.0f)                  env->ThrowError("%sdFact MUST be greater than 1.0(%f)",myName,dFact);
    if(dMin<0.1f)                   env->ThrowError("%sdMin MUST be greater than 0.1(%f)",myName,dMin);
    if(mode !=2) {
        if(dMinLen<=1)              env->ThrowError("%sdMinLen MUST be greater than 1(%d)",myName,dMinLen);
    }
    if(dCW<0.0f || dCW>1.0f)        env->ThrowError("%s0.0 <= dCW <= 1.0(%f)",myName,dCW);
    if(dCorHi<0.0f || dCorHi>1.0f)  env->ThrowError("%s0.0 <= dCorHi <= 1.0(%f)",myName,dCorHi);


    if(CDf< -1  || CDf>255)         env->ThrowError("%s-1 <= CDf <= 255(%d)",myName,CDf);
    if(CTh< 0.0 || CTh>100.0)       env->ThrowError("%s0.0 <= CTh <= 100.0(%f)",myName,CTh);

    if(oFla<0    || oFla>12)        env->ThrowError("%s0 <= oFla <= 12(%d)",myName,oFla);

    if(dclip_vi.pixel_type!=0xA0000008)
        ChromaI=false;                              // Not TRUE YV12, Switch ChromaI OFF
    if(ChromaI && dclip_vi.height&0x03) env->ThrowError("%s ChromaI=True and dClip YV12 height not multiple of 4",myName);

    if(dclip_vi.pixel_type==0xE0000000) {
        dCW=0.0;                                    // Y8 switch OFF ChromaWeight
    }

    if(dCW==0.0) {                                  // Always Luma only, RGB -> Luma_Y)
        CDf=-1;                                     // dont check for color
    }

    if(dclip_vi.IsRGB() && Matrix<0||Matrix>3)      env->ThrowError("%s0 <= Matrix <= 3(%d)",myName,Matrix);

    if(w <= 0) w += dclip_vi.width  - x;
    if(h <= 0) h += dclip_vi.height - y;
    if(altscan && ((h & 0x01) == 0)) --h;   // If altscan then ensure ODD number of lines, last line other field does not count.
    altscan=(altscan && h!=1);

    if(x <  0 || x >=dclip_vi.width)                env->ThrowError("%sInvalid dClip X coord (%d)",myName,x);
    if(y <  0 || y >=dclip_vi.height)               env->ThrowError("%sInvalid dClip Y coord (%d)",myName,y);
    if(w <= 0 || x + w > dclip_vi.width)            env->ThrowError("%sInvalid dClip W coord for X(%d)",myName,w);
    if(h <= 0 || y + h > dclip_vi.height)           env->ThrowError("%sInvalid dClip H coord for Y(%d)",myName,h);

    AVSValue ret;
    if(ForceProcess) {
        PClip pc = new SCSC(
            mode,myName,dMinLen,Motion_vi.num_frames,
            MotionC,dclip,MotionC,MotionC,
            dPd,dCor,dFact,dMin,dCW,dCorHi,
            x,y,w,h,
            altscan,CDf,CTh,ChromaI,Matrix,
            Override,Project,
            oFla,
            false,false,false,env);
        double STim = RT_TimerHP_Lo();
        int n,cnt=Motion_vi.num_frames;
        for(n=0;n<cnt;++n) {
            PVideoFrame src = pc->GetFrame(n,env);
        }
        double Tim = RT_TimerHP_Lo() - STim;
        dprintf("%sForceProcess %.3fsecs (%.3fmins) %.3f FPS",myName,Tim,Tim/60.0,Motion_vi.num_frames/Tim);
        Project = "";
        ret = 0;
    } else {
        if(Show) { // Always exist, no try/catch
            int size = Motion_vi.height / 12;
            int cent = Motion_vi.height / 2;
            const char *names[]={NULL,NULL,"Align","Size","Y","Text_Color"};
            AVSValue  avsv[6]={MotionC,"MOTION",5,size,cent,0xFFFF44};
            MotionC  = env->Invoke("Subtitle", AVSValue(avsv, 6),names).AsClip();
            avsv[0] = StartC;
            avsv[1] = "START OF SCENE";
            avsv[4] = cent-size;
            avsv[5] = 0x44FF44;
            StartC  = env->Invoke("Subtitle", AVSValue(avsv, 6),names).AsClip();
            avsv[0] = EndC;
            avsv[1] = "END OF SCENE";
            avsv[4] = cent+size;
            avsv[5] = 0xFF44FF;
            EndC = env->Invoke("Subtitle", AVSValue(avsv, 6),names).AsClip();
        }
        ret = new SCSC(mode,myName,dMinLen,Motion_vi.num_frames,
            MotionC,dclip,StartC,EndC,
            dPd,dCor,dFact,dMin,dCW,dCorHi,
            x,y,w,h,
            altscan,CDf,CTh,ChromaI,Matrix,
            Override,Project,
            oFla,
            Show,Verbose,Ver,env);
    }
    DPRINTF("%sCREATE OUT",myName)
    return ret;
}
Full source (work in progress):- http://www.mediafire.com/download/9q...0-20160116.zip

EDIT: You would not want to use eg Subtitle in GetFrame itself (with static text) due to heavy constructor overhead (same applies to Scriptclip, but people still use it there despite overhead).

EDIT: The NULL's in names[] requirement for un-named args, was found by trial and error, not seen any docs for that.

EDIT: In above snippet, MotionC, StartC and EndC are all identical size, and size of returned clip, dclip (detection clip)
can be other size (or colorspace), and so dclip cannot be the primary clip given to GenericVideoFilter(_child).
__________________
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; 5th August 2016 at 14:51.
StainlessS is offline   Reply With Quote
Old 5th August 2016, 15:51   #213  |  Link
jpsdr
Registered User
 
Join Date: Oct 2002
Location: France
Posts: 2,637
Quote:
Originally Posted by StainlessS View Post
You might get a better answer if you tell exactly what you want to do (Invoke aint so difficult).
I wanted to try to do something with the resize functions.
My first step would has been to be able to compile and create an external plugin with the actual code, but it uses turn functions (in the getframe), but it's the russian dolls. Try to include turn functions needs to include xxx function, which needs yyy... It has no ends, so the other idea is to "invoke", but i wanted to know if there was something else.
I'll change my way of doing things, and try another approach.
Thanks for the answers.
jpsdr is offline   Reply With Quote
Old 14th August 2016, 12:58   #214  |  Link
ultim
AVS+ Dev
 
ultim's Avatar
 
Join Date: Aug 2013
Posts: 359
Quote:
Originally Posted by jpsdr View Post
I wanted to try to do something with the resize functions.
My first step would has been to be able to compile and create an external plugin with the actual code, but it uses turn functions (in the getframe), but it's the russian dolls. Try to include turn functions needs to include xxx function, which needs yyy... It has no ends, so the other idea is to "invoke", but i wanted to know if there was something else.
I'll change my way of doing things, and try another approach.
Thanks for the answers.
env->Invoke() is your best option. It is THE recommended way, as it guarantees that the core will have knowledge of the filters you construct, including all the benefits like automatic caching and optimally calculated MT modes.
__________________
AviSynth+
ultim is offline   Reply With Quote
Old 16th August 2016, 00:07   #215  |  Link
slavanap
Registered User
 
slavanap's Avatar
 
Join Date: May 2011
Location: Moscow, Russia
Posts: 124
jpsdr, ultim,
I suggest to use this way to call env->Invoke in Avisynth, because it looks more understandable instead arrays of AVSValues.
Here's the code.
Here the usage example with Stack(Horizontal|Vertical).
And this example uses named argument.
I would be glad to read your reviews about my method.

Last edited by slavanap; 27th August 2016 at 03:11. Reason: links updated
slavanap is offline   Reply With Quote
Old 25th August 2016, 07:50   #216  |  Link
ultim
AVS+ Dev
 
ultim's Avatar
 
Join Date: Aug 2013
Posts: 359
Quote:
Originally Posted by slavanap View Post
jpsdr, ultim,
I suggest to use this way to call env->Invoke in Avisynth, because it looks more understandable instead arrays of AVSValues.
Here's the code.
Here the usage example with Stack(Horizontal|Vertical).
And this example uses named argument.
I would be glad to read your reviews about my method.
Nice! I need to look at it more closely to think about whether it always works, but if it does, I'd even consider making that snippet part of the avs+ header, if that is okay with you.
__________________
AviSynth+
ultim is offline   Reply With Quote
Old 25th August 2016, 08:23   #217  |  Link
jpsdr
Registered User
 
Join Date: Oct 2002
Location: France
Posts: 2,637
Quote:
Originally Posted by slavanap View Post
jpsdr, ultim,
I suggest to use this way to call env->Invoke in Avisynth, because it looks more understandable instead arrays of AVSValues.
Maybe it is for you, but unfortunately not for me...
Too much things i don't understand and not used to. Probably again C++ things too much ++ for me.
But thanks for sharing it, maybe ultim will instead be more interested by it (but please, if possible, try to not break VS2010 compatibility header... )
jpsdr is offline   Reply With Quote
Old 27th August 2016, 03:18   #218  |  Link
slavanap
Registered User
 
slavanap's Avatar
 
Join Date: May 2011
Location: Moscow, Russia
Posts: 124
ultim,
It works, at least with my plugin
And you may even not ask about publishing -- just check the license -- it is GPL compatible:
https://github.com/slavanap/ssifSource/


jpsdr,
The code sample uses variadic templates.
http://en.cppreference.com/w/cpp/lan...parameter_pack

Looks like MS added support for it only in VS 2013:
https://msdn.microsoft.com/en-us/library/hh567368.aspx

I jumped from VS 2008 right to 2015, thus I haven't noticed all bottlenecks.
slavanap is offline   Reply With Quote
Old 27th August 2016, 14:18   #219  |  Link
jpsdr
Registered User
 
Join Date: Oct 2002
Location: France
Posts: 2,637
Quote:
Originally Posted by slavanap View Post
jpsdr,
The code sample uses variadic templates.
Ouch... Too much ++ for me...
jpsdr is offline   Reply With Quote
Old 27th August 2016, 19:07   #220  |  Link
slavanap
Registered User
 
slavanap's Avatar
 
Join Date: May 2011
Location: Moscow, Russia
Posts: 124
Quote:
Originally Posted by jpsdr View Post
Ouch... Too much ++ for me...
It may look difficult, but it is completely not so. You may not even know how this template with conjunction of a structure works to use it.

I'll explain this one in details below. Please don't forget that we need compiler that supports C++11 features.

Assume we have this code in our app. Just a structure and a couple of functions. And we want to call this Avisynth function and grab its result in C++.
Code:
filename = "test.png"
image = imagesource(filename, pixel_type = "RGB32")

// In C++ we will use this code:

//IScriptEnvironment* env = ...
std::string filename = "test.png";
PClip image = AvsCall(
        env,    // IScriptEnvironment*
        "imagesource",     // function name
        filename.c_str(),   // first argument
        AvsNamedArg("pixel_type", "RGB32") // second argument (with name specified)
    )
    .AsClip(); // we need a PClip as a result -- not AVSValue

// When you call AvsCall variadic template function that way,
// the template is going to be instantiated according to parameters
// specified and their types. Thus template becomes a function
// instance:

struct AvsNamedArg {
    AVSValue value;
    const char *name;
    AvsNamedArg(const char* name, const AVSValue& value) : name(name), value(value) { }
    operator AVSValue() const { return value; }

    template<typename T> static const char* GetName(const T& v) {
        return nullptr;
    }
};
template<> inline const char* AvsNamedArg::GetName(const AvsNamedArg& v) {
    return v.name;
}

template<>
AVSValue AvsCall(IScriptEnvironment* env, const char* name, const char* a1, const AvsNamedArg& a2) {
    const char* arg_names[2] = { AvsNamedArg::GetName(a1), AvsNamedArg::GetName(a2) };
    AVSValue arg_values[2] = { a1, a2 };
    return env->Invoke(name, AVSValue(arg_values, 2), arg_names);
}

// a1 actual type not `const char*` but `const char* const&` but that does not make any difference here.
// sizeof...(Args) deduced to `2` -- 2 variadic arguments

// Then we may simplify C++ code a little bit by replacing
// AvsNamedArg::GetName with actual return values, not another
// template function call (see AvsNamedArg::GetName function
// implementation). For all types except AvsNamedArg passed
// as its argument we get `nullptr`, for `AvsNamedArg` we get
// its .name field.
template<>
AVSValue AvsCall(IScriptEnvironment* env, const char* name, const char* a1, const AvsNamedArg& a2) {
    const char* arg_names[2] = { nullptr, a2.name };
    AVSValue arg_values[2] = { AVSValue(a1), AVSValue(a2) };
    return env->Invoke(name, AVSValue(arg_values, 2), arg_names);
}

// Now remember, we are calling 

PClip image = AvsCall(env, "imagesource", filename.c_str(), AvsNamedArg("pixel_type", "RGB32")).AsClip();

// Or by steps

AvsNamedArg namedArg("pixel_type", "RGB32");
AVSValue ret = AvsCall(env, "imagesource", filename.c_str(), namedArg);
PClip image = ret.AsClip();

// Look at AvsNamedArg constructor.
// We have: { namedArg.name = "pixel_type"; namedArg.value = AVSValue("RGB32"); }
// Now just follow simplifications:

// 1. Expand the function call
AvsNamedArg namedArg("pixel_type", "RGB32");
    const char* arg_names[2] = { nullptr, namedArg.name };
    AVSValue arg_values[2] = { AVSValue(filename.c_str()), AVSValue(namedArg) };
AVSValue ret = env->Invoke("imagesource", AVSValue(arg_values, 2), arg_names);
PClip image = ret.AsClip();

// 2. substitute namedArg fields with its values. AVSValue(namedArg) == AVSValue(namedArg.value) -- see operator AvsNamedArg::AVSValue().
const char* arg_names[2] = { nullptr, "pixel_type" };
AVSValue arg_values[2] = { AVSValue(filename.c_str()), AVSValue("RGB32") };
AVSValue ret = env->Invoke("imagesource", AVSValue(arg_values, 2), arg_names);
PClip image = ret.AsClip();

// 3. And simplify a little bit further
const char* arg_names[2] = { nullptr, "pixel_type" };
AVSValue arg_values[2] = { filename.c_str(), "RGB32" };
PClip image = env->Invoke("imagesource", AVSValue(arg_values, 2), arg_names).AsClip();

// this is it. We now get standard env->Invoke call.
slavanap is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 23:22.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.