pinterf / TIVTC

TIVTC and TDeint
57 stars 9 forks source link

Allow hybrid=1 scenechange decimation strategy when hybrid=0 #50

Open flossy83 opened 6 months ago

flossy83 commented 6 months ago

The hybrid=1 mode has a neat feature where if it detects a single isolated cycle of video frames (eg. 30p) and the cycle contains a scenechange frame, then it decimates the frame adjacent to the scenechange instead of the one with the lowest diff in the cycle. This can help avoid stutters around scenechanges due to field cadence breaks in the source, so I wanted to allow this behaviour for the hybrid=0 mode as well.

The implementation defaults to original behaviour to keep backwards compatibility with previous scripts. The new behaviour only comes into effect if the user manually enables it with sceneDec=true and only when mode=0.

example1

Demo video (prerendered): https://drive.google.com/uc?export=download&id=1UK68kcE20CXu8MfRR5DnUALvp9fooKJl You'll have to keep your eye on Jerry O'Connell's face right before the scenechange to see it.

Test script to reproduce

LWLibavVideoSource("C:\clip1.mkv", repeat=true) 
# clip1.mkv: https://drive.google.com/uc?export=download&id=1LMlovnns_UtfVS25RnIkEuRGZVFop0lS
# sorry for the file size but if I shorten it with ffmpeg it offsets the position of the cadence break

tfm = TFM(slow=2, pp=0, hint=false).Trim(12640,12760) 

left = tfm
\ .TDecimate(sceneDec=false, chroma=false, denoise=true, hint=false, display=true)
\ .Spline36Resize(720,540)

right = tfm
\ .TDecimate(sceneDec=true, chroma=false, denoise=true, hint=false, display=true)
\ .Spline36Resize(720,540)

StackHorizontal(left, right)
Loop(5)

Another example to try and visualise it more clearly, here the cadence break is created manually with DeleteFrame()

LWLibavVideoSource("C:\clip2.mkv", repeat=true) 
# clip2.mkv: https://drive.google.com/uc?export=download&id=1HdaoJiagh_meHmaC4zoMGC1mfhykc_8r

tfm = TFM(slow=2, pp=0, hint=false).DeleteFrame(220, 226)

left = tfm
\ .TDecimate(chroma=false, denoise=true, hint=false, sceneDec=false, display=true)
\ .Spline36Resize(720,540) 

right = tfm
\ .TDecimate(chroma=false, denoise=true, hint=false, sceneDec=true, display=true)
\ .Spline36Resize(720,540)

StackHorizontal(left, right).Trim(120, 220)
Loop(5)

Note that cadence breaks in the source can also cause duplicate frames around scenechanges, and this feature doesn't get rid of those. Those duplicates can be blended over by doing a second pass of TDecimate in hybrid=3 mode and controlling false positives with a ScriptClip to look at the cycle metrics via the new frame properties.