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 26th June 2013, 00:46   #21  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,442
Quote:
Originally Posted by jordanh View Post
This function is parsing a single function and its arguments
Code:
AVSValue ScriptEnvironment::Invoke(const char* name, const AVSValue args, const char** arg_names) {...
..can it be that this function is the one that's used for any dll function call like child->geframe?
That is the API function (env->Invoke()) which is used to call any function that has been installed in Avisynth's function table via env->AddFunction(). This includes all built-in script functions and filters, as well as those provided by plugins.
child->GetFrame() is not called via Invoke() - it is called directly by filters.

Quote:
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...
As I said in my previous post, the starting point is the Import() function, which is called (via Invoke()) by the VfW interface (main.cpp), or by an Avisynth library client, to parse the script file and create the filter graph.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 26th June 2013, 00:50   #22  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 55
Thanks Gavino!
That was the breakthough.

Avisynthplugininit is used multiple times to look up exported functions of loaded plugins, it may be a bad idea to do something else on the env than exporting functions...

The function that actually opens the avs file and kicks off parsing and first executions is this:

Code:
//script.cpp

AVSValue Import(AVSValue args, void*, IScriptEnvironment* env) {...

AVSValue eval_args[] = { (char*)buf, script_name };
    result = env->Invoke("Eval", AVSValue(eval_args, 2));
..
}

Code:
//avisynth.cpp
//called by Import function above, seems to parse line by line and execute functions in given order (script order)

AVSValue ScriptEnvironment::Invoke(const char* name, const AVSValue args, const char** arg_names) {
My interpretation is, that there is no "compliation" time like referred above, but i am absolutely not sure if i interpret it right. It is just executing each function one after the other, isnt it?
jordanh is offline   Reply With Quote
Old 26th June 2013, 01:02   #23  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,442
Quote:
Originally Posted by jordanh View Post
My interpretation is, that there is no "compliation" time like referred above, but i am absolutely not sure if i interpret it right. It is just executing each function one after the other, isnt it?
Yes, you're right - the word 'compilation' is a bit misleading and I've never been fully comfortable with it.

Essentially, it is 'interpreting' the script, evaluating expressions, calling functions and, where appropriate, assigning results to variables. The 'compilation' that takes place refers to the building of the filter graph which is the result of the script (a value of type PClip).

This is in contrast to 'runtime', ie the subsequent frame serving phase where frames are requested from the graph by calling its GetFrame() function.

EDIT: You might find this useful:
http://avisynth.nl/index.php/The_script_execution_model
__________________
GScript and GRunT - complex Avisynth scripting made easier

Last edited by Gavino; 26th June 2013 at 01:07.
Gavino is offline   Reply With Quote
Old 26th June 2013, 15:40   #24  |  Link
IanB
Avisynth Developer
 
Join Date: Jan 2003
Location: Melbourne, Australia
Posts: 3,167
AvisynthPluginInit2/3 is the entry point called when Avisynth loads an external plugin .dll.

It is called on the first occurrence of a LoadPlugin() call of that .dll. If the dll is already known it is not called a second time.

For plugins that are auto loaded from the plugin folder at IScriptEnvironment creation time, it is called once as the plugin is prescanned and can be called a second time if the .dll has been released and when a defined function is referenced in the script. Referencing a function from a released auto load plugin causes it to be reloaded.

You can actually call any IScriptEnvironment function in your AvisynthPluginInit2/3 routine, but because auto load plugins might be released it is normally accepted that only AddFunction calls should be made. i.e. you should not do anything that latter needs something from the address space of the plugin .dll as it may well not be present at all or at a different memory location.

Such activity should be performed in the Apply function registered by the AddFunction call.

Whenever the Apply function is called the optional registered user_data value is supplied as the second argument. The user_data is of type void* and may be any constant or pointer value that you wish. E.g you may register varying function names with the same Apply function and each with a different user_data value to tell them apart. Or you could provide the address of a structure that all instances of a function can have access to.
IanB is offline   Reply With Quote
Old 27th June 2013, 06:51   #25  |  Link
pbristow
Registered User
 
pbristow's Avatar
 
Join Date: Jun 2009
Location: UK
Posts: 269
Can I just say how delighted I am that my suggestion has triggered all this activity?

I haven't had a chance to try out jordanh's prototype yet, but I've seen a comment in the discussion requesting CTRL-V (paste) to work. I assume jordonh was just doing proof-of-concept of the integration-with-avisynth part of the problem, rather than worrying about details of how the file selector itself would look and function...? But just to be clear on what I had in mind for that, I'd like something that opens up the standard Windows "Explorer"-type file selector, as seen in many, many existing applications (VirtualDub, for example). That supports CTRL-V for inserting pathnames and filenames into the relevant fields, as well as drag-and-drop, the ability to create new folders and do a bit of filesystem tidying before you open your file, and so on... not to mention integrating well with all sorts of third-party add-ons such as Listary (See http://www.listary.com/ ), which provides a really useful set of tools to stop me getting lost in the vast and twisty labyrinth of my ever-growing filesystem... ). I've seen various freeware tools that re-invent the wheel on file selection, with various degees of success, but none of them provide the power - not to mention the consistency of user experience - that you get by just using the standard tool.

Of course, the possible downsides of that are that (a) it's inherently Windows-specific (but presumably the folks working on the Linux port of avisynth, VapourSynth, etc. could produce a version that calls whatever the standard/most popular file selection UI is on the platform in question...?), and (b) there may be some licensing implications (?).

Anyway, thanks for your efforts. I look forward to seeing how this turns out.

(You might even shame me into getting my own hands dirty with a compiler again... It's been a couple of years at least since my last attempt died, along with the laptop hard drive upon which I'd just spent two weeks setting up my development environment... )

Last edited by pbristow; 27th June 2013 at 06:57.
pbristow is offline   Reply With Quote
Old 27th June 2013, 07:05   #26  |  Link
pbristow
Registered User
 
pbristow's Avatar
 
Join Date: Jun 2009
Location: UK
Posts: 269
Oh, on the "compilation" wording debate: I would call it "instantiation", i.e. the phase during which an instance of the Avisynth working environment is being created. (N.B. sometimes more than one such instance is created by a script, e.g. if it uses MP_Pipeline.)
pbristow is offline   Reply With Quote
Old 27th June 2013, 15:37   #27  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Quote:
Originally Posted by jordanh View Post
@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?
Sorry jordanh, we seem to have misunderstood each other.
I have no real concerns on your submission, perhaps I was a little too wordy (said too much).
I have not as yet tried the plugin, dont need it just yet, and busy doing something else at the moment,
but I will and thank you very much for taking the time to make your submission,
it is much appreciated.
__________________
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 offline   Reply With Quote
Old 27th June 2013, 17:31   #28  |  Link
pbristow
Registered User
 
pbristow's Avatar
 
Join Date: Jun 2009
Location: UK
Posts: 269
Just tried out jordanh's prototype: Yes! That's exactly what I wanted it to do. Thankyou!

Although I do think assigning the name to a variable is better than fixed variable names. One of my intended uses is for a script that analyses the difference between two or more clips, where these have been created by different versions of an AVS script I'm developing. The idea is to be able to run the comparaison script in one instance of VirtualDub (or directly in Daum PotPlayer), and then select the files to be compared. This will be repeated multiple times, as I generate more test clips with new versions of the main script, home in on which version of processing is working best. Obviously for that, I need separate variable names, but for now I can work around that using "Testfile1 = SELECTEDFILE" etc. before calling the pop-up again.

Oh, and seeing "Save as" in the title bar for an *input* file selector made me panic for a moment.
pbristow is offline   Reply With Quote
Old 28th June 2013, 00:00   #29  |  Link
jordanh
Registered User
 
Join Date: Apr 2013
Location: Vienna, Austria
Posts: 55
Hehe... finally someone tried it :-)
Thank YOU (pbristow) for this nice project idea! Mostly the simple ideas are the best. Maybe you really find the esteam to pull out development tools again and finish the plugin on your own ;-) ...setting a few parameters for filechooser and returning the value from the function should do it.

@Stainlesss: As i now understand know how things work in detail, i would have had more understanding for what you wrote too - and be able to interpret your messages right.
Basically it was only the wording "compile" in general and especially "compile time plugin" (still don't understand what you mean with that) that made me so much working on this thread.

From my understanding, avisynth is a mix of different stuff, especially the directshow/vfw interface, but the avisynth script language is something i'd prefer to call officially an "interpreted script language".

Last edited by jordanh; 28th June 2013 at 00:03.
jordanh is offline   Reply With Quote
Old 28th June 2013, 01:05   #30  |  Link
TheFluff
Excessively jovial fellow
 
Join Date: Jun 2004
Location: rude
Posts: 1,100
Avisynth script is neither interpreted nor a scripting language in the traditional senses of those words; if you want to be technical about it, it's more of a graph description language than anything else. The term "Avisynth" generally refers to the entire package of a video filtering library, its public API, the third-party libraries written using that API ("plugins"), the scripting engine that builds filter chains using the video filtering library and the VFW output driver that lets ordinary VFW applications retrieve frames from the filtering library without having to interface with its API.

Last edited by TheFluff; 28th June 2013 at 01:09.
TheFluff is offline   Reply With Quote
Old 20th July 2013, 23:09   #31  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
I finally got around to trying this out (thank you jordanh), had to install vs2010 runtimes (thought I had already installed it),
but am getting an

Quote:
Evaluate: System exception - Access Violation
at this line "fileselectionpopup()".

In Dependency walker (EDIT: for AVS_FilenameSelector.dll), shows message:-

Quote:
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
and hilites the mpr.dll (14/4/2008) 5.1.2600.5512, as the culprit. (WXP32).

Anybody got an idea on what that means ?

EDIT: Seems unresolved import due to WNetRestoreConnectionA which is probably not the cause of the
access violation.
__________________
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; 20th July 2013 at 23:25. Reason: clarify
StainlessS is offline   Reply With Quote
Old 25th July 2013, 22:30   #32  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Previous post access violation probably down to the function used, available only Vista+, so a no-no on XP.

Here an XP+ WINAPI solution, not terribly well tested, but something for you to play with.

FSel.dll, FselOpen function.

Code:
/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

// Compile for minimum supported system. MUST be defined before includes.
// NEED to use SDK for updated headers, OR TK3 will give error messages/Warnings about Beta versions.

#define WINVER          0x0501          // XP
#define _WIN32_WINNT    0x0501          // XP
#define NTDDI_VERSION   0x05010300      // XP SP3
#define _WIN32_IE       0x0603          // 0x0603=IE 6 SP2, 0x0700=1e7, 0x0800=1e8
//
//
#include <windows.h>
#include <stdio.h>
#include <commdlg.h>                    // OS Specific WINVER (Mainly)
#include <Shlobj.h>                     // IE Specific _WIN32_IE
//
#include "avisynth.h"
//

/*
    typedef struct tagOFN {
      DWORD         lStructSize;
      HWND          hwndOwner;                  // NULL no owner
      HINSTANCE     hInstance;
      LPCTSTR       lpstrFilter;                // the filter
      LPTSTR        lpstrCustomFilter;
      DWORD         nMaxCustFilter;
      DWORD         nFilterIndex;               // we default ALWAYS 1 (ie first one)
      LPTSTR        lpstrFile;                  // initial filename, also for return filename
      DWORD         nMaxFile;                   // size of filename buffer
      LPTSTR        lpstrFileTitle;
      DWORD         nMaxFileTitle;
      LPCTSTR       lpstrInitialDir;            // the initial directory or current if null
      LPCTSTR       lpstrTitle;                 // Title Bar text, eg 'Open file'
      DWORD         Flags;
      WORD          nFileOffset;
      WORD          nFileExtension;
      LPCTSTR       lpstrDefExt;
      LPARAM        lCustData;
      LPOFNHOOKPROC lpfnHook;
      LPCTSTR       lpTemplateName;
    #if (_WIN32_WINNT >= 0x0500)
      void *        pvReserved;
      DWORD         dwReserved;
      DWORD         FlagsEx;
    #endif // (_WIN32_WINNT >= 0x0500)
    } OPENFILENAME, *LPOPENFILENAME;
*/




int dprintf(char* fmt, ...) {
char printString[2048];
    char *p=printString;
    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);
    } else {
        OutputDebugString(printString);
    }
    return p-printString;                       // strlen printString
}


AVSValue __cdecl  FSelOpen(AVSValue args, void* user_data, IScriptEnvironment* env) {
    char * myName="FSelOpen: ";
    const char * myFilter=
        "All files (*.*)|*.*|"
        "Avi Files (*.avi;*.XVid;*.DivX)|*.avi;*.XVid;*.DivX|"
        "Mpg files (*.vob;*.mpg;*.mpeg;*.m1v;*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro)|*.vob;*.mpg;*.mpeg;*.m1v;"
        "*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro|"
        "Other Vid (*.mkv;*.Wmv;*.mp4;*.flv;*.ram;*.rm)|*.mkv;*.Wmv;*.mp4;*.flv;*.ram;*.rm|"
        "Audio Files (*.mp3;*.mpa;*mp1;*.mp2;*.wav)|*.mp3;*.mpa;*mp1;*.mp2;*.wav|"
        "Avs files (*.avs;*.avsi)|*.avs;*.avsi|"
        "Text files (*.txt;*.log;*.asc)|*.txt;*.log;*.asc|"
        "Image files (*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff)|*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff|"
        "Bat files (*.bat)|*.bat|";
        "Exe files (*.exe)|*.cmd";

    const char * title  =args[0].AsString(NULL);
    const char * dir    =args[1].AsString(NULL);            // Default current dir
    const char * filt   =args[2].AsString(myFilter);
    const char * fn     =args[3].AsString("");
    const bool multi    =args[4].AsBool(false);
    if(strlen(filt)>4096-3)                 env->ThrowError("%sFilter too long",myName);
    char filt2[4096];
    const char *p=filt;

    int ix=0;
    while(*p) {                                     // convert from PIPE '|' separated to nul separated filter strings
        if(*p=='|') {
            filt2[ix++]='\0';
            ++p;
        } else {
            filt2[ix++]=*p++;
        }
    }
    filt2[ix++]='\0';   filt2[ix]='\0';         // Double nul term


    int size = (multi) ? 65536 : (MAX_PATH * 2);
    int len=strlen(fn) + 1;
    if(len>size)    size=len;
    char *szFile = new char [size];                 // buffer for file name
    if(szFile==NULL)                        env->ThrowError("%sCannot allocate memory",myName);
    strcpy(szFile,fn);                              // set initial filename
    int flgs= \
        OFN_PATHMUSTEXIST |
        OFN_FILEMUSTEXIST |
        OFN_HIDEREADONLY  |     // hide readonly check box
        OFN_LONGNAMES     |
        OFN_NOCHANGEDIR;        // restore original current directory if user changed. Does NOT work for GetOpenFileName.

    if(multi) flgs |=(OFN_ALLOWMULTISELECT|OFN_EXPLORER) ;

    OPENFILENAME ofn;                               // common dialog box structure
    ZeroMemory(&ofn, sizeof(ofn));                  // Initialize OPENFILENAME
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = NULL;                           // owner window, we dont have one
    ofn.lpstrFile = szFile;                         // filename buff
    ofn.nMaxFile  = size;                           // size of filename buff
    ofn.lpstrFilter = filt2;                        // Converted filt string
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = dir;
    ofn.lpstrTitle=title;                           // Title shown in Title Bar
    ofn.Flags = flgs;
    // Display the Open dialog box.

    if (GetOpenFileName(&ofn)!=TRUE)  {
        delete [] szFile;
        DWORD ret = CommDlgExtendedError();
        if(ret==0) {
            dprintf("%sUser CANCELLED",myName);
            return 0;
        }
        switch(ret) {
        case FNERR_BUFFERTOOSMALL:  dprintf("%sFilename buffer Too Small",myName); break;
        case FNERR_INVALIDFILENAME: dprintf("%sInvalid filename",myName); break;
        case FNERR_SUBCLASSFAILURE: dprintf("%sSubClass failure (low memory)",myName); break;
        case CDERR_DIALOGFAILURE:   dprintf("%sDialog box creation failure",myName); break;
        case CDERR_FINDRESFAILURE:  dprintf("%sFind resource failure",myName); break;
        case CDERR_INITIALIZATION:  dprintf("%sDialog box initialization failure (usually memory)",myName); break;
        case CDERR_LOADRESFAILURE:  dprintf("%sLoad resource failure",myName); break;
        case CDERR_LOADSTRFAILURE:  dprintf("%sLoad string failure",myName); break;
        case CDERR_LOCKRESFAILURE:  dprintf("%sLock resource failure",myName); break;
        case CDERR_MEMALLOCFAILURE: dprintf("%sUnable to allocate memory structures",myName); break;
        case CDERR_MEMLOCKFAILURE:  dprintf("%sUnable to lock memory associated with handle",myName); break;
        case CDERR_NOHINSTANCE:     dprintf("%sNo instance handle",myName); break;
        case CDERR_NOHOOK:          dprintf("%sNo hook",myName); break;
        case CDERR_NOTEMPLATE:      dprintf("%sNo template",myName); break;
        case CDERR_REGISTERMSGFAIL: dprintf("%sRegisterWindowMessage returned an error",myName); break;
        case CDERR_STRUCTSIZE:      dprintf("%sInvalid lStructSize member",myName); break;
        default:                    dprintf("%sUnknown error",myName); break;
        }
        return (int)ret;
    }
    int off=ofn.nFileOffset;
    if(!multi || (off>0 && szFile[off-1]=='\\')) {      // single filename selected
//      dprintf("%s OK Single file = %s",myName,szFile);
        AVSValue retstr = env->SaveString(szFile);
        delete [] szFile;
        return retstr;
    }
    p=szFile;
    int nstr=0;
    while(*p) {         // Count gotten strings, 1st is dir, then filenames. Ends in double nul.
        while(*p) {
            ++p;
        }
        ++p;
        ++nstr;
    }
    int dirlen=off;                                 // including nul (will convert to '\\').
    int fullen = (p - szFile - off) + ((nstr - 1) * dirlen) + 1;        // +1 for final nul term.
    char *mfiles = new char [fullen];               // buffer for multiple expanded file names, '\n' separated
    if(mfiles==NULL) {
        delete [] szFile;
        env->ThrowError("%sCannot allocate multiselect files buffer",myName);
    }
    char *d=mfiles;                                 // Dest multiselect files buffer
    char *s=&szFile[off];                           // point at 1st filename node
    for(int i=nstr-1;--i>=0;) {                     // Convert to filenames with full path
        char *r=szFile;                             // point at path
        while(*r)
            *d++=*r++;                              // Copy path
        *d++='\\';                                  // backslash separator
        while(*s)
            *d++=*s++;                              // append filename
        ++s;                                        // skip nul
        *d++='\n';                                  // '\n' multiline separator
    }
    *d='\0';                                        // nul term
    delete [] szFile;
//  dprintf("%sOK = %s",myName,mfiles);
    AVSValue retstr = env->SaveString(mfiles);
    delete [] mfiles;
    return retstr;
}
And test script

Code:
########
# FSelOpen() by StainlessS
#
# Function FSelOpen(string "title"="Open",string "dir"="",string  "filt",string "fn="",bool "multi"=false)
#
# Function to select EXISTING filename. Would need something similar to select SAVE filename, or Folder Select.
#
# Title = Title bar text.
# Dir   = Directory, "" = Current
# Filt  = Lots, most of below with a few more mpeg. [Displayed text | wildcard] [| more pairs of Displayed text and wildcard, in pairs ONLY].
#         first one is default.
# fn    = Initially presented filename (if any).
# multi = Multiply Select filenames. Allows selection of more than one filename. RT_Stats v1.20 Required for MULTI=true
#
# Returns
#   int, 0, user CANCELLED.
#   int, non zero is error (error sent to DebugView window).
#   String, Filename selected, Chr(10) separated multiline string if MULTI==true (and multiple files selected).
#
########

TITLE ="Open a File, if you really really want to"
DIR   =""
FILT  = "All files (*.*)|*.*|"
     \ + "Image files (*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff)|*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff|"
     \ + "Mpg files (*.vob;*.mpg;*.mpeg etc)|*.vob;*.mpg;*.mpeg;*.m1v;*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro|"
     \ + "Avi Files (*.avi)|*.avi|"
     \ + "Avs files (*.avs;*.avsi)|*.avs;*.avsi|"
     \ + "Text files (*.txt)|*.txt"

FN    ="AnyAnyAnyOldIron.txt"
MULTI = false   # True requires RT_Stats

result = FSelOpen(title=TITLE,dir=DIR,Filt=FILT,fn=FN,multi=MULTI)

Assert(result.IsString,"FSelOpen: Error="+String(Result))

colorbars

Lines = (!MULTI) ? 1 : RT_TxtQueryLines(result)     # Inquire how many filenames we got,
                                                    # Can use eg RT_TxtGetLine(result,Line) Where Line valid from 0 to Lines - 1.
(MULTI) ? RT_Debug(Result) : NOP                    # to DebugViewWindow
result= (MULTI) ? RT_StrReplace(Result,Chr(10),"\n") : result     # Convert For SubTitle
result="We got " + String(Lines) + " Filenames\n\n" + result
return Subtitle(result,lsp=0)
EDIT:
Update to v1.01 TAKE 2, Removed FSelOpen() script RT_Stats requirement unless MULTI = true. Here:
Link removed, see post #37.

EDIT: see also post #37 and #38 for additional parts
__________________
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; 15th December 2018 at 14:43.
StainlessS is offline   Reply With Quote
Old 25th July 2013, 23:40   #33  |  Link
pbristow
Registered User
 
pbristow's Avatar
 
Join Date: Jun 2009
Location: UK
Posts: 269
Ooh, this looks powerful! Thanks StainlessS.

[GIVES IT A TRY]

Bwahaha! I love the default filenames.

Alas, the test script fails as I don't have the RT_ functions, but tweaking it to just use "AVISource(result)" works fine for single files. I like the idea of being able to pre-set the filetypes/extensions available (so that you don't mistakenly try to open a non-video file, or open that fuzzy old .mpg with a script that's designed to work with nice clean HiRes .mkv files. )

Thanks again.
pbristow is offline   Reply With Quote
Old 26th July 2013, 00:36   #34  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
@pbristow, hope you saw the EDIT:

Quote:
I don't have the RT_
not that expensive, quite cheap really.
Also, a number of tools to read in eg text files, count multiline strings (whether or
not last line is n/l terminated, sort a multiline pseudo array of int/float strings,
write a results text/log file and more. My current favorite is RT_Subtitle, is FAST,
if you do decide to treat yourself, try the scrolling end credits type snippet, its
quite impressive for a few lines of script (about 5 or 6).

EDIT: If I do any further work on this, it will of course be going into RT_Stats plugin,
I'm unlikely to do anything further with FSel.dll, if anyone wants to expand and keep
as a separate, they are welcome.
__________________
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; 26th July 2013 at 01:14.
StainlessS is offline   Reply With Quote
Old 26th July 2013, 09:17   #35  |  Link
pbristow
Registered User
 
pbristow's Avatar
 
Join Date: Jun 2009
Location: UK
Posts: 269
Quote:
Originally Posted by StainlessS View Post
@pbristow, hope you saw the EDIT:
Seen it, downloaded it, thankyou.

(I also found I *had* downloaded RT_Stats, just hadn't got around to installing and testing it. )
pbristow is offline   Reply With Quote
Old 27th July 2013, 00:25   #36  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Update to FSel.dll, v1.01.

Added FselSaveAs() and FSelFolder().

FSelSaveAs script
Code:
########
# FSelSaveAs() by StainlessS
#
# Function FSelSaveAs(string "title"="Open",string "dir"="",string  "filt",string "fn="")
#
# Function to select filename for Save.
#
# Title = Title bar text.
# Dir   = Directory, "" = Current
# Filt  = Lots, most of below with a few more mpeg. [Displayed text | wildcard] [| more pairs of Displayed text and wildcard, in pairs ONLY].
#         first one is default.
# fn    = Initially presented filename (if any).
#
# Returns
#   int, 0, user CANCELLED.
#   int, non zero is error (error sent to DebugView window).
#   String, Filename selected.
########

TITLE ="Save a File, if you think you know what you are doing"
DIR   =""
FILT  = "All files (*.*)|*.*|"
     \ + "Image files (*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff)|*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff|"
     \ + "Mpg files (*.vob;*.mpg;*.mpeg etc)|*.vob;*.mpg;*.mpeg;*.m1v;*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro|"
     \ + "Avi Files (*.avi)|*.avi|"
     \ + "Avs files (*.avs;*.avsi)|*.avs;*.avsi|"
     \ + "Text files (*.txt)|*.txt"

FN    ="AnyAnyAnyOldIron.txt"

result = FSelSaveAs(title=TITLE,dir=DIR,Filt=FILT,fn=FN)

Assert(result.IsString,"FSelSaveAs: Error="+String(Result))

return colorbars.Subtitle(Result)
FSelFolder script
Code:
########
# FSelFolder() by StainlessS
#
# Function FSelFolder(string "title"="",string "dir"=".")
#
# Function to select Folder.
#
# Title = UNDERNEATH the title bar text, for instructions.
# Dir   = Directory, Default "." = Current, ""=Root.
#
# Returns
#   int, 0, user CANCELLED.
#   int, non zero is error (ie -1, error sent to DebugView window, usually selecting non Folder object eg 'My Computer').
#   String, Folder selected (minus trailing BackSlash).
########

TITLE ="USE THIS TO SELECT A FOLDER"
DIR="."         # Current Dir (Default)
#DIR=""         # Root, My Computer
#DIR="D:\avs\"  # Something Else
result = FSelFolder(title=TITLE,dir=DIR)

Assert(result.IsString,"FSelFolder: Error="+String(Result))

return colorbars.Subtitle(result)
Original FSelOpen much the same as at #post 32 above.

EDIT: For those that like to watch a movie and read scrolling text at the same time. Requires RT_Stats v1.20.
Code:
avi = FSelOpen("Select an AVI",Filt="*.AVI|*.AVI")
Assert(avi.IsString,"FSelOpen: Error="+String(avi))
AVISource(AVI)
txt = FSelOpen("Select a Text file",Filt="*.txt|*.txt")
Assert(txt.IsString,"FSelOpen: Error="+String(txt))
Txt=RT_ReadTxtFromFile(txt)
Return ScriptClip("""RT_Subtitle("%s",Txt,align=2,y=height+100-current_frame,expy=true)""") # Requires RT_Stats v1.20
Prompts for AVI file, then for a Txt file

EDIT: FSelOpen, will only allow selecting existing files. FSelSaveAs, prompts for Overwrite if existing selected.

Update to v1.01 TAKE 2, Removed FSelOpen() script RT_Stats requirement unless MULTI = true. Here:
Link removed, see post #37.
__________________
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; 27th July 2013 at 19:03.
StainlessS is offline   Reply With Quote
Old 27th July 2013, 19:02   #37  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Update to FSelOpen, FSelSaveas and FSelFolder functs, FSel.dll v1.02

Fixed bug in filter scanning, update FSelFolder to resizable dialog box with Makefolder button.

Here:
http://www.mediafire.com/download/82...28TAKE3%29.zip

Very last Fsel.dll version, have added to RT_stats.

EDIT: May not be online longer than a month or so.
__________________
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; 27th July 2013 at 19:25.
StainlessS is offline   Reply With Quote
Old 31st July 2013, 14:23   #38  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Post update, added the FSelSaveAs() and FSelFolder() source (with filter parse bug fixed) , see also posts #32 and #37 for other parts of source.
Link to zip in previous post.
Code:
AVSValue __cdecl  FSelSaveAs(AVSValue args, void* user_data, IScriptEnvironment* env) {
    char * myName="FSelSaveAs: ";
    const char * myFilter=
        "All files (*.*)|*.*|"
        "Avi Files (*.avi;*.XVid;*.DivX)|*.avi;*.XVid;*.DivX|"
        "Mpg files (*.vob;*.mpg;*.mpeg;*.m1v;*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro)|*.vob;*.mpg;*.mpeg;*.m1v;"
        "*.m2v;*.mpv;*.tp;*.ts;*.trp;*.m2t;*.m2ts;*.pva;*.vro|"
        "Other Vid (*.mkv;*.Wmv;*.mp4;*.flv;*.ram;*.rm)|*.mkv;*.Wmv;*.mp4;*.flv;*.ram;*.rm|"
        "Audio Files (*.mp3;*.mpa;*mp1;*.mp2;*.wav)|*.mp3;*.mpa;*mp1;*.mp2;*.wav|"
        "Avs files (*.avs;*.avsi)|*.avs;*.avsi|"
        "Text files (*.txt;*.log;*.asc)|*.txt;*.log;*.asc|"
        "Image files (*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff)|*.bmp;*.jpg;*.jpe;*.jpeg;*.png;*.tga;*.tif;*.gif;*.tiff|"
        "Bat files (*.bat)|*.bat";

    const char * title  =args[0].AsString(NULL);
    const char * dir    =args[1].AsString(NULL);            // Default current dir
    const char * filt   =args[2].AsString(myFilter);
    const char * fn     =args[3].AsString("");
    if(strlen(filt)>4096-3)                 env->ThrowError("%sFilter too long",myName);
    char filt2[4096];
    const char *p=filt;

    int ix=0;
    while(*p) {                                     // convert from PIPE '|' separated to nul separated filter strings
        if(*p=='|') {
            filt2[ix++]='\0';
            ++p;
        } else {
            filt2[ix++]=*p++;
        }
    }
    filt2[ix++]='\0';   filt2[ix]='\0';             // Double nul term

    int size = MAX_PATH * 2;
    int len=strlen(fn) + 1;
    if(len>size)    size=len;
    char *szFile = new char [size];                 // buffer for file name
    if(szFile==NULL)                        env->ThrowError("%sCannot allocate memory",myName);
    strcpy(szFile,fn);                              // set initial filename
    int flgs= \
        OFN_OVERWRITEPROMPT |
        OFN_LONGNAMES       |
        OFN_NOCHANGEDIR;        // restore original current directory if user changed. Does NOT work for GetOpenFileName.

    OPENFILENAME ofn;                               // common dialog box structure
    ZeroMemory(&ofn, sizeof(ofn));                  // Initialize OPENFILENAME
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = NULL;                           // owner window, we dont have one
    ofn.lpstrFile = szFile;                         // filename buff
    ofn.nMaxFile  = size;                           // size of filename buff
    ofn.lpstrFilter = filt2;                        // Converted filt string
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = dir;
    ofn.lpstrTitle=title;                           // Title shown in Title Bar
    ofn.Flags = flgs;

    // Display the Open dialog box.
    if (GetSaveFileName(&ofn)!=TRUE)  {
        delete [] szFile;
        DWORD ret = CommDlgExtendedError();
        if(ret==0) {
            dprintf("%sUser CANCELLED",myName);
            return 0;
        }

        switch(ret) {
        case FNERR_BUFFERTOOSMALL:  dprintf("%sFilename buffer Too Small",myName); break;
        case FNERR_INVALIDFILENAME: dprintf("%sInvalid filename",myName); break;
        case FNERR_SUBCLASSFAILURE: dprintf("%sSubClass failure (low memory)",myName); break;
        case CDERR_DIALOGFAILURE:   dprintf("%sDialog box creation failure",myName); break;
        case CDERR_FINDRESFAILURE:  dprintf("%sFind resource failure",myName); break;
        case CDERR_INITIALIZATION:  dprintf("%sDialog box initialization failure (usually memory)",myName); break;
        case CDERR_LOADRESFAILURE:  dprintf("%sLoad resource failure",myName); break;
        case CDERR_LOADSTRFAILURE:  dprintf("%sLoad string failure",myName); break;
        case CDERR_LOCKRESFAILURE:  dprintf("%sLock resource failure",myName); break;
        case CDERR_MEMALLOCFAILURE: dprintf("%sUnable to allocate memory structures",myName); break;
        case CDERR_MEMLOCKFAILURE:  dprintf("%sUnable to lock memory associated with handle",myName); break;
        case CDERR_NOHINSTANCE:     dprintf("%sNo instance handle",myName); break;
        case CDERR_NOHOOK:          dprintf("%sNo hook",myName); break;
        case CDERR_NOTEMPLATE:      dprintf("%sNo template",myName); break;
        case CDERR_REGISTERMSGFAIL: dprintf("%sRegisterWindowMessage returned an error",myName); break;
        case CDERR_STRUCTSIZE:      dprintf("%sInvalid lStructSize member",myName); break;
        default:                    dprintf("%sUnknown error",myName); break;
        }
        return (int)ret;
    }
//  dprintf("%s OK Single file = %s",myName,szFile);
    AVSValue retstr = env->SaveString(szFile);
    delete [] szFile;
    return retstr;
}




/*
typedef struct _browseinfo {
  HWND              hwndOwner;          // A handle to the owner window for the dialog box.
  PCIDLIST_ABSOLUTE pidlRoot;           // Root folder to browse from PIDL (NULL = DeskTop)
  LPTSTR            pszDisplayName;     // returned name, Presumed MAX_PATH characters
  LPCTSTR           lpszTitle;          // Title Bar String
  UINT              ulFlags;
  BFFCALLBACK       lpfn;               // Calback functionm, Can be NULL.
  LPARAM            lParam;
  int               iImage;
} BROWSEINFO, *PBROWSEINFO, *LPBROWSEINFO;
*/


int CALLBACK FSelFolderCallback(HWND hwnd,UINT uMsg,LPARAM lp, LPARAM pData) {
    // The callback function required to init desired path to folder, rather than root (Desktop)
    // meaning of lp depends on uMsg type
    // pData is application defined data for the callback function.
    char szPath[MAX_PATH*2];
    switch(uMsg) {
    case BFFM_INITIALIZED:                                          // Selects the specified folder Path
        szPath[0]='\0';
        {   // Need Brace to init below s without error.
            char*s=(char*)pData;
            if(s!=NULL) {
                if(s[0]=='.'&&s[1]=='\0') {
                    if(!GetCurrentDirectory(sizeof(szPath), szPath))
                        szPath[0]='\0';
                } else {
                    strcpy(szPath,s);
                }
            }
        }
        SendMessage(hwnd, BFFM_SETSELECTION, TRUE,(LPARAM) szPath);
        break;
    case BFFM_SELCHANGED:                                           // Indicates the selection has changed.
        if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szPath)) {       // convert pidl to path
            SendMessage(hwnd, BFFM_SETSTATUSTEXT,0,(LPARAM)szPath); // Send path
        }
        break;
    }
    return 0;   // Always returns 0
}

AVSValue __cdecl  FSelFolder(AVSValue args, void* user_data, IScriptEnvironment* env) {
    char * myName="FSelDir: ";
    const char * title  =args[0].AsString("");
    const char * dir    =args[1].AsString(".");         // Default to '.' = current directory

    LPMALLOC pMalloc;                                       // Shell allocator
    if (!SUCCEEDED(SHGetMalloc(&pMalloc))) {                // Did we successfully get the shell mem alloc interaface
        env->ThrowError("%sCannot get Shell Alloc Interface",myName);
    }

    char szFold[MAX_PATH * 2];
    strcpy(szFold,dir);
    int flgs= \
        BIF_STATUSTEXT        |
        BIF_RETURNFSANCESTORS |
        BIF_RETURNONLYFSDIRS  |                         // File system objects only (selectable), DONT SEEM TO WORK PROPER.
        BIF_EDITBOX           |                         // EDITBOX (ie 4.0 + Only)
        BIF_NEWDIALOGSTYLE;                             // 6.0 + only (xp+)
    BROWSEINFO bi;                                      // Browse structure
    ZeroMemory(&bi,sizeof(bi));                         // clr
    bi.hwndOwner        = NULL;                         // No owner window
    bi.pidlRoot         = NULL;                         // Desktop
    bi.pszDisplayName   = NULL;                         // We are gonna get path ourselves
    bi.lpszTitle        = title;
    bi.ulFlags          = flgs;
    bi.lpfn             = FSelFolderCallback;           // Browse callback function
    bi.lParam           = (LPARAM)szFold;
    //
    LPITEMIDLIST pidl = SHBrowseForFolder(&bi); // return NULL on user CANCEL, else pidl, user must free using shell allocator
    if (pidl==NULL) {
        dprintf("%sUser CANCELLED",myName);
        pMalloc->Release();                             // done with shell allocator
        return 0;
    }
    bool b = (SHGetPathFromIDList(pidl,szFold)!=0); // Converts an item identifier list to a file system path (MUST be filesystem)
    pMalloc->Free(pidl);                        // free the pidl
    pMalloc->Release();                         // done with shell allocator
    if(!b) {
        dprintf("%sNot a Filesystem Object",myName);
        return -1;
    }
//  dprintf("%s OK Single file = %s",myName,szFold);
    return env->SaveString(szFold);
}



extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
  env->AddFunction("FSelOpen"  ,"[title]s[dir]s[filt]s[fn]s[multi]b",FSelOpen,0);
  env->AddFunction("FSelSaveAs","[title]s[dir]s[filt]s[fn]s",FSelSaveAs,0);
  env->AddFunction("FSelFolder","[title]s[dir]s",FSelFolder,0);
  return 0;
}
EDIT: the "OFN_NOCHANGEDIR; // restore original current directory if user changed. Does NOT work for GetOpenFileName."

comment seems untrue, seems that the file selector has it's own version of current directory which it keeps as user selected
for a certain amount of time and then reverts to current directory when that time expires. Current working directory is not changed
by the functions.
__________________
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; 15th December 2018 at 14:48.
StainlessS 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 17:24.


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