Synopsis

ConvertFPS( new_rate [, zone = nlines ] [, vbi = nlines ] [, clip ] )

Description

ConvertFPS() is a video filter for the Avisynth video frameserver. It is available as of Avisynth 1.0beta7.

The filter attempts to convert the frame rate of clip to new_rate without dropping or inserting frames, providing a smooth conversion with results similar to those of hardware converters. The output will have (almost) the same duration as clip, but the number of frames will change proportional to the ratio of target and source frame rates.

The filter has two operating modes. If the optional argument zone is not present, it will blend adjacent video frames, weighted by a blend factor proportional to the frames' relative timing ("Blend Mode"). If zone is present, it will switch from one video frame to the next ("Switch Mode") whenever a new source frame begins, that is, usually somewhere in the middle of a target frame. The parameter zone specifies the height of the transition region in which the current frame will be blended into the next. Switch Mode assumes that the output will be shown on a TV where each frame is scanned from top to bottom.

Blend Mode will cause visible, although slight, blurring of motion. This is a typical artifact of frame rate conversion and can be seen on commercial video tapes and TV programs as well. When working with interlaced video, it is important to let the filter operate on individual fields, not on the interlaced frames. (See Examples below.)

Switch Mode is an attempt to avoid motion blurring, but comes at the expense of slight flicker and motion artifacts. Horizontal and vertical pans may show a slight wobble. Still frames from this conversion show "broken" or "bent" vertical lines in moving scenes. Scene transitions may occur in the middle of a frame. Nevertheless, the results do look less blurry than in "Blend Mode".

Neither mode is perfect. Which one to choose depends on personal preference and on the footage to be converted. Switch Mode is probably only suitable if the output will be shown on a TV, not on a computer screen.

Frame rate conversion is inherently difficult. This filter implements two common methods used by commercial Prosumer-level converter systems. The results are typically quite good. More sophisticated systems employ motion interpolation algorithms, which are difficult to get right, but, if done right, do yield superior results.

With field-based input, the parity of the converted frames is undefined. The filter simply outputs a sequence of alternating top and bottom fields, starting with the parity of the first field of the input clip. With frame-based input, parity is left unchanged. If the input is interlaced, it must be deinterlaced first, otherwise the output will be incorrect. In essence, the filter algorithm assumes that each frame of the input represents a single point in time (not two, as with interlaced frames). Since the output represents points in time at changing, fractional intervals between the input time points, the parity of the input clip is lost in the conversion. If interlaced output is desired, it must be re-assembled with other operations. Its parity can be chosen freely. See the example below.

Footage converted with this filter should not be converted again. Blurriness builds up quickly in subsequent generations.

The audio data are not touched by this filter. Audio will remain synchronized, although the length of the audio data may slightly differ from that of the video data after the conversion. This is because the output can only contain an integer number of frames. This effect will be more pronounced for shorter clips. The difference in length should be ignored.

Parameters

new_rate Target frame rate. Can be integer or floating point number. In Blend Mode, new_rate must be at least 2/3 (66.7%) of the source frame rate, or an error will occur. This is to prevent frame skipping. If you need to slow down the frame rate more than that, use Switch Mode.
zone (Optional) If specified, puts the filter into Switch Mode. Integer number greater or equal to zero. If zero, the filter will perform a hard switch, that is, it will immediately display the next frame below the switch line. If greater than zero, specifies the height (in lines) of the transition zone, where one frame is gradually blended into the next. zone=80 yields good results for full-size standard video (480/576 active lines). The transition is done in the same way as in PeculiarBlend(). zone must be less or equal than the number of lines of the target frame that correspond to the duration of the source frame. This is typically 5/6 or 6/5 of the target frame height, that is, a few hundred lines. An error occurs if a larger value is chosen.
vbi (Optional) In Switch Mode, specifies that the filter should apply a timing correction for the vertical blanking interval (VBI). Integer number greater than zero, indicating the height of the VBI of the target frames, in lines. Typically vbi=49 for PAL and vbi=45 for NTSC, but these values are not critical. Ignored in Blend Mode.

Example

Interlaced NTSC->PAL conversion
  AVISource("NTSC_clip.avi")       # Get source clip
  Bob()                            # Separate fields and interpolate them to full height at double rate.
  BicubicResize(768,576)           # Resize to PAL square-pixel frame size. (Use 720,576 for CCIR.)
  ConvertFPS(50)                   # Convert field rate to PAL, using Blend Mode.
  SeparateFields()                 # Now undo Bob():  Separate even and odd lines of each "frame" ...
  SelectEvery(4,0,3)               # ... and re-assemble a string of fields, even (bottom) field first.
                                   # (Use SelectEvery(4,1,2).AssumeTFF() for odd (top) field first.)
  Weave()                          # Re-interlace the fields into a frame-based clip.

This example will also work with frame-based NTSC material, even with telecined film (movies). For film material, however, you will get better results by using an inverse-telecine filter and speeding up the frame rate from 23.976 to 25fps.

Bugs/Limitations

Blending ought to be done with a 4-tap interpolator, followed by an adaptive low-pass filter, to reduce flicker. One day I might do that.

There is no provision to detect scene changes. The filter will happily blend together adjacent frames at a transition, creating a type of fast "fade" effect. This is barely noticeable during normal playback, but can sometimes get annoying, especially with editing or slow-motion.

Not all input parameter values are necessarily checked for sanity.

Author

Ole Hansen < ole at redvw dot com >

See also

AssumeFPS(), ChangeFPS(), PeculiarBlend()