pinterf / TIVTC

TIVTC and TDeint
55 stars 8 forks source link

CFrameDiff prevf=-2 #39

Closed flossy83 closed 10 months ago

flossy83 commented 1 year ago

Hello, I tried to PM you on doom9 but it says your inbox is full.

I was wondering if you might be available to add a small feature: CFrameDiff(prevf=-2) to compare current frame with 2 frames behind, similar to Avisynth YDifferenceToNext(-2). Also positive number to compare current with n frames ahead if possible.

Seem to be able to do it with...

ScriptClip(last,
\ """
    # compare current_frame with current_frame-2

    FDiff = CFrameDiff(prevf=true,
    \ DeleteFrame(current_frame-1)
    \ .DuplicateFrame(current_frame-2))

\ """ , after_frame=true )

...but not sure if this only works as a fluke since adding the duplicate frame to the end of the clip does NOT work, so something is fishy with the above solution in the way that Avisynth references frames internally which I don't understand - especially since I require multithreading which isn't really threadsafe with ScriptClips in the first place.

pinterf commented 1 year ago

It seems to be a good idea. It's impossible that I can do anything within weeks (even if it does not seem to be a big change - but docs, release, etc.. needs time as well), but please, ping me occasionally if you are impatient.

flossy83 commented 1 year ago

Thanks, no hurry or pressure on you. In the meantime I can use the bodge solution.

I think CFrameDiff is better than YUVDiff, because imagine you have a grey background with a white square moving around inside the frame, in this case YUVDiff will report nothing because total YUV didn't change, but CFrameDiff does report a difference eg. on this pattern https://www.youtube.com/watch?v=hkN3PRPh00E

YUVDiff also gives me larger values on very slow pans that are high contrast or high APL. It's a bit random too depending on the shapes of objects entering/leaving the frame. I can sort of work around it by compressing the dynamic range a bit with something like Levels(0, 1.0, 255, 35, 220) but it's a bodge and I don't even really understand why it helps.

The reason I need to look back 2 frames is because in 50fps video the cadence is either 1:1 or 2:2 so the only way to get the previous frame for both is to look 2 frames behind.

flossy83 commented 1 year ago

It would also be great if we could compare the framediff between 2 clips eg LumaDifference(clip1, clip2)

flossy83 commented 1 year ago

Also just to note that CFieldDiff appears broken, like some kind of overflow problem. This was reported on doom9 TIVTC thread as well. But it may be a moot point if CFieldDiff is the same as CFrameDiff(SeparateFields()) ?

pinterf commented 1 year ago

As for introducing an 'offset': could you pls check this internal build? (along with the your frame property issue #40)

https://drive.google.com/uc?export=download&id=1wG2iwSLPcltHOqefS98r3FMsVLgpTU27

See changelogs: CHANGELOG-TIVTC.md and TDecimate - READ ME.txt

flossy83 commented 1 year ago

Thanks, I can confirm it generates the same framediff values with this test:

ScriptClip(last, 
\ """
    # current_frame-1
    old_p1 = String(CFrameDiff(last))                       

    # current_frame-2   
    old_p2 = String(CFrameDiff(last                         
    \ .DeleteFrame(current_frame-1)
    \ .DuplicateFrame(current_frame-2)))

    # current_frame-3           
    old_p3 = String(CFrameDiff(last
    \ .DeleteFrame(current_frame-1, current_frame-2)
    \ .DuplicateFrame(current_frame-3, current_frame-3)))

    # current_frame-1
    new_p1 = String(CFrameDiff(last, offset=1, prevf=true)) 

    # current_frame-2   
    new_p2 = String(CFrameDiff(last, offset=2, prevf=true))

    # current_frame-3
    new_p3 = String(CFrameDiff(last, offset=3, prevf=true))

    # current_frame+1
    old_n1 = String(CFrameDiff(last, prevf=false))  

    # current_frame+2   
    old_n2 = String(CFrameDiff(last
    \ .DeleteFrame(current_frame+1)
    \ .DuplicateFrame(current_frame+2), prevf=false))

    # current_frame+3                   
    old_n3 = String(CFrameDiff(last
    \ .DeleteFrame(current_frame+1, current_frame+2)
    \ .DuplicateFrame(current_frame+3, current_frame+3), prevf=false))

    # current_frame+1
    new_n1 = String(CFrameDiff(last, offset=1, prevf=false))    

    # current_frame+2   
    new_n2 = String(CFrameDiff(last, offset=2, prevf=false))

    # current_frame+3
    new_n3 = String(CFrameDiff(last, offset=3, prevf=false))

    # values should match
    SubTitle(last, old_p1 + ", " + new_p1 + "\n" +
    \              old_p2 + ", " + new_p2 + "\n" +
    \              old_p3 + ", " + new_p3 + "\n\n" + 

    \              old_n1 + ", " + new_n1 + "\n" +
    \              old_n2 + ", " + new_n2 + "\n" +
    \              old_n3 + ", " + new_n3 , lsp=10)

\ """, after_frame=true )

Sometimes it's useful to compare frame diff between 2 different clips, eg. checking how similar a deinterlaced frame is to an IVTC'd frame to determine if it can be swapped for an IVTC'd frame.

YUV diff seems to do a decent job at that, but would be nice to have CFrameDiff as an option too.