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
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 15th October 2021, 01:14   #41  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
I'm currently concentrating on the OP's specific problem, dup/drop OR drop/dupe, single instance adjacent in either order, [and not based on any cycle nor FrameRate].

EDIT: Dont know if of any use

Code:
Function MMaskFromPrevClip(clip c,Int "MaskType",Float "Gamma",Int "thSCD1",Int "thSCD2") {
	# MaskType:- 0=Motion, 1=SAD, 2=Occlusion, 3=Horizontal, 4=Vertical, 5=ColorMap.
	MaskType=Default(MaskType,0)  Gamma=Default(Gamma,1.0)  thSCD1=Default(thSCD1,400)  thSCD2=Default(thSCD2,130)
	sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
	fv=sup.MAnalyse(isb=false,delta=1,blksize=16)
	Return c.MMask(fv,Gamma=1.0,kind=MaskType,thSCD1=thSCD1,thSCD2=thSCD2)
}

Function MMaskFromNextClip(clip c,Int "MaskType",Float "Gamma",Int "thSCD1",Int "thSCD2") {
	# MaskType:- 0=Motion, 1=SAD, 2=Occlusion, 3=Horizontal, 4=Vertical, 5=ColorMap.
	MaskType=Default(MaskType,0)  Gamma=Default(Gamma,1.0)  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.MMask(bv,Gamma=1.0,kind=MaskType,thSCD1=thSCD1,thSCD2=thSCD2)
}
Code:
Function EndOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") {   # All Luma Samples set 255 at EOS, else 0
    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 StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at SOS, else 0
    thSCD1=Default(thSCD1,400)  thSCD2=Default(thSCD2,130)
    sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
    fv=sup.MAnalyse(isb=false,delta=1,blksize=16)
    Return c.MSCDetection(fv,thSCD1=thSCD1,thSCD2=thSCD2)
}

Function SceneCutClip(clip c,Int "thSCD1",Int "thSCD2") {     # All Luma pixel = 0 =Norm, 1=EOS, 2=SOS, 3=EOS & SOS
    thSCD1=Default(thSCD1,400)  thSCD2=Default(thSCD2,130)
    Sup  = c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
    BvEos= Sup.MAnalyse(isb=True,  delta=1,blksize=16)
    FvSos= Sup.MAnalyse(isb=False, delta=1,blksize=16)
    Eos  = c.MSCDetection(BvEos,thSCD1=thSCD1,thSCD2=thSCD2)
    Sos  = c.MSCDetection(FvSos,thSCD1=thSCD1,thSCD2=thSCD2)
    Return MT_Lutxy(Eos,Sos,yexpr="y 0 == x 0 == 0 1 ? x 0 == 2 3 ? ?",u=-128,v=-128)
}
EDIT: Added below
It works sorta like ScSelect/ScSelect_HBD, but you must also Provide a "BOTH" [ie both EOS and SOS detect] clip (you can choose whatever solution you like for that possible outcome).
You will likely fire a BOTH if there is a single frame scene cut, ie and 'odd' frame that belongs neither with previous nor following scenes.
Code:
Function SceneCutSelectClip(clip dClip,clip Start,clip End,clip Both,clip Motion,Int "thSCD1",Int "thSCD2") { # (c) ssS:  https://forum.doom9.org/showthread.php?p=1955111#post1955111
    thSCD1=Default(thSCD1,400)  thSCD2=Default(thSCD2,130)
    Sup  = dClip.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
    BvEos= Sup.MAnalyse(isb=True,  delta=1,blksize=16)
    FvSos= Sup.MAnalyse(isb=False, delta=1,blksize=16)
    Eos  = dClip.MSCDetection(BvEos,thSCD1=thSCD1,thSCD2=thSCD2).crop(0,0,4,4)
    Sos  = dClip.MSCDetection(FvSos,thSCD1=thSCD1,thSCD2=thSCD2).crop(0,0,4,4)
    CondS="""
        ix = (Sos.AverageLuma>0?1:0) + (Eos.AverageLuma>0?2:0)
        Return ix==0?Motion:ix==1?Start:ix==2?End:Both
    """
    ARGS="Motion,CondS,Motion,Start,End,Both,Eos,Sos"
    Motion.GSCriptClip(CondS,Args=ARGS,After_Frame=True,Local=True) # Requires Grunt
}

# Client
AviSource("D:\hard sub - 01 WEBdlRip 720p, 23.976.mkv.AVI")
dclip = BilinearResize(320,240).Blur(1.0)  # Whatever (just testing frame size can be different to other clips)
ConvertToRGB32                             # Just testing works where Dclip colorspace is differenct from the other clips.
Motion = Last
Start  = Subtitle("START",size=64,align=5)
End    = Subtitle("END",size=64,align=5)
Both   = Subtitle("BOTH",size=64,align=5)
SceneCutSelectClip(dClip,Start,End,Both,Motion,400,130)
__________________
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; 16th August 2023 at 21:44.
StainlessS is offline   Reply With Quote
Old 16th October 2021, 16:35   #42  |  Link
stephen22
Registered User
 
Join Date: Jan 2007
Posts: 88
Quote:
Originally Posted by StainlessS View Post
@Stephen22, when are you gonna post a reasonable length sample ?
You seem to visit every day, why arn't you responding, have you fixed it ? [They're a nasty bunch here, but not that scary really].
Sorry for delay in responding. Thanks so much for all your interest. Thought I'd chat more when I failed to solve the problem. But actually this seems to work quite well

Code:
loadplugin ("C:\program files (x86)\avisynth\plugins\mvtools2.dll")
c=AviSource("D:\Video\wares-28-09-2021-17-35-08.avi") 


super=MSuper(c, pel=2)
vfe=manalyse(super,truemotion=true,isb=false,delta =1)
vbe=manalyse(super,truemotion=true,isb=true,delta= 1)
filldrops = mflowinter(c,super,vbe,vfe,time=50)
#filldrops=subtitle(filldrops,"mv")

filldrops2=duplicateframe(filldrops,0).trim(0,framecount-1) #nudge by 1 frame

#1 fix dupedrop
dupedrop = ConditionalFilter(c, filldrops, c, "YDifferenceFromPrevious()", "lessthan", "1")
fixed1=ConditionalFilter(c, dupedrop, c, "ydifferencefromprevious(selectevery(c,1,-1))", "lessthan", "ydifferencefromprevious(selectevery(c,1,1))")

#2 fix remaining dupes, assuming dropdupe
fixed2 = ConditionalFilter(fixed1, filldrops2, fixed1, "YDifferencetonext()", "lessthan", "1")

return fixed2
My video is from a screen copier (Flashback) and the dupes are 99% just before or just after the drop. It doesn't work at all for those that aren't adjacent, or obviously for the occasional double dupe.

Found quite a few entertaining quirks in AviSynth. Amazing how it can (quickly) reference clips generated by its own runtime routines.

John I can't get your script to work - there seems to be an undefined function "mt_merge" at line 47.

Must now study all these scripts - great to learn from the experts.
stephen22 is offline   Reply With Quote
Old 16th October 2021, 17:52   #43  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Good, you seem happy, your god must be smiling upon you.

mt_merge is masktools2 filter.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 17th October 2021, 11:44   #44  |  Link
stephen22
Registered User
 
Join Date: Jan 2007
Posts: 88
Thanks

Quote:
Originally Posted by StainlessS View Post
"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
All of them.
stephen22 is offline   Reply With Quote
Old 17th October 2021, 15:38   #45  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
I had sorta meant how many are infinitely bigger than the other infinities, [dont remember exactly how I wanted to phrase it]
but I did not have room in the limited sig text allowed, about 260 chars, so I just cut it short with about 1 char spare.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 17th October 2021, 18:15   #46  |  Link
stephen22
Registered User
 
Join Date: Jan 2007
Posts: 88
Yes, I understood right.
Answer: all of them.
Thanks so much for your help and encouragement.

John your script is marvellous. I have videos from an HDMI/PAL converter that are not nearly so easy, with random dupes, sometimes 2 or 3 at a time, usually well away from the drops. Your script makes a big difference. I think I've got the general idea, starting with drops and then smoothing everything out, but I'll have to study it further to get the details.

It needed one or two tweaks for us lesser mortals, loading in masktools2 and tivtc, and generalising the framerate numerator in MFlowFps to round(framerate(source)*2) for the benefit of PAL users, but it's ingenious and very effective. Thanks very much.
stephen22 is offline   Reply With Quote
Old 17th October 2021, 22:58   #47  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,695
I'm trying to improve the matching (see the thread I started), and then will get around to building a workaround to the TDecimate. The script is good, but I think it can be a LOT better.
johnmeyer is offline   Reply With Quote
Old 21st October 2021, 22:49   #48  |  Link
stephen22
Registered User
 
Join Date: Jan 2007
Posts: 88
It works extremely well for me - though it does weird things at scene changes. I've respectfully suggested adding a tiny modification to your brilliant Black/White algorithm

Code:
MyMask2=ConditionalFilter(source,blackframe,MyMask,
    \"((YDifferenceFromPrevious(selectevery(source, 1, -1)) + 
    \ YDifferenceFromPrevious(selectevery(source, 1,-2)) + 
    \ YDifferenceFromPrevious(selectevery(source, 1,-3)) +
    \ YDifferenceFromPrevious(selectevery(source, 1,-4)) + 
    \ YDifferenceFromPrevious(selectevery(source, 1,-5)) +
    \ YDifferenceFromPrevious(selectevery(source, 1,-6)) ) / 6 ) / 
    \ (YDifferenceFromPrevious(source) + 0.01)","lessthan","SceneThresh")

Return MyMask2
SceneThresh = 0.25 seems to work quite well here. I do 6 measurements because in my footage there can be 3 dupes in 4 frames.
stephen22 is offline   Reply With Quote
Old 22nd October 2021, 00:13   #49  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,695
Yeah, I never got around to detecting scene changes, so thanks for doing that. I assume you sum MyMask2 with my existing mask?

As for my work on improving detection, I did quite a bit of work on using motion estimation, but that effort yielded no usable results. More importantly, when I tried my existing YDifference detection on some pretty challenging (low motion) test cases that I manufactured, it worked every time.

So, the only thing left is to fix the TDecimate problem. Zorr's idea of doing the decimation three times and then comparing will make the script too slow and, as I said, in good humor when the idea was first proposed, it is a delightful kludge.

I have another idea, which is to simply do the decimation in two passes. After all, TDecimate works with 3:2 pulldown and there is never any boundary problem. Therefore, I think the TDecimate failure may be related to having such a high decimation rate, where almost every single frame is duplicated. So my idea is to decimate half of the frames to be removed and then, with a slightly different Cycle parameter, decimate the other half.

I'm on another project now, so I won't get to it right away.

Last edited by johnmeyer; 22nd October 2021 at 04:27.
johnmeyer is offline   Reply With Quote
Reply


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 04:44.


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