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

Reply
 
Thread Tools Search this Thread Display Modes
Old 22nd June 2013, 21:34   #1  |  Link
pbristow
Registered User
 
pbristow's Avatar
 
Join Date: Jun 2009
Location: UK
Posts: 262
Setting filenames and opening files

Hi all, I have a few questions for anyone who is familiar with the internals of AVIsynth. Not urgent. Consider this a moment of light relief from your intensive hacking and modding duties.

Q1) If I write a script such as:
Code:
Filename = "text" + ".avi"
AVIsource(Filename)
...and invoke it via VirtualDub, at what point does the value "text.avi" get assigned to the variable Filename? Is it during the instantiation of avisynth, when plugins etc. are loaded? Or is it when the controlling application (VDub or whatever) asks for its first frame to be served, and AVIsource is called for the first time, realises it needs a filename, and triggers the evaluation of the preceding line?


Q2) What I'm working around to is the following idea: Suppose I (or someone else) wrote a function or a plug-in that prompts the user for a filename/path (via a standard Windows-style file selector) and then returns that filename/path, and used it as follows:

Code:
Filename = SelectFile()
AVIsource(Filename)
When would the user see the filename prompt? Would it pop up as soon as the avisynth script was loaded, or only once the calling app demanded the first frame of video (e.g. when they pressed "play" on a player)?


Q3) Has anyone ever written such a file-selector plug-in, or thought of adding such a function to Avisynth itself?


Cheers.
pbristow is offline   Reply With Quote
Old 22nd June 2013, 21:53   #2  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
The assignment takes place during script loading, which occurs when the controlling application first opens the script file and before any frames are requested.

So if you had a plugin that prompted for an input file, the prompt would appear on script loading (so-called 'compile time').

For an example of such a plugin (albeit for the output file rather than input file), see SoundOut().
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 22nd June 2013, 23:11   #3  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,905
Such a plugin would need to be implemented as a compile time plugin (as Gavino says) and would be processed in
script order and results available to other following compile time functions (like string concatenation, in script order)
and also standard filter functions (whose constructors are also called in script order).
__________________
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 ???
StainlessS is online now   Reply With Quote
Old 23rd June 2013, 14:22   #4  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 48
I really like this idea. It should be supported out of the box.

As i liked it and it sounded like an hour of work, i started implementing.
It really was easy, but unfortunately i still struggle with the win32 wchar and this stuff.. so in the end it took nearly 3,5 hours ;-)

First you need to install microsoft visual c++ redistributeable version 2010, i believe the 32 bit one. Try the x64 one if this fails.
http://www.microsoft.com/de-at/download/confirmation.aspx?id=5555

In attachment, you find the source code and a built version in the /release directory.

Place the dll in the avisynth plugins folder and use it this way:

Code:
fileselectionpopup()
directshowsource(SELECTEDFILE)
subtitle (SELECTEDFILE)
This is just an example code, but pretty functional. I will not continue any work on this, but anyone who likes can use this as a starting point.
Attached Files
File Type: zip AVS_FilenameSelector.zip (35.9 KB, 26 views)

Last edited by jordanh; 27th June 2013 at 23:44. Reason: private link deleted
jordanh is offline   Reply With Quote
Old 23rd June 2013, 16:19   #5  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
Originally Posted by jordanh View Post
... use it this way:
Code:
fileselectionpopup()
directshowsource(SELECTEDFILE)
subtitle (SELECTEDFILE)
Why not just have the function return a string, as pbristow suggested, rather than setting a (hard-coded?) variable SELECTEDFILE?
Code:
filename = fileselectionpopup()
directshowsource(filename)

# also allowing simply:
directshowsource(fileselectionpopup())
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 23rd June 2013, 19:07   #6  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 48
Quote:
Originally Posted by Gavino View Post
Why not just have the function return a string, as pbristow suggested, rather than setting a (hard-coded?) variable SELECTEDFILE?
Code:
filename = fileselectionpopup()
directshowsource(filename)

# also allowing simply:
directshowsource(fileselectionpopup())

You are welcome to patch it ;-) (you just need visual studio 2010 c++ express for it, its free. I think its really not more than retruning the "filename" string instead of hardcoded "true" from the fileselectionpopup function...

Other features that may be interesting for this plugin would be to introduce parameters for fileselectionpopup() like
fileselectionpopup(extensions = ".mxf,.mpg...",startfolder = "c:\")

EDIT: acutally, i like setting stuff into hardcoded variable names. This way, it is just more obvious what is going on when you look over a script. It is a kind of standardisation.
The negative sides of hardcoded variable names is clear: first there is the documentation issue, second it can be overwritten. It would be better to use more complex variablenames for this kind of integration.

Last edited by jordanh; 23rd June 2013 at 19:11.
jordanh is offline   Reply With Quote
Old 23rd June 2013, 19:55   #7  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,905
Here how to return strings:-

Code:
    char * strlit="AnyOldName";
    int len=strlen(strlit);
    char * s=new char[len+1];
    if(s==NULL)
        env->ThrowError("Cannot Allocate string mem");
    strcpy(s,strlit);                               // dup
    char *e=s+len;                                  // point at nul

//  make safe copy of string (freed on Avisynth closure)
    AVSValue ret =  env->SaveString(s,e-s);         // e-s is text len only (excl nul) {SaveString uses memcpy)
//  AVSValue ret =  env->SaveString(s);             // alternative, Avisynth uses strlen to ascertain length
//  AVSValue ret =  env->SaveString(s,-1);          // alternative, Avisynth uses strlen to ascertain length
    delete [] s;                                    // delete our temp s buffer
    return ret;                                     // return Saved Str as AVSValue

//  return strlit;                                  // Alternative to MOST of above code char* converted to AVSValue.
//  return "AnyOldName";                            // Alternative to ALL of above code char* converted to AVSValue.
// String literals are read only and at constant address and so need not be saved.
above untested

Would be nice if it was as Avisynthesizer, using template to select source clips and auto create an
avs based on template. (EDIT: This is complete BS, create avs from within avs ??? (although it still could have usage))
EDIT: OK, a bit less BS, run template AVS, import clip into that template using fileselector,
which is basically what has been the suggested use by OP (I post like I play chess, without bothering to think)


Fixed name a bad idea, would make selecting multiple files eg input clip and output log files awkward.
__________________
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; 24th June 2013 at 06:24.
StainlessS is online now   Reply With Quote
Old 24th June 2013, 08:10   #8  |  Link
Forensic
Registered User
 
Join Date: Apr 2008
Location: California, USA
Posts: 128
My two cents

A more useful variant would be a single AVIsynth command or plug-in call that paused the AVIsynth script while it waited for user input. In this way the input could be assigned to a variable used for anything the coder needed, including opening the designated file name. The feature should have both a default and timer variable that, if specified, set the maximum seconds before the process is aborted to return the specified default value.

A nice plus would be if the input supported a CTRL-V clipboard paste.
Forensic is offline   Reply With Quote
Old 24th June 2013, 09:52   #9  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
Originally Posted by StainlessS View Post
Here how to return strings:-
...
Worth noting that most of these considerations (use of SaveString and freeing locally allocated memory) also apply when setting a script variable instead of returning a string.

In jordanh's function, there is actually a memory leak of up to 1256 bytes per call (although fairly unimportant in a function that is called only at compile-time and probably only once).
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 24th June 2013, 22:01   #10  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 48
OK, now it is getting interesting.
Up in front, i dont see any issues with the "execution time" of this stuff.

From my understanding, it behaves like this:
1) the avisynthplugininit function of all plugins is called at start of runtime, or "compile time" as the other say, in script order
2) getFrame is only called when the initializing application requests a frame.

one just needs to do the SetVar stuff within the init function, thats it. Its just about the script order.

I tend to open a new thread for gathering requirements of a new "external communcation plugin".

First i must ask about the environment everyone is envisioning.
You have to know, in my head it it only gets interesting when it can also be used in non-interactive mode. Meaning that avisynth is invoked by a background service and no user is logged in to the server where avisynth is runing on.
Please state a few comments on this.
I see SNMP, Mail, GUI by Script, commandline and many else communications.
What makes sense, is there anything that gives unlimited power like just calling external programs and returning their return value?

@Stainless: Thats extremely good code up there, thanks! Why not put that to the c++ wiki on avisynth.org? :-)

@forensic: i did not understand the CTRL-V stuff. what kind of usercontext are you reffering to, what exactly is the content of clipboard?

EDIT: we could send preview frames as base64 string (websites?) too :-)

Last edited by jordanh; 24th June 2013 at 22:10.
jordanh is offline   Reply With Quote
Old 24th June 2013, 23:29   #11  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,905
Avisynthplugininit, just lets Avisynth know what functions are available, their names, argument names and types, so it can check
what is legal during compile time. (EDIT: Avisynth does not know what arg values are legal, and your code must do checks on those)

Quote:
getFrame is only called when the initializing application requests a frame
Yes, but that only happens once the filter graph has been built. (EDIT that frame is returned once graph is built).
Before that, during compile time, as constructors are called and Filtered clips added to the graph, the parts of the graph that has already been
built are available to compile time filters, and even runtime clip functions eg can getframe on already existing partial chain, although
some tricks may be necessary if using standard builtin funcs like eg AverageLuma. (GScript is wonderfull).
EDIT: You can even force a filter constructor/destructor during compile time (after processing using eg GScript) so making any output
file available to subsequent functions (I love automation), useful in a sort of prescan to avoid 2 pass
(EDIT: Do 2 pass but automatically, one after the other, 1st pass without display so possibly a bit quicker) .

Quote:
like just calling external programs and returning their return value?
RT_Call(), is a function in RT_Stats collection of mainly runtime/compile time functions. Calls external program
(eg MediaInfo) but only returns a status on whether process was successfully started.
Code:
RT_Call(String Cmd,bool "Hide"=false,bool "Debug"=false)
 Run an external program using supplied cmd command line, hiding the console window if Hide==True.
 Debug, If true, send some debug info to debugview including return code from called process.
 DOS Filenames should be enclosed in quotes to avoid the system misinterpreting spaces in filenamess, see RT_QuoteStr().
 Returns 0 if process successfully started, otherwise non zero (ie 1).
  Example to write Aspect Ratio in form "1.333" to file D:\OUT\MEDINFO.TXT using command line version of MediaInfo.
   RT_Call(RT_QuoteStr("D:\TEST\MediaInfo.Exe") + " --LogFile=" + RT_Quotestr("D:\OUT\MEDINFO.TXT") + \
       " --Inform=Video;%DisplayAspectRatio% " + RT_Quotestr("D:\VID\1.mpg"))
Can then read results file using RT type functions.

EDIT:
There is also an example somewhere on-site using ImageMagic (although I think that spelling is wrong).
CallCmd (based on Call) does pretty much the same thing but is a standard filter function which allows calling
an external command on particular frames, or in constructor,/destructor of filter.

Quote:
why not put that to the c++ wiki
Because I'm very lazy and hate writing documentation (EDIT: but YOU are very welcome to do that).

By the way, latest Avisynth header for v2.5 is version 3, you used version 2 in FileSelector example.

Would prefer to see something that does not depend on the Foundation class libraries, I'm not a Windows progger
but have done a little WINAPI stuff eg RT_Call mentioned above.

@Forensic, presumably you meant text on clipboard, when I get around to it I'll see if I can figure out how to do that, for RT_Stats
(ie just get text from clipboard rather than CTRL-V, EDIT: if you meant BitMap, then say, I guess it would not be much more difficult).
__________________
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; 25th June 2013 at 09:27.
StainlessS is online now   Reply With Quote
Old 25th June 2013, 01:01   #12  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 48
Quote:
Originally Posted by StainlessS View Post
Avisynthplugininit, just lets Avisynth know what functions are available, their names, argument names and types, so it can check
what is legal during compile time.
That means, we have an even earlier point of setting variables than the point where the exported "main" function is used. I dont know what to do with it now, but i feel there are some usecases too.
In the end, the fileselection plugin i sumitted above does the SetVar stuff only when it is exported main function is called in the avs script. Avisynth is still able to build the graph.
I stay at: No problem regarding "execution" time.

Any other feature requests, design proposals or similar?
Especially use-cases for needed userinteraction (besides loading a source file) would be interesting...

Last edited by jordanh; 25th June 2013 at 01:03.
jordanh is offline   Reply With Quote
Old 25th June 2013, 01:18   #13  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 48
Quote:
Originally Posted by StainlessS View Post
Because I'm very lazy and hate writing documentation (EDIT: but YOU are very welcome to do that).
Done, thanks for sharing :-)
jordanh is offline   Reply With Quote
Old 25th June 2013, 01:37   #14  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,905
Quote:
even earlier point of setting variables
Presumably, there are others that could say better than my guess.
The void pointers within Avisynthplugininit are intended to pass info from that func into your Create type funcs, but only the
Avisynth "Glitterati" seem to know much about that. (eg alloc mem, init and pass secret info to your create func, I think,
also I think, something in Avisynth SDK docs, "Non-clipsample" I think, something to do with fonts and AtExit)

Building the Graph is basically compile time.

Execution time is never going to be an issue with a Fileselector (except that you have to wait for a human to do something, you could wait hours).
EDIT: A Timeout on such a File Selector (as suggested by Forensic) is likely to be a much bigger deal that the FileSelector itself.

Would love to see non Foundation Class Library source (to give me a starter), I could then include similar funcs into RT_stats.
would need FS (Fileselector) for Existing file ie input and non existing files eg Output, also Multiselect files for group selection.
(EDIT: I also usually only use VS6 or Toolkit III compilers and so would not want anything reliant on VS2008 etc, also,
I think Foundation Class Library stuff not available in some Express versions VS and so would want to avoid).

I'm as said earlier, not a windows progger, never actually liked the PC, but all other machines now deceased, so have no alternative except Apple.
Would love it though if you could impart some of you knowledge, so I could copy most of it off you.

EDIT: Thanx J, that's now two (I think) entries on Wiki I've got.

J, I have a thread that is really for C to Avisynth CPP quick learner guide that might have something that might interest
you. Obviously you are an accomplished programmer and dont need any kind of beginner guide (much less of a CPP beginner than me)
but there may (or may not) be some things that might be of use, not too long, might be worth a look).

here:
http://forum.doom9.org/showthread.php?t=163082

EDIT: The main reason I suggest this is I've put in debug messages to see where the init is and constructor/destructor calls are etc.

EDIT: Also, I think I'm correct in saying that during eg Eval/ScriptClip, you are then in a NEW compile time period, where a chunk of text is
evaluated in real time, where previous statements about compile time mostly hold true.

EDIT: RT_Stats has an RT_Debug() function which outputs strings to DebugView Window, great for tracking whats happening,
can also wrap it in ScriptClip or eg FrameEvaluate to see what is happening during Frame Serving stage.
__________________
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; 25th June 2013 at 16:42.
StainlessS is online now   Reply With Quote
Old 25th June 2013, 14:03   #15  |  Link
Wilbert
Moderator
 
Join Date: Nov 2001
Location: Netherlands
Posts: 6,310
@jordanh,

Please use avisynth.nl the next time. I've added it to http://avisynth.nl/index.php/Cplusplus_API#AddFunction.
Wilbert is offline   Reply With Quote
Old 25th June 2013, 21:38   #16  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 48
Thanks Wilbert!
@everything else:
I would like to have a look at avisynth source code in order to learn how and when all this stuff is done.

By now i didnt look too much into the avisynth source code too much, but i am very interested in.
Anyone has a clue where the script parsing and execution stuff is done? i wasnt able to find it in avisynth.cpp or directshow_source.cpp...

@Stainlesss: sorry, i really dont understand your concerns. Refering to the submitted example plugin above, i could do anything i like once the script engine calls the exported (env->AddFunction) function that is called from the avs script in order to request a userinput.
Did you try the plugin?
jordanh is offline   Reply With Quote
Old 25th June 2013, 22:05   #17  |  Link
Groucho2004
 
Groucho2004's Avatar
 
Join Date: Mar 2006
Posts: 3,878
Quote:
Originally Posted by jordanh View Post
Anyone has a clue where the script parsing and execution stuff is done?
Code:
src\core\parser
Groucho2004 is offline   Reply With Quote
Old 25th June 2013, 22:31   #18  |  Link
TheFluff
Excessively jovial fellow
 
Join Date: Jun 2004
Location: rude
Posts: 1,043
Quote:
Originally Posted by jordanh View Post
EDIT: acutally, i like setting stuff into hardcoded variable names. This way, it is just more obvious what is going on when you look over a script. It is a kind of standardisation.
The negative sides of hardcoded variable names is clear: first there is the documentation issue, second it can be overwritten. It would be better to use more complex variablenames for this kind of integration.
I'm pretty sure this is the wrongest thing I've ever read on doom9, and I've read a lot of posts with people being wrong here. Please, if you value other people's sanity, make your function return the value.
TheFluff is offline   Reply With Quote
Old 25th June 2013, 22:56   #19  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
Originally Posted by jordanh View Post
Anyone has a clue where the script parsing and execution stuff is done?
Quote:
Originally Posted by Groucho2004 View Post
Code:
src\core\parser
and the 'entry point' is basically the Import() and Eval() functions in src\core\parser\script.cpp.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 26th June 2013, 00:25   #20  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 48
@TheFluff: sorry for not explaining my reasons, thats a too long story. I basically agree with you, it was a bad decision to use this method in the example above.
However, the plugin above is clearly commented as non productive, example and not continued. You show a strange way to submit feature requests.
The Plugin above cannot be continued, its just a proof of concept. Stainlesss already required non MS Foundation code, so it needs to be rewritten from scratch anyway. (its only about 20 interesting lines of code...)
By now i still only have 3 requirements for the plugin:
* dont use win32 api
* support default and timeout
* return values

..and only one usecase: file selection
Arent there other situations when a user decision would be nice to have?



Back to the Topic:

Meanwhile thanks to Groucho i got out, that functions of interest are:

Code:
//avisynth.cpp

// Constructor of ScriptEnvironment:

ScriptEnvironment::ScriptEnvironment()
...
    global_var_table->Set("true", true);
    global_var_table->Set("false", false);
    global_var_table->Set("yes", true);
    global_var_table->Set("no", false);

...
    PrescanPlugins();//doesnt call any function of the plugin
    ExportFilters(); //doesnt call any function of the plugin

This function is parsing a single function and its arguments
Code:
//avisynth.cpp

AVSValue ScriptEnvironment::Invoke(const char* name, const AVSValue args, const char** arg_names) {...

//ends up in: (didnt get out what exactly this does)

   // ... and we're finally ready to make the call
retval = f->apply(AVSValue(args3, args3_count), f->user_data, this);
..can it be that this function is the one that's used for any dll function call like child->geframe?

Still, i struglle getting out, where the parsing stuff is used from. What i need to get out is where the part of "compilation" or parsing or whatever people above are referring to...
jordanh 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 15:00.


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