videoffmpeglibvlcavisynth

The fast video frame jump access in FFMS2


FFMS2 offers the frame-accurate access on multiple video codecs. But it is slow when we do the long distance frame jump access.

What enables the fast frame jump access, or how existing video players like VLC achieves this?


Solution

  • Video players use the time-to-fileposition index that is incorporated into video files. When you navigate to some timecode the player reads that index, finds a prior keyframe, decodes all frames between the found keyframe and a frame corresponding to the requested timecode, then displays it. In most cases a lot of extra work is done to get that frame, that's why this scheme wasn't adopted in AviSynth and generally in video processing software.

    Theoretically it's possible to make a hybrid plugin that won't need indexing and will provide the same accuracy and roughly the same speed for simple use cases but it will require rewriting all file source filters for every format in FFMPEG so, naturally, no one ever tried that.

    Currently the Avisynth-based solutions are:

    1. FFMS2

      It first indexes the entire file and builds a special cache file with pointers to each frame thus making it possible to use random/arbitrary frame access afterwards.

      Indexing includes decoding of video data (and optionally audio) so the entire file is read from disk. That's why the process is slow for large files.

    2. AviSource/LSMASHVideoSource

      A few video formats support precise frame access and don't require indexing in AviSynth:

      • .AVI when opened via the built-in AviSource() filter
      • .MP4 and .MOV when opened via LSMASHVideoSource() filter from L-SMASH-Works
    3. DirectShowSource/dss2

      Instant opening of files with mostly precise frame-seeking (but not guaranteed) is possible with the built-in DirectShowSource() or dss2() filter from DSS2mod (originally a part of Haali media splitter, you may load its avss.dll as AviSynth plugin). There are many limitations.