View Single Post
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