I've been doing some digging and came across this thread on the topic from 10 years ago. It references a script from another thread from 20 years ago. https://forum.doom9.net/showthread.php?t=172258
Regardless of age the users claim it works well enough.
Is there a filter that can effectively accomplish this bit of code at the beginning of the script? I would hope that there would be some advances in the last 10-20 years.
Function FieldMatch(Clip C) {
Global PP = C.DuplicateFrame(0)
Global CC = C
Global NN = C.DeleteFrame(0)
P2 = PP.SeparateFields()
C2 = CC.SeparateFields()
N2 = NN.SeparateFields()
Global PC = Interleave(P2.SelectEven(),C2.SelectOdd()).Weave()
Global CP = Interleave(C2.SelectEven(),P2.SelectOdd()).Weave()
Global CN = Interleave(C2.SelectEven(),N2.SelectOdd()).Weave()
Global NC = Interleave(N2.SelectEven(),C2.SelectOdd()).Weave()
Global Deint = QTGMC(CC).SelectEven()
Return ScriptClip(CC, \
"!CC.IsCombedTIVTC(CThresh=12,Chroma=True,BlockX=16,BlockY=32) ? CC : " + \
"!NN.IsCombedTIVTC(CThresh=12,Chroma=True,BlockX=16,BlockY=32) ? NN : " + \
"!CN.IsCombedTIVTC(CThresh=12,Chroma=True,BlockX=16,BlockY=32) ? CN : " + \
"!NC.IsCombedTIVTC(CThresh=12,Chroma=True,BlockX=16,BlockY=32) ? NC : " + \
"!PP.IsCombedTIVTC(CThresh=12,Chroma=True,BlockX=16,BlockY=32) ? PP : " + \
"!CP.IsCombedTIVTC(CThresh=12,Chroma=True,BlockX=16,BlockY=32) ? CP : " + \
"!PC.IsCombedTIVTC(CThresh=12,Chroma=True,BlockX=16,BlockY=32) ? PC : Deint")
}
TFM(Order=-1,Mode=5,PP=2,Clip2=FieldMatch(),Slow=2,MChroma=False,Ubsco=False,CThresh=12,Chroma=True)
TDecimate(Mode=1)
# List of all candidates in priority order
candidates = [cc, nn, cn, nc, pp, cp, pc, deint]
# Precompute IsCombed for each clip
combed_flags = [core.tdm.IsCombed(clip, cthresh=12, chroma=True, blockx=16, blocky=32) for clip in candidates]
def select_frame(n, f):
for i in range(len(combed_flags) - 1): # skip deint until end
if not f[i].props._Combed:
return candidates[i]
return candidates[-1] # fallback to deint if all are combed
return core.std.FrameEval(cc, eval=lambda n: select_frame(n, [cf.get_frame(n) for cf in combed_flags]))
# Import scripts
import qtgmc
import smdegrain
import validate
# Source: 'G:\Usenet\Incoming\Futurama S01E01 Space Pilot 3000 DVD.mkv'
# Current color space: YUV420P8, bit depth: 8, resolution: 720x480, frame rate: 29.97fps, scanorder: telecine (soft), yuv luminance scale: limited, matrix: 470bg, transfer: bt.601, primaries: bt.601 ntsc, format: mpeg-2
# Loading G:\Usenet\Incoming\Futurama S01E01 Space Pilot 3000 DVD.mkv using BestSource)
clip = core.bs.VideoSource(source="G:/Usenet/Incoming/Futurama S01E01 Space Pilot 3000 DVD.mkv", cachepath="J:/tmp/Futurama S01E01 Space Pilot 3000 DVD_bestSource", track=0, hwdevice="opencl")
frame = clip.get_frame(0)
# setting color matrix to 470bg.
clip = core.std.SetFrameProps(clip, _Matrix=vs.MATRIX_BT470_BG)
# setting color transfer (vs.TRANSFER_BT601), if it is not set.
if validate.transferIsInvalid(clip):
clip = core.std.SetFrameProps(clip=clip, _Transfer=vs.TRANSFER_BT601)
# setting color primaries info (to vs.PRIMARIES_BT470_BG), if it is not set.
if validate.primariesIsInvalid(clip):
clip = core.std.SetFrameProps(clip=clip, _Primaries=vs.PRIMARIES_BT470_BG)
# setting color range to TV (limited) range.
clip = core.std.SetFrameProps(clip=clip, _ColorRange=vs.RANGE_LIMITED)
# making sure frame rate is set to 29.97fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
# making sure the detected scan type is set (detected: telecine (soft))
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_TOP) # tff
# removing grain using SMDegrain
clip = smdegrain.SMDegrain(input=clip, tr=3, thSAD=1300, thSADC=2400, interlaced=True, tff=True, opencl=True, device=-1)
# Deinterlacing using TIVTC
import fieldmatch
clip = core.tivtc.TFM(clip=clip, mode=5, clip2=fieldmatch.FieldMatch(clip),slow=2,mChroma=False,ubsco=False,scthresh=12,chroma=True)
clip = core.tivtc.TDecimate(clip=clip, mode=1)# new fps: 23.976
# Making sure content is preceived as frame based
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_PROGRESSIVE) # progressive
# adjusting output color from: YUV420P8 to YUV420P10 for NVEncModel
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P10, range_s="limited")
# set output frame rate to 23.976fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# output
clip.set_output()
but one still ends up with broken frames:
my previous try:
# removing grain using SMDegrain
clip = smdegrain.SMDegrain(input=clip, tr=3, thSADC=2400, interlaced=True, opencl=True, device=-1, tff=False)
clip2clip = clip
clip2clip = qtgmc.QTGMC(Input=clip2clip, Preset="fast", opencl=True, TFF=False, FPSDivisor=2)
# Deinterlacing using TIVTC
clip = core.tivtc.TFM(clip=clip, mode=5, blockx=64, blocky=64, MI=64, clip2=clip2clip)
clip = core.tivtc.TDecimate(clip=clip, mode=7, rate=23.9760, dupThresh=0.04, vidThresh=3.50, sceneThresh=15.00, blockx=16, blocky=16)# new fps: 23.976
# Making sure content is preceived as frame based
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_PROGRESSIVE) # progressive
# denoising using mClean
clip = denoise.mClean(clip=clip)
seems to perform better here (and can be directly set in Hybrid)
Cu Selur
----
Dev versions are in the 'experimental'-folder of my GoogleDrive, which is linked on the download page.
clip2clip = clip
clip2clip = qtgmc.QTGMC(Input=clip2clip, Preset="slow", TFF=True, FPSDivisor=2)
# Deinterlacing using TIVTC
clip = core.tivtc.TFM(clip=clip, mode=5, scthresh=12.00, mmsco=False, chroma=True, clip2=clip2clip)
clip = core.tivtc.TDecimate(clip=clip, mode=7, rate=23.9760, dupThresh=0.04, vidThresh=3.50, sceneThresh=15.00)# new fps: 23.976
# Making sure content is preceived as frame based
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_PROGRESSIVE) # progressive
# removing grain using MCDegrain
clip = degrain.mcdegrainsharp(clip=clip, bblur=0.25, csharp=0.25)
It's not perfect, but it does pretty well.
There are a few chroma problems I noticed, but they are minor from what I've found, and MCDegrain reduces the bleeding.
It leaves interlaced frames where there are 3-4 interlaced frames in a row.
I'm going to process a few episodes and check the results.
Update: 23.976 fps was way too jerky so I changed it in TDecimate to 29.97 fps. Looks much better.
The pilot episode appears to be the only one so far with the chroma issues. Subsequent episodes have more progressive frames and more predictable interlacing.