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. |
17th April 2016, 22:29 | #21 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
MorphDupes_MI.avs Part 2 of 2 (Too big, Copy/Paste together)
Code:
c myName="MorphDupes_MI: " Assert(RT_FunctionExist("GScriptClip"),myName+"Essential GRunT plugin installed, http://forum.doom9.org/showthread.php?t=139337") Assert(RT_FunctionExist("GScript"),myName+"Essential GScript plugin installed, http://forum.doom9.org/showthread.php?t=147846") Assert(RT_FunctionExist("CallCmd"),myName+"Essential CallCmd plugin installed, http://forum.doom9.org/showthread.php?t=166063") Assert(RT_FunctionExist("ForceProcessAVI"),myName+"Essential TWriteAVI plugin installed, http://forum.doom9.org/showthread.php?t=172837") Assert(RT_FunctionExist("MSuper"),myName+"Essential MvTools v2 plugin installed, http://forum.doom9.org/showthread.php?t=131033") DifByN = Default(DifByN,-1) Th = Float(Default(Th, 0.000)) DifByN2= Default(DifByN2,-1) Th2 = Float(Default(Th2,16.000)) CW = Float(Default(CW,1.0/3.0)) MaxInterp= Default(MaxInterp,3) ForceProcess = Default(ForceProcess, false) Show = !ForceProcess && Default(Show, false) Stack = Show && Default(Stack, false) Verbose= Show && Default(Verbose, false) pel = Default(pel,2) sharp = Default(sharp,2) rfilter= Default(rfilter,2) ml = Float(default(ml,100.0)) SC_thSCD1=Default(SC_thSCD1,400) SC_thSCD2=Default(SC_thSCD2,130) Assert(!IsRGB,RT_String("%sYUV only",myName)) Assert(DifByN>=-1,RT_String("%s-1 <= DifByN(%d)",myName,DifByN)) Assert(Th>=0.0,RT_String("%s0.0 <= Th(%f)",myName,Th)) Assert(DifByN2>=-1,RT_String("%s-1 <= DifByN2(%d)",myName,DifByN2)) Assert(Th2>Th || DifByN2 > DifByN || (DifByN<0&&DifByN2>0)||(DifByN>0&&DifByN2<0),RT_String("%sTh < Th2(%f) when similar type Thresholds",myName,Th2)) Assert(CW>=0.0 && CW <= 1.0,RT_String("%s0.0 <= CW <= 1.0(%f)",myName,CW)) Assert(MaxInterp>=0 && MaxInterp<=9,RT_String("%sMaxInterp 0 -> 9(%d)",myName,MaxInterp)) In = c c = Stack ? StackVertical(c,c) : c DB = RT_GetFullPathName("~"+RT_LocalTimeString+".DB") /* Fields 0) Status, 0=Unknown (unvisited), 1 = Unique frame, 2 = Duplicate of prev frame. 1) 1 = Replace Duplicate (valid for Status Dupe Frames only), else 0. 2) Dupe Start Unique, (valid for Status Dupe Frames only). Set ALWAYS when Status is 2 (Dupilcate) All following dupes are duplicate of THIS. 3) Dupe End Unique, (valid for Status Dupe Frames only). Set ALWAYS when Status is 2 (Dupilcate) Either end of both Unknown and Duplicate, are ALWAYS partitioned with at least a single Unique frame. Frames 0 and FrameCount-1 are always Unique. */ RT_DBaseAlloc(DB,FrameCount,"iiii") RT_DBaseSetField(DB,0,0,1) RT_DBaseSetField(DB,FrameCount-1,0,1) # Set first and Last Frames to Unique Frame FmtU = "%d] U\aGDSIB\a- \aG{1/1}\a- : RunCnt=%d : RunMax=%d\nPrev->Curr = %f" FmtV = RT_string("DifByN =%d : Th =%f\nDifByN2 =%d : Th2=%f\nMaxInterp=%d",DifByN,Th,DifByN2,Th2,MaxInterp) FmtDBS="%d] \aGU\a-DS\aGI\a-B {%d/%d} : RunCnt=%d : RunMax=%d\nPrev->Curr =%10.6f\nFrameDif =%10.6f (Unique<->n, DifByN)\n" + \ "RunDif =\a%c%10.6f\a- (Unique<->Unique, DifByN2)\nBlendWeight=%10.6f" FmtDB="%d] \aGU\a-D\aGSI\a-B {%d/%d} : RunCnt=%d : RunMax=%d\nPrev->Curr =%10.6f\nFrameDif =%10.6f (Unique<->n, DifByN)\n" + \ "RunDif =\a%c%10.6f\a- (Unique<->Unique, DifByN2)\nBlendWeight=%10.6f" FmtDI="%d] \aGU\a-D\aGS\a-I\aGB\a- {%d/%d} : RunCnt=%d : RunMax=%d\nPrev->Curr =%10.6f\n" + \ "FrameDif =%10.6f (Unique<->n, DifByN)\nRunDif =%10.6f (Unique<->Unique, DifByN2)" FuncS=""" Function Fn@@@(clip clp,String DB,Int DifByN,Float Th,Int DifByN2,Float Th2,Float CW,Int MaxInterp,Bool Stack,Bool Show,Bool Verbose, \ String FmtU,String FmtV,String FmtDBS,String FmtDB,String FmtDI) { clp = Stack ? clp.Crop(0,0,-0,clp.Height/2): clp clp n = current_frame Status = RT_DBaseGetField(DB,n,0) if(Show || Status != 1) { # In here if Show or NOT Unique Frame (ie dupe or unvisited) if(Show || Status==0) { # Show or Unknown Status # Diff Prev <-> Curr fd_p = (DifByN<0) \ ? RT_FrameDifference(Last,Last,n=n,n2=n-1,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=n,n2=n-1,Thresh=DifByN) if(fd_p > Th) { # Is Unique frame if(Status != 1) { # Unvisited # Assert(Status==0,RT_String("Status Not 0(%d:%f)",Status,fd_p)) RT_DBaseSetField(DB,n,0,1) # Set Unique Status Status = 1 } } else { # Dupe FC=FrameCount # Assert(Status!=1 || n==0 || n==FC-1,RT_String("Status Is 1 (%d:%f)",Status,fd_p)) if(Status==0) { # We MUST first scan backwards to find frame that is Unique to its predecessor (we are not necessarily a dupe of that frame) StartU=n for(i=n-1,0,-1) { # Exit with i==-1 (should NEVER HAPPEN, frame 0 is Unique) Stat = RT_DBaseGetField(DB,i,0) # Assert(Stat==0 || Stat==1,"Stat out of bounds (not 0 or 1)") StartU = i if(Stat==0) { # Status Unknown fd = (DifByN<0) \ ? RT_FrameDifference (Last,Last,n=i,n2=i-1,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=i,n2=i-1,Thresh=DifByN) if(fd > Th) { RT_DBaseSetField(DB,i,0,1) # Set Unique Status, Following frames are dupe of this i = -1 # Break, Exit with i==-2 } } Else { i = -2 # Break, Exit with i==-3 } } # Assert(i!=-1,"Stat Not Found backwards") EndU = n for(i=n+1,FC-1) { # Exit with i==FC (should NEVER HAPPEN, last frame is Unique) Stat = RT_DBaseGetField(DB,i,0) # Assert(Stat==0 || Stat==1,"Stat out of bounds (not 0 or 1)") EndU = i if(Stat==0) { # Status Unknown fd = (DifByN<0) \ ? RT_FrameDifference (Last,Last,n=i,n2=i-1,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=i,n2=i-1,Thresh=DifByN) if(fd > Th) { RT_DBaseSetField(DB,i,0,1) # Set Unique Status i = FC # Break, Exit with i==FC=+1 } } Else { i = FC+1 # Break, Exit with i==FC+2 } } # Assert(i > FC,"Stat Not Found forwards") for(i=StartU+1,EndU-1) { RT_DBaseSet(DB,i,2,1,StartU,EndU) # Set Dupe of Predecessor Status } } Status=2 } } Replace = RT_DBaseGetField(DB,n,1) if(Replace==1) { StartU = RT_DBaseGetField(DB,n,2) EndU = RT_DBaseGetField(DB,n,3) frames = EndU-StartU-1 Global RunCnt@@@=(n==StartU+1) ? RunCnt@@@+1 : RunCnt@@@ Global RunMax@@@=Max(RunMax@@@,frames) Pos = n-StartU SC = (SC@@@.RT_AverageLuma(n=EndU,W=1,H=1) != 0) # EndU is Scene Change Start Of New Scene FrmDif = (DifByN<0) \ ? RT_FrameDifference (Last,Last,n=StartU,n2=n,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=StartU,n2=n,Thresh=DifByN) Dif2 = (DifByN2<0) \ ? RT_FrameDifference (Last,Last,n=StartU,n2=EndU,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=StartU,n2=EndU,Thresh=DifByN2) TooDif=(Dif2>Th2) Blend = (SC || TooDif|| Frames > MaxInterp) if(Blend) { if(SC) { Weight = 1.0 * Pos / Frames Last = Merge(clp.Trim(StartU,-1),clp.Trim(EndU-1,-1),Weight) (Show)?RT_Subtitle(FmtDBS,n,pos,Frames,RunCnt@@@,RunMax@@@,fd_p,FrmDif,TooDif?33:45,Dif2,Weight) : NOP } else { Weight = 1.0 * Pos / (Frames+1) Last = Merge(clp.Trim(StartU,-1),clp.Trim(EndU,-1),Weight) (Show)?RT_Subtitle(FmtDB,n,Pos,Frames,RunCnt@@@,RunMax@@@,fd_p,FrmDif,TooDif?33:45,Dif2,Weight) : NOP } } else { Eval(RT_String("Last = I%0.2d_%0.2d@@@.Trim(%d,-1)",Frames,n-StartU,StartU)) (Show)?RT_Subtitle(FmtDI,n,Pos,Frames,RunCnt@@@,RunMax@@@,fd_p,FrmDif,Dif2) : NOP } } if(Show) { (Replace!=1) ? RT_subtitle(FmtU,n,RunCnt@@@,RunMax@@@,fd_p) : NOP (Verbose) ? RT_Subtitle("%s",FmtV,Align=1) : NOP (Stack) ? StackVertical(Last, Subtract(clp.Trim(n-1,-1),clp.Trim(n,-1))) : Last } } # End (Show || Status) Return Last } ####################################### # Unique Global Variables Initialization ####################################### Global RunMax@@@=0 Global RunCnt@@@=0 thSCD1=(8*8)*255 thSCD2=255 BLEND=False bs=(In.width>960) ? 16 : 8 supFilt = In.Blur(0.6).MSuper(pel=2,sharp=sharp,rfilter=rfilter,hpad=16, vpad=16) sup = In.MSuper(pel=2,sharp=sharp,rfilter=rfilter,hpad=16, vpad=16, levels=1) SC_fv=supFilt.MAnalyse(isb=false, delta=1,blksize=bs,overlap=bs/2) SC_fv=MRecalculate(sup,SC_fv,blksize=bs/2,overlap=bs/4,thSAD=100) Global SC@@@=In.MSCDetection(SC_fv,thSCD1=SC_thSCD1,thSCD2=SC_thSCD2) For(Bad=1,MaxInterp) { 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=bs/4,thSAD=100)",Bad,Bad)) Eval(RT_String("I%0.2d_fv=MRecalculate(sup,I%0.2d_fv,blksize=bs/2,overlap=bs/4,thSAD=100)",Bad,Bad)) for(i=1,Bad) { Eval(RT_String("Global I%0.2d_%0.2d@@@=In.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)) } } ####################################### # Unique Runtime Call, GScriptClip must be a one-liner: ####################################### ARGS = "DB,DifByN,Th,DifByN2,Th2,CW,MaxInterp,Stack,Show,Verbose,FmtU,FmtV,FmtDBS,FmtDB,FmtDI" c.GScriptClip("Fn@@@(last, "+ARGS+")", local=true, args=ARGS) """ ####################################### # Unique Identifier Definition ####################################### GIFunc="MorphDupes_MI" # Function Name, Supply unique name for your multi-instance function. GIName=GIFunc+"_InstanceNumber" # Name of the Instance number Global RT_IncrGlobal(GIName) # Increment Instance Global (init to 1 if not already exists) GID = GIFunc + "_" + String(Eval(GIName)) InstS = RT_StrReplace(FuncS,"@@@","_"+GID) # RT_WriteFile("DEBUG_"+GID+".TXT","%s",InstS) GScript(InstS) (ForceProcess) ? ForceProcessAVI : NOP CallCmd(close=RT_String("""CMD /C chcp 1252 && del "%s" """,DB), hide=true, Synchronous=7) # Auto delete DB file on clip closure. Return Last }
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 6th March 2018 at 06:47. |
6th March 2018, 06:50 | #23 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Bugfix in script 2 posts previous.
No effect really, as bug was in a commented out Assert. Changes in blue Code:
FC=FrameCount # Moved before next line # Assert(Status!=1 || n==0 || n==FC-1,RT_String("Status Is 1 (%d:%f)",Status,fd_p)) # Blue added
__________________
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 ??? |
22nd July 2018, 09:28 | #25 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
As time (& capability) permits I am converting all to x64 (unfortunately, me gots bout 100 projects currently active )
Currently, I think only CallCmd not implemented in x64, and also TWriteAVI v2.0, CallCmd no real problem, in fact probably just needs changed headers and a bit of fiddling, and should be OK. TWriteAVI however, is beyond me, I identified about 4 problems in source, (1 fixed here locally), but other 3 I have no idea how to approach, (2 I think were CPP related, I aint a CPP programmer), and 1 was the fact that there is a lot of x86 ASM used, me dont talk dat lingo, so no go. Maybe someone else more at home with CPP and x86 ASM could have a bash.
__________________
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 ??? |
22nd July 2018, 10:21 | #26 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Lirk, see below requirements for v1.10. [should be workable on x64]
EDIT: There were a couple of bug fixes in Duplicity script, here:- https://forum.doom9.org/showthread.p...ight=duplicity MorphDupes_MI_1.10.avs Part 1 of 2 (Too big, Copy/Paste together) Code:
Function MorphDupes_MI(clip c, Int "DifbyN",Float "Th",Int "DifbyN2",Float "Th2",Float "CW",Int "MaxInterp", \ Bool "Stack", bool "Show", Bool "ForceProcess",Bool "Verbose", \ int "pel",int "sharp",int "rfilter",Float "ml",Int "SC_thSCD1",Int "SC_thSCD2") { /* MorphDupes_MI v1.10, by StainlessS. http://forum.doom9.org/showthread.php?p=1764865#post1764865 Finds runs of duplicates and replaces them with either Interpolated or blended frames. Planar, YUY2. Audio, no change. Multi-Instance capable. Plugins:- MvTools (c) Manoa/Fizick & Others : GScript and Grunt (c) Gavino, RT_Stats, TWriteAVI v2.0, CallCmd, (c) StainlessS. Either AVS+ or GScript plugin required. Can only use ForceProcess=True if TWriteAVI v2.0 is installed. Will Auto Delete temp DBase file if CallCmd is installed, otherwise user has to delete manually. MorphDupes_MI(clip c, Int "DifbyN"=-1,Float "Th"=0.0,Int "DifbyN2"=-1,Float "Th2"=16.0,Float "CW"=1.0/3,Int "MaxInterp"=3, \ Int "Stack"=False, bool "Show"=False,Bool "ForceProcess"=False,Bool "Verbose"=False, \ int "pel"=2,int "sharp"=2,int "rfilter"=2,Float "ml"=100.0,Int "SC_thSCD1"=400,Int "SC_thSCD2"=130) There are two Difference measuring options to measure whether a frame is a duplicate or not and switched via DifByN, if DifByN is -1 (default), then uses RT_FrameDifference function (together with CW=ChromaWeight setting, default 1.0/3, 0.0=Luma only) and Th threshold to determine duplicate status. RT_FrameDifference returns the average pixel difference for the two comparison frames. If DifByN is >= 0, then switches to using RT_LumaPixelsDifferent(Thresh=DifByN) where DifByN is also a control arg to RT_LumaPixelsDifferent. RT_LumaPixelsDifferent returns the percentage of pixels where the luma difference between corresponding pixels is greater than a threshold (DifByN). If the difference measure between current frame and it's predecessor (measured via RT_Framedifference or RT_LumaPixelsDifferent) is <= Th, then it is deemed a duplicate frame. Elsewhere we use the term 'Unique Start' frame, this is the frame at head of run of dupes [the frame of which others are a copy], and unique in that it is different from its predecessor. Frames Determined to be Duplicates: For frames that are determined to be duplicates, there are two modes of operation, Interpolation, and Blend, the two modes are partly user adjustable and partly automatic. MaxInterp (default 3) governs the greatest number of duplicate frames that can be Interpolated, setting it to 0 will be always in Blend mode. If a Scene change is detected via mvtools MSCDetection(thSCD1=SC_thSCD1,thSCD2=SC_thSCD2) on the last frame in duplicate run, and the frame following a run of duplicates, then it will also drop down to Blend mode, using the Start Unique frame and frame BEFORE End Unique frame as the source frames of blend. In addition, if the End Unique frame is NOT a scene change, but it is too different to the Start Unique frame (via DifByN2 and Th2), then it will again drop to blend mode but using the End Unique frame as a blend source frame (DifByN2 and Th2 work in exactly the same way as previously noted for DifByN and Th). Args:- DifByN, Default -1. -1 or greater. Frame comparison mode selection and thresh arg to RT_LumaPixelsDifferent() function (when DifByN >= 0). Th, Default 0.0, A difference Threshold for value returned by either RT_FrameDifference or RT_LumaPixelsDifferent() to determine duplicate status of a frame. DifByN == -1 : Uses RT_FrameDifference as measure. DifByN >= 0 : Uses RT_LumaPixelsDifferent as measure. DifByN and Th are used to establish duplicate status of a frame, if result of above DifByN selected function is <= Th, then frames are judged to be same (dupe). By default it looks for Indentical frame dupes. DifByN2, Default -1. -1 or greater. Frame comparison mode selection and thresh arg to RT_LumaPixelsDifferent() function (when DifByN2 >= 0). Th2, Default 16.0, 0.0 or more. Th2 MUST be greater than Th if DifByN2 comparison mode selection is the same as DifByN. DifByN2 and Th2 work in exactly the same way as DifByN and Th. Th2 is a difference Threshold for value returned by either RT_FrameDifference or RT_LumaPixelsDifferent() to determine if the duplicate run Unique Start frame is too different to the Unique End frame (that follows a run of duplicates). If the Unique End frame IS too different to the Unique Start frame, then switches down to blend mode for the current run of dupes. CW, Default 1.0/3.0, 0.0->1.0. ChromaWeight arg to RT_FrameDiffernce (if DifbyN or DifByN2 are -1), 0.0 = Luma only. MaxInterp, Default 3, 0 -> 9. Maximum number of frames that may be Interpolated. Stack, default False, If True show StackVertical the difference between current frame and its predecessor. Switched off if Show is false. Show, Default False. Show some metrics stuff if true. Switched off if ForceProcess = true. ForceProcess, Default false. If true then scan entire clip doing the dupe blend replacement automatically, and then return result when completed. Will take time to scan entire clip. Auomatically switches OFF Show and Stack when ForceProcess = true. Verbose, Default False. Show some args if true and Show=True. pel, Default 2, MvTools arg to MSuper() for interpolation. See MvTools. range=1 or 2 or 4 sharp, Default 2, MvTools arg to MSuper() for interpolation. See MvTools. range=0 -> 2 rfilter, Default 2, MvTools arg to MSuper() for interpolation. See MvTools. range=0 -> 4 ml Default 100.0, MvTools arg to MFlowInter() for interpolation. See MvTools. range=greater than 0.0. SC_thSCD1 Default 400, MvTools arg to MSCDetection(thSCD1) for scene change detection. See MvTools.range = 0->(8*8)*255 SC_thSCD2 Default 130, MvTools arg to MSCDetection(thSCD2) for scene change detection. See MvTools.range = 0-> 255 ###### Metrics shown:- nnnn] UDSIB {a/b} : RunCount=c : RunMax=d Prev->Curr = fff.ffffff FrameDif = fff.ffffff (Unique<->n, DifByN) RunDif = fff.ffffff (Unique<->Unique, DifByN2) BlendWeight= fff.ffffff Where, nnnn, = Frame Number Flags UDSIB (where hi-lited) U = Unique frame (not at duplicate) D = Duplicate. S = Scene Change follows duplicate run. I = Interpolate mode used. B = Blend mode used. {a/b} = a'th frame in run of b dupes. RunCount=c, = Number of duplicate runs encountered so far. RunMax =d, = length of longest duplicate run encountered so far. Prev->Curr = DifByN metric difference between current frame and its predecessor. FrameDif = DifByN metric difference between Unique Start frame and current duplicate frame. (Only shown for Duplicates) RunDif = DifByN2 metric difference between Unique Start frame and Unique End frame following duplicate run. (Only shown for Duplicates) BlendWeight = Weight arg to Merge() two frames in blend mode. (Only shown for Blended Duplicates) */
__________________
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; 22nd July 2018 at 10:31. |
22nd July 2018, 10:23 | #27 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
MorphDupes_MI_1.10.avs Part 2 of 2
Code:
c myName="MorphDupes_MI: " IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript") HasCallCmd=RT_FunctionExist("CallCmd") HasTWriteAVI=RT_FunctionExist("ForceProcessAVI") Assert(IsAvsPlus || HasGScript,RT_String("%sNeed either GScript or AVS+",myName)) Assert(RT_FunctionExist("GScriptClip"),myName+"Essential GRunT plugin installed, http://forum.doom9.org/showthread.php?t=139337") Assert(RT_FunctionExist("MSuper"),myName+"Essential MvTools v2 plugin installed, http://forum.doom9.org/showthread.php?t=131033") DifByN = Default(DifByN,-1) Th = Float(Default(Th, 0.000)) DifByN2= Default(DifByN2,-1) Th2 = Float(Default(Th2,16.000)) CW = Float(Default(CW,1.0/3.0)) MaxInterp= Default(MaxInterp,3) ForceProcess = Default(ForceProcess, false) Show = !ForceProcess && Default(Show, false) Stack = Show && Default(Stack, false) Verbose= Show && Default(Verbose, false) pel = Default(pel,2) sharp = Default(sharp,2) rfilter= Default(rfilter,2) ml = Float(default(ml,100.0)) SC_thSCD1=Default(SC_thSCD1,400) SC_thSCD2=Default(SC_thSCD2,130) Assert(!IsRGB,RT_String("%sYUV only",myName)) Assert(DifByN>=-1,RT_String("%s-1 <= DifByN(%d)",myName,DifByN)) Assert(Th>=0.0,RT_String("%s0.0 <= Th(%f)",myName,Th)) Assert(DifByN2>=-1,RT_String("%s-1 <= DifByN2(%d)",myName,DifByN2)) Assert(Th2>Th || DifByN2 > DifByN || (DifByN<0&&DifByN2>0)||(DifByN>0&&DifByN2<0),RT_String("%sTh < Th2(%f) when similar type Thresholds",myName,Th2)) Assert(CW>=0.0 && CW <= 1.0,RT_String("%s0.0 <= CW <= 1.0(%f)",myName,CW)) Assert(MaxInterp>=0 && MaxInterp<=9,RT_String("%sMaxInterp 0 -> 9(%d)",myName,MaxInterp)) Assert(!ForceProcess || HasTWriteAVI,myName+"TWriteAVI v2.0 plugin required for ForceProcess.") In = c c = Stack ? StackVertical(c,c) : c DB = RT_GetFullPathName("~"+RT_LocalTimeString+".DB") /* Fields 0) Status, 0=Unknown (unvisited), 1 = Unique frame, 2 = Duplicate of prev frame. 1) 1 = Replace Duplicate (valid for Status Dupe Frames only), else 0. 2) Dupe Start Unique, (valid for Status Dupe Frames only). Set ALWAYS when Status is 2 (Dupilcate) All following dupes are duplicate of THIS. 3) Dupe End Unique, (valid for Status Dupe Frames only). Set ALWAYS when Status is 2 (Dupilcate) Either end of both Unknown and Duplicate, are ALWAYS partitioned with at least a single Unique frame. Frames 0 and FrameCount-1 are always Unique. */ RT_DBaseAlloc(DB,FrameCount,"iiii") RT_DBaseSetField(DB,0,0,1) RT_DBaseSetField(DB,FrameCount-1,0,1) # Set first and Last Frames to Unique Frame FmtU = "%d] U\aGDSIB\a- \aG{1/1}\a- : RunCnt=%d : RunMax=%d\nPrev->Curr = %f" FmtV = RT_string("DifByN =%d : Th =%f\nDifByN2 =%d : Th2=%f\nMaxInterp=%d",DifByN,Th,DifByN2,Th2,MaxInterp) FmtDBS="%d] \aGU\a-DS\aGI\a-B {%d/%d} : RunCnt=%d : RunMax=%d\nPrev->Curr =%10.6f\nFrameDif =%10.6f (Unique<->n, DifByN)\n" + \ "RunDif =\a%c%10.6f\a- (Unique<->Unique, DifByN2)\nBlendWeight=%10.6f" FmtDB="%d] \aGU\a-D\aGSI\a-B {%d/%d} : RunCnt=%d : RunMax=%d\nPrev->Curr =%10.6f\nFrameDif =%10.6f (Unique<->n, DifByN)\n" + \ "RunDif =\a%c%10.6f\a- (Unique<->Unique, DifByN2)\nBlendWeight=%10.6f" FmtDI="%d] \aGU\a-D\aGS\a-I\aGB\a- {%d/%d} : RunCnt=%d : RunMax=%d\nPrev->Curr =%10.6f\n" + \ "FrameDif =%10.6f (Unique<->n, DifByN)\nRunDif =%10.6f (Unique<->Unique, DifByN2)" FuncS=""" Function Fn@@@(clip clp,String DB,Int DifByN,Float Th,Int DifByN2,Float Th2,Float CW,Int MaxInterp,Bool Stack,Bool Show,Bool Verbose, \ String FmtU,String FmtV,String FmtDBS,String FmtDB,String FmtDI) { clp = Stack ? clp.Crop(0,0,-0,clp.Height/2): clp clp n = current_frame Status = RT_DBaseGetField(DB,n,0) if(Show || Status != 1) { # In here if Show or NOT Unique Frame (ie dupe or unvisited) if(Show || Status==0) { # Show or Unknown Status # Diff Prev <-> Curr fd_p = (DifByN<0) \ ? RT_FrameDifference(Last,Last,n=n,n2=n-1,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=n,n2=n-1,Thresh=DifByN) if(fd_p > Th) { # Is Unique frame if(Status != 1) { # Unvisited # Assert(Status==0,RT_String("Status Not 0(%d:%f)",Status,fd_p)) RT_DBaseSetField(DB,n,0,1) # Set Unique Status Status = 1 } } else { # Dupe # Assert(Status!=1 || n==0,RT_String("Status Is 1 (%d:%f)",Status,fd_p)) if(Status==0) { # We MUST first scan backwards to find frame that is Unique to its predecessor (we are not necessarily a dupe of that frame) StartU=n for(i=n-1,0,-1) { # Exit with i==-1 (should NEVER HAPPEN, frame 0 is Unique) Stat = RT_DBaseGetField(DB,i,0) # Assert(Stat==0 || Stat==1,"Stat out of bounds (not 0 or 1)") StartU = i if(Stat==0) { # Status Unknown fd = (DifByN<0) \ ? RT_FrameDifference (Last,Last,n=i,n2=i-1,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=i,n2=i-1,Thresh=DifByN) if(fd > Th) { RT_DBaseSetField(DB,i,0,1) # Set Unique Status, Following frames are dupe of this i = -1 # Break, Exit with i==-2 } } Else { i = -2 # Break, Exit with i==-3 } } # Assert(i!=-1,"Stat Not Found backwards") FC=FrameCount EndU = n for(i=n+1,FC-1) { # Exit with i==FC (should NEVER HAPPEN, last frame is Unique) Stat = RT_DBaseGetField(DB,i,0) # Assert(Stat==0 || Stat==1,"Stat out of bounds (not 0 or 1)") EndU = i if(Stat==0) { # Status Unknown fd = (DifByN<0) \ ? RT_FrameDifference (Last,Last,n=i,n2=i-1,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=i,n2=i-1,Thresh=DifByN) if(fd > Th) { RT_DBaseSetField(DB,i,0,1) # Set Unique Status i = FC # Break, Exit with i==FC=+1 } } Else { i = FC+1 # Break, Exit with i==FC+2 } } # Assert(i > FC,"Stat Not Found forwards") for(i=StartU+1,EndU-1) { RT_DBaseSet(DB,i,2,1,StartU,EndU) # Set Dupe of Predecessor Status } } Status=2 } } Replace = RT_DBaseGetField(DB,n,1) if(Replace==1) { StartU = RT_DBaseGetField(DB,n,2) EndU = RT_DBaseGetField(DB,n,3) frames = EndU-StartU-1 Global RunCnt@@@=(n==StartU+1) ? RunCnt@@@+1 : RunCnt@@@ Global RunMax@@@=Max(RunMax@@@,frames) Pos = n-StartU SC = (SC@@@.RT_AverageLuma(n=EndU,W=1,H=1) != 0) # EndU is Scene Change Start Of New Scene FrmDif = (DifByN<0) \ ? RT_FrameDifference (Last,Last,n=StartU,n2=n,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=StartU,n2=n,Thresh=DifByN) Dif2 = (DifByN2<0) \ ? RT_FrameDifference (Last,Last,n=StartU,n2=EndU,ChromaWeight=CW) \ : RT_LumaPixelsDifferent(Last,Last,n=StartU,n2=EndU,Thresh=DifByN2) TooDif=(Dif2>Th2) Blend = (SC || TooDif|| Frames > MaxInterp) if(Blend) { if(SC) { Weight = 1.0 * Pos / Frames Last = Merge(clp.Trim(StartU,-1),clp.Trim(EndU-1,-1),Weight) (Show)?RT_Subtitle(FmtDBS,n,pos,Frames,RunCnt@@@,RunMax@@@,fd_p,FrmDif,TooDif?33:45,Dif2,Weight) : NOP } else { Weight = 1.0 * Pos / (Frames+1) Last = Merge(clp.Trim(StartU,-1),clp.Trim(EndU,-1),Weight) (Show)?RT_Subtitle(FmtDB,n,Pos,Frames,RunCnt@@@,RunMax@@@,fd_p,FrmDif,TooDif?33:45,Dif2,Weight) : NOP } } else { Eval(RT_String("Last = I%0.2d_%0.2d@@@.Trim(%d,-1)",Frames,n-StartU,StartU)) (Show)?RT_Subtitle(FmtDI,n,Pos,Frames,RunCnt@@@,RunMax@@@,fd_p,FrmDif,Dif2) : NOP } } if(Show) { (Replace!=1) ? RT_subtitle(FmtU,n,RunCnt@@@,RunMax@@@,fd_p) : NOP (Verbose) ? RT_Subtitle("%s",FmtV,Align=1) : NOP (Stack) ? StackVertical(Last, Subtract(clp.Trim(n-1,-1),clp.Trim(n,-1))) : Last } } # End (Show || Status) Return Last } ####################################### # Unique Global Variables Initialization ####################################### Global RunMax@@@=0 Global RunCnt@@@=0 thSCD1=(8*8)*255 thSCD2=255 BLEND=False bs=(In.width>960) ? 16 : 8 supFilt = In.Blur(0.6).MSuper(pel=2,sharp=sharp,rfilter=rfilter,hpad=16, vpad=16) sup = In.MSuper(pel=2,sharp=sharp,rfilter=rfilter,hpad=16, vpad=16, levels=1) SC_fv=supFilt.MAnalyse(isb=false, delta=1,blksize=bs,overlap=bs/2) SC_fv=MRecalculate(sup,SC_fv,blksize=bs/2,overlap=bs/4,thSAD=100) Global SC@@@=In.MSCDetection(SC_fv,thSCD1=SC_thSCD1,thSCD2=SC_thSCD2) For(Bad=1,MaxInterp) { 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=bs/4,thSAD=100)",Bad,Bad)) Eval(RT_String("I%0.2d_fv=MRecalculate(sup,I%0.2d_fv,blksize=bs/2,overlap=bs/4,thSAD=100)",Bad,Bad)) for(i=1,Bad) { Eval(RT_String("Global I%0.2d_%0.2d@@@=In.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)) } } ####################################### # Unique Runtime Call, GScriptClip must be a one-liner: ####################################### ARGS = "DB,DifByN,Th,DifByN2,Th2,CW,MaxInterp,Stack,Show,Verbose,FmtU,FmtV,FmtDBS,FmtDB,FmtDI" c.GScriptClip("Fn@@@(last, "+ARGS+")", local=true, args=ARGS) """ ####################################### # Unique Identifier Definition ####################################### GIFunc="MorphDupes_MI" # Function Name, Supply unique name for your multi-instance function. GIName=GIFunc+"_InstanceNumber" # Name of the Instance number Global RT_IncrGlobal(GIName) # Increment Instance Global (init to 1 if not already exists) GID = GIFunc + "_" + String(Eval(GIName)) InstS = RT_StrReplace(FuncS,"@@@","_"+GID) # RT_WriteFile("DEBUG_"+GID+".TXT","%s",InstS) HasGScript ? GScript(InstS) : Eval(InstS) # Use GSCript if installed (loaded plugs override builtin) (ForceProcess) ? ForceProcessAVI : NOP # If CallCmd available then Auto delete DB file on clip closure, else user must delete. (HasCallCmd) ? CallCmd(close=RT_String("""CMD /C chcp 1252 && del "%s" """,DB), hide=true, Synchronous=7) : NOP Return Last } EDIT: Damn, it looks like it already does support (although under name Sciptclip instead of GScriptClip, [ie 'Args' & 'Local' args], and also eg AverageLuma(clip c,int int i) for delta relative current_frame). I'll do mod and update again in a little while to remove GRunt requirement for Avs+. EDIT: Forget what I said about Grunt, seems we have problems with AVS+ replacing Grunt, will implement Gruntless script when possible.
__________________
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; 22nd July 2018 at 14:14. |
22nd July 2018, 15:21 | #29 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
As I said in post #25, I dont know how to update TWriteAVI for x64, that aint likely to change.
However, as hi-lited in BLUE in post #26 [updated for you today] Code:
Either AVS+ or GScript plugin required. Can only use ForceProcess=True if TWriteAVI v2.0 is installed. Will Auto Delete temp DBase file if CallCmd is installed, otherwise user has to delete manually. You also dont need CallCmd, if not installed then will have to delete temp Dbase file manually. All other plugins are available in x64, so you are pretty much good to go.
__________________
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; 22nd July 2018 at 15:26. |
22nd July 2018, 15:30 | #30 | Link |
Registered User
Join Date: Jan 2018
Posts: 33
|
Script runs, but it doesn't work properly (threshold=0.1). Video has 2-3 dropped frames at once and metrics shows that they are detected but script return previous frame after dropped. Why by default threshold=0? Does this script generate blended frames as ConvertFPS, or interpolate it as SVPflow or MVTools?
Duplicity can only generate text file with dropped frames, or also can interpolate it? It would be better to retain detection method from filldrops3 or gamedropfix_v5, but replace generation method from interpolate by MVTools to blend as in ConvertFPS. Last edited by Lirk; 5th August 2018 at 00:18. |
23rd July 2018, 01:20 | #31 | Link | |||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
Quote:
Quote:
Metrics show what is being used. Code:
nnnn] UDSIB {a/b} Flags UDSIB (where hi-lited) U = Unique frame (not at duplicate) D = Duplicate. S = Scene Change follows duplicate run. I = Interpolate mode used. B = Blend mode used. {a/b} = a'th frame in run of b dupes. Code:
# Return Clip Difference of input clips (amp==true = Amplified, show==true = show background) Function ClipDelta(clip clip1,clip clip2,bool "amp",bool "show") { amp=Default(amp,false) show=Default(show,false) c2=clip1.levels(128-32,1.0,128+32,128-32,128+32).greyscale() c1=clip1.subtract(clip2) c1=(amp)?c1.levels(127,1.0,129,0,255):c1 return (show)?c1.Merge(c2):c1 } Import(".\MorphDupes_MI_1.01.avs") AviSource(".\g.avi") O=LAst MorphDupes_Mi(Th=0.05,Show=true,Verbose=True) D1=ClipDelta(Last,O) D2=ClipDelta(Last,O,Amp=true) TOP=StackHorizontal(O,Last) BOT=StackHorizontal(D1,D2) StackVertical(TOP,BOT) /* ORIGINAL # OUTPUT ########################## OUT-ORG # OUT-ORG AMP'ed */ From Mediafire below in my sig, EDIT: The purpose of MaxInterp (Default=3) and of Th2 (Default=16.0), is to prevent Interpolation and drop down to Blend mode. I personally dont like when MvTools produces nasty swirly results due to differences between interpolation source frames being too different from each other. If you dont care about producing the swirlies, then set MaxInterp=9 (max) and th2=255.0. then will use Interpolation mode always (up to 9 interpolated frames, and drop down to blend mode if greater than 9 frames). Setting MaxInterp=0, will always use blend mode. (It kinda amazes me when people wanna interpolate 20 or 30 frames, blend mode is nearly always gonna be less awful 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; 23rd July 2018 at 15:59. |
|||
24th July 2018, 09:51 | #32 | Link |
Registered User
Join Date: Jan 2018
Posts: 33
|
https://www.mediafire.com/folder/qm6...ejuvno8/shared
l-orig.mp4 - original th(0).mp4 - th=0 th(0.1).mp4 - th=0.1 Last edited by Lirk; 5th August 2018 at 00:18. |
24th July 2018, 16:39 | #33 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Thanks for the samples Lirk, a real pig of a clip I think.
MorphDupes_MI Frame 97 requires Th of at least 0.6, but then the very dark scene at beginning has no chance of being detected as moving. Duplicity with ThG of 1.0 (will be new default) fairs better with your clip but only if ThL is bumped up from 8 to about 31, frame 97 (although looks like dupe) has at least 1 luma pixel difference of about 30, thats a lot to accept as dupe. EDIT: Even at Duplicity ThL of 8, there are 0.19% of pixels more than 8 luma levels different to corresponding pixels of prev frame. EDIT: And 0.022% at ThL of 16. Give me a little time to play with this.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 24th July 2018 at 16:52. |
5th August 2018, 16:13 | #34 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Lirk, I see your there.
I have not forgotten you and had to mod Duplicity() to be able to cope with samples like the one you provided, when I've got that in more final condition, I shall mod MorphDupes_MI and it should be way better than currently. (RT_Stats v2.00 Beta_11 RT_FrameMovement is required for the better detection and so I could not really use it in earlier scripts, as not many would be adventurous enough to use it, a real scaredy-cat bunch we got here).
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 5th August 2018 at 16:57. |
7th June 2019, 12:12 | #36 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Lirk,
See Duplicity2, easily cope with your difficult clip. https://forum.doom9.org/showthread.p...ght=Duplicity2
__________________
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; 11th June 2019 at 22:21. |
11th June 2019, 14:28 | #37 | Link | |
Registered User
Join Date: Jan 2018
Posts: 33
|
Quote:
|
|
11th June 2019, 20:35 | #38 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Needed a little adjustment to ThB for your clip, (ThB=2.5, default ThG*2.0=2.0), your dupes are significantly different.
Frames showing higher than default, Code:
57 block detect 2.035400 62 block detect 2.302979 # Block detect ThB must greater than this eg 2.5 ThG, never/almost never need change. ThB, adjust higher if dupe is not flagged as dupe (a little higher than the metrics in Orange for aB). ThP, probably never need change this emergency detect setting of 64 (for single moving pixel). These setting detect your dupes perfectly. Is set to detect up to 3 dupes. interpolating at most single dupe, blending if more than 1, you choose, Interpolations not brilliant especially lights glinting on very dark car bonnet. Try with ShowDOT=true, to remove metrics and still show indicator on corrected frame. Code:
Import(".\Duplicity2.Avsi") ###### FN = ".\Lirk.AVI" DBase = ".\Lirk_Det.DB" ###### Avisource(FN) SRC=Last ### Mode=2 # 0=Write Frames only : 1=Replace Dupes with Exact Dupes : 2= Interpolate/Blend Duplicates. ThG=1.0 # 1.0, Primary Frame Global Detect ThB=2.5 # ThG*2.0 ThP=64 # 64, Single Pixel Detect MaxDupLen=3 # Max detected, if more then is considered static sequence not duplicate) MaxInterp=1 # Max Interpolated frames when Mode=2 (More than MaxInterp & less or equal to MaxDupLen then uses Blend mode) InterpFast=false Show=True ShowDot=false ShowBlk=true VERB=True ### TITLE=true STACK=True STACK4=False ### Result=SRC.Duplicity2(Mode=Mode,ThG=ThG,ThB=ThB,ThP=ThP,MaxDupLen=MaxDupLen,MaxInterp=MaxInterp, \ Show=False,InterpFast=InterpFast,DBase=(STACK4||!SHOW)?DBase:"") Metrics=SRC.Duplicity2(Mode=Mode,ThG=ThG,ThB=ThB,ThP=ThP,MaxDupLen=MaxDupLen,MaxInterp=MaxInterp, \ Show=True,Verb=VERB,ShowBlk=ShowBlk,ShowDot=ShowDot,InterpFast=InterpFast,DBase=(STACK4||!SHOW)?"":DBase) Dif=Subtract(Result,SRC) SRC = (TITLE) ? SRC.TSub("Src") : SRC Result = (TITLE) ? Result.TSub("Result") : Result Metrics = (TITLE) ? Metrics.TSub("Metrics") : Metrics Dif = (TITLE) ? Dif.TSub("Dif(Result,Src)") : Dif LFT=StackVertical((STACK4||!SHOW)?Result:Metrics,SRC) RGT=StackVertical(Metrics,Dif) STK4=StackHorizontal(LFT,RGT) (STACK4) ? STK4 : (STACK) ? LFT : (Show)?Metrics:Result Return Last # Stack Overhead Subtitle Text, with optional FrameNumber shown. Function TSub(clip c,string Tit,Bool "ShowFrameNo",Int "Col"){ c.BlankClip(height=20,Color=Default(Col,0)) (Default(ShowFrameNo,False))?ScriptClip("""Subtitle(String(current_frame,"%.f] """+Tit+""""))"""):Subtitle(Tit) Return StackVertical(c).AudioDubEx(c) } I think I posted Duplicity2 script about 20 minutes after your last visit (which was maybe I think back in August 2018), so you just missed it. EDIT: You might even want to try DropDeadGorgeous() with ScanAhead of about 5, might produce smoother result. (Use the same DBase as created by above script). If you post on result, do it in Duplicity thread, thanx. EDIT: The bad interpolations of black car in dark with bright glints, think maybe mvtools cannot lock well on scene (lots of black), so probably blending rather than interpolating, maybe raise IthSCD2 from default 130 (although run risk of bad interp elsewhere when not dark scene). If dont work, restore IthSC2 and try raise IthSC1. EDIT: On 2nd thoughts, maybe just accept blends on the two black car lights glinting frames, best not mess up the others for the sake of two frames that will likely not get much[if any] better. EDIT Quote:
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 11th June 2019 at 22:03. |
|
12th June 2019, 13:29 | #39 | Link | |
Registered User
Join Date: Jan 2018
Posts: 33
|
Quote:
|
|
12th June 2019, 15:14 | #40 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
You only need set args that are not same as defaults autoload script. If you dont want eg 4 window display, then create your own script without all the extra stuff.
__________________
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; 12th June 2019 at 15:16. |
|
Thread Tools | Search this Thread |
Display Modes | |
|
|