Post #1 of Many.
Code:
Function Duplicity2(clip c,"Mode",Float "ThG",Float "ThB", Int "ThP",Float "IgP",Int "ThK",
\ Int "MaxDupLen",Int "LagMax",Int "MaxInterp",
\ int "BlkW",int "BlkH",int "OLapX",Int "OLapY",
\ Int "X",Int "Y",Int"W",Int "H",Float "CW",Bool "ChromaI",Bool "AltScan",
\ Int "SPad", Int "SSharp", Int "SRFilter", [* MSuper *]
\ Int "ABlkSize", Int "AOverlap", Int "ASearch",Int "ADct", [* MAnalyse *]
\ Int "RBlkSize", Int "ROverlap", Int "RthSAD", [* MRecalculate *]
\ Float "Iml", Bool "IBlend", Int "IthSCD1", Int "IthSCD2", [* MFlowInter *]
\ Int "OthSCD1",Int "OthSCD2", [* Duplicates Detection Override *]
\ String "OverRide",String "Frames",Bool "Ranges",Bool "FrameAsRange",
\ Bool "Show",Bool "Verb",Bool "ShowBlk",Bool "Dim",Bool "ShowDot",
\ Bool "InterpFast",String "DBase"
\ ){
Function D2_Hit_Marker(int W, Int H, Bool "Hit", Int "BW", Int "BH",Int "PW",Int "PH",Bool "YV12",Bool "Mod2") {
Hit=Default(hit,False) BW=Max(Default(BW,W/8),1) BH=Max(Default(BH,H/8),1)
BW2=(W>4)?BW*2:BW BH2=(H>4)?BH*2:BH
PW=Max(Default(PW,BW/8),1) PH=Max(Default(PH,BH/8),1) is26 = VersionNumber>=2.6
YV12=(!is26) ? True : Default(YV12,False) Mod2=Default(Mod2,True) Mod = (YV12||Mod2) ? 2 : 1
CanvasW=(W+Mod-1)/Mod*Mod CanvasH=(H+Mod-1)/Mod*Mod
Rpn= RT_String("x %d < x %d >= | y %d < | y %d >= | x %d < x %d >= | & y %d < y %d >= | & ",BW,W-BW,BH,H-BH,BW2,W-BW2,BH2,H-BH2)
Rpn= (Hit) ? Rpn + RT_String("x %d < x %d >= | y %d < | y %d >= | | ",PW,W-PW,PH,H-PH) : Rpn
Rpn= Rpn + RT_String("x %d < y %d < & & 255 0 ?",W,H)
Blankclip(width=CanvasW,height=CanvasH,Length=1,pixel_type=YV12?"YV12":"Y8").Killaudio
return mt_lutspa(relative = false,yExpr=Rpn, chroma = "-128")
}
c myName="Duplicity2: " VER=2.13
Assert(RT_Version() >= 1.99911,RT_String("%sNeed RT_Stats v2.00Beta11(%s)",myName,RT_VersionString))
IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript")
HasGRunt =RT_FunctionExist("GScriptClip") HasMvTools=RT_FunctionExist("MSuper")
HasMaskTools=RT_FunctionExist("MT_Lutxy") HasRemoveGrain=RT_FunctionExist("RemoveGrain")
HasCallCmd = RT_FunctionExist("CallCmd") IsAvs26=VersionNumber>=2.6
###
Mode = Default(Mode,0)
ThG=Default(ThG,1.0) ThB=Default(ThB,ThG*2.0) ThP=Default(ThP,64) IgP=Default(IgP,0.0)
ThK=Default(ThK,7) MaxDupLen=default(MaxDupLen,9) LagMax=default(LagMax,MaxDupLen) MaxInterp = Default(MaxInterp,9)
BlkW=Default(BlkW,64) BlkH=Default(BlkH,BlkW) OLapX=Default(OLapX,BlkW/2) OLapY=Default(OLapY,BlkH/2)
X=default(X,0) Y=default(Y,0) W=default(W,0) H=default(H,0)
CW=Default(CW,0.0) ChromaI=Default(ChromaI,False) AltScan=Default(AltScan,False)
SPad = Default(SPad,16) SSharp = Default(SSharp,1) SRFilter= Default(SRFilter,4)
ABlkSize = Default(ABlkSize,16) AOverlap= Default(AOverlap,4) ASearch = Default(ASearch,3) ADct = Default(ADct,0)
RBlkSize = Default(RBlkSize,8) ROverlap= Default(ROverlap,2) RthSAD = Default(RthSAD,100)
Iml = Default(Iml,200.0) IBlend = Default(IBlend,True) IthSCD1 = Default(IthSCD1,400) IthSCD2= Default(IthSCD2,130)
OthSCD1 = Default(OthSCD1,400) OthSCD2 = Default(OthSCD2,130)
Override=Default(OverRide,"") Frames=Default(Frames,"Frames.txt") Ranges=Default(Ranges,True) FrameAsRange=Default(FrameAsRange,False)
Show=Default(Show,True) Verb=Default(Verb,True)
Showblk=Default(ShowBlk,true) Dim=Default(Dim,true) ShowDot=Show?Default(ShowDot,False):False
InterpFast=Default(InterpFast,True) DBase=Default(DBase,"")
####
Assert(0 <= Mode <= 2,RT_String("%s0 <= Mode(%d) <= 2",myName,Mode))
Assert(1 <= MaxDupLen,RT_String("%s1 <= MaxDupLen(%d)",myName,MaxDupLen))
Assert(1 <= LagMax,RT_String("%s1 <= LagMax(%d)",myName,LagMax))
Assert(0 <= MaxInterp <= 9,RT_String("%s0 <= MaxInterp(%d) <= 9",myName,MaxInterp))
Assert(IsAvsPlus || HasGScript,RT_String("%sNeed either GScript or AVS+",myName))
Assert(HasGRunt,RT_String("%sNeed GRunt:-https://forum.doom9.org/showthread.php?t=139337 ",myName))
Assert(HasMVTools,RT_String("%sNeed MvTools2:-http://forum.doom9.org/showthread.php?t=131033",myName))
Assert(HasMaskTools,RT_String("%sNeed MaskTools",myName))
Assert(Mode!=2 || MaxInterp==0 || HasRemoveGrain,RT_String("%sNeed RemoveGrain",myName))
Assert(IsYV12||(IsAvs26&&(IsY8||IsYV16||IsYV24)),RT_String("%sOnly Standard v2.6 Planar Supported (excepting YV411)",myname))
MaxInterp=Min(MaxInterp,MaxDupLen)
W = (W > 0) ? (W + X) - Width : W H = (H > 0) ? (H + Y) - Height : H # Make -ve relative width,height
X = (X+3) / 4 * 4 Y = (Y+3) / 4 * 4 # Round UP (inwards) Mod 4
W = (W-3) / 4 * 4 H = (H-3) / 4 * 4 # Round DOWN(inwards) Mod 4
W = Width - X + W H = Height - Y + H # +ve width,height
DC=Crop(X,Y,W,H) BlkW=Min(DC.Width,BlkW) BlkH=Min(DC.Height,BlkH)
(Show && !ShowDot && DIM && Mode==0 && (W!=Width || H!=Height)) ? levels(16,1.0,235,16+48,235-48,Coring=False).Overlay(DC,x=X,y=Y) : Last
DB=(DBase=="") ? RT_GetFullPathName("~@@@_"+RT_LocalTimeString+".DB") : RT_GetFullPathName(DBase)
FuncS="""
Function EndOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at EOS
thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130)
sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
bv=sup.MAnalyse(isb=true, delta=1,blksize=16)
Return c.MSCDetection(bv,thSCD1=thSCD1,thSCD2=thSCD2)
}
###
Function ChrIsNul(String S) {return RT_Ord(S)== 0}
Function ChrIsHash(String S) {return RT_Ord(S)==35}
Function ChrIsStar(String S) {return RT_Ord(S)==42}
Function ChrIsComma(String S) {return RT_Ord(S)==44}
Function ChrIsHyphen(String S) {return RT_Ord(S)==45}
Function ChrIsDigit(String S) {C=RT_Ord(S) return C>=48&&C<=57}
Function ChrEatWhite(String S) {i=1 C=RT_Ord(S,i) While(C==32||C>=8&&C<=13) {i=i+1 C=RT_Ord(S,i)} return i>1?MidStr(S,i):S}
Function ChrEatDigits(String S) {i=1 C=RT_Ord(S,i) While(C>=48&&C<=57) {i=i+1 C=RT_Ord(S,i)} return i>1?MidStr(S,i):S}
###
Function Fn@@@(clip c,clip dc,String DB,Int Mode,Float ThG,Float ThB,Int ThP,Float IgP,Int ThK,
\ Int MaxDupLen, Int LagMax,Int MaxInterp,
\ Int BlkW,Int BlkH,Int OLapX,Int OLapY,Int X,Int Y,Float CW,Bool ChromaI,Bool Altscan,
\ Int OthSCD1,Int OthSCD2,String Frames,Bool Ranges,Bool FrameAsRange,
\ Bool Show,Bool Verb,Bool ShowBlk,Bool ShowDot,Bool InterpFast
\) {
c n=current_frame FC=c.FrameCount
Stat=RT_DBaseGetField(DB,n,FLD_STAT@@@)
if(Stat == 0) { # In here if unvisited
if(RT_FrameDifference(dc,dc,n=n,n2=n-1,ChromaWeight=CW,chromai=ChromaI) > ThG) { # dif to prev
# Uniq_KOverride OR Unique
Stat=(ThK>0 && RT_YPlaneMinMaxDifference(dc,n=n,Threshold=0.2)<ThK)?FLG_UK@@@:FLG_UU@@@
RT_DBaseSetField(DB,n,FLD_STAT@@@,Stat)
Global nDone@@@=nDone@@@+1
if(nDone@@@==FC) { RT_DBaseSetId(DB,1,FC) }
} else {
# MUST scan backwards to find frame that is Unique to its predecessor(we're not necessarily a dupe of that frame)
StartU = -1
for(i=n-1,0,-1) { # Exit with i==-1 (should NEVER HAPPEN, frame 0 is Unique)
if(RT_DBaseGetField(DB,i,FLD_STAT@@@)==0) { # Stat Unknown
if(RT_FrameDifference(dc,dc,n=i,n2=i-1,ChromaWeight=CW,chromai=ChromaI) > ThG) {
StartU=i
# Set Unique/Uniq_KOverride Stat
RT_DBaseSetField(DB,StartU,FLD_STAT@@@,(ThK>0&&RT_YPlaneMinMaxDifference(dc,n=i,Threshold=0.2)<ThK)?FLG_UK@@@:FLG_UU@@@)
Global nDone@@@=nDone@@@+1
if(nDone@@@==FC) { RT_DBaseSetId(DB,1,FC) }
i = -1 # Break, Exit with i==-2
}
} Else { StartU=i i = -2 } # Break, Exit with i==-3
}
# Assert(i!=-1,myName@@@+"Uniq Not Found backwards")
EndU = FC
for(i=n+1,FC-1) { # Exit with i==FC (should NEVER HAPPEN, last frame is Unique)
if(RT_DBaseGetField(DB,i,FLD_STAT@@@)==0) { # Stat Unknown
if(RT_FrameDifference(dc,dc,n=i,n2=i-1,ChromaWeight=CW,chromai=ChromaI) > ThG) {
EndU=i
# Set Unique/Uniq_KOverride Stat
RT_DBaseSetField(DB,EndU,FLD_STAT@@@,(ThK>0 && RT_YPlaneMinMaxDifference(dc,n=i,Threshold=0.2)<ThK)?FLG_UK@@@:FLG_UU@@@)
Global nDone@@@=nDone@@@+1
if(nDone@@@==FC) { RT_DBaseSetId(DB,1,FC) }
i = FC # Break, Exit with i==FC=+1
}
} Else { EndU=i i = FC+1 } # Break, Exit with i==FC+2
}
# Assert(i > FC,myName@@@+"Uniq Not Found forwards")
Anchor=StartU
for(i=StartU+1,EndU-1) {
Count=1 Stat=0
if(ThK>0 && RT_YPlaneMinMaxDifference(dc,n=i,Threshold=0.2)<ThK) {
Anchor=Max(Anchor,i-LagMax)
RT_DBaseSetField(DB,i,0,FLG_NUK@@@,StartU,EndU,Anchor,0) # Count Field NOT SET
for(j=i+1,EndU-1) {
Anchor=j-1
if(RT_YPlaneMinMaxDifference(dc,n=j,Threshold=0.2)<ThK) {
Count=Count+1
RT_DBaseSetField(DB,j,0,FLG_NUK@@@,StartU,EndU,Anchor,j-i) # Count Field NOT SET
} else { j=EndU }
}
} Else {
Anchor=Max(Anchor,i-LagMax)
if((RT_FrameMovement(dc,dc,n=i,n2=Anchor,ChromaWeight=CW,AltScan=AltSCan,
\ ChromaI=ChromaI,BlkW=BlkW,BlkH=BlkH,OLapX=OLapX,OLapY=OLApY,BlkTh=ThB)>ThB) ||
\(RT_LumaPixelsDifferent(dc,dc,n=i,n2=Anchor,Thresh=ThP)>IgP) ||
\(RT_FrameDifference(dc,dc,n=i,n2=Anchor,ChromaWeight=CW,chromai=ChromaI)> ThG)
\) { # Start of LoMotion SubSequence
RT_DBaseSetField(DB,i,0,FLG_LM@@@,StartU,EndU,Anchor,0) # Count Field NOT SET
for(j=i+1,EndU-1) {
Anchor=j-1
if(
\ (
\ (RT_FrameMovement(dc,dc,n=j,n2=Anchor,ChromaWeight=CW,AltScan=AltSCan,
\ ChromaI=ChromaI,BlkW=BlkW,BlkH=BlkH,OLapX=OLapX,OLapY=OLApY,BlkTh=ThB)>ThB) ||
\ (RT_LumaPixelsDifferent(dc,dc,n=j,n2=Anchor,Thresh=ThP)>IgP) ||
\ (RT_FrameDifference(dc,dc,n=j,n2=Anchor,ChromaWeight=CW,chromai=ChromaI)>ThG)
\ ) && (ThK<=0 || RT_YPlaneMinMaxDifference(dc,n=j,Threshold=0.2)>=ThK)
\ ) {
Count=Count+1
RT_DBaseSetField(DB,j,0,FLG_LM@@@,StartU,EndU,Anchor,j-i) # Count Field NOT SET
} Else { j=EndU }
}
} Else { # Start of Dupe SubSequence
RemAnchor=Anchor # Remember Anchor at start of dupe run
for(j=i+1,EndU-1) {
Anchor=Max(Anchor,j-LagMax)
if(
\ (RT_FrameMovement(dc,dc,n=j,n2=Anchor,ChromaWeight=CW,AltScan=AltSCan,
\ ChromaI=ChromaI,BlkW=BlkW,BlkH=BlkH,OLapX=OLapX,OLapY=OLApY,BlkTh=ThB)<=ThB) &&
\ (RT_LumaPixelsDifferent(dc,dc,n=j,n2=Anchor,Thresh=ThP)<=IgP) &&
\ (RT_FrameDifference(dc,dc,n=j,n2=Anchor,ChromaWeight=CW,chromai=ChromaI) <= ThG) &&
\ (ThK<=0 || RT_YPlaneMinMaxDifference(dc,n=j,Threshold=0.2)>=ThK)
\ ) {
Count=Count+1
} Else { j=EndU }
}
Anchor=RemAnchor # restore duprun anchor
if(Count>MaxDupLen) {Stat=FLG_DS@@@} # MaxDupLen OverRide
Else {
if(Mode!=1 && i+Count==EndU && OthSCD2 < 255 && OthSCD1 < 8*8*255) {
Tmp_c = c.Trim(i-1,-1) + c.Trim(i+Count,-1)
Stat=(EndOfSceneClip(Tmp_c,OthSCD1,OthSCD2).RT_AverageLuma(n=0,w=1,h=1).Int != 0)?FLG_DE@@@:FLG_DUP@@@
} Else {Stat=FLG_DUP@@@}