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 Development

Closed Thread
 
Thread Tools Search this Thread Display Modes
Old 29th December 2018, 23:53   #4361  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
Is there any in-depth documentation for env->AddFunction anywhere? I seem to remember there are some rules on using + to allow a variable-sized list of parameters but I can't remember what they are, and no matter what I try I either get an "Invalid parameters" error or my extra parameter gets assigned to the first unspecified named parameter.
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline  
Old 30th December 2018, 00:25   #4362  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post what you are trying.
I had one helluva time trying to get Prune() to work (got coerced into retrying and it eventually all worked ok, still no idea what it was I was doing wrong, starting again from scratch and everything worked perfectly).

Pretty much everything known is below [NOTE, we used i*, ie zero or more ints, if using i+ then requires at least 1 arg in array else error]
Code:
// The following function is the function that actually registers the filter in AviSynth
// It is called automatically, when the plugin is loaded to see which functions this filter contains.
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
    env->AddFunction("FrameSel", "ci*[SCmd]s[Cmd]s[Show]b[Ver]b[Reject]b[Ordered]b[Debug]b[Extract]i", Create_FrameSel, 0);

    // The AddFunction has the following paramters:
    // AddFunction(Filtername , Arguments, Function to call,0);

    // Arguments is a string that defines the types and optional nicknames of the arguments for you filter.
    // c - Video Clip
    // i - Integer number
    // f - Float number
    // s - String
    // b - boolean
    // . - Any type (dot)
    //      Array Specifiers
    // i* - Integer Array, zero or more
    // i+ - Integer Array, one or more
    // .* - Any type Array, zero or more
    // .+ - Any type Array, one or more
    //      Etc

    return "`FrameSel' FrameSel plugin";
    // A freeform name of the plugin.
}
Some stuff ripped from various FRAMESEL routines
Code:
// from creator function
AVSValue    Frames = args[1];                              // Frames, Array of frame numbers as filter arguments


// from Frames, CMD, SCMd parser
bool ProcFrames = (Frames.ArraySize()!=0);

if(ProcFrames) {
    int nFrms = Frames.ArraySize();
    if(Pass==0) {
        OutFrameCount += nFrms;
    } else {
        int i;
        for(i=0;i<nFrms; ++i) {
            int frm=Frames[i].AsInt();
            if(frm < 0 || frm >= NumFrames) {
                if(fp)          {fclose(fp);    fp=NULL;}
                if(FrameDat)    {delete[] FrameDat; FrameDat = NULL;}
                env->ThrowError("%s*ERROR* filter arg frames[%d]=%d, out of clip.\n",myName,i+1,frm);
            }
            if(RunOff < OutFrameCount) {
                FrameDat[RunOff]=frm;
            }
            ++RunOff;
        }
    }
} // End, ProcFrames
EDIT:
Quote:
I seem to remember there are some rules on using +
Yep, you need use eg i* rather than i+, probably.
EDIT: Further args immediately following eg 'i*' must NOT be of type int (will be swallowed by the i* Array, I think,
unless using named arg, eg nextInt=NextInt where "i*[nextint]i").
If using ".*[nextint]i" (zero or more variables of any type), then MUST (I think) use named arg ie nextInt=NextInt.
I have to use eg Append=True/False in eg RT_WriteFile as all args before the Optional Append Arg are of variable type and number.

EDIT:
Code:
 env->AddFunction("RT_WriteFile",				"ss.*[Append]b",RT_WriteFile, 0);
Code:
AVSValue __cdecl RT_WriteFile(AVSValue args, void* user_data, IScriptEnvironment* env) {
    char *myName="RT_WriteFile: ";
    const char *ofn     = args[0].AsString();
    const char *fmt     = args[1].AsString();
    AVSValue datn       = args[2];                          // data
    const bool append   = args[3].AsBool(false);

    int arrsz           = datn.ArraySize();

    enum {
        CHICKEN=64
    };

    // what size buffer we need ?
    int i,mem=int(strlen(fmt) + 1 + CHICKEN);
    for(i=0;i<arrsz;++i) {
        if(datn[i].IsString()) {
            const char *st=datn[i].AsString();
            mem += int(strlen(st) + 1 + CHICKEN);
        } else {
            mem += 8 + CHICKEN;     // no particular reason why so big, just chicken factor.
        }
    }

    char *pbuf = new char[(mem+1)*2];
    if(pbuf==NULL)
        env->ThrowError("%sCannot allocate memory",myName);

    char *ptem=pbuf+(mem+1);            // temp buffer

    const unsigned char* r= (const unsigned char*)fmt;
    char *p=pbuf;
    int  c,ix=0;
    int t=0;

    // Parse text and insert variables
    while(c=*r) {
        if(c=='%') {
            ++r;
            if(*r=='\0') {
                *p++ ='%';
            } else if(*r=='%') {
                *p++=*r++;              // replace escaped double % with single
            } else {
                if(ix>=arrsz) {
                    delete [] pbuf;
                    env->ThrowError("%sExpecting data arg (%d)",myName,ix+1);
                }
                char *tp=ptem;
                *tp++='%';
                if(*r=='-' || *r=='+' || *r=='0' || *r==' ' || *r=='#')     // flags
                    *tp++=*r++;
                if(*r=='*') {                                       // int holds length
                    t=datn[ix].IsBool()         ?1: \
                            datn[ix].IsString() ?2: \
                            datn[ix].IsInt()        ?3: \
                            datn[ix].IsFloat()  ?4: \
                            0;
                    if(t!=3)    {
                        delete [] pbuf;
                        env->ThrowError("%sUnsupported data type, Expecting Width as Int (%d)",myName,ix+1);
                    }
                    tp+=sprintf(tp,"%d",datn[ix].AsInt());
                    ++r;                                            // skip '*'
                    ++ix;                                           // next data
                } else {
                    while(*r>='0' && *r<='9') {
                        *tp++ = *r++;
                    }
                }
                if(*r=='.') {
                    *tp++ =  *r++;                                      // precision prefix
                    if(*r=='*') {                                       // int holds length
                        t=datn[ix].IsBool()         ?1: \
                                datn[ix].IsString() ?2: \
                                datn[ix].IsInt()        ?3: \
                                datn[ix].IsFloat()  ?4: \
                                0;
                        if(t!=3) {
                            delete [] pbuf;
                            env->ThrowError("%sUnsupported data type, Expecting Precision as Int (%d)",myName,ix+1);
                        }
                        tp+=sprintf(tp,"%d",datn[ix].AsInt());
                        ++r;                                            // skip '*'
                        ++ix;                                           // next data
                    } else {
                        while(*r>='0' && *r<='9') {
                            *tp++ = *r++;
                        }
                    }
                }
                t=datn[ix].IsBool()         ?1: \
                        datn[ix].IsString() ?2: \
                        datn[ix].IsInt()        ?3: \
                        datn[ix].IsFloat()  ?4: \
                        0;
                // type
                if( (*r=='c' ) || (*r=='C' ) ||                                         // char as int
                    (*r=='d' || *r=='i') ||                                             // int
                    (*r=='o' || *r=='u' || *r=='x' || *r=='X'))  {                      // unsigned int
                    if(t!=3)    {
                        int tmpc=*r;
                        delete [] pbuf;
                        env->ThrowError("%sType='%c', Expecting Int data (%d)",myName,tmpc,ix+1);
                    }
                    *tp++=*r++;
                    *tp='\0';
                    p+=sprintf(p,ptem,datn[ix].AsInt());
                    ++ix;                                                               // next data
                } else if(*r=='e' || *r=='E' || *r=='f' || *r=='g' || *r=='G') {        // double
                    if(t!=4&&t!=3)  {
                        int tmpc=*r;
                        delete [] pbuf;
                        env->ThrowError("%sType='%c', Expecting Float (%d)",myName,tmpc,ix+1);
                    }
                    *tp++=*r++;
                    *tp='\0';
                    p+=sprintf(p,ptem,datn[ix].AsFloat());
                    ++ix;                                                               // next data
                } else if((*r=='s')||(*r=='S')) {                                                   // string
                    if(t!=2&&t!=1)  {
                        delete [] pbuf;
                        env->ThrowError("%sType='s', Expecting String (%d)",myName,ix+1);
                    }
                    *tp++=*r++;
                    *tp='\0';
                    if(t==1) {  // Bool
                        p+=sprintf(p,ptem,datn[ix].AsBool()?"True":"False");
                    } else {    // String
                        p+=sprintf(p,ptem,datn[ix].AsString());
                    }
                    ++ix;                                                               // next data
                } else {
                    int tmpc=*r;
                    delete [] pbuf;
                    env->ThrowError("%sUnknown format type '%c' (%d)",myName,tmpc,ix+1);
                }
            }
        } else if(c == '\\') {
            ++r;
            c=*r;
            // abfnrtv
            switch (c) {
            case '\0' : *p++='\\';              break;      // copy single backslash at end of string
            case '\\' : *p++=*r++;              break;      // replace double backslash with single backslash
            case 'n' :  ++r;        *p++='\n';  break;
            case 'r' :  ++r;        *p++='\r';  break;
            case 't' :  ++r;        *p++='\t';  break;
            case 'v' :  ++r;        *p++='\v';  break;
            case 'f' :  ++r;        *p++='\f';  break;
            case 'b' :  ++r;        *p++='\b';  break;
            case 'a' :  ++r;        *p++='\a';  break;
            default :   *p++='\\';  *p++=*r++;  break;      // anything else we copy backslash and whatever follows
            }
        } else {
            *p++=*r++;
        }
    }
    *p=0;                                           // nul term

    if(ix<arrsz) {
        delete [] pbuf;
        env->ThrowError("%sUnexpected data arg (%d)",myName,ix+1);
    }

    char *omode=(append)?"a+t":"wt";
    FILE * fp;
    // we use write in text mode, let C insert '\r'.
    if((fp=fopen(ofn, omode ))==NULL) {                     // Cannot output file
        delete [] pbuf;
        return -1;
    }
    int lines = 0;
    char *s,*is;
    s=is=pbuf;;
    do {
        c=*s;
        if(c=='\n' || c=='\r' || c == '\0') {
            if(is<s) {
                if(fwrite(is,s-is,1,fp)!=1) {
                    delete [] pbuf;
                    fclose(fp);
                    return -1;                                      // write file error
                }
            }
            if(c=='\n') {
                ++s;
                if(*s=='\r')
                    ++s;
            } else if(c=='\r') {
                ++s;
                if(*s=='\n')
                    ++s;
            }
            if(is<s) {
                if (fputc('\n',fp)==EOF) {
                    delete [] pbuf;
                    fclose(fp);
                    return -1;                                          // write file error
                }
                ++lines;
            }
            is=s;
        } else {
            ++s;
        }
    } while (*is);                                                  // !!! Exit when 1st char in string is end
    delete [] pbuf;
    fclose(fp);
    return lines;
}
__________________
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; 30th December 2018 at 02:20.
StainlessS is offline  
Old 30th December 2018, 22:44   #4363  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
I think I figured it out. f* has to go before any named parameters, otherwise if you try to include the array after the use of a named parameter, it tries to assign those numbers to other, unused named parameters. Or something like that.
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline  
Old 31st December 2018, 13:13   #4364  |  Link
gaak
Registered User
 
Join Date: Apr 2016
Posts: 27
I'm looking for a 64 bit version of tritical's TBilateral. Is there a thread for this? Or to make a request for one?
gaak is offline  
Old 31st December 2018, 13:28   #4365  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
The source code for TBilateral includes inline assembly which isn't supported for x64 (in Visual Studio, anyway), so you might be out of luck unless someone wants to rewrite it.
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline  
Old 31st December 2018, 13:28   #4366  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by davidhorman View Post
I think I figured it out. f* has to go before any named parameters, otherwise if you try to include the array after the use of a named parameter, it tries to assign those numbers to other, unused named parameters. Or something like that.
Just as with avs script Functions, optional named args follow after compulsory un-named args[EDIT: un-named in plugin, obviously cannot have un-named args in script funcs], and once you have a single optional arg, then all following ones must also be optional. (otherwise weird things could happen in plugin, script function would complain about it, I think)

EDIT: David, me just got back from shop (Lidl) and trying out the Tio Nico sherry (for my damn cough), its quite lovely and unexpectedly flavoured with raisins and treacle, very dark flavour, never tasted a sherry like it I think. Less than six quid, and easily worth double that. [EDIT: In Waitrose, it is double that]
__________________
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 January 2019 at 14:34.
StainlessS is offline  
Old 1st January 2019, 02:37   #4367  |  Link
Groucho2004
 
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
Quote:
Originally Posted by gaak View Post
I'm looking for a 64 bit version of tritical's TBilateral.
Added to my plugin collection
__________________
Groucho's Avisynth Stuff
Groucho2004 is offline  
Old 2nd January 2019, 01:06   #4368  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
Just curious, but what is it about info() that seems to make it really slow? Showframenumber seems similarly slow, but subtitle isn't. Is that because subtitle renders the text once and only has to composite it onto each frame? Is text rendering really that slow?

Info's speed also seems to depend greatly on video size. Is it possibly missing some optimisations to do with compositing extent?
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline  
Old 2nd January 2019, 02:20   #4369  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by davidhorman View Post
what is it about info() that seems to make it really slow? Showframenumber seems similarly slow, but subtitle isn't. Is that because subtitle renders the text once and only has to composite it onto each frame? Is text rendering really that slow?

Info's speed also seems to depend greatly on video size. Is it possibly missing some optimisations to do with compositing extent?
Subtitle fixed text, requires prepping one time only (prior to frame serving, ie in constructor), ShowFrameNumber() or Info() (frame number and time) require prepping at each GetFrame [EDIT: Calling Subtitle Constructor in each and every frame, with big overhead].
Prepp'ing, calls some system function (probably via ApplyMessage) to find size of Subtitle for font etc, (together with eg kerning of each character), and that part is slow. Also, depending upon size of subtitle string, and size of clip, so subtitle may also have to be resized to fit clip (for eg alert error box).

For any kind of plugin metrics output, Subtitle is a slow option and best avoided, see Info.h, or perhaps even DDigit, although neither of them will work in non 8 bit colorspaces.

EDIT: Current Info.h was refactored by IanB most recently about May 2013, (may require a couple of simple warnings fixes for x64 compile).
Info.h available in ClipClop source[with any required x64 warning fixed], if you cannot find it elsewhere. [pre IanB refactored versions have several bugs]

EDIT: More bout it here:- https://forum.doom9.org/showthread.php?t=175443

Info.h and DDigit are lots faster than Subtitle [Fixed monospace font, 10x20 pixels, DDigit also uses Info.h font].
EDIT: IanB refactored Info.h is both font and code, DDigit uses Info.h font only[renamed], the code part being removed.
__________________
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; 6th January 2019 at 04:29.
StainlessS is offline  
Old 5th January 2019, 03:04   #4370  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
Another development question:

Is setting the following:

Code:
vi.audio_samples_per_second
vi.nchannels
vi.sample_type
vi.num_audio_samples
sufficient and complete for setting a clip's audio properties?
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline  
Old 5th January 2019, 03:15   #4371  |  Link
Groucho2004
 
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
Quote:
Originally Posted by davidhorman View Post
Another development question:

Is setting the following:

Code:
vi.audio_samples_per_second
vi.nchannels
vi.sample_type
vi.num_audio_samples
sufficient and complete for setting a clip's audio properties?
Yes. I also use these in AVSMeter.
__________________
Groucho's Avisynth Stuff
Groucho2004 is offline  
Old 5th January 2019, 03:17   #4372  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
Thanks Groucho.
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline  
Old 5th January 2019, 03:29   #4373  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,915
Better than nchannels is maskchannels to define a audio clip.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline  
Old 5th January 2019, 04:21   #4374  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
From Avisynth.h [version 6]
Code:
  int audio_samples_per_second;   // 0 means no audio
  int sample_type;                // as of 2.5
  __int64 num_audio_samples;      // changed as of 2.5
  int nchannels;                  // as of 2.5
For some things, is handy to have access to v2.58 avs header (AVISYNTH HEADER = 3) for the BAKED CODE rather than from function call.
(The v2.60 FINAL Compressed Help [*.chm] file available from my MediaFire Account DATA Folder, has both Avisynth v2.60 final and v2.58 baked code
headers available from the HTML table of files).


EDIT: From BAKED CODE in V2.58 header (Source Not available in Version 6 header)
Code:
  // useful functions of the above
  bool HasVideo() const { return (width!=0); }
  bool HasAudio() const { return (audio_samples_per_second!=0); }

EDIT:
Internal functions, Global Options:- http://avisynth.nl/index.php/Interna...Global_Options
Quote:
OPT_dwChannelMask

global OPT_dwChannelMask(int v) v2.60
This option enables you to set ChannelMask. It overrides WAVEFORMATEXTENSIBLE.dwChannelMask[[2] which is set according to this table

0x00004, // 1 -- -- Cf
0x00003, // 2 Lf Rf
0x00007, // 3 Lf Rf Cf
0x00033, // 4 Lf Rf -- -- Lr Rr
0x00037, // 5 Lf Rf Cf -- Lr Rr
0x0003F, // 5.1 Lf Rf Cf Sw Lr Rr
0x0013F, // 6.1 Lf Rf Cf Sw Lr Rr -- -- Cr
0x0063F, // 7.1 Lf Rf Cf Sw Lr Rr -- -- -- Ls Rs
__________________
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 January 2019 at 09:39.
StainlessS is offline  
Old 5th January 2019, 10:59   #4375  |  Link
tebasuna51
Moderator
 
tebasuna51's Avatar
 
Join Date: Feb 2005
Location: Spain
Posts: 6,915
Quote:
Originally Posted by StainlessS View Post
global OPT_dwChannelMask(int v) v2.60
Is a usseless option.

Who know the ChannelMask of a audio are the decoders, do you know any decoder (ffms2.dll, LSMASHSource.dll, NicAudio.dll, ...) than set ChannelMask to the appropiate value?

There are any audio encoder/player, than accept avs input, than use that global variable if defined?

Also, if there are two, or more, audios processed at same time, how we can distinguise both?

The ChannelMask must be a property of each audio clip.
__________________
BeHappy, AviSynth audio transcoder.
tebasuna51 is offline  
Old 5th January 2019, 11:30   #4376  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
OPT_AllowFloatAudio
OPT_UseWaveExtensible
OPT_dwChannelMask

Are optionally set to signal info to eg MPC-HC and VDub2. [Not sure if VD2 supports FloatAudio, old VDub did not, but MPC-HC does]

Quote:
Is a usseless option.
Makes one wonder why they were implemented then.

Quote:
Also, if there are two, or more, audios processed at same time, how we can distinguise both?
Dont think AVI (and therefore AVS) generally support more than 1 audio stream, so the problem does not often arise.
[VDub does have some code connected to multiple audio streams, but I aint ever seen more than 1 used, also dont know if fully implemented in VDub].
__________________
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 January 2019 at 12:05.
StainlessS is offline  
Old 5th January 2019, 13:12   #4377  |  Link
Groucho2004
 
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
Quote:
Originally Posted by davidhorman View Post
Another development question:

Is setting the following:

Code:
vi.audio_samples_per_second
vi.nchannels
vi.sample_type
vi.num_audio_samples
sufficient and complete for setting a clip's audio properties?
I just noticed that you wrote "setting a clip's audio properties" (as opposed to getting). The answer is still yes. "KillAudio()" for example sets all 4 to 0, effectively removing the audio from a clip.
__________________
Groucho's Avisynth Stuff
Groucho2004 is offline  
Old 5th January 2019, 13:34   #4378  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,904
Quote:
Don't think AVI (and therefore AVS) generally support more than 1 audio stream, so the problem does not often arise.
Yep, you're right, Avisynth always outputs a single audio stream of x channels, which is why whenever I have two languages (like CH.1-2 Stereo Full Mix German - CH.3-4 Stereo Full Mix English) I index them both, then use MergeChannels to make a single audio stream with 4 channels and then I specify how to divide them and encode them separately to the encoder.
FranceBB is offline  
Old 5th January 2019, 13:54   #4379  |  Link
wonkey_monkey
Formerly davidh*****
 
wonkey_monkey's Avatar
 
Join Date: Jan 2004
Posts: 2,496
Before I go ahead and do this, can anyone raise any objections to the idea of using an audio channel to pass metadata? My filter passes data through the video frame, but it also needs to send a few bytes of metadata with it, so my plan is to override GetAudio and just paste those bytes into the buffer. The other filter in the partnership will then call GetAudio to get the metadata.

Good idea? Bad idea?
__________________
My AviSynth filters / I'm the Doctor
wonkey_monkey is offline  
Old 5th January 2019, 14:20   #4380  |  Link
DJATOM
Registered User
 
DJATOM's Avatar
 
Join Date: Sep 2010
Location: Ukraine, Bohuslav
Posts: 377
Indeed it's a bad practice. In Vapoursynth we can pass external metadata with frame properties, but avisynth lacks that functionality. As workaround you probably can add external metadata as hints, like it was implemented in the TIVTC filters.
__________________
Me on GitHub
PC Specs: Ryzen 5950X, 64 GB RAM, RTX 2070
DJATOM is offline  
Closed Thread

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 00:51.


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