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.

 

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

Reply
 
Thread Tools Search this Thread Display Modes
Old 2nd February 2021, 21:51   #1  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
how to handle external clips in avisynth plugin

I'm making a plugin and it uses an edeint clip to take the deinterlaced frames from. I'd like to know how to handle the case in which no edeint clip is given because of forgetfulness (like the thr parameter is set but no edeint is given) and when is not given because the user wants not to use it and skip the code block (the thr parameter is set to saturation). I'd like also to know if it is possible to set it to a dummy clip that works with getframe and so on and if not, would be possible to set it to default a bob(last) clip? I hope I'm clear.

If you want to look at the code let me know.
Ceppo is offline   Reply With Quote
Old 2nd February 2021, 23:30   #2  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Code:
    env->AddFunction("GamMac"  ,
        "c[LockChan]i[Scale]i[RedMul]f[GrnMul]f[BluMul]f"
        "[Th]f[loTh]f[hiTh]f[LockVal]f[RngLim]i[GamMax]f"
        "[dc]c"
        "[x]i[y]i[w]i[h]i[omin]i[omax]i"
        "[Show]b[Verbosity]i[Coords]b[Dither]b"
        ,Create_GamMac  , 0);

        // ...
Code:
AVSValue __cdecl Create_GamMac(AVSValue args, void* user_data, IScriptEnvironment* env) {
    char *myName="GamMac: ";
    PClip   child    = args[0].AsClip();
    const VideoInfo &vi=child->GetVideoInfo();
    if(!vi.IsRGB())                         env->ThrowError("%sRGB Only",myName);
    if(vi.width==0||vi.num_frames<=0)       env->ThrowError("%sClip has no video",myName);
    int     LockChan = args[1 ].AsInt(1);
    int     Scale    = args[2 ].AsInt(1);
    double  RedMul   = args[3 ].AsFloat(1.0);
    double  GrnMul   = args[4 ].AsFloat(1.0);
    double  BluMul   = args[5 ].AsFloat(1.0);
    float   Th       = (float)args[6 ].AsFloat(0.00);
    double  loTh     = args[7 ].AsFloat(Th);
    double  hiTh     = args[8 ].AsFloat(Th);
    double  LockVal  = args[9 ].AsFloat(128.0);
    int     RngLim   = args[10].AsInt(11);
    double  GamMax   = args[11].AsFloat(10.0);
    PClip   dc       = (args[12].IsClip()) ? args[12].AsClip() : child;

    // ...
Above, we made same as child clip, to avoid separate usage of dc,
you could just as easily set it to NULL and alter behaviour based on that.

Does that solve your problem.


EDIT:
Code:
class GamMac : public GenericVideoFilter {
private:
    PClip           dc;
    const int       LockChan;
    const int       Scale;

    // ...
Code:
GamMac::GamMac(PClip _child,PClip _dc,
            int _LockChan,int _Scale,double _RedMul,double _GrnMul,double _BluMul,
            double _loTh,double _hiTh,double _LockVal,
            int _RngLim,double _GamMax,
            int _xx,int _yy,int _ww,int _hh,int _omin,int _omax,
            bool _Show,int _Verbosity,bool _dither,
            IScriptEnvironment* env) :
            GenericVideoFilter(_child),
            dc(_dc),
            LockChan(_LockChan),Scale(_Scale),RedMul(_RedMul),GrnMul(_GrnMul),BluMul(_BluMul),
            loTh(_loTh),hiTh(_hiTh),LockVal(_LockVal),
            RngLim(_RngLim),GamMax(_GamMax),
            xx(_xx),yy(_yy),ww(_ww),hh(_hh),omin(_omin),omax(_omax),
            Show(_Show),Verbosity(_Verbosity),Dither(_dither) {
    // ...
Sort of similar usage to in GetFrame
Code:
void GamMac::CountDcRGB(int n,IScriptEnvironment* env) {
    // vi and vi2 are same colorspace and number of frames, so can use vi for n and ColorSpace.
    n = (n<0) ? 0 : (n>= vi.num_frames) ? vi.num_frames - 1 : n;
    unsigned int *R=cnt[0],*G=cnt[1],*B=cnt[2];
    memset(R,0,sizeof(R[0])*256);   memset(G,0,sizeof(G[0])*256);   memset(B,0,sizeof(B[0])*256);
    PVideoFrame src =   dc->GetFrame(n, env);
    int height      =   src->GetHeight();
    int pitch       =   src->GetPitch();
    const int step  =   (vi.IsRGB32()) ? 4 : 3;
    // ...
And use something like this if necessary in GetFrame.
Code:
    const VideoInfo &vi2=dc->GetVideoInfo();
__________________
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; 2nd February 2021 at 23:50.
StainlessS is offline   Reply With Quote
Old 3rd February 2021, 11:04   #3  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
Thank you for your help. Just wondering if it was still possible to set a default bob/QTGMC clip.
Ceppo is offline   Reply With Quote
Old 3rd February 2021, 16:39   #4  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
If I understand you correctly, then maybe do something like
Code:
// In Create_GamMac()
    PClip   dc;
    if(args[12].IsClip()) {
        dc = args[12].AsClip();
    } else {
         // do invoke bob/QTGMC on child, or whatever in here, assign to dc
    }
EDIT: Defo need try/catch on invoke.
I don't like using non builtin filters in CPP plugin, also,
QTGMC() has [I think] a few different versions, with different args probably, have to use Named Invoke arguments
and only use args common in all versions of QTGMC().

Probably easier to demand user supply bobbed dc, and complain if not supplied.
Can still specify as optional, but detect not supplied in the Create_GamMac thing, and ThrowError.
Also gives user control over bobber used.
EDIT:
Although you could also use some bobber Eval() string instead of dc, again with try/catch and
so user has control of bob, but that aint much different to the user having to provide a pre-bobbed dc clip.
__________________
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; 3rd February 2021 at 16:58.
StainlessS is offline   Reply With Quote
Old 3rd February 2021, 19:57   #5  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
I see thank you.
Ceppo is offline   Reply With Quote
Old 3rd February 2021, 20:22   #6  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Maybe also of use, demos optional named args for invoke, from Uglarm() plug.
Code:
    if(ShowMode >= 2) {
        DPRINTF("ShowMode=%d",ShowMode)
        ret = new Uglarm(ret,Pat_X,Pat_Y,Pat_W,Pat_H,SAR,BlurPower,Msk,xmod,ymod,hasChroma,ShowMode,env);
        DPRINTF("Returned from Uglarm constructor")
        // Blank Border
        if(Blank) {
            DPRINTF("Showing BLANK LetterBox")
            // Letterbox (clip, int top, int bottom, [int left], [int right], int "color")
            // un-named args NULL names
            AVSValue    LetterBox_Args[6]   = {  ret,   ClipY, vi.height-ClipY-ClipH,  ClipX, vi.width-ClipX-ClipW, 0x000000 };
            const char* LetterBox_Names[6]  = {  NULL,   NULL,                  NULL,   NULL,              NULL,     "color" };
            try {
                DPRINTF("Calling Invoke LetterBox (Blank)")
                ret = env->Invoke("LetterBox", AVSValue(LetterBox_Args,6),LetterBox_Names).AsClip();
                DPRINTF("Invoke LetterBox Succeeds (Blank)")
            } catch (IScriptEnvironment::NotFound) {
                DPRINTF("Invoke LetterBox Fails (Blank)")
                env->ThrowError("%sWhoa! Could not Invoke LetterBox! (Blank)",myName);
            }
            DPRINTF("Done Uglarm Blank")
        }
Using only optional named arg "color" for Letterbox().
DPRINTF stuff just some of my debug code.
EDIT: When I wrote above, I could find little info on named args, in particular the NULL (un-named) ones prior to using named arg,
I tried using "", which failed, and found NULL is required.

EDIT:

Here code of the DPRINTF() thing, is handy for debugging which is easily switched off in final.

Part of my compilier.h
Code:
#ifndef __COMPILER_H__

    #define BUG

    #define __COMPILER_H__


    #ifdef BUG
        #if _MSC_VER >= 1500                                    // VS 2008+
            // Call as eg DPRINTF("Forty Two = %d",42)          // No Semi colon
            // C99 Compiler (eg VS2008)
            #define DPRINTF(fmt, ...)   dprintf(fmt, ##__VA_ARGS__);       // No Semi colon needed
        #else
            // OLD C89 Compiler: (eg VS6)
            // Call as eg DPRINTF(("Forty Two = %d",42))        // Enclosed in double parentethis, No Semi colon
            #define   DPRINTF(x)      dprintf x;
        #endif
    #else
        #if _MSC_VER >= 1500                                    // VS 2008+
            // C99 Compiler (eg VS2008)
            #define DPRINTF(fmt,...)                            /* fmt */
        #else
            // OLD C89 Compiler: (eg VS6)
            #define DPRINTF(x)                                  /* x */
        #endif
    #endif

    extern int __cdecl dprintf(char* fmt, ...);

#endif // __COMPILER_H__
can set #define BUG inside compiler.h or remove it and set before including compiler.h,
if BUG defined, will print debugging stuff else not.

and then somewhere else in source [View debug in DebugView, below outputs eg "Uglarm: Some message" ]
Code:
#ifdef BUG
    int __cdecl dprintf(char* fmt, ...) {
        char printString[2048]="Uglarm: ";                              // Must be nul Termed, eg "Test: " or ""
        char *p=printString;
        for(;*p++;);
        --p;                                                            // @ null term
        va_list argp;
        va_start(argp, fmt);
        vsprintf(p, fmt, argp);
        va_end(argp);
        for(;*p++;);
        --p;                                                            // @ null term
        if(printString == p || p[-1] != '\n') {
            p[0]='\n';                                                  // append n/l if not there already
            p[1]='\0';
        }
        OutputDebugString(printString);
        return int(p-printString);                                      // strlen printString
    }
#endif // BUG
Can use like
Code:
    DPRINTF("Forty two = %d",42)    // No ending semi-colon, "Uglarm: Forty two = 42"  # Use DebugView to view output.
DebugView from SysInternals [ie M$]:- https://docs.microsoft.com/en-us/sys...oads/debugview
__________________
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; 4th February 2021 at 22:21.
StainlessS is offline   Reply With Quote
Old 5th February 2021, 11:46   #7  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
Quote:
if(ShowMode >= 2) {
DPRINTF("ShowMode=%d",ShowMode)
ret = new Uglarm(ret,Pat_X,Pat_Y,Pat_W,Pat_H,SAR,BlurPower,Msk,xmod,ymod,hasChroma,ShowMode,env);
DPRINTF("Returned from Uglarm constructor")
// Blank Border
if(Blank) {
DPRINTF("Showing BLANK LetterBox")
// Letterbox (clip, int top, int bottom, [int left], [int right], int "color")
// un-named args NULL names
AVSValue LetterBox_Args[6] = { ret, ClipY, vi.height-ClipY-ClipH, ClipX, vi.width-ClipX-ClipW, 0x000000 };
const char* LetterBox_Names[6] = { NULL, NULL, NULL, NULL, NULL, "color" };
try {
DPRINTF("Calling Invoke LetterBox (Blank)")
ret = env->Invoke("LetterBox", AVSValue(LetterBox_Args,6),LetterBox_Names).AsClip();
DPRINTF("Invoke LetterBox Succeeds (Blank)")
} catch (IScriptEnvironment::NotFound) {
DPRINTF("Invoke LetterBox Fails (Blank)")
env->ThrowError("%sWhoa! Could not Invoke LetterBox! (Blank)",myName);
}
DPRINTF("Done Uglarm Blank")
}
Thanks, is good to know. I will keep the link saved for future reference. About DebugView, I started C++ after Christmas so at the moment is a bit hard for me, but I will keep it in mind.
Ceppo is offline   Reply With Quote
Old 5th February 2021, 16:16   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
OK,
You can just use instead eg,
Code:
OutputDebugString("Hello");  // Single entire string ONLY, needs include stdio.h [I think]
DebugView allows you to see your debug messages, its maybe harder Not-To-Use it.
Any kind of debugging makes life easier, especially if learning, you can see where it went wrong, or where it got to before it went wrong.

I use debugview even with avs script, RT_Stats RT_DebugF() for output.

EDIT: DPRINTF() [or dprintf() which dont switch off when you dont define BUG], uses the same style as standard C printf()
or sprintf().
__________________
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 February 2021 at 16:29.
StainlessS is offline   Reply With Quote
Old 7th February 2021, 14:04   #9  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 339
I see, thank you.
Ceppo 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 12:31.


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