Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

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

Reply
 
Thread Tools Search this Thread Display Modes
Old 2nd February 2016, 23:36   #1  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
SawBones(FrameSurgeon)

SawBones/FrameSurgeon, a VirtualDub2/Avisynth script, utility combo to edit bad frames.
Create Command file in VirtualDub2 with Sawbones, and use Command file in Avisynth script function FrameSurgeon().

SawBones.ReadMe.txt (v1.12) [Requires VirtualDub2 recent build 43602+, or thereabouts, and Windows system NotePad]
Code:
SawBones v1.12, (c) StainlessS @ Doom9:- https://forum.doom9.org/showthread.php?t=173158

SawBones/FrameSurgeon, a VirtualDub2/Avisynth script, utility combo to edit bad frames.

NOTE, VirtualDub2, formerly named VirtualDubFilterMod by 'Shekh the Magnificent':- https://forum.doom9.org/showthread.php?t=172021
(Sawbones v1.12 requires the new renamed version ie VirtualDub2, somewhere in the region of build 43602+).

Create Command file in VirtualDub2 [VDub2] with Sawbones, and use Command file in Avisynth script function FrameSurgeon.
SawBones now requires VirtualDub2, and also requires standard system NotePad, both NotePad and VDub2 AVS Script editor
windows should be open (you can make them smallish and leave them above/below the VDub2 main window). Sawbones will appear as a
little icon on the Right Hand Side of the task bar (SawBones does not have a window).

Quick intro:
    Create a Command.txt file and load into NotePad. Create a client script calling FrameSurgeon with args
        FrameSurgeon(...,Cmd="Command.txt",Final=False,Show=True)
    and open this client script in VDub2 and with the VDub2 Script editor window open, then run SawBones, now you are set to go.
        You can scroll through a video clip in VDub2, and press the SawBones "Frame Delete" key combo to insert a FrameSurgeon
    delete (DEL n) command for the current frame into the NotePad Editor. You press the keys with VDub2 as the active window (not NotePad).
    After entering the frame delete command, you could (if desired) then press the 'Save & Refresh' key combo, and the contents of
    NotePad Command.txt file will be saved, and then VDub2 will reload the script at the same position so you can see the deleted frame.
    (In actual fact, when using FrameSurgeon with Sawbones, you should use the FrameSurgeon args Final=False,Show=True, so that
    FrameSurgeon will not actually delete frames, but only mark the frames with some "DUMMY_DELETE" type subtitle in red,
    deleting them for real would screw up any further edits, plus you can scroll back and forth to see what
    frames will be deleted and perhaps spot any mistakes). Save your Command.txt file, you can now run the same client
    script with Final=True,Show=False to edit the clip for real, job done.


*** Current frame is shown in VDub2 in the middle of the status bar. ***
*** Ranges are marked in VDub2 via HOME and END keys, shown at Left of status bar (when marked). ***
*** FXd clips (where d is Digit 1-9) are user provided to FrameSurgeon.avs function and default to source clip if not user supplied. ***
*** Interpolation commands in FrameSurgeon are for Planar and YUY2 only (may depend upon mvtools version), others any colorspace. ***

It is important to NOT do any VDub2 clip editing, if you eg delete a frame in VDub2 [DELETE key], then all frames after
that frame will be off by 1, and so all SawBones edited ranges/frames inserted later into NotePad file will be also off by 1.
SawBones uses CTRL/DELETE and CTRL/SHIFT/DELETE keys for deletion, rather than VDub2 DELETE key.

The VDub2 loaded clip can be either an AVI or AVS clip, it makes no difference but the Save & Refresh command will NOT
work as expected with an AVI, as it will try to reload an avs script, not an AVI, so suggest that always use AVS as input to
VDub2 with Sawbones.
You could eg have a stacked avs script multi-window frame open in VDub2 so as to choose from your FXd clips within Sawbones.


All SawBones Keyboard commands that are inserted into NotePad command Text file:-

    CTRL/F1             CopyFromPrevious frame to current frame (ie replace source current frame n with source frame n - 1. (CP n)
    CTRL/F2             CopyFromNext frame to current frame (ie replace source current frame n with source frame n + 1. (CN n)

    CTRL/1              Replace current frame with same frame from FX1 clip. (FX1 n)
    CTRL/2              Replace current frame with same frame from FX2 clip. (FX2 n)
    CTRL/3              Replace current frame with same frame from FX3 clip. (FX3 n)
    CTRL/4              Replace current frame with same frame from FX4 clip. (FX4 n)
    CTRL/5              Replace current frame with same frame from FX5 clip. (FX5 n)
    CTRL/6              Replace current frame with same frame from FX6 clip. (FX6 n)
    CTRL/7              Replace current frame with same frame from FX7 clip. (FX7 n)
    CTRL/8              Replace current frame with same frame from FX8 clip. (FX8 n)
    CTRL/9              Replace current frame with same frame from FX9 clip. (FX9 n)

    CTRL/SHIFT/1        Replace range with same range from FX1 clip. (FX1 s,e)
    CTRL/SHIFT/2        Replace range with same range from FX2 clip. (FX2 s,e)
    CTRL/SHIFT/3        Replace range with same range from FX3 clip. (FX3 s,e)
    CTRL/SHIFT/4        Replace range with same range from FX4 clip. (FX4 s,e)
    CTRL/SHIFT/5        Replace range with same range from FX5 clip. (FX5 s,e)
    CTRL/SHIFT/6        Replace range with same range from FX6 clip. (FX6 s,e)
    CTRL/SHIFT/7        Replace range with same range from FX7 clip. (FX7 s,e)
    CTRL/SHIFT/8        Replace range with same range from FX8 clip. (FX8 s,e)
    CTRL/SHIFT/9        Replace range with same range from FX9 clip. (FX9 s,e)

    CTRL/SHIFT/ALT/1    Interpolate current frame n using source n-1 and n+1 as source frames. (I1 n)
    CTRL/SHIFT/ALT/2    Interpolate 2 frames starting at current frame n, using source n-1 and n+2 as source frames. (I2 n)
    CTRL/SHIFT/ALT/3    Interpolate 3 frames starting at current frame n, using source n-1 and n+3 as source frames. (I3 n)
    CTRL/SHIFT/ALT/4    Interpolate 4 frames starting at current frame n, using source n-1 and n+4 as source frames. (I4 n)
    CTRL/SHIFT/ALT/5    Interpolate 5 frames starting at current frame n, using source n-1 and n+5 as source frames. (I5 n)
    CTRL/SHIFT/ALT/6    Interpolate 6 frames starting at current frame n, using source n-1 and n+6 as source frames. (I6 n)
    CTRL/SHIFT/ALT/7    Interpolate 7 frames starting at current frame n, using source n-1 and n+7 as source frames. (I7 n)
    CTRL/SHIFT/ALT/8    Interpolate 8 frames starting at current frame n, using source n-1 and n+8 as source frames. (I8 n)
    CTRL/SHIFT/ALT/9    Interpolate 9 frames starting at current frame n, using source n-1 and n+9 as source frames. (I9 n)

    CTRL SHIFT ALT /    Interpolate Range. Ie in Avisynth Inclusive mode, where range is 100,101 [2 frames] then result = (I2 100)
                        The specified range start and end are the outer bad frames.
                        You can change this key combination used for "Interpolate Range" by changing the ini file item
                        "KEY_InterpolateRange=^+!{/}", to something else, in sequence they are CTRL(^) SHIFT(+), ALT(!) and '/' keys
                        pressed together. The Sawbones.ini file is created upon first use of the executable.

    CTRL/DELETE         Delete current frame. (DEL n) [FrameSurgeon Frame/Range deletes are processed AFTER ALL interpolations/replacements]
    CTRL/SHIFT/DELETE   Delete range (DEL s,e)
                            NOTE. If using below "Save & Refresh" with Avisynth loaded script, then DO NOT USE ANY delete commands
                        within SawBones UNLESS, you call FrameSurgeon with arg "FINAL=FALSE". The FrameSurgeon arg FINAL=FALSE,
                        causes FrameSurgeon to NOT actually delete frames, it will only MARK those frames as being targetted for deletion
                        (the frames will show some kind of DUMMY_DELETE text subtitled onto those frames). If you do not call FrameSurgeon with
                        FINAL=FALSE, then FrameSurgeon will indeed delete the frames, but VDub2/Sawbones will have no idea that
                        it has been done, and further replacements or deletions will be on the WRONG ranges.
                            IMPORTANT:- See also below Save & Refresh command.

    CTRL/SHIFT/ALT/,    Save & Refresh.
                        Ie, Save NotePad Command.txt, refresh/reload Avisynth Script, jumping back to original position in VDub2.
                        You can change this key combination used for "Save & Refresh" by changing the ini file item
                        "KEY_NotepadSaveAndRefresh=^+!{,}" to something else, in sequence they are CTRL(^) SHIFT(+), ALT(!) and ',' keys
                        pressed together. The Sawbones.ini file is created upon first use of the executable.
                        NOTE, it is quite difficult to find key combo's that are not used system wide, and also not used by VDub2.
                        It does also not improve matters where eg Graphics cards install a whole bunch of additional hotkey combos, reducing what
                        is available to the user. (Who actually thinks they need permanent system wide hotkeys to access graphic card settings,
                        almost useless and just an annoyance [particularly if they supplant your own hotkeys], disable if at all possible).
                        Some key combos may not work on some international keyboards and so you can change ALL key combos in the ini file,
                        a couple of URL links to further info will be embedded in the ini file.
                        Hopefully most Sawbones key combos are available to you, they were made deliberately a little awkard
                        in the hope that they are not used elsewhere on your system, if they already in-use then I'm afraid you may need to mod the
                        Sawbones ini file (after ascertaining what keys ARE available to you).
                        NOTE, Save & Refresh requires that VDub2 Script Editor window is also open to refresh the avisynth script
                          (perhaps best if you make it small and stack it next to the NotePad window).
                        If Script Editor is NOT open, then only a NotePad save of the Command text is done, we cannot refresh/reload the avs script
                        into VDub2 if script editor is not open.
                        IMPORTANT:- See also above DELETE commands.

    CTRL/SHIFT/ALT/PAUSE is TERMINATE Program (or close via System Tray icon). PAUSE is also known as BREAK, usually next to Scroll Lock.

NOTE: A range shown in VDub status bar as eg "Selecting Frames 100-102(2 frames)" represents frames 100 and 101, frame 102 is exclusive and
does not count. By default, SawBones uses Inclusive END frame ranges (same as Avisynth where end frame DOES count).
You can change the default behaviour to behave the same as VDub by Running SawBones.Exe at least once and changing the auto created
SawBones.ini file contents from "RangeEndIsExclusive=0" to "RangeEndIsExclusive=1". When using VDub "RangeEndIsExclusive=1" mode,
we subtract 1 from the End Frame to convert to Avisynth End Frame Inclusive specification when writing range to NotePad command.
When sending a command using VDub exclusive mode with a status bar range of "100-100(frames=0)", it will beep and show a "No Frames"
type error message for a few seconds, in Avisynth Inclusive mode it will send a 1 frame range command to the NotePad window.

It is easy to see what is happening as the NotePad window will be visible and after each insertion into NotePad, an ENTER key
will also be sent to move the cursor down one line, each command is on its own line. If you make a mistake, it is easy to
just switch to NotePad window and delete the erroneous line (Notepad window needs to be only a few lines tall).

Where same frames are flagged for replacment mulitple times, later one will take precidence.
All frame/range deletes will be done AFTER replacements, multiple deletes on same frame will only result on single frame deletion.
Already Interpolated frame/range CANNOT be replaced and will produce an error (In avs script), but they can be deleted.

FrameSurgeon.avs requires either AVS+ or GScript, MvTools, RT_Stats, FrameSel, ClipClop and Prune Plugins.

Sawbones.exe AutoiIt compiled executable with source provided (SawBones.au3), just click Menu Tools/build to create executable
(In Scite4AutoIt3 editor). Requires AutoIt3 and  Scite4AutoIt3 editor to re-build executable.
AutoIt:- https://www.autoitscript.com/site/
Also see Next post.

See next post.

See Mediafire or SendSpace below in my sig

Last edited by StainlessS; 13th August 2022 at 15:45. Reason: Update
StainlessS is offline   Reply With Quote
Old 2nd February 2016, 23:38   #2  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
text too big for previous post
Code:
Default: SawBones.ini file, created on first use of Sawbones.Exe (can just delete ini file and will be recreated on next execution)
You can edit the "KEY_xxxxx" entries in the [UserKeys] Section, and also the "Comment" entry in the [UserComment] Section.
##############
    [Default]
    COMMENT_1= : SawBones v1.12
    COMMENT_2= : RangeEndIsExclusive: 0 = Avisynth : 1 = VirtualDub
    RangeEndIsExclusive=0
    [UserKeys]
    COMMENT_1= : Accelerator keys:- CTRL=^ ALT=! SHIFT=+ WINDOWS=#
    COMMENT_2= : Accelerators before key characters eg '^{a}' not '{a}^'
    COMMENT_3= : Wrap the character part (excluding ^+!#) in curly braces eg {1} for key 1
    COMMENT_4= : Use Lowercase for alphabetic keys eg {a} not {A}
    COMMENT_5= : Where multiple characters on same keyboard key, use the lower one.
    COMMENT_6= : eg CTRL/SHIFT/ALT/a = '^+!{a}' and CTRL/F1 = '^{F1}'
    COMMENT_7= : Hotkeys must not be in use by system nor by VirtualDub2 main window.
    COMMENT_8= : More=http://www.autoitscript.com/autoit3/docs/functions/Send.htm
    COMMENT_9= : More=http://www.autoitscript.com/autoit3/docs/functions/HotKeySet.htm
    COMMENT10= : Count of currently modified HotKeys = 0
    KEY_DeleteFrame=^{DELETE}
    KEY_DeleteRange=^+{DELETE}
    KEY_CopyFrameFromSourcePrevious=^{F1}
    KEY_CopyFrameFromSourceNext=^{F2}
    KEY_ReplaceFrameWith_FX1=^{1}
    KEY_ReplaceFrameWith_FX2=^{2}
    KEY_ReplaceFrameWith_FX3=^{3}
    KEY_ReplaceFrameWith_FX4=^{4}
    KEY_ReplaceFrameWith_FX5=^{5}
    KEY_ReplaceFrameWith_FX6=^{6}
    KEY_ReplaceFrameWith_FX7=^{7}
    KEY_ReplaceFrameWith_FX8=^{8}
    KEY_ReplaceFrameWith_FX9=^{9}
    KEY_ReplaceRangeWith_FX1=^+{1}
    KEY_ReplaceRangeWith_FX2=^+{2}
    KEY_ReplaceRangeWith_FX3=^+{3}
    KEY_ReplaceRangeWith_FX4=^+{4}
    KEY_ReplaceRangeWith_FX5=^+{5}
    KEY_ReplaceRangeWith_FX6=^+{6}
    KEY_ReplaceRangeWith_FX7=^+{7}
    KEY_ReplaceRangeWith_FX8=^+{8}
    KEY_ReplaceRangeWith_FX9=^+{9}
    KEY_Interpolate_1=^+!{1}
    KEY_Interpolate_2=^+!{2}
    KEY_Interpolate_3=^+!{3}
    KEY_Interpolate_4=^+!{4}
    KEY_Interpolate_5=^+!{5}
    KEY_Interpolate_6=^+!{6}
    KEY_Interpolate_7=^+!{7}
    KEY_Interpolate_8=^+!{8}
    KEY_Interpolate_9=^+!{9}
    KEY_InterpolateRange=^+!{/}
    KEY_NotepadSaveAndRefresh=^+!{,}
    [UserComment]
    Comment=QWERTY_UK
##############

A SawBones created Command file may look something like this:-
(Later commands take presidence so order does matter, Interpolated ranges CANNOT be replaced[error in FrameSurgeon] but can be later deleted)

##############
    DEL 400,449    # Delete frames 400 to 449 (AFTER ALL replacments done, ie as if at end of command file)
    I3  10         # Interp 3 frames 10 -> 12, using 9 and 13 as source
    I   20         # Interp single frame 20, using 19 and 21 as source
    I   24,26      # Interp range 24,26, using 23 and 27 as source (limited to max 9 bad frames).
    CP  40         # Replace frame 40 with frame 39
    CN  41         # Replace frame 41 with frame 42
    FX1 50,199     # replace range 50,199 with same range from FX1 clip
    FX2 300,599    # replace range 300,599 with same range from FX2 clip
##############

        SawBones, is a compiled AutoIt script utility. https://www.autoitscript.com/site/autoit/
    AutoIt was initially designed for PC “roll out” situations to reliably automate and configure thousands of PCs.
    Over time it has become a powerful language that supports complex expressions, user functions, loops and everything
    else that veteran scripters would expect.

    FrameSurgeon.avs requires either AVS+ or GScript, MvTools, RT_Stats, FrameSel, ClipClop and Prune Plugins.

##############
ssS
The stupendous VirtualDub2 (formerly VirtualDubFilterMod, by Shekh the magnificent):- https://forum.doom9.org/showthread.php?t=172021
DebugView (view error and debug messages from various programs):- https://docs.microsoft.com/en-us/sys...oads/debugview
FrameSurgeon sends some messages to DebugView.
EDIT:
When Final=False, Delete commands appear like so (marked for deletion only, only deleted for real when Final=True)
Set FINAL=False when using SawBones.
Reason:- If a frame were deleted for real in FrameSurgeon, then any deletes following that frame would (in sawbones) all be off by 1 frame.
Off by 1 frame thing would not affect non delete edits, as deletes are processed only after all other edits are done.
(SawBones/VirtualDub2, have no idea what Avisynth has deleted before clip was loaded into VirtualDub)
One additional advantage of the Dummy Delete frames is that you can see what will be deleted when FINAL=True.
__________________
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; 13th August 2022 at 15:51. Reason: Update
StainlessS is offline   Reply With Quote
Old 2nd February 2016, 23:39   #3  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
FrameSurgeon.avs (Excluding above posted text extracted from FrameSurgeon)

EDIT: Made FrameSurgeon Final default=True.

Code:
Function FrameSurgeon(clip c, String "Scmd",String "Cmd",bool "Show",Int "ShowMode",int "dv",
        \ clip "FX1",clip "FX2",clip "FX3",clip "FX4",clip "FX5",clip "FX6",clip "FX7",clip "FX8",clip "FX9",
        \ int "pel",int "sharp",int "rfilter",Float "ml",Bool "Final",Bool "NoErr") {
    myName="FrameSurgeon: "
    IsAvsPlus=FindStr(UCase(versionString),"AVISYNTH+")!=0  HasGScript=RT_FunctionExist("GScript")
    Assert(IsAvsPlus || HasGSCript, RT_String("%sNeed either GScript or AVS+",myName))
    Scmd    = Default(Scmd,"")         # User supplied list of newline separated commands.
    Cmd     = Default(Cmd,"")          # User supplied Filename containing newline separated commands.
    Show    = Default(Show,false)      # Show Info on frame
    ShowMode= Default(ShowMode,0)      # 0 = ClipClop (pre Delete frames), 1 = Prune/FrameSel (Post Delete Frames).
    dv      = Default(dv,0)            # ClipClop DebugView level (0 - 4, Need DebugView utility)
    Final   = Default(Final,True)      # Do Real Deletes if true
    NoErr   = Default(NoErr,false)     # If true, Ingore FXd commands for undefined FXd clips.
    ############
    Cmd = (Cmd!="") ? RT_GetFullPathName(Cmd) : ""

    FuncS="""
        Function FrameSurgeonRejectRanges(clip c,String "Cmd",Bool "Show",int "dv") {
            PruneCmd = RT_GetFullPathName("~Prune_"+RT_LocalTimeString+".txt")
            FrameSel_CmdReWrite(c,PruneCmd,cmd=Cmd,reject=true,Prune=True,range=true)
            Prune(c,Cmd=PruneCmd,FadeIn=True,FadeSplice=True,FadeOut=True,Fade=1.0,show=Show,dv=dv)
            RT_FileDelete(PruneCmd)
            Return Last
        }
        Function FSIsDigit(String S)   {return (RT_Ord(S)>=48&&RT_Ord(S)<=57)}
        Function FSIsComma(String S)   {return RT_Ord(S)==44}
        Function FSIsHyphen(String S)  {return RT_Ord(S)==45}
        Function FSEatWhite(String S)  {pos=1 While(RT_Ord(S,pos=pos)==32||RT_Ord(S,pos=pos)==9){pos=pos+1} return(pos>1)?MidStr(S,pos):S}
        Function FSEatDigits(String S) {pos=1 While(RT_Ord(S,pos=pos)>=48&&RT_Ord(S,pos=pos)<=57){pos=pos+1} return(pos>1)?MidStr(S,pos):S}
        Function FSEatOSep(String S)   {pos=1 While(RT_Ord(S,pos=pos)==40||RT_Ord(S,pos=pos)==44){pos=pos+1} return(pos>1)?MidStr(S,pos):S}

        Function FrameSurgeonSplitCommands(String CmdS,String ClopCmdFN,String DelCmdFN,Bool Final,String RetName) {
            # Separate commands in CmdS into ClipClop, and FrameSel Reject frame commands
            myName="FrameSurgeonSplitCommands: "
            fxUsed=0
            IdStat=False
            Lines = RT_TxtQueryLines(CmdS)
            For(i=0,Lines-1) {
                SSS=RT_TxtGetLine(CmdS,i).FSEatWhite
                if(SSS!="" && RT_Ord(SSS)!=35) {                                    # NOT Empty line or Hash (#) ALL Comment
                    if(RT_FindStr(SSS,"DEL",Sig=False)==1) {                        # 'DEL' delete command
                        S=MidStr(SSS,4).FSEatWhite
                        Assert(FSIsDigit(S),RT_String("%sLINE_%d Expecting frame number after 'DEL'\n'%s'",myName,i+1,SSS))
                        if(Final) {
                            RT_WriteFile(DelCmdFN,"%s",S,Append=True)               # Copy remainder of line (FrameSel/Prune parses Range)
                        } else {
                            RT_WriteFile(DelCmdFN,"DUMMYDELETE %s",S,Append=True)   # Copy remainder of line
                        }
                    } else if(RT_Ord(SSS)==45) {                                    # '-' delete command
                        S=MidStr(SSS,2).FSEatWhite
                        Assert(FSIsDigit(S),RT_String("%sLINE_%d Expecting frame number after '-'\n'%s'",myName,i+1,SSS))
                        if(Final) {
                            RT_WriteFile(DelCmdFN,"%s",S,Append=True)               # Copy remainder of line (FrameSel/Prune parses Range)
                        } else {
                            RT_WriteFile(DelCmdFN,"DUMMYDELETE %s",S,Append=True)   # Copy remainder of line
                        }
                    } else if(FSIsDigit(SSS)){
                        Assert(false,RT_String("%sLINE_%d Cannot use clip index in FrameSurgeon\nMUST use Command Mnemonic\n'%s'",myName,i+1,SSS))
                    } else {
                        if(RT_Ord(SSS)==73||RT_Ord(SSS)==105) {                 # 'I?' or 'i?' Command used ?
                            IdStat=true                                         # We got at least 1 Interpolate command
                            if(RT_Ord(SSS,2)<48||RT_Ord(SSS,2)>57) {            # IF NOT 'Id' nor 'id' Command
                                STEM=SSS.MidStr(2).FSEatWhite.FSEatOSep         # Eat 'I' and white space and separators ['(' or ',']
                                Assert(STEM.FSIsDigit,RT_String("%sLINE_%d Expecting Interpolate Start frame\n'%s'",myName,i+1,SSS))
                                SFrm=RT_NumberValue(STEM)
                                EFrm=SFrm
                                STEM=STEM.FSEatDigits.FSEatWhite
                                HasComma=STEM.FSIsComma
                                STEM=(HasComma)?STEM.MidStr(2):STEM
                                STEM=STEM.FSEatWhite
                                HasNeg=STEM.FSIsHyphen
                                STEM=(HasNeg)?STEM.MidStr(2):STEM
                                STEM=STEM.FSEatWhite
                                HasDigit=STEM.FSIsDigit
                                Assert(HasDigit||!HasComma,RT_String("%sLINE_%d Expecting Interpolate End frame\n'%s'",myName,i+1,SSS))
                                Assert(HasDigit||!HasNeg,RT_String("%sLINE_%d Expecting Interpolate -ve Frame Count\n'%s'",myName,i+1,SSS))
                                EFrm=(HasDigit) ? RT_NumberValue(STEM) : EFrm
                                STEM=STEM.FSEatDigits
                                Frms= (HasNeg) ? EFrm : EFrm-SFrm+1
                                Assert(Frms>=1 && Frms<=9,RT_String("%sLINE_%d Interpolate Frame Count 1 to 9 ONLY\n'%s'",myName,i+1,SSS))
                                SSS=RT_String("I%d %d%s",Frms,SFrm,STEM)         # Simulate ClipClop Id Command
                            }
                        } else if((RT_Ord(SSS)==70||RT_Ord(SSS)==102)&&(RT_Ord(SSS,2)==88||RT_Ord(SSS,2)==120)) { # 'FX' or 'fx' Command used ?
                            num=RT_Ord(SSS,3)-48
                            if(num>=1 && num<=9) {
                                fxUsed=RT_BitSet(fxUsed,num)
                            }
                        }
                        RT_WriteFile(ClopCmdFN,"%s",SSS,Append=True)                 # Copy ClipClop Commands (ClipClop parses Range)
                    }
                }
            }
            Eval(RT_String("Global %s=%d",retName,fxUsed))  # Set Return Global for client
            Return IdStat
        }
        # Temp file Names
        ClopCmdFN = RT_GetFullPathName("~ClipClop_" + RT_LocalTimeString(file=True)+".txt")
        DelCmdFN  = RT_GetFullPathName("~Delete_"   + RT_LocalTimeString(file=True)+".txt")
        # Init to zero, one-time Globals, for returning which FXd clips used in commands
        retNameC="G_FS_FxUsedC_"+RT_LocalTimeString(file=True)  Eval(RT_String("Global %s=0",retNameC))
        retNameS="G_FS_FxUsedS_"+RT_LocalTimeString(file=True)  Eval(RT_String("Global %s=0",retNameS))
        # Separate into Replace(ClipClop) and Delete(FrameSel/Prune) Commands, Cmd File Processed first
        UseMvTools=(Cmd!=""&&Exist(Cmd)) ? FrameSurgeonSplitCommands(RT_ReadTxtFromFile(Cmd),ClopCmdFN,DelCmdFN,Final,retNameC) : False
        UseMvTools=(SCmd!="")            ? FrameSurgeonSplitCommands(SCmd,ClopCmdFN,DelCmdFN,Final,retNameS)||UseMvTools        : UseMvTools
        Assert(c.IsPlanar||c.IsYUY2||!UseMvTools,"FrameSurgeon: Id Interpolation commands Planar and YUY2 ONLY")
        # Get FrameSurgeonSplitCommands results from one-time Globals
        Eval(RT_String("fxUsedC=%s",retNameC))  Eval(RT_String("fxUsedS=%s",retNameS))
        # find FXd commands used for undefined FXd clips
        FXErr=0 E_C_Str="" E_S_Str=""
        for(i=1,9) {
            Eval(RT_string("Fxdef=FX%d.Defined",i))
            if(!fxDef) {
                if(RT_BitTst(fxUsedC,i) || RT_BitTst(fxUsedS,i)) {
                    FXErr=FXErr+1
                    if(RT_BitTst(fxUsedC,i)) {
                        STemp=RT_String("*** WARNING *** FX%d Used in CMD but not supplied as clip\n",i)
                        E_C_Str=E_C_Str+STemp
                    }
                    if(RT_BitTst(fxUsedS,i)) {
                        STemp=RT_String("*** WARNING *** FX%d Used in SCMD but not supplied as clip\n",i)
                        E_S_Str=E_S_Str+STemp
                    }
                }
            }
        }
        if(FXErr!=0) {
            # FXd clip is used in SCMD or CMD, BUT NOT supplied by client script
            RT_DebugF("\n%s%s",E_C_Str,E_S_Str,name=myName)
            Assert(NoErr || SHOW || !FINAL,RT_String("%sFINAL=True (Set NoErr=True to Ignore below commands, src will be used)\n%s%s",myName,E_C_Str,E_S_Str))
        }
        ############
        BSZ     = c.Height/(40*2)*2  FSZ=c.Height/(5*2)*2
        LBOX    = c.LetterBox(BSZ,BSZ,BSZ,BSZ,$0000FF)
        SYNTH   = (Show||!FINAL) # If SHOW or FINAL=False then synthesize UnDefined FXd clips (subtitled), Otherwise use src clip c.
        FX1     = Default(FX1,(SYNTH)?LBOX.Subtitle("FX1",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        FX2     = Default(FX2,(SYNTH)?LBOX.Subtitle("FX2",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        FX3     = Default(FX3,(SYNTH)?LBOX.Subtitle("FX3",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        FX4     = Default(FX4,(SYNTH)?LBOX.Subtitle("FX4",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        FX5     = Default(FX5,(SYNTH)?LBOX.Subtitle("FX5",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        FX6     = Default(FX6,(SYNTH)?LBOX.Subtitle("FX6",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        FX7     = Default(FX7,(SYNTH)?LBOX.Subtitle("FX7",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        FX8     = Default(FX8,(SYNTH)?LBOX.Subtitle("FX8",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        FX9     = Default(FX9,(SYNTH)?LBOX.Subtitle("FX9",Align=5,Size=FSZ,Text_Color=$0000FF):c)
        ###
        ###
        DUMMYDELETE = c.LetterBox(BSZ,BSZ,BSZ,BSZ,$FF0000).Subtitle("DUMMY DELETE",Align=5,Size=FSZ/2,Text_Color=$FF0000)
        CP          = c.DeleteFrame(c.Framecount()-1).DuplicateFrame(0)
        CN          = c.DuplicateFrame(c.Framecount()-1).DeleteFrame(0)
        ###
        NICKNAME=("  # Define ClipClop Command mnemonics allowed in command string and file.
            DUMMYDELETE=1    # PRIVATE COMMAND, for FINAL=False
            CP         =2    # CopyFromPrevious (frame n replaced with frame n-1)
            CN         =3    # CopyFromNext     (frame n replaced with frame n+1)
            FX1        =4    # FX1 (User replacement FXd clips)
            FX2        =5    # FX2
            FX3        =6    # FX3
            FX4        =7    # FX4
            FX5        =8    # FX5
            FX6        =9    # FX6
            FX7        =10   # FX7
            FX8        =11   # FX8
            FX9        =12   # FX9
        ")
        if(!FINAL && Exist(DelCmdFN)) {
            RT_WriteFile(ClopCmdFN,"%s",RT_ReadTxtFromFile(DelCmdFN),Append=True)   # Append Delete Prune commands to ClipClop command file
            RT_FileDelete(DelCmdFN)                                                 # DONT PRUNE
            ShowMode=0                                                              # Force ClipClop ShowMode
        }
        if(!UseMvTools) {
            Clopped = (Exist(ClopCmdFN)) ? c.ClipClop(
                \ DUMMYDELETE,
                \ CP,
                \ CN,
                \ FX1,FX2,FX3,FX4,FX5,FX6,FX7,FX8,FX9,
                \ cmd=ClopCmdFN,sCmd="",show=(SHOW&&ShowMode==0),ver=False,dv=DV,NoErr=False,nickname=NICKNAME,Purge=True
            \) : c
        } else {
            pel     = Default(pel,2)           # Default as for MSuper(), ie 2, range=1 or 2 or 4
            sharp   = Default(sharp,2)         # Default as for MSuper(), ie 2, range=0 -> 2
            rfilter = Default(rfilter,2)       # Default as for MSuper(), ie 2, range=0 -> 4
            ml      = Float(default(ml,100.0)) # Default as for MFlowInter(), ie 100.0, range=greater than 0.0.
            ###
            thSCD1=(8*8)*255  thSCD2=255  BLEND=False   bs=(CP.width>960) ? 16 : 8
            supFilt  = CP.Blur(0.6).MSuper(pel=2,sharp=sharp,rfilter=rfilter,hpad=16, vpad=16)
            sup      = CP.MSuper(pel=2,sharp=sharp,rfilter=rfilter,hpad=16, vpad=16, levels=1)
            For(Bad=1,9) {
                Eval(RT_String("I%0.2d_bv=supFilt.MAnalyse(isb=true, delta=%d,blksize=bs,overlap=bs/2)",Bad,Bad+1))
                Eval(RT_String("I%0.2d_fv=supFilt.MAnalyse(isb=false,delta=%d,blksize=bs,overlap=bs/2)",Bad,Bad+1))
                Eval(RT_String("I%0.2d_bv=MRecalculate(sup,I%0.2d_bv,blksize=bs/2,overlap=2,thSAD=100)",Bad,Bad))
                Eval(RT_String("I%0.2d_fv=MRecalculate(sup,I%0.2d_fv,blksize=bs/2,overlap=2,thSAD=100)",Bad,Bad))
                for(i=1,Bad) {
                    Eval(RT_String("I%0.2d_%0.2d=CP.MFlowInter(sup,I%0.2d_bv,I%0.2d_fv,time=100.0*%d/%d,ml=ml,Blend=BLEND,thSCD1=thSCD1,thSCD2=thSCD2)",
                        \ Bad,i,Bad,Bad,i,Bad+1))
                }
            }
            ###
            NICKNAME=NICKNAME+("
            I1 =13:1  # Interpolate 1
            I2 =14:2  # Interpolate 2
            I3 =16:3  # Interpolate 3
            I4 =19:4  # Interpolate 4
            I5 =23:5  # Interpolate 5
            I6 =28:6  # Interpolate 6
            I7 =34:7  # Interpolate 7
            I8 =41:8  # Interpolate 8
            I9 =49:9  # Interpolate 9
            ")
            ###
            Clopped = (Exist(ClopCmdFN)) ? c.ClipClop(
                \ DUMMYDELETE,
                \ CP,
                \ CN,
                \ FX1,FX2,FX3,FX4,FX5,FX6,FX7,FX8,FX9,
                \ I01_01,
                \ I02_01,I02_02,
                \ I03_01,I03_02,I03_03,
                \ I04_01,I04_02,I04_03,I04_04,
                \ I05_01,I05_02,I05_03,I05_04,I05_05,
                \ I06_01,I06_02,I06_03,I06_04,I06_05,I06_06,
                \ I07_01,I07_02,I07_03,I07_04,I07_05,I07_06,I07_07,
                \ I08_01,I08_02,I08_03,I08_04,I08_05,I08_06,I08_07,I08_08,
                \ I09_01,I09_02,I09_03,I09_04,I09_05,I09_06,I09_07,I09_08,I09_09,
                \ cmd=ClopCmdFN,sCmd="",show=(SHOW&&ShowMode==0),ver=False,dv=DV,NoErr=False,nickname=NICKNAME,Purge=True
            \) : c
        }
    """
    IsAvsPlus?Eval(FuncS):GScript(FuncS)
    Result = (Exist(DelCmdFN)) ? FrameSurgeonRejectRanges(clopped,Cmd=DelCmdFN,show=(SHOW&&ShowMode==1),dv=dv) : Clopped
    RT_FileDelete(ClopCmdFN)    RT_FileDelete(DelCmdFN)     # Delete Temps
    Return Result
}
__________________
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; 17th April 2018 at 16:08. Reason: Update
StainlessS is offline   Reply With Quote
Old 16th April 2016, 20:09   #4  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
SawBones.au3 source
Code:
#cs ----------------------------------------------------------------------------
    This program is free software; you can redistribute it and/or modify it under any terms terms you like.

    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.
    Use at you own risk.

#ce ----------------------------------------------------------------------------
; SawBones v1.09 by StainlessS ... compiled with AutiIt v3.3.14.5

#include <MsgBoxConstants.au3>
#include <Misc.au3>
Opt("MustDeclareVars", 1)
;;;
Global Const $Version       = "SawBones v1.09"
Global Const $APP_NAME      = "SawBones.Exe"
Global Const $APP_INI       = "SawBones.ini"
Global Const $Watching      = "    SawBones is WATCHING    "
Global Const $APPTitle      = "VirtualDub2"                              ; VirtualDub2 matches as "VirtualDub2" with traiiling "Build number" on title bar.
Global Const $ScriptTitle   = "VirtualDub2 Script Editor"                ; VirtualDub2 Script Editor Window
Global Const $ScriptControl = "[CLASS:Scintilla; INSTANCE:1]"
Global Const $VdFrameNo     = "[CLASS:Edit; INSTANCE:1]"                 ; Frame Indicator box (bottom middle of window, just above status line)
Global Const $VDRange       = "[CLASS:msctls_statusbar32; INSTANCE:1]"   ; Frame Range (bottom Left of window, 'Selecting Frames...' when range selected)
;
; CAN CHANGE below "Notepad" and "Edit" to change editor, use AutoIt Au3Info program to get names (try 1st with NotePad.exe to see how to use it).
Global Const $EdTitle     = "[CLASS:Notepad]"                        ; NotePad Window name.
Global Const $EditControl = "[CLASS:Edit; INSTANCE:1]"               ; NotePad text editor window control.
;

;
Global Const $Doze    = 250
Global Const $ShowCntLimit = 3000 / $Doze                            ; Show 'Sawbones is WATCHING' for about 3 secs
Global $InAPP     = False
Global $ShowCnt   = 0
Global $HotkeyMods= 0

; SAVED to / GOTTEN from ini file
Global $USER_RangeEndIsExclusive=0                                   ; 0=Avisynth, 1=VDub : Will Get from SawBones.ini if exists
; User keys, change and re-build executable (Quite difficult to find keys that are not used by VirtualDub or System and available on international keyboards)
Global $USER_Comment="QWERTY_UK"
;
; Get some defaults from ini file (if exists).
$USER_RangeEndIsExclusive  = Int(IniRead(@ScriptDir & "\" & $APP_INI, "Default",  "RangeEndIsExclusive", $USER_RangeEndIsExclusive))
$USER_Comment  = IniRead(@ScriptDir & "\" & $APP_INI, "UserComment",  "Comment", $USER_Comment)


Global Const $AllKeys     = 34
Global const $KeyName     = 0
Global const $KeyDefault  = 1
Global const $KeyFuncName = 2
Global const $KeyUserSet  = 3

Global $KEYS[$AllKeys][4] = [ _
    ["KEY_TerminateProgram",            "^+!{PAUSE}",  "Fn_Terminate",         ""], _
    ["KEY_DeleteFrame",                 "^{DELETE}",   "Fn_DeleteFrame",       ""], _
    ["KEY_DeleteRange",                 "^+{DELETE}",  "Fn_DeleteRange",       ""], _
    ["KEY_CopyFrameFromSourcePrevious", "^{F1}",       "Fn_CopyFromPrev",      ""], _
    ["KEY_CopyFrameFromSourceNext",     "^{F2}",       "Fn_CopyFromNext",      ""], _
    ["KEY_ReplaceFrameWith_FX1",        "^{1}",        "Fn_DigitKey_C_1",      ""], _
    ["KEY_ReplaceFrameWith_FX2",        "^{2}",        "Fn_DigitKey_C_2",      ""], _
    ["KEY_ReplaceFrameWith_FX3",        "^{3}",        "Fn_DigitKey_C_3",      ""], _
    ["KEY_ReplaceFrameWith_FX4",        "^{4}",        "Fn_DigitKey_C_4",      ""], _
    ["KEY_ReplaceFrameWith_FX5",        "^{5}",        "Fn_DigitKey_C_5",      ""], _
    ["KEY_ReplaceFrameWith_FX6",        "^{6}",        "Fn_DigitKey_C_6",      ""], _
    ["KEY_ReplaceFrameWith_FX7",        "^{7}",        "Fn_DigitKey_C_7",      ""], _
    ["KEY_ReplaceFrameWith_FX8",        "^{8}",        "Fn_DigitKey_C_8",      ""], _
    ["KEY_ReplaceFrameWith_FX9",        "^{9}",        "Fn_DigitKey_C_9",      ""], _
    ["KEY_ReplaceRangeWith_FX1",        "^+{1}",       "Fn_DigitKey_CS_1",     ""], _
    ["KEY_ReplaceRangeWith_FX2",        "^+{2}",       "Fn_DigitKey_CS_2",     ""], _
    ["KEY_ReplaceRangeWith_FX3",        "^+{3}",       "Fn_DigitKey_CS_3",     ""], _
    ["KEY_ReplaceRangeWith_FX4",        "^+{4}",       "Fn_DigitKey_CS_4",     ""], _
    ["KEY_ReplaceRangeWith_FX5",        "^+{5}",       "Fn_DigitKey_CS_5",     ""], _
    ["KEY_ReplaceRangeWith_FX6",        "^+{6}",       "Fn_DigitKey_CS_6",     ""], _
    ["KEY_ReplaceRangeWith_FX7",        "^+{7}",       "Fn_DigitKey_CS_7",     ""], _
    ["KEY_ReplaceRangeWith_FX8",        "^+{8}",       "Fn_DigitKey_CS_8",     ""], _
    ["KEY_ReplaceRangeWith_FX9",        "^+{9}",       "Fn_DigitKey_CS_9",     ""], _
    ["KEY_Interpolate_1",               "^+!{1}",      "Fn_Interp_1",          ""], _
    ["KEY_Interpolate_2",               "^+!{2}",      "Fn_Interp_2",          ""], _
    ["KEY_Interpolate_3",               "^+!{3}",      "Fn_Interp_3",          ""], _
    ["KEY_Interpolate_4",               "^+!{4}",      "Fn_Interp_4",          ""], _
    ["KEY_Interpolate_5",               "^+!{5}",      "Fn_Interp_5",          ""], _
    ["KEY_Interpolate_6",               "^+!{6}",      "Fn_Interp_6",          ""], _
    ["KEY_Interpolate_7",               "^+!{7}",      "Fn_Interp_7",          ""], _
    ["KEY_Interpolate_8",               "^+!{8}",      "Fn_Interp_8",          ""], _
    ["KEY_Interpolate_9",               "^+!{9}",      "Fn_Interp_9",          ""], _
    ["KEY_InterpolateRange",            "^+!{/}",      "Fn_InterpRange",       ""], _
    ["KEY_NotepadSaveAndRefresh",       "^+!{,}",      "Fn_NotepadSave",       ""]]
Local $i
for $i =  0 to $AllKeys - 1
    $KEYS[$i][$KeyUserSet] = IniRead(@ScriptDir & "\" & $APP_INI, "UserKeys", $KEYS[$i][$KeyName],  $KEYS[$i][$KeyDefault])
    if $KEYS[$i][$KeyDefault] <> $KEYS[$i][$KeyUserSet] Then
        $HotkeyMods = $HotkeyMods + 1
    Endif
Next

;
If _Singleton($APP_NAME, 1) = 0 Then
    MsgBox($MB_SYSTEMMODAL, "Warning", "An occurrence of " & $APP_NAME & " is already running")
    Exit
EndIf
OnAutoItExitRegister("Fn_AtExit") ; Whatever cleanup to do on termination

; Delete the INI file.
FileDelete(@ScriptDir & "\" & $APP_INI)
; Update ini file.
IniWrite(@ScriptDir & "\" & $APP_INI, "Default",  "COMMENT_1",           " : " & $Version)
IniWrite(@ScriptDir & "\" & $APP_INI, "Default",  "COMMENT_2",           " : RangeEndIsExclusive: 0 = Avisynth : 1 = VirtualDub")
IniWrite(@ScriptDir & "\" & $APP_INI, "Default",  "RangeEndIsExclusive", $USER_RangeEndIsExclusive)
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_1",           " : Accelerator keys:- CTRL=^ ALT=! SHIFT=+ WINDOWS=#")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_2",           " : Accelerators before key characters eg '^{a}' not '{a}^'")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_3",           " : Wrap the character part (excluding ^+!#) in curly braces eg {1} for key 1")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_4",           " : Use Lowercase for alphabetic keys eg {a} not {A}")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_5",           " : Where multiple characters on same keyboard key, use the lower one.")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_6",           " : eg CTRL/SHIFT/ALT/a = '^+!{a}' and CTRL/F1 = '^{F1}'")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_7",           " : Hotkeys must not be in use by system nor by VirtualDub2 main window.")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_8",           " : More=http://www.autoitscript.com/autoit3/docs/functions/Send.htm")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT_9",           " : More=http://www.autoitscript.com/autoit3/docs/functions/HotKeySet.htm")
IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", "COMMENT10",           " : Count of currently modified HotKeys = " & $HotkeyMods)
; Update User set Keys in ini file.
for $i = 1 to $AllKeys - 1
    IniWrite(@ScriptDir & "\" & $APP_INI, "UserKeys", $KEYS[$i][$KeyName],     $KEYS[$i][$KeyUserSet] )
Next
IniWrite(@ScriptDir & "\" & $APP_INI, "UserComment", "Comment",     $USER_Comment )
;;; Done updating ini file

; CTRL+SHIFT+ALT+PAUSE {PAUSE aka BREAK} is TERMINATE Program (or close via System Tray icon)
HK_Set($KEYS[0][$KeyUserSet],$KEYS[0][$KeyFuncName],$KEYS[0][$KeyName])

; Main Program Loop
Do
    If Not $InAPP Then
        If WinActive($APPTitle) And WinExists($EdTitle) Then
            Bind()                                                    ; Make HotKeys active
            $InAPP = True
        EndIf
    Else
        If Not WinActive($APPTitle) Or Not WinExists($EdTitle) Then
            UnBind()                                                  ; Deactivate Hotkeys
            $InAPP = False
        EndIf
    EndIf
    Sleep($Doze)
    If $ShowCnt > 0 Then
        $ShowCnt = $ShowCnt - 1
        If $ShowCnt = 0 Then
            ToolTip("")                                               ; Display time expired, Switch off "SawBones is WATCHING"
        EndIf
    EndIf
Until (1+1 <> 2)                                                      ; 4E4, ... for a long time.

;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;

Func HK_Set($HK, $Fn,$KN="")
    Local $OK
    if HotKeySet($HK, $Fn) = 0 then
        Local $tHK
        if $KN = "" then
            $tHK=$HK
        Else
            $tHK=$KN & "=" & $HK
        endif
        MsgBox($MB_SYSTEMMODAL, "SawBones Error", "Hotkey '" & $tHK & "' Could not be set" & @CRLF & "Perhaps already in use by system" & @CRLF & "Sawbones Exits")
        Exit(1)
    EndIf
EndFunc

Func Bind()
    local $i
    for $i = 1 to $AllKeys -1
        HK_Set($KEYS[$i][$KeyUserSet],$KEYS[$i][$KeyFuncName],$KEYS[$i][$KeyName])
    Next
    Local $W = @CRLF & $Watching & @CRLF & @CRLF & "      HotKeys Changed = " & $HotkeyMods & "    " & @CRLF
    if $USER_RangeEndIsExclusive <> 0 Then
        $W = $W & @CRLF & " --- Range End Is Exclusive --- " & @CRLF
    EndIf
    if $USER_Comment <> "" Then
        $W = $W & @CRLF & "  User Comment = " & $USER_Comment & "  " & @CRLF
    EndIf
    $ShowCnt = $ShowCntLimit
    ToolTip($W)
EndFunc

Func UnBind()
    ToolTip("")                         ; switch off tooltips.
    $ShowCnt = 0
    ; Disable HotKeys
    local $i
    for $i = 1 to $AllKeys - 1
        HotKeySet($KEYS[$i][$KeyUserSet])
    Next
EndFunc


Func Fn_AtExit()
    HotKeySet($KEYS[0][$KeyUserSet])          ; Disable Program Terminate Hotkey
    UnBind()
EndFunc

Func Fn_Terminate()
    Exit 0; Goodbye cruel world.    ; Will call Fn_AtExit to clean up (assuming OnAutoItExitRegister registered to Fn_AtExit)
EndFunc

;;;;;;;;;;;;;;;;

Func Fn_DeleteFrame()
    Local $Frm=GetFrameNo()
    if $Frm <> "" Then
        ControlSend($EdTitle, "", $EditControl, "DEL " & $Frm, 1) ; Send DEL Frame Number                   RAW
        ControlSend($EdTitle, "", $EditControl, "{ENTER}", 0)     ; Send ENTER key, 1 line down.            COOKED
    endif
EndFunc

Func Fn_DeleteRange()
    Local $Rng=GetRange()
    if $Rng <> "" Then
        ControlSend($EdTitle, "", $EditControl, "DEL " & $Rng, 1) ; Send DEL Range (might be Only FrameNo)   RAW
        ControlSend($EdTitle, "", $EditControl, "{ENTER}", 0)     ; Send ENTER key, 1 line down.             COOKED
    endif
EndFunc

Func Fn_CopyFromPrev()
    Local $Frm=GetFrameNo()
    if $Frm <> "" Then
        $Frm = Int($Frm)
        if $Frm==0 Then
            ToolTip("Cannot CopyFromPrevious at Frame 0")
            $ShowCnt = $ShowCntLimit * 2
            Beep(500,50)
        Else
            ControlSend($EdTitle, "", $EditControl, "CP  " & $Frm, 1) ; Send CP Frame Number                 RAW
            ControlSend($EdTitle, "", $EditControl, "{ENTER}", 0)     ; Send ENTER key, 1 line down.         COOKED
        EndIf
    endif
EndFunc

Func Fn_CopyFromNext()
    Local $Frm=GetFrameNo()
    if $Frm <> "" Then
        ControlSend($EdTitle, "", $EditControl, "CN  " & $Frm, 1) ; Send CN Frame Number                     RAW
        ControlSend($EdTitle, "", $EditControl, "{ENTER}", 0)    ; Send ENTER key, 1 line down.              COOKED
    endif
EndFunc

;;;;;;;;;;;

Func Fn_DigitKey_C_1()          ; CTRL/1                : FX1 Frame
    FX_Key(False,1)
EndFunc
Func Fn_DigitKey_C_2()          ; CTRL/2                : FX2 Frame
    FX_Key(False,2)
EndFunc
Func Fn_DigitKey_C_3()          ; CTRL/3                : FX3 Frame
    FX_Key(False,3)
EndFunc
Func Fn_DigitKey_C_4()          ; CTRL/4                : FX4 Frame
    FX_Key(False,4)
EndFunc
Func Fn_DigitKey_C_5()          ; CTRL/5                : FX5 Frame
    FX_Key(False,5)
EndFunc
Func Fn_DigitKey_C_6()          ; CTRL/6                : FX6 Frame
    FX_Key(False,6)
EndFunc
Func Fn_DigitKey_C_7()          ; CTRL/7                : FX7 Frame
    FX_Key(False,7)
EndFunc
Func Fn_DigitKey_C_8()          ; CTRL/8                : FX8 Frame
    FX_Key(False,8)
EndFunc
Func Fn_DigitKey_C_9()          ; CTRL/9                : FX9 Frame
    FX_Key(False,9)
EndFunc

;;;;;;;;;;

Func Fn_DigitKey_CS_1()          ; CTRL/SHIFT/1          : FX1 Range
    FX_Key(True,1)
EndFunc
Func Fn_DigitKey_CS_2()          ; CTRL/SHIFT/2          : FX2 Range
    FX_Key(True,2)
EndFunc
Func Fn_DigitKey_CS_3()          ; CTRL/SHIFT/3          : FX3 Range
    FX_Key(True,3)
EndFunc
Func Fn_DigitKey_CS_4()          ; CTRL/SHIFT/4          : FX4 Range
    FX_Key(True,4)
EndFunc
Func Fn_DigitKey_CS_5()          ; CTRL/SHIFT/5          : FX5 Range
    FX_Key(True,5)
EndFunc
Func Fn_DigitKey_CS_6()          ; CTRL/SHIFT/6          : FX6 Range
    FX_Key(True,6)
EndFunc
Func Fn_DigitKey_CS_7()          ; CTRL/SHIFT/7          : FX7 Range
    FX_Key(True,7)
EndFunc
Func Fn_DigitKey_CS_8()          ; CTRL/SHIFT/8          : FX8 Range
    FX_Key(True,8)
EndFunc
Func Fn_DigitKey_CS_9()          ; CTRL/SHIFT/9          : FX9 Range
    FX_Key(True,9)
EndFunc

Func FX_Key($IsRange,$HKP)
    if $HKP>=1 and $HKP<=9 Then
        Local $Op="FX" & $HKP & "  "
        Local $Rng=""
        if $IsRange Then
            $Rng = GetRange()
        else
            $Rng = GetFrameNo()
        EndIf
        if $Rng <> "" Then
            ControlSend($EdTitle, "", $EditControl, $Op & $Rng, 1)   ;                                 RAW
            ControlSend($EdTitle, "", $EditControl, "{ENTER}", 0)    ; Send ENTER key, 1 line down.    COOKED
        EndIf
    EndIf
EndFunc


;;;;;;;;;;

Func Fn_Interp_1()               ; CTRL/SHIFT/ALT/1          : Interpolate 1 frame
    InterpNum(1)
EndFunc
Func Fn_Interp_2()               ; CTRL/SHIFT/ALT/2          : Interpolate 2 frame
    InterpNum(2)
EndFunc
Func Fn_Interp_3()               ; CTRL/SHIFT/ALT/3          : Interpolate 3 frame
    InterpNum(3)
EndFunc
Func Fn_Interp_4()               ; CTRL/SHIFT/ALT/4          : Interpolate 4 frame
    InterpNum(4)
EndFunc
Func Fn_Interp_5()               ; CTRL/SHIFT/ALT/5          : Interpolate 5 frame
    InterpNum(5)
EndFunc
Func Fn_Interp_6()               ; CTRL/SHIFT/ALT/6          : Interpolate 6 frame
    InterpNum(6)
EndFunc
Func Fn_Interp_7()               ; CTRL/SHIFT/ALT/7          : Interpolate 7 frame
    InterpNum(7)
EndFunc
Func Fn_Interp_8()               ; CTRL/SHIFT/ALT/8          : Interpolate 8 frame
    InterpNum(8)
EndFunc
Func Fn_Interp_9()               ; CTRL/SHIFT/ALT/9          : Interpolate 9 frame
    InterpNum(9)
EndFunc
Continued @ post #6
__________________
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; 17th April 2018 at 13:03. Reason: Update
StainlessS is offline   Reply With Quote
Old 29th June 2016, 22:03   #5  |  Link
Barabba
Registered User
 
Barabba's Avatar
 
Join Date: Jul 2007
Posts: 48
thank you for reporting that.. wonderful job,
any chances to see this process automatic? it may check the previous and next frame, use one of them when one is ok, if not interpolate with the closest good one..
thank you
Barabba is offline   Reply With Quote
Old 30th June 2016, 01:58   #6  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Too big for post, continued from post #4.
Code:
Func InterpNum($N)
    if $N>=1 and $N<=9 Then
        Local $Frm = GetFrameNo()
        if $Frm <> "" Then
            $Frm=Int($Frm)
            if $Frm = 0 Then
                ToolTip("Cannot Interpolate Frame 0")
                $ShowCnt = $ShowCntLimit * 2
                Beep(500,50)
            Else
                ControlSend($EdTitle, "", $EditControl, "I" & $N & "  " & $Frm & "  # " & $Frm & "," & $Frm+$N-1, 1) ; Send Ix StartFrameNo # s,e       RAW
                ControlSend($EdTitle, "", $EditControl, "{ENTER}", 0)    ; Send ENTER key, 1 line down.                                                 COOKED
            Endif
        EndIf
    EndIf
EndFunc

Func Fn_InterpRange()
    Local $Rng=GetRange()
    if $Rng <> "" Then
        Local $ICnt= 0
        Local $S=""
        While($Rng <> "" and StringIsDigit(StringMid($Rng,1,1)))
            $S = $S & StringMid($Rng,1,1)
            $Rng = StringMid($Rng,2)
        Wend
        if $S <> "" Then
            Local $IS=Number($S)
            Local $IE=$IS
            if StringMid($Rng,1,1) = "," then
                $Rng = StringMid($Rng,2)
                Local $E=""
                While($Rng <> "" and StringIsDigit(StringMid($Rng,1,1)))
                    $E = $E & StringMid($Rng,1,1)
                    $Rng = StringMid($Rng,2)
                Wend
                if $E <> "" then
                    $IE=Number($E)
                Endif
            Endif
            $ICnt=$IE-$IS+1                 ; Interpolation Frame Range
            If $ICnt > 9 Then
                ToolTip("Interpolate Range 1 to 9 frames ONLY")
                $ShowCnt = $ShowCntLimit * 2
            Elseif $IS = 0 Then
                ToolTip("Cannot Interpolate Frame 0")
                $ShowCnt = $ShowCntLimit * 2
                $ICnt=0
            Elseif $ICnt >= 1 Then
                ControlSend($EdTitle, "", $EditControl, "I" & $ICnt & "  " & $IS & "  # " & $IS & "," & $IE, 1) ; Send Ix StartFrameNo      RAW
                ControlSend($EdTitle, "", $EditControl, "{ENTER}", 0)                ; Send ENTER key, 1 line down.                         COOKED
            Endif
        Endif
        if $ICnt < 1 or $ICnt > 9 Then
            Beep(500,50)
        EndIf
    Endif
Endfunc



Func Fn_NotepadSave()
    ; MsgBox($MB_SYSTEMMODAL, "", "NotePad Save")
    ControlSend($EdTitle, "", $EditControl, "^{s}" , 0) ; Send CTRL/S to NotePad, ie Save (FileSelector pop-up if not named)                COOKED
    If NOT WinExists($ScriptTitle) Then
        ToolTip("Sending NotePad Save ONLY")
    Else
        Local $state = WinGetState($ScriptTitle)
        If BitAND($state, 16) Then
            WinSetState($ScriptTitle,"", @SW_RESTORE)                           ; " Restoring Window from Minimized State"
            WinActivate($ScriptTitle,"")
            Sleep(50)
        EndIf
        ControlSend($ScriptTitle, "", $ScriptControl, "{F5}" , 0)   ; Send F5, save File and  Refresh to VirtualDub2 Script Editor  COOKED
        If BitAND($state, 16) Then
            Sleep(50)
            WinActivate($APPTitle,"")
        EndIf
        ToolTip("Sent ScriptEditor Save & Refresh")
    EndIf
    $ShowCnt = $ShowCntLimit * 4
Endfunc

;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;

Func GetFrameNo()                   ; Return VirtualDub Frame Number as string, else "" on Error
    Local $Frm = ""
    Local $E = ControlGetText($APPTitle,"", $VdFrameNo)
    ; MsgBox($MB_SYSTEMMODAL, "", "The text in Edit1 is: " & $E)
    if StringLeft($E,6) = "Frame " Then             ; Case Insignificant
        $E= StringMid($E,7)                         ; Strip 'Frame '
        While $E <> "" and StringIsDigit(StringMid($E,1,1))
            $Frm = $Frm & StringMid($E,1,1)
            $E=StringMid($E,2)
        Wend
    EndIf
    if $Frm=="" then
        Beep(500,50)
    EndIf
    Return $Frm
EndFunc

Func GetRange()           ; Return Selected Range as string, else "" on Error (comma separated range or single frame if only 1 frame ramge)
    Local $Rng = ""
    Local $S = ControlGetText($APPTitle,"", $VdRange)
    if StringMid($S,1,17) = "Selecting frames " Then   ; Case Insignificant
        $S = StringMid($S,18)                          ; Strip 'Selecting Range '
        While $S <> "" and StringIsDigit(StringMid($S,1,1))
            $Rng = $Rng & StringMid($S,1,1)
            $S=StringMid($S,2)
        Wend
        if StringMid($S,1,1) = "-" then
            Local $E=StringMid($S,2)                              ; Strip '-'
            Local $RngE=""
            if StringIsDigit(StringMid($E,1,1)) then
                While $E<> "" and StringIsDigit(StringMid($E,1,1))
                    $RngE = $RngE & StringMid($E,1,1)
                    $E=StringMid($E,2)
                Wend
                Local $IS=Number($Rng)
                Local $IE=Number($RngE)
                if $USER_RangeEndIsExclusive <> 0 then
                    $IE = $IE - 1                                 ; VDub, End of Range is Exclusive
                EndIf
                if $IE < $IS Then
                    $Rng=""
                    ToolTip("Range Is Exclusive (No Frames)")
                    $ShowCnt = $ShowCntLimit * 2
                Elseif $IE > $IS Then
                    $Rng = StringFormat("%d,%d",$IS,$IE)
                EndIf
            EndIf
        Endif
    Else
        ToolTip("No Range")
        $ShowCnt = $ShowCntLimit * 2
    EndIf
    if $Rng=="" then
        Beep(500,50)
    EndIf
    Return $Rng
EndFunc
Below original post #6.

Quote:
Originally Posted by Barabba View Post
it may check the previous and next frame, use one of them when one is ok, if not interpolate with the closest good one..
There lies the rub, how does one tell if one of them is good, we have no way of telling what a frame is supposed to look like or if it is bad (ie how does one define 'ok', and which is the 'closest one', and closest to what).

A decompressor can tell if there is a problem during decode, and 'conceal' the problem by eg duplicating a frame, in avisynth, all frames are already fully decoded and uncompressed, we do not know if there is/was a problem, nor what it is.

If you can come up with a rule, eg a black frame with nearly identical frames either side is a 'bad' frame, then maybe that could be fixed, but without some kind of rule we would have no idea whatsoever what is good or bad.

ffmpeg, is quite a lot better of late than it used to be and can conceal errors (leastwise thats what it says during conversion), perhaps if you have sufficient disk space you could at least try that BEFORE or instead of SawBones/FrameSurgeon (it might auto get rid of a lot of problems or at least conceal them a little).

Perhaps a simple remux would help (but maybe not), might require decode and recode as lossless video, (audio could be copied or decompressed to PCM lossless)

Perhaps have a try with below
Whatever.bat
Code:
REM We DO NOT LIKE SPACES IN FILE NAMES (REM == REMark ie comment)

setlocal

REM Where to Find ffmpeg
set FFMPEG="C:\BIN\ffmpeg.exe"

REM Where to get input file, No terminating Backslash, "." = current directory (ie same as dir .bat file)
set INDIR="."

REM Where to place output file, No terminating Backslash. "." would be same as .bat file
set OUTDIR="D:"

REM Below, can add extensionas as eg *.WMV (SPACE separated)
FOR %%A IN (*.mp4 *.vob *.mpg *.TS) DO (

REM ****** Un-REM ONLY one of below lines *******.
    %FFMPEG% -i "%INDIR%\%%A" -vcodec copy    -acodec copy      "%OUTDIR%\%%~nxA.MKV"
REM %FFMPEG% -i "%INDIR%\%%A" -vcodec utvideo -acodec copy      "%OUTDIR%\%%~nxA.MKV"                
REM %FFMPEG% -i "%INDIR%\%%A" -vcodec utvideo -acodec pcm_s16le "%OUTDIR%\%%~nxA.AVI"     
REM *********************************************.

)

REM ... Above UN-REM'ed lines : 
REM      (1) Remux, copy both video and audio   (output MKV). 
REM      (2) UtVideo lossless video, copy audio (output MKV).
REM      (3) UtVideo lossless video, PCM audio  (output AVI). 

Pause
EDIT: Original Barabba thread:- http://forum.doom9.org/showthread.php?t=173645
__________________
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; 17th April 2018 at 13:05.
StainlessS is offline   Reply With Quote
Old 30th June 2016, 17:18   #7  |  Link
geometer
Registered User
 
Join Date: Dec 2015
Posts: 59
there are features in decompressors/pre-indexers to write down time stamp logs. couldn't such functionality also be extended to include frame integrity/quality reporting? shouldn't be too difficult with the source code available.
geometer is offline   Reply With Quote
Old 30th June 2016, 17:20   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by geometer View Post
there are features in decompressors/pre-indexers to write down time stamp logs. couldn't such functionality also be extended to include frame integrity/quality reporting? shouldn't be too difficult with the source code available.
Not for me, already got too much on my plate, sorry.

EDIT: FrameSurgeon.avs could still be used by other software, it is not at all limited to use with Sawbones, indeed
Sawbones is an add-on to FrameSurgeon script, for ease of use setting up command files.
Messing with decompressors would be best left to someone already familiar with such sources(sourcecode).

EDIT: If you could point out a tool that already produces lists of bad frames, then do supply it, and I may take a peek.

EDIT: Also note, DoctorFrames() from ClipClop plugin supports up to 20 Interpolated frames, also supports CP and CN commands
(no deletes or FXd). [supporting up to 20 Interpolation frames + CP + CN, uses up about 240 clips of 256 available in ClipClop
and hammers system resources severely (I think originally 22 interpolation frames did use up exactly 256 clips and made system unstable due to that. Was reason to reduce to 20 interp frames, more stable, fewer Out-of-mem type crashes).

EDIT: Above number of clips do not include eg MVSuper or forward/backward vector clips.
__________________
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 June 2016 at 17:51.
StainlessS is offline   Reply With Quote
Old 30th June 2016, 17:28   #9  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
SawBones(FrameSurgeon) v1.02 - 30 June 2016, new version, see 1st post.

Posts 1 and 2 updated, updates marked in BLUE.

Added,
CTRL/SHIFT/ALT/? Interpolate Range. Ie in Avisynth Inclusive mode, where range is 100,101 [2 frames] then result command = "I2 100"
The specified range start and end are the outer bad frames.

Just avoids having to count number of frames to interpolate. Interpolate range still limited to 9 frames.

EDIT: No change to FrameSurgeon.avs
__________________
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 June 2016 at 18:09.
StainlessS is offline   Reply With Quote
Old 28th August 2017, 23:28   #10  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
SawBones(FrameSurgeon) v1.03 - 28 Aug 2017, new version, see 1st post.

Sawbones no change but version bump to v1.03 to match FrameSurgeon.avs.

FrameSurgeon.avs, versioned at v1.03.
Now errors if you attempt to give ClipClop clip index instead of command mnemonic (eg requires CP n, means CopyFromPrevious frame n-1 to frame n).
Just a bit safer (less likely user mishaps) to disable direct clip index use.

Added optional 'I n' and 'I s,e' commands (ie can specify frame/range separate from command, eg 'I 101,103' instead of 'I3 101'), in blue below
(still limited to max interpolation of 9 frames).
Code:
        "I1  n"        Interpolate 1 frame n (using source frames n-1 and n+1 as Interpolation source frames, (Id commands Planar, YUY2 only).
        "I2  n"        Interpolate 2 frames starting at frame n, (using source frames n-1 and n+2).
        "I3  n"        Interpolate 3 frames starting at frame n, (using source frames n-1 and n+3).
        "I4  n"        Interpolate 4 frames starting at frame n, (using source frames n-1 and n+4).
        "I5  n"        Interpolate 5 frames starting at frame n, (using source frames n-1 and n+5).
        "I6  n"        Interpolate 6 frames starting at frame n, (using source frames n-1 and n+6).
        "I7  n"        Interpolate 7 frames starting at frame n, (using source frames n-1 and n+7).
        "I8  n"        Interpolate 8 frames starting at frame n, (using source frames n-1 and n+8).
        "I9  n"        Interpolate 9 frames starting at frame n, (using source frames n-1 and n+9).
        "I   n"        Interpolate 1 frame n (using source frames n-1 and n+1 as Interpolation source frames.
        "I   s,e"      Interpolate range s to e (max range 9 frames, using source frames s-1 and e+1 as source frames).
Added, FrameSurgeon_DEMO.avs
Code:
Import("FrameSurgeon.avs")

### Config ###
SHOW=True                                           # Show ClipClop OR Prune Metrics
SHOWMODE=0                                          # 0=ClipClop metrics, 1=Prune Metrics (Show deletions rather than replacements)
SCMD=""                                             # Not Using SCMD in this DEMO
CMD="DEMO_Command.txt"
DV=5                                                # 0=ERRORS ONLY, 5=FULL Debug to DebugView(Google)
STACK=True

### Source clip and Simulated replacement clips ###
src=Colorbars.killaudio.ConvertToYV12.ShowFrameNumber(Size=72,x=320,y=240)
FX1=src.FlipHorizontal              # Light denoising or whatver
FX2=FX1.FlipVertical                # Heavy denoising or whatver

### Edit or No Edit ###
CMD=(CMD!="") ? RT_GetFullPathName(CMD) : ""
PROCESS = (SCMD!="" || (CMD!="" && Exist(CMD)))     # Skip FrameSurgeon if no String nor file commands.
Result = (PROCESS) ? FrameSurgeon(src,scmd=SCMD,cmd=CMD,Show=Show,ShowMode=SHOWMODE,dv=DV,fx1=FX1,fx2=FX2) : src

### Stack For View ###
TOP=StackHorizontal(src.RtSub("Source",True),FX1.RtSub("FX1",True))
BOT=StackHorizontal(FX2.RtSub("FX2",True),Result.RtSub("Result",True))
Return (STACK) ? StackVertical(TOP,BOT) : Result


/*
    Can use above script where DEMO_Command.txt file does not exist and will not produce error, ie use same script and Demo_Command.txt
    with VirtualDub, Sawbones, and NotePad.
*/
DEMO_Command.txt
Code:
DEL 400,449    # Delete frames 400 to 449 (AFTER ALL replacments done)
I3  10         # Interp frames 10 -> 12, using 9 and 13 as source
I9  20	       # Interp frames 20 -> 28, using 19 and 29 as source  # EDIT: or I 20,28
CP  30         # Replace frame 30 with frame 29
CN  31         # Replace frame 31 with frame 32
FX1 50,199     # replace range 50,199 with same range from FX1 clip
DEL 1000,-1000 # Delete frames 1000 to 1999 (AFTER ALL replacments done) # EDIT: Added
FX2 300,599    # replace range 300,599 with same range from FX2 clip
EDIT: FrameSurgeon.avs, Changed IsYV12 colorspace detection to IsPlanar detection, allow use with mvtools
that support other planar colorspaces, will error if YUY2 and mvtools version does not support it.
EDIT: -ve frame end (frame count) NOT supported for Range interpolation ie 'I 100,-9' will fail (guess I might implement if required).
EDIT: Note, frame/range deletes have a 1ms linear FadeOut/FadeIn at splices simulating zero crossing, to prevent 'Cracks' in audio.
__________________
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; 29th August 2017 at 01:00.
StainlessS is offline   Reply With Quote
Old 30th August 2017, 23:02   #11  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
SawBones/FrameSurgeon v1.04, new version see 1st post.
Posts #1 to #4 updated.

MAIN difference, can within Sawbones press a key combo to Save contents of NotePad Command file, and auto
refresh avs into VirtualDubFilterMod (now almost a requirement), so you can see edits that you have already done.
(Replacements and Interpolations done, and deletions marked (subtitled) but not actually deleted until FrameSurgeon called with
FINAL=True)


FrameSurgeon_DEMO.avs
Code:
Import("../FrameSurgeon.avs")

### Config #############################################
FINAL=False                 # Change to TRUE to do real DELETES (FALSE only shows where deletes would occur, ALWAYS use FALSE with SawBones)
### One of below strings
SCMD="""                 # Demo Test
    CP  100              # CP, Single frame args ONLY. Replace 100 with frame 99.
    CN  101              # CN, Single frame args ONLY. REplace 101 with frame 102.
    I9  110              # Id, Single frame args ONLY. Interpolate 9 frames starting at frame 110.
    FX1 200,299          # Replace 200->299 with same range from FX1 clip. (FXd clips default source if not supplied, Subtitled if Show)
    FX2 300,399
    FX3 400,499
    FX4 500,-50          # Replace 50 frames starting at 500.
    FX5 550,-50          # Replace 50 frames starting at 550. NOTE, as not defined in this script FX5 defaults Subtitled source clip.
    FX6 600,-100         # Replace 100 frames starting at 600. NOTE, as not defined in this script FX6 defaults Subtitled source clip.
    FX7 700,-100         # Replace 100 frames starting at 700. NOTE, as not defined in this script FX7 defaults Subtitled source clip.
    DEL 800,899
    DEL 900,-100         # Del 100 frames starting from 900
    DEL 2000,0           # Del from 2000 to end of clip.
"""
#SCMD=""

### One of below strings (CMD file is processed before SCMD, where multiple replacements on same frame)
CMD="FrameSurgeon_DEMO_Cmd.TXT" # Command file, perhaps created via SawBones.
#CMD = ""

SHOW=!FINAL                 # Show ClipClop OR Prune Metrics
SHOWMODE=0                  # 0=ClipClop metrics, 1=Prune Metrics (Show remaining after deletions rather than replacements)
DV=4                        # 0=ERRORS ONLY, 4=FULL Debug to DebugView(Google)
NOERR=False                 # Set True if wanting to IGNORE FXd commands for undefined FXd clips.

# MvTools, Interpolate args (see mvTools)
PEL=2
SHARP=2
RFILTER=2
ML=100.0
#
STACK=(!FINAL || SHOW)          # Auto stack window OFF when FINAL==True and SHOW==FALSE
########################################################

### Source clip ###
src=Colorbars.killaudio.ConvertToYV12
src=src.ShowFrameNumber(Size=src.Height/6,x=src.Width/2,y=src.Height/3)

### Simulated replacement clips ###
FX1 = src.FlipVertical
FX2 = src.FlipHorizontal
FX3 = src.Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58)
FX4 = src.Sharpen(1.0).Sharpen(1.0).Sharpen(1.0)

### Edit or No Edit ###
CMD=(CMD!="") ? RT_GetFullPathName(CMD) : ""
PROCESS = (SCMD!="" || (CMD!="" && Exist(CMD)))     # Skip FrameSurgeon if no String nor file commands (yet).

Result = (PROCESS)
        \ ? FrameSurgeon(src,scmd=SCMD,cmd=CMD,Show=Show,ShowMode=SHOWMODE,dv=DV,
        \   fx1=FX1,fx2=FX2,fx3=FX3,fx4=FX4,
        \   pel=PEL,sharp=SHARP,rfilter=RFILTER,ml=ML,
        \   Final=FINAL,NoErr=NOERR)
        \ : src

### Stack For View ###
BSZ=4 BCOL=$FF00FF
Ssrc=src.RtSub("Source",True)   SFX1=FX1.RtSub("FX1",True)  SFX2=FX2.RtSub("FX2",True)
SFX3=FX3.RtSub("FX3",True)      SFX4=FX4.RtSub("FX4",True)  SResult=Result.RtSub("Result",True)
TOP=StackHorizontal(Ssrc,Ssrc.BlankClip(width=BSZ,Color=BCOL),SFX1,Ssrc.BlankClip(width=BSZ,Color=BCOL),SFX2)
BOT=StackHorizontal(SFX3,Ssrc.BlankClip(width=BSZ,Color=BCOL),SFX4,Ssrc.BlankClip(width=BSZ,Color=BCOL),SResult)
Return (STACK) ? StackVertical(TOP,TOP.BlankClip(height=BSZ,Color=BCOL),BOT) : Result

# Stack Overhead RT_Subtitle Text, with optional FrameNumber shown.
Function RtSub(clip c,string Tit, Bool "ShowFrameNo") {
    c.BlankClip(height=20)
    (Default(ShowFrameNo,False)) ? ScriptClip("""RT_Subtitle("%d] %s",current_frame,""""+Tit+"""")""") : RT_Subtitle("%s",Tit)
    Return StackVertical(c).AudioDubEx(c)
}

Return Last
FrameSurgeon_DEMO_Cmd.txt
Code:
CP  1000             # CP, Single frame args ONLY. Replace 1000 with frame 999.
CN  1001             # CN, Single frame args ONLY. REplace 1010 with frame 1002.
I9  1010             # Id, Single frame args ONLY. Interpolate 9 frames starting at frame 1010.
FX1 1200,1299        # Replace 1200->1299 with same range from FX1 clip. (FXd clips default source if not supplied, Subtitled if Show)
FX2 1300,1399
FX3 1400,1499
FX4 1500,-100        # Replace 100 frames starting at 1500.
FX5 1600,-50         # Replace 50 frames starting at 1600. # NOTE FX5 NOT defined in script
DEL 1700,1799
DEL 1800,-100        # Del 100 frames starting from 1800

SawBones_DEMO.avs
Code:
Import("../FrameSurgeon.avs")

### Config ###
FINAL=False                 # Change to TRUE to do real DELETES (FALSE only shows where deletes would occur, ALWAYS use FALSE with SawBones)
SCMD=""                     # Not Using SCMD (string command) in this DEMO
CMD="SawBones_DEMO_Cmd.txt" # Command file, perhaps created via SawBones.
SHOW=!FINAL                 # Show ClipClop OR Prune Metrics
SHOWMODE=0                  # 0=ClipClop metrics, 1=Prune Metrics (Show remaining after deletions rather than replacements)
DV=4                        # 0=ERRORS ONLY, 4=FULL Debug to DebugView(Google)
NOERR=False                 # Set True if wanting to IGNORE FXd commands for undefined FXd clips.
                            #     (In DEMO, FX9 command is used in CMD but not supplied in FrameSurgeon call, set True to ignore that command)
# MvTools, Interpolate args (see mvTools)
PEL=2
SHARP=2
RFILTER=2
ML=100.0
#
STACK=(!FINAL || SHOW)          # Auto stack window OFF when FINAL==True and SHOW==FALSE
##############

### Source clip ###
src=Colorbars.killaudio.ConvertToYV12
src=src.ShowFrameNumber(Size=src.Height/6,x=src.Width/2,y=src.Height/3)

### Simulated replacement clips ###
FX1=src.FlipHorizontal          # Light denoising or whatver
FX2=FX1.FlipVertical            # Heavy denoising or whatver

### Edit or No Edit ###
CMD=(CMD!="") ? RT_GetFullPathName(CMD) : ""
PROCESS = (SCMD!="" || (CMD!="" && Exist(CMD)))     # Skip FrameSurgeon if no String nor file commands (yet).

Result = (PROCESS)
        \ ? FrameSurgeon(src,scmd=SCMD,cmd=CMD,Show=Show,ShowMode=SHOWMODE,dv=DV,
        \   fx1=FX1,fx2=FX2,
        \   pel=PEL,sharp=SHARP,rfilter=RFILTER,ml=ML,
        \   Final=FINAL,NoErr=NOERR)
        \ : src

### Stack For View ###
BSZ=4 BCOL=$FF00FF
Ssrc=src.RtSub("Source",True)   SFX1=FX1.RtSub("FX1",True)  SFX2=FX2.RtSub("FX2",True)  SResult=Result.RtSub("Result",True)
TOP=StackHorizontal(Ssrc,Ssrc.BlankClip(width=BSZ,Color=BCOL),SFX1)
BOT=StackHorizontal(SFX2,Ssrc.BlankClip(width=BSZ,Color=BCOL),SResult)
Return (STACK) ? StackVertical(TOP,TOP.BlankClip(height=BSZ,Color=BCOL),BOT) : Result

# Stack Overhead RT_Subtitle Text, with optional FrameNumber shown.
Function RtSub(clip c,string Tit, Bool "ShowFrameNo") {
    c.BlankClip(height=20)
    (Default(ShowFrameNo,False)) ? ScriptClip("""RT_Subtitle("%d] %s",current_frame,""""+Tit+"""")""") : RT_Subtitle("%s",Tit)
    Return StackVertical(c).AudioDubEx(c)
}

/*

    Can use above script where DEMO_Command.txt file does not exist and will not produce error, ie use same script and Demo_Command.txt
    with VirtualDubFilterMod, Sawbones, and NotePad.

      Sawbones v1.04, used with Notepad and VirtualDubFilterMod, "Save & Refresh avs" key combo 'CTRL/ALT/,' (COMMA by default, little SawBones.au3
    mod and rebuild maybe necessary for some international keyboards to select some key other than comma) saves the NotePad file, and if
    VDubFilterMod Script Editor window is open, then will send F5 key to the script editor window (ie Save AVS file and refresh, re-open at original
    frame). These mods will basically save the command file and then reload the AVS with range replacements already done.
    If using with SawBones and marking deletions, then ENSURE that FINAL=FALSE, which will only mark frames for deletion, otherwise further deletions
    or replacements later in clip will be wrong (VirtualDubFilteRMod/Sawbones, have no idea what editing has been done within Avisynth).

*/
SawBones_DEMO_CMD.TXT
Code:
DEL 1,4        # Delete frames 1 to 4 (AFTER ALL replacments done)
DEL 6,-2       # Delete 2 frames 6 to 7 (AFTER ALL replacments done)
DEL 8          # Delete frame 8 (AFTER ALL replacments done)
DEL 400,449    # Delete frames 400 to 449 (AFTER ALL replacments done)
I3  10         # Interp 3 frames 10 -> 12, using 9 and 13 as source
I   20,28      # Interp 9 frames 20 -> 28, using 19 and 29 as source
I   30,-5      # Interp 5 frames 30 -> 34, using 29 and 35 as source
CP  40         # Replace frame 40 with frame 39
CN  41         # Replace frame 41 with frame 42
FX1 50,199     # replace range 50,199 with same range from FX1 clip
FX1 250,-50    # replace 50 frames range 250,299 with same range from FX1 clip
DEL 1000,-1000 # Delete frames 1000 to 1999 (AFTER ALL replacments done)
FX2 300,599    # replace range 300,599 with same range from FX2 clip
FX9 700,-100   # Replace range 700->799 with same range from FX9 clip (UNDEFINED in default demo, will show in demo subtitled as FX9)
DEL 10000,0    # Delete frames 10,000 to last frame (AFTER ALL replacments done)
SawBones_Usage.txt
Code:
Using Sawbones with this demo, (In brief)

Open SawBones_DEMO_Cmd.txt in NotePad, and move cursor to last line. Make window small, just showing about two lines, but leave open.
Open Sawbones_DEMO.avs in VirtualDubFilteRMod, and open the script editor window (tools menu, script Editor, can minimize to on TaskBar).
Resize VirtiualDubFilterMod so that you can see it together with small NotePad window open.
Open SawBones.

Continue. (see SawBones SawBones.ReadMe.Txt for available commands).
__________________
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; 31st August 2017 at 04:12.
StainlessS is offline   Reply With Quote
Old 31st August 2017, 03:47   #12  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Oops, a few corrections, re-upped zip (only had 1 download, no version bump).

Post #2 correction (Final was originally another name, and default True, forgot to invert some True's to False and False to True)
Code:
Final Default False,       If False, then DOES NOT Delete any ranges, replace only. Delete Operations only occur if this arg is True.
                             Set False, when using SawBones together with NotePad and VirtualDubFilterMod (with Script Editor Window Open).
                             When False, will not do deletions, will instead show frames marked with "DUMMY DELETE" in frame center.
                             Purpose, to avoid editing errors using SawBones v1.04 "Save & Refresh" AVS, keyboard command. (Not a
                             good idea to edit clip where deletions have already been done, ie edits after first deletion, would all be wrong).
                             Change to FINAL=True, when all edits including deletions are complete, where real deletions will ensue.
                             If later adding some edits to a command file using SawBones, then set FINAL=False until editing complete.

Post #3 correction (was "SplitCommands: ")
Code:
myName="FrameSurgeonSplitCommands: "
Post #4 correction (somehow got changed back to $KEY_CTRL_SHIFT_ALT & "?", would still work same (at least on my keyboard)
Code:
Global $USER_KEY_InterpRange=$KEY_CTRL_SHIFT_ALT & "/"  ; User can choose a suitable key for Interpolate Range (default "?")
# EDIT: Above, Damn, should be changed in comment too
Posts 2, 3 and 4 corrected.

EDIT: In re-upped zip, also made this amendment to FrameSurgeon_DEMO.avs (show STACK 6 windows, with FX1->FX4, was only FX1->FX2)
Code:
Import("../FrameSurgeon.avs")

### Config #############################################
FINAL=False                 # Change to TRUE to do real DELETES (FALSE only shows where deletes would occur, ALWAYS use FALSE with SawBones)
### One of below strings
SCMD="""                 # Demo Test
    CP  100              # CP, Single frame args ONLY. Replace 100 with frame 99.
    CN  101              # CN, Single frame args ONLY. REplace 101 with frame 102.
    I9  110              # Id, Single frame args ONLY. Interpolate 9 frames starting at frame 110.
    FX1 200,299          # Replace 200->299 with same range from FX1 clip. (FXd clips default source if not supplied, Subtitled if Show)
    FX2 300,399
    FX3 400,499
    FX4 500,-50          # Replace 50 frames starting at 500.
    FX5 550,-50          # Replace 50 frames starting at 550. NOTE, as not defined in this script FX5 defaults Subtitled source clip.
    FX6 600,-100         # Replace 100 frames starting at 600. NOTE, as not defined in this script FX6 defaults Subtitled source clip.
    FX7 700,-100         # Replace 100 frames starting at 700. NOTE, as not defined in this script FX7 defaults Subtitled source clip.
    DEL 800,899
    DEL 900,-100         # Del 100 frames starting from 900
    DEL 2000,0           # Del from 2000 to end of clip.
"""
#SCMD=""

### One of below strings (CMD file is processed before SCMD, where multiple replacements on same frame)
CMD="FrameSurgeon_DEMO_Cmd.TXT" # Command file, perhaps created via SawBones.
#CMD = ""

SHOW=!FINAL                 # Show ClipClop OR Prune Metrics
SHOWMODE=0                  # 0=ClipClop metrics, 1=Prune Metrics (Show remaining after deletions rather than replacements)
DV=4                        # 0=ERRORS ONLY, 4=FULL Debug to DebugView(Google)
NOERR=False                 # Set True if wanting to IGNORE FXd commands for undefined FXd clips.

# MvTools, Interpolate args (see mvTools)
PEL=2
SHARP=2
RFILTER=2
ML=100.0
#
STACK=(!FINAL || SHOW)          # Auto stack window OFF when FINAL==True and SHOW==FALSE
########################################################

### Source clip ###
src=Colorbars.killaudio.ConvertToYV12
src=src.ShowFrameNumber(Size=src.Height/6,x=src.Width/2,y=src.Height/3)

### Simulated replacement clips ###
FX1 = src.FlipVertical
FX2 = src.FlipHorizontal
FX3 = src.Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58).Blur(1.58)
FX4 = src.Sharpen(1.0).Sharpen(1.0).Sharpen(1.0)

### Edit or No Edit ###
CMD=(CMD!="") ? RT_GetFullPathName(CMD) : ""
PROCESS = (SCMD!="" || (CMD!="" && Exist(CMD)))     # Skip FrameSurgeon if no String nor file commands (yet).

Result = (PROCESS)
        \ ? FrameSurgeon(src,scmd=SCMD,cmd=CMD,Show=Show,ShowMode=SHOWMODE,dv=DV,
        \   fx1=FX1,fx2=FX2,fx3=FX3,fx4=FX4,
        \   pel=PEL,sharp=SHARP,rfilter=RFILTER,ml=ML,
        \   Final=FINAL,NoErr=NOERR)
        \ : src

### Stack For View ###
BSZ=4 BCOL=$FF00FF
Ssrc=src.RtSub("Source",True)   SFX1=FX1.RtSub("FX1",True)  SFX2=FX2.RtSub("FX2",True)
SFX3=FX3.RtSub("FX3",True)      SFX4=FX4.RtSub("FX4",True)  SResult=Result.RtSub("Result",True)
TOP=StackHorizontal(Ssrc,Ssrc.BlankClip(width=BSZ,Color=BCOL),SFX1,Ssrc.BlankClip(width=BSZ,Color=BCOL),SFX2)
BOT=StackHorizontal(SFX3,Ssrc.BlankClip(width=BSZ,Color=BCOL),SFX4,Ssrc.BlankClip(width=BSZ,Color=BCOL),SResult)
Return (STACK) ? StackVertical(TOP,TOP.BlankClip(height=BSZ,Color=BCOL),BOT) : Result

# Stack Overhead RT_Subtitle Text, with optional FrameNumber shown.
Function RtSub(clip c,string Tit, Bool "ShowFrameNo") {
    c.BlankClip(height=20)
    (Default(ShowFrameNo,False)) ? ScriptClip("""RT_Subtitle("%d] %s",current_frame,""""+Tit+"""")""") : RT_Subtitle("%s",Tit)
    Return StackVertical(c).AudioDubEx(c)
}

Return Last
EDIT: DAMN, default in FrameSurgeon for Final should be false, but its true. (EDIT: Or should stay true, hard to decide)
__________________
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; 1st September 2017 at 09:20.
StainlessS is offline   Reply With Quote
Old 17th April 2018, 13:09   #13  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
SawBones/FrameSurgeon v1.09, update. See 1st Post.

Required, Either AVS+ or GSCript, MvTools2, RT_Stats, FrameSel, Prune, ClipClop.
+ Recompiled for new version AutoIt v3.3.14.5, released Mar 16 2018.

EDIT: Now requires formerly named VirtualDubFilteRMod newly renamed as VirtualDub2.

EDIT: ShortCutsMan by NirSoft:- https://www.nirsoft.net/utils/shman.html
A handy tool to list system wide shortcuts (sort via Shortcuts tab).
NOTE, Nirsoft is sometimes flagged as some kind of malware site, due to it providing password showing utilities, etc.
NirSoft is clean and an exceptional quality utility provider, quite similar to the SysInternals site that was bought out by M$.



EDIT: Actually, above does not show system hotkeys eg WINDOWS/F for Find, I thought it did, only non system, system wide hotkeys shown. (ie hotkeys user set on shortcuts in 'Program Files' or on DeskTop shortcuts).

EDIT: Made FrameSurgeon Final default=True.
__________________
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; 17th April 2018 at 16:07.
StainlessS is offline   Reply With Quote
Old 23rd July 2019, 19:10   #14  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Sawbones Update to v1.11, see first post.

Reason, at some point VirtualDub2 must have renamed one of its controls, and SawBones no longer worked at all.

Original
Code:
Global Const $Version       = "SawBones v1.10"
Global Const $APP_NAME      = "SawBones.Exe"
Global Const $APP_INI       = "SawBones.ini"
Global Const $Watching      = "    SawBones is WATCHING    "
Global Const $APPTitle      = "VirtualDub2"                              ; VirtualDub2 matches as "VirtualDub2" with traiiling "Build number" on title bar.
Global Const $ScriptTitle   = "VirtualDub2 Script Editor"                ; VirtualDub2 Script Editor Window
Global Const $ScriptControl = "[CLASS:Scintilla; INSTANCE:1]"
Global Const $VdFrameNo     = "[CLASS:Edit; INSTANCE:1]"                 ; Frame Indicator box (bottom middle of window, just above status line)
Global Const $VDRange       = "[CLASS:msctls_statusbar32; INSTANCE:1]"   ; Frame Range (bottom Left of window, 'Selecting Frames...' when range selected)
Now, changed in blue
Code:
Global Const $Version       = "SawBones v1.11"
Global Const $APP_NAME      = "SawBones.Exe"
Global Const $APP_INI       = "SawBones.ini"
Global Const $Watching      = "    SawBones is WATCHING    "
Global Const $APPTitle      = "VirtualDub2"                              ; VirtualDub2 matches as "VirtualDub2" with traiiling "Build number" on title bar.
Global Const $ScriptTitle   = "VirtualDub2 Script Editor"                ; VirtualDub2 Script Editor Window
Global Const $ScriptControl = "[CLASS:Scintilla; INSTANCE:1]"
Global Const $VdFrameNo     = "[CLASS:Static; INSTANCE:1]"               ; Frame Indicator box (bottom middle of window, just above status line)
Global Const $VDRange       = "[CLASS:msctls_statusbar32; INSTANCE:1]"   ; Frame Range (bottom Left of window, 'Selecting Frames...' when range selected)
EDIT: If you already have the source and AutoIt, simply change the Blue hi-lited stuff above, and hit F7 in AutoIt script editor to rebuild.
__________________
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; 23rd July 2019 at 19:18.
StainlessS is offline   Reply With Quote
Old 12th August 2022, 23:23   #15  |  Link
ABurns
Registered User
 
ABurns's Avatar
 
Join Date: Aug 2017
Posts: 56
Sawbones seems to have stopped working since upgrading to Windows 11. Sawbones 1.11_20190723 and VDub2 44282 worked great under Windows 10 but now none of the hotkeys do anything. Notepad just stays blank. Is there something at play here I'm missing? Anybody else experienced this?
ABurns is offline   Reply With Quote
Old 13th August 2022, 15:31   #16  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
SawBones / FrameSurgeon v1.12, new version, see first post.

Sorry, ABurns, think I cocked up there,
Had not set to auto update command file, via NotePad save file, following a user command key combo,
had left in a sort of 'debug' state.

hope this works ok for you.
SawBones-v1.12_20220813.zip[~460KB]:- https://www.mediafire.com/file/png0u...20813.zip/file

Say if still problems, (I aint using W11).
__________________
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; 13th August 2022 at 15:37.
StainlessS is offline   Reply With Quote
Old 13th August 2022, 17:35   #17  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Here, a sort of template demo, I'll add to next version.

Sawbones_DEMO_2.avs
Code:
# *** NOTE ***, Default command text file is empty {SawBones_DEMO_2_Cmd.txt}, you may add your own edits with sawbones.

Import("../FrameSurgeon.avs")
#Import("./Spotless.avsi")        # Spotless script used via this demo, if not in plugins

### Source clip ##########
FN = ".\Test.AVI".RT_GetFullPathName        # Your Test file name
Avisource(FN,Pixel_type="YV12")
#LSmashVideoSource(FN)
#FFVideoSource(FN)
#LWLibAvVideoSource(FN)
### End Source Clip ######

### Config ###
FINAL=False                   # Change to TRUE to do real DELETES (FALSE only shows where deletes would occur, ALWAYS use FALSE with SawBones)
SCMD=""                       # Not Using SCMD (string command) in this DEMO
CMD="SawBones_DEMO_2_Cmd.txt" # Command file, perhaps created via SawBones.
SHOW=!FINAL                   # Show ClipClop OR Prune Metrics
SHOWMODE=0                    # 0=ClipClop metrics, 1=Prune Metrics (Show remaining after deletions rather than replacements)
DV=4                          # 0=ERRORS ONLY, 4=FULL Debug to DebugView(Google)
NOERR=False                   # Set True if wanting to IGNORE FXd commands for undefined FXd clips.

# MvTools, Interpolate args (see mvTools)
PEL=2
SHARP=2
RFILTER=2
ML=100.0
# SpotLess args
THSAD  = 5000
THSAD2 = 4900
BLKSZ  = 16
#

Src = Last
### 4 FX replacement clips [ Requires SpotLess script] ###
FX1 = src.SpotLess(RadT=1,thsad=THSAD,thsad2=THSAD2,BlkSz=BLKSZ)
FX2 = src.SpotLess(RadT=2,thsad=THSAD,thsad2=THSAD2,BlkSz=BLKSZ)
FX3 = src.SpotLess(RadT=3,thsad=THSAD,thsad2=THSAD2,BlkSz=BLKSZ)
FX4 = src.SpotLess(RadT=4,thsad=THSAD,thsad2=THSAD2,BlkSz=BLKSZ)

### Edit or No Edit ###
CMD=(CMD!="") ? RT_GetFullPathName(CMD) : ""
PROCESS = (SCMD!="" || (CMD!="" && Exist(CMD)))     # Skip FrameSurgeon if no String nor file commands (yet).

Result = (PROCESS)
        \ ? FrameSurgeon(src,scmd=SCMD,cmd=CMD,Show=Show,ShowMode=SHOWMODE,dv=DV,
        \   fx1=FX1,fx2=FX2,fx3=FX3,fx4=FX4,                    [* + any additional FXn clips up to max FX9 *]
        \   pel=PEL,sharp=SHARP,rfilter=RFILTER,ml=ML,
        \   Final=FINAL,NoErr=NOERR)
        \ : src

Return Result

/*
    Simple 4 user set FXn clips, all using SpotLess with varying RadT args.
    Also can use standard FrameSurgeon CP {Copy From Previous frame} and CN {Copy From Next Frame},
    and any of the Interpolate frames [1 to 9] commands, and also the Delete commands.

    Above demo, only shows a single result window, which when no edit commands for current frame, will be as source, otherwise
    as for the chosen edit command. This single window script, may be more convienient where stacked multi-window script would not
    show results in full size. Downside is that you cannot see what your chosen edit frame will look like before inserting command.
    If the chosen edit does not look good, then can edit out that line in NotePad window, and try another edit, eg FX2 SpotLess(RadT=2)
    instead of FX1 Spotless(RadT=1) because it did not get rid of double frame spot.

*/
Need also add file,
SawBones_DEMO_2_Cmd.txt
As empty file [prior to using script for 1st time, you'll load this empty one into NotePad].

Bit of a description.
Code:
Using Sawbones with this demo, (In brief)

Open SawBones_DEMO_2_Cmd.txt in NotePad, and move cursor to last line. Make window small, just showing about two lines, but leave open.
Open Sawbones_DEMO_2.avs in VirtualDub2 (formerly VirtualDubFilterMod), and open the script editor window (tools menu, script Editor,
can minimize to on TaskBar). Resize VirtualDub2 so that you can see it together with small NotePad window open. Open SawBones.

Continue. (see SawBones SawBones.ReadMe.Txt for available commands).

*** NOTE ***
SawBones_DEMO_2_Cmd.txt file is empty, you can add your own edits with Sawbones.

I personally like to open the command file in NotePad on a 2nd monitor, same for VDub2 script edit window.
EDIT: All above files inside SawBones-v1.12_20220813/SawBones_DEMO_2 folder.

EDIT: I picked up a 2nd hand {used} H.P. VGA 4:3 1280x1024 19" monitor at CEX in UK, for £1.50, nobody wants them any more.
{dont expect too many similar deals, the one I found was actually on the floor in corner of shop with a price on it,
I could not resist such a bargain, works great and in W10 can even set up to work alongside a 4K HDR [10 bit] 28 inch monitor}
It also needed a DisplayPort to VGA adapter which cost more than the monitor.
Good to use with SawBones; put NotePad and VDub2 script editor windows on 2nd monitor,
also handy for Debugging output, eg via DebugView {google}, and eg RT_DebugF() avisynth commands.

EDIT:
A frame from the 1st demo multi-window script in the zip.


And another from the single window template demo_2 script.


The Dummy Delete frames are just place holders used within Sawbones to show which frames have been marked for deletion,
they are only actually removed when using Sawbones / FrameSurgeon with FINAL=TRUE.
__________________
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; 13th August 2022 at 18:38.
StainlessS is offline   Reply With Quote
Old 16th August 2022, 00:41   #18  |  Link
ABurns
Registered User
 
ABurns's Avatar
 
Join Date: Aug 2017
Posts: 56
Thanks! Will let you know if it works.
ABurns is offline   Reply With Quote
Old 16th August 2022, 00:48   #19  |  Link
ABurns
Registered User
 
ABurns's Avatar
 
Join Date: Aug 2017
Posts: 56
Still not working with 1.12, sorry to say. When I click to make VDub the active window I get the "Sawbones is WATCHING" message, and when I press a hotkey I get "Sending Notepad Save ONLY." But nothing ever appears in Notepad.
ABurns is offline   Reply With Quote
Reply

Tags
avspmod, editing, virtualdub

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 12:59.


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