Log in

View Full Version : Fix duplicate frames resulting from bad analog capture


johnmeyer
29th October 2009, 19:58
My JVC SR-VS30U VCR (which has a built-in analog to DV digitizer) often drops frames when converting EP VHS tapes to DV. When a frame is dropped, the previous frame is duplicated in order to maintain audio sync (it is a lousy VCR, but when it works the captures are fantastic).

Four years ago, Mug Funky had the same problem and wrote a nifty script which detects duplicates, then synthesizes a frame and inserts it in place of the duplicated frame:

automated framedrop filler script :) (http://forum.doom9.org/showthread.php?t=104294&highlight=filldrops+filldropsI)

Very cool stuff. However, it was written for the original MVTools, not MVTools2; it didn't take advantage of the multi-threaded version of AVISynth; and most important, it wasn't designed to work with interlaced video.

In response to some help I asked for a year ago when converting kinescopes back to "real" video (a technique I have now have working really well) Mikeytown2 provided a version of Mug's technique that works on interlaced video:

Kinescope restoration back to 60i (http://forum.doom9.org/showthread.php?p=1164937#post1164937)

Here's a script that is based on Mug Funky's original idea, using some of the enhancements suggested by Mikeytown2. Because it uses MVTools2 and the modified AVISynth, it runs really fast on my multi-core computer. Also, it is designed for interlaced video.

So, if you do a lot of capture and restore work on VHS video, and your capture system sometimes drops frames, this script does a great job of fixing the stutter that these drops introduce.

#This script finds exact duplicate frames and then interpolates a new frame in place of the duplicate.
#It works on interlaced video.

loadplugin("C:\Program Files\AviSynth 2.5\plugins\MVTools\mvtools2.dll")

filename = "e:\output_duplicate_frames.txt"

setMTMode(5)
AVISource("e:\frameserver.avi").ConvertToYV12.killaudio()
setMTMode(2,0)

filldropsI(last)

#-------------------
function filldropsI (clip c)
{
even = c.SeparateFields().SelectEven()
super_even=MSuper(even,pel=2)
vfe=manalyse(super_even,truemotion=true,isb=false,delta=1)
vbe=manalyse(super_even,truemotion=true,isb=true,delta=1)
filldrops_e = mflowinter(even,super_even,vbe,vfe,time=50)

odd = c.SeparateFields().SelectOdd()
super_odd=MSuper(odd,pel=2)
vfo=manalyse(super_odd,truemotion=true,isb=false,delta=1)
vbo=manalyse(super_odd,truemotion=true,isb=true,delta=1)
filldrops_o = mflowinter(odd,super_odd,vbo,vfo,time=50)

evenfixed = ConditionalFilter(even, filldrops_e, even, "YDifferenceFromPrevious()", "equals", "0")
oddfixed = ConditionalFilter(odd, filldrops_o, odd, "YDifferenceFromPrevious()", "equals", "0")

Interleave(evenfixed,oddfixed)
Weave()
AssumeFrameBased()
AssumeBFF()
}

Gavino
29th October 2009, 20:18
Why do you have AssumeFieldBased()?
Following InterLeave() and Weave(), the video is decidedly frame based (which is nothing to do with interlaced v progressive).

See http://avisynth.org/mediawiki/Interlaced_fieldbased.

johnmeyer
30th October 2009, 05:55
Why do you have AssumeFieldBased()?Thanks for the input and the link to the Wiki, and I stand corrected and have gone back and changed my initial post to change it to frame based. As the Wiki itself states, "... contrary to what you might expect, this flag is not related to interlaced video." I did read the AVISynth documentation, but it was not clear (at least to me) and I thought that field based referred to interlaced and frame base referred to progressive. I know understand that field based means that you are dealing with individual fields. I guess I might need this in order to make sure that AVISynth keeps track of field dominance in some situation where I hadn't first used separatefields() to create fields.

Again, thanks for the correction.