View Single Post
Old 16th June 2010, 23:04   #13  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,691
I have had to deal with all manner of badly done frame-rate conversions, usually dealing with NTSC -> PAL -> NTSC. I end up with video that has big jumps where too many frames (or fields) were deleted. Sometime, strangely, the video also has duplicates. So, you end up with video that stutters and hesitates, something I assume you are seeing in your video.

There is no universal solution, because the solution depends on the actual cadence of your footage. However, here is a code snippet I found a long time ago here in the forum that may come in handy:
Code:
function filldrops (clip c)
{
vf=c.mvanalyse(truemotion=true,pel=2,isb=false,delta=1,idx=1)
vb=c.mvanalyse(truemotion=true,pel=2,isb=true,delta=1,idx=1)
global filldrops_d = c.mvflowinter(vb,vf,time=50,idx=1)
global filldrops_c = c
c.scriptclip("""ydifferencefromprevious()==0? filldrops_d : filldrops_c""")

}
usage:
This code finds all duplicated frames and replaces the second instance of two duplicate frames with a motion-estimated frame. As you can see from the code, it only does this if the "ydifferencefromprevious" value is exactly zero. I think you might be able to adapt this, perhaps, to do exactly the opposite, namely to look for unusually large differences between frames, and synthesize a new frame from this. By itself, this code isn't going to solve your problem, but it may be a useful building block.

FWIW, here is the interlaced version I created which uses MVTools2 instead of MVTools. The above code was created by someone else, but only works on progressive. Also, I slightly increased the comparison parameter so the algorithm will synthesize a motion-estimated field even if the two adjacent fields are not perfectly identical.

This leads to an important concept for you to understand:
It is generally OK if your script occasionally unecessarily creates a synthesized frame (or field, for interlaced video).
As you already know, you'd rather use the original frames wherever possible, but if once in awhile your script goofs and substitutes an interpolated frame, as long as this doesn't happen often, it won't matter. After all, the video is going to have lots of interpolated frames, so if you have a few extra, it is usually not a big deal.

Code:
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()", "lessthan", "0.1")
  oddfixed  = ConditionalFilter(odd,  filldrops_o, odd,  "YDifferenceFromPrevious()", "lessthan", "0.1")

  Interleave(evenfixed,oddfixed)
  Weave()
# Following line removed after suggestion by Gavino
#  AssumeFieldBased()
  AssumeBFF()
}
Oh, if you want to replace the first frame rather than the second frame, use this code (this is for progressive frames using MVTools2):
Code:
function filldropsnext (clip c)
{
  previous = Loop(c,2,0,0)
  super=MSuper(previous,pel=2)
  vfe=manalyse(super,truemotion=true,isb=false,delta=1)
  vbe=manalyse(super,truemotion=true,isb=true,delta=1)
  filldrops = mflowinter(previous,super,vbe,vfe,time=50)
  fixed = ConditionalFilter(c, filldrops, c, "YDifferenceToNext()", "lessthan", "0.1")
  return fixed
}
P.S. Just after I posted I read the post suggesting using cfile, etc. I spent several years developing a technique to do exactly what he was suggesting. Once you do this as a two-pass operation, you can spend time with the parameter file and use a spreadsheet to figure out exactly which frames you want to decimate. So, you could use motion interpolation to increase the frame rate; run the software to get the cfile.txt file; put this in Excel and decide which pattern of frames or fields you want to decimate; create a new file that has the decimation frames; and then run the second pass. You can get exactly what you want with this approach, but it isn't exactly automatic.

Last edited by johnmeyer; 17th June 2010 at 17:33. Reason: Added cfile information; Later edit to remove AssumeFieldBased()
johnmeyer is offline   Reply With Quote