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. |
29th December 2018, 23:53 | #4361 | Link |
Formerly davidh*****
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.
|
30th December 2018, 00:25 | #4362 | Link | |
HeartlessS Usurer
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. } 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 Quote:
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. |
|
30th December 2018, 22:44 | #4363 | Link |
Formerly davidh*****
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.
|
31st December 2018, 13:28 | #4366 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
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. |
|
1st January 2019, 02:37 | #4367 | Link |
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
|
Added to my plugin collection
__________________
Groucho's Avisynth Stuff |
2nd January 2019, 01:06 | #4368 | Link |
Formerly davidh*****
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? |
2nd January 2019, 02:20 | #4369 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
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. |
|
5th January 2019, 03:15 | #4371 | Link |
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
|
Yes. I also use these in AVSMeter.
__________________
Groucho's Avisynth Stuff |
5th January 2019, 04:21 | #4374 | Link | |
HeartlessS Usurer
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 (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:
__________________
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. |
|
5th January 2019, 10:59 | #4375 | Link |
Moderator
Join Date: Feb 2005
Location: Spain
Posts: 6,915
|
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. |
5th January 2019, 11:30 | #4376 | Link | ||
HeartlessS Usurer
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:
Quote:
[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. |
||
5th January 2019, 13:12 | #4377 | Link |
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
|
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 |
5th January 2019, 13:34 | #4378 | Link | |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 2,902
|
Quote:
|
|
5th January 2019, 13:54 | #4379 | Link |
Formerly davidh*****
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? |
5th January 2019, 14:20 | #4380 | Link |
Registered User
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.
|
Thread Tools | Search this Thread |
Display Modes | |
|
|