# FFV1

Canonical URL: https://encode.wiki/codecs/video/ffv1/
Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf
Status: current
License: CC BY-SA 4.0
Checksum (SHA-256): d909df13f68d5f160e4b4c197a679342e17a16ce0ee3b9c29b5f76c39cb17f97

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](https://www.rfc-editor.org/rfc/rfc9043.html), 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](/codecs/video/utvideo/), 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.

## Archival encode

```sh
ffmpeg -i input.mov -c:v ffv1 -level 3 -g 1 -coder 1 -slicecrc 1 -c:a copy output.mkv
```

| Option | Why |
| --- | --- |
| `-level 3` | FFV1 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 1` | Every frame is a keyframe. See below. |
| `-coder 1` | Range 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 1` | A 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 N` | Number 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 1` | Larger 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.

## Check the encode is lossless

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

```sh
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.

## Versions and playback

- 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](/reference/video-codec-support/).
