Skip to content

FFV1

currentMigrated from docs/video/FFV1.mdx at 37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0

FFV1 is a lossless video codec designed by Michael Niedermayer and developed in FFmpeg. Versions 0, 1 and 3 are specified in IETF RFC 9043, and it is one of the standard preservation formats in film and video archives, usually in Matroska. It compresses much better than fast lossless codecs such as Ut Video, at the cost of speed.

It handles YCbCr (4:2:0, 4:2:2, 4:4:4 and others), RGB, grayscale and alpha at 8 to 16 bits per sample, interlaced material, and in version 3 per-slice CRCs for error detection.

Terminal window
ffmpeg -i input.mov -c:v ffv1 -level 3 -g 1 -coder 1 -slicecrc 1 -c:a copy output.mkv
OptionWhy
-level 3FFV1 version 3: slices, multithreaded decoding and CRCs. FFmpeg 8.0 and later default to it; older builds could pick version 0 or 1 for SD sources, so archival recipes pin it. Version 4 is experimental in FFmpeg and its IETF draft has expired.
-g 1Every frame is a keyframe. See below.
-coder 1Range coder instead of the default Golomb-Rice coder; noticeably smaller files for 8-bit sources. Above 8 bits FFmpeg switches to it automatically. -coder 2 selects the same mode.
-slicecrc 1A CRC in every slice so damage can be detected and located. Already the default in version 3; set it to make the intent explicit on older builds.
-slices NNumber of slices per frame, which sets how many threads can decode it. FFmpeg picks a count from the frame size (20 at 1080p); many archives set 16 or 24. The count has little effect on file size. FFmpeg rejects counts it cannot lay out for the frame size.
-context 1Larger context model. The size difference is small and can go either way depending on content.

FFV1 keeps its entropy-coder state from frame to frame until the next keyframe resets it, so with a GOP larger than one, damage in one frame can spoil every frame up to the next keyframe. -g 1 makes FFV1 truly intra-only: the file gets slightly bigger, and a damaged frame stays a single lost frame.

FFmpeg maps only one video and one audio stream by default. Add -map 0 to keep every track. Matroska cannot hold a MOV timecode track, so also add -dn for such sources; the start timecode is still kept as a tag.

FFV1 stores the pixel format you give it. Do not convert RGB to YUV or reduce bit depth on the way in.

Compare per-frame hashes of the source and the FFV1 file:

Terminal window
ffmpeg -i input.mov -f framemd5 input.framemd5
ffmpeg -i output.mkv -f framemd5 output.framemd5
diff input.framemd5 output.framemd5

FFmpeg decodes 8-bit RGB FFV1 as bgr0. For a gbrp source, add -pix_fmt gbrp to the second command so both sides are hashed in the same format.

  • Version 0 was marked stable in 2006, version 1 (more bit depths) in 2009 and version 3 (slices, CRCs) in 2013. Version 2 only ever existed in experimental form.
  • FFmpeg also has a Vulkan encoder, ffv1_vulkan, for GPU encoding.
  • Browsers and dedicated hardware decoders do not play FFV1. Keep it as the preservation master and make an AVC, VP9 or AV1 copy for viewing; see video codec support.