rav1e
37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0The fastest and safest AV1 encoder.
rav1e is an AV1 encoder written in Rust with hand-written assembly, developed by Xiph.org and Mozilla. It is BSD-2-Clause licensed. Its defaults are sensible, it is easy to build, and it is the AV1 encoder behind several Rust and AVIF tools: libavif can use it (avifenc -c rav1e), and the cavif/ravif AVIF encoder is built on it.
Where rav1e stands
Section titled “Where rav1e stands”The latest stable release is v0.8.1 (June 2025). The weekly pre-release builds stopped in September 2025. Since then the repository has seen mostly maintenance commits (toolchain bumps, lint fixes) rather than encoder work.
For video, most encoders now use SVT-AV1 (or one of its community forks) or aomenc. rav1e is considerably slower than SVT-AV1, and the mendevi encoder dataset found SVT-AV1 better at equal encoding time. rav1e has changed little since, while SVT-AV1 has kept improving. rav1e is still a reasonable choice if you need a pure-Rust library or already use it through libavif or GStreamer. For a new video workflow, start with SVT-AV1.
Install
Section titled “Install”Prebuilt binaries are on the releases page, and most distributions package rav1e. To build v0.8.1 you need a Rust toolchain and, on x86-64, NASM 2.14.02 or newer:
cargo install --locked rav1eOr build the tagged release from source:
git clone --branch v0.8.1 https://github.com/xiph/rav1e.gitcd rav1ecargo build --releaseThe binary is at target/release/rav1e. rav1e picks its SIMD code paths at runtime, so a normal build already uses your CPU’s AVX2/AVX-512. RUSTFLAGS="-C target-cpu=native" produces a binary that only runs on CPUs like yours.
Encode
Section titled “Encode”rav1e reads Y4M and writes IVF. The input is a positional argument: -i is the minimum keyframe interval, not an input switch, so older commands like rav1e -i input.y4m do not work.
rav1e input.y4m -o output.ivf --quantizer 80 --speed 6Pipe from FFmpeg to encode anything else. 10-bit output is more efficient and bands less, even from 8-bit sources:
ffmpeg -i input.mkv -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | \ rav1e - -o output.ivf --quantizer 80 --speed 6 --photon-noise 8FFmpeg still needs -strict -1 to write Y4M above 8 bits. Mux the IVF into MKV or MP4 afterwards (for example ffmpeg -i output.ivf -i input.mkv -map 0:v -map 1:a -c copy final.mkv), or use mkvmerge.
For 4K, add tiles. They help both encoding speed and decoding speed:
ffmpeg -i input.mkv -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | \ rav1e - -o output.ivf --quantizer 72 --speed 6 --tile-cols 2 --photon-noise 8Two-pass target bitrate
Section titled “Two-pass target bitrate”rav1e input.y4m -o /dev/null --bitrate 3000 --first-pass stats.binrav1e input.y4m -o output.ivf --bitrate 3000 --second-pass stats.bin--bitrate is in kbit/s. The first pass also writes a video file, so send it to /dev/null (otherwise the second pass stops to ask before overwriting). In bitrate mode --quantizer becomes the worst (maximum) quantizer allowed, and --min-quantizer the best. Each pass reads the input, so use a file or regenerate an identical pipe.
Options that matter
Section titled “Options that matter”| Option | Default | Notes |
|---|---|---|
--quantizer N | 100 | Constant quantizer, 1–255 (0 aborts: lossless is not implemented). Lower is higher quality. This is the AV1 base_q_idx scale (see below). |
--speed N, -s | 6 | 0 (slowest) to 10 (fastest). Faster speeds also shorten the RDO lookahead (40 frames at speeds 0–2, 30 at 3–5, 20 at 6–7, 10 at 8–10). |
--photon-noise N | 0 (off) | AV1 film-grain synthesis, strength 0–64. The decoder adds the noise, so it costs almost no bitrate and can mask banding. It does not copy the source’s grain. It also lowers full-reference metric scores, so turn it off when comparing encodes with metrics. |
--tile-cols N, --tile-rows N, --tiles N | automatic | Tile counts (powers of two), not log2 values. --tiles sets a minimum total and cannot be combined with the other two. More tiles raise thread utilisation and decoder parallelism at a small efficiency cost. |
--threads N | all logical CPUs | Thread pool size. A single rav1e encode does not use many cores well without more tiles. On many-core machines, running several chunked encodes (e.g. via Av1an) scales better. |
--keyint N, -I / --min-keyint N, -i | 240 / 12 | Maximum and minimum keyframe distance in frames. Scene-cut keyframes are on by default. |
--tune | Psychovisual | Psnr optimises for the metric and looks worse. Leave the default. |
--bitrate N, --first-pass, --second-pass | quantizer mode | Bitrate targeting, single or two-pass. |
--no-scene-detection | off | For chunked encoders that place keyframes themselves. |
--primaries, --transfer, --matrix, --range | unspecified, limited range | Colour signalling written into the stream. It labels the colour; it does not convert it. |
--mastering-display, --content-light | unset | HDR10 static metadata. |
For HDR10, signal the colour and static metadata from your source:
rav1e input.y4m -o output.ivf --quantizer 80 --speed 6 \ --primaries BT2020 --transfer SMPTE2084 --matrix BT2020NCL \ --mastering-display "G(0.17,0.797)B(0.131,0.046)R(0.708,0.292)WP(0.3127,0.329)L(1000,0.0001)" \ --content-light 1000,400Replace the mastering-display and content-light values with your source’s. ffprobe -show_frames -read_intervals "%+#1" prints them as fractions, which you need to convert to decimals and cd/m². HDR10+ dynamic metadata is not supported in a release: quietvoid’s pull request #3000, which adds --hdr10plus-json, is still unmerged.
FFmpeg (librav1e)
Section titled “FFmpeg (librav1e)”ffmpeg -i input.mkv -c:v librav1e -qp 80 -speed 6 -c:a libopus output.mkv-qp maps to --quantizer, and -tiles/-tile-rows/-tile-columns map to the tile options. Other settings go through -rav1e-params key=value:key=value, which only accepts rav1e’s C API keys: speed, quantizer, min_quantizer, bitrate, key_frame_interval, min_key_frame_interval, switch_frame_interval, reservoir_frame_delay, rdo_lookahead_frames, low_latency, no_scene_detection, tune, tiles, tile_rows, tile_cols, threads, still_picture, level and enable_timing_info.
FFmpeg librav1e private options (n9.0.2)
Section titled “FFmpeg librav1e private options (n9.0.2)”These are the private options of the librav1e encoder in FFmpeg 9.0.2. Generic FFmpeg options also reach rav1e: -g and -keyint_min set the keyframe interval, -b:v (bit/s) switches to bitrate mode with -qmax (default 255) and -qmin as quantizer limits, -pass 1/-pass 2 run a two-pass encode (needs -b:v), -threads sets the thread pool, and the input’s colour range, primaries, transfer and matrix are signalled automatically. -rav1e-params is applied first, so these and the private options below override the same setting given there.
Private AVOptions (6 options)
| Option | Default | Type and range | What it does |
|---|---|---|---|
-qp | -1 | int, -1–255 | Constant quantizer, same scale as --quantizer. -1 leaves rav1e’s default of 100. Takes priority over -b:v if both are given. |
-speed | -1 | int, -1–10 | Speed preset, as --speed. -1 leaves rav1e’s default of 6. Setting it resets the speed-derived keys rdo_lookahead_frames and no_scene_detection given in -rav1e-params. |
-tiles | 0 | int, ≥ -1 | Minimum total tile count, as --tiles; rav1e picks the rows and columns and ignores -tile-rows/-tile-columns. 0 or -1 leaves tiling to rav1e. |
-tile-rows | 0 | int, ≥ -1 | Number of tile rows: a count (power of two), not log2. 0 or -1 leaves it automatic. |
-tile-columns | 0 | int, ≥ -1 | Number of tile columns, same rules as -tile-rows. The FFmpeg name is -tile-columns, not -tile-cols. |
-rav1e-params | unset | dictionary | key=value pairs separated by :, using rav1e’s C API keys (listed above), not CLI flag names. Booleans must be true or false, and bitrate is in bit/s. Put speed first: it resets lookahead and scene-detection keys. Bad keys only warn. |
Complete native parameter reference
Section titled “Complete native parameter reference”Every option of the rav1e 0.8.1 command-line encoder. Options of the advanced subcommand go after the main options and the advanced keyword (rav1e in.y4m -o out.ivf advanced --save-config enc.toml). Named values such as Psnr, Full or BT2020 are case-insensitive.
Input and output (7 options)
| Option | Default | What it does |
|---|---|---|
INPUT | required | Y4M input file, or - for stdin. It is positional: -i is --min-keyint, not an input flag. |
--output, -o | required | IVF output file, or - for stdout. A file name must end in .ivf or have no extension. |
-y | off | Overwrite an existing output file. Without it rav1e asks for confirmation on stdin, so an encode with piped input exits instead. |
--limit, -l | 0 (all frames) | Stop after this many frames. --still-picture allows at most 1. |
--skip | 0 | Read and discard this many frames from the start of the input before encoding. |
--help, -h | — | Print help; -h gives the short form. |
--version, -V | — | Print the version. --version also shows the compiler, assembly level and whether threading and unstable features were built in. |
Rate control and speed (9 options)
| Option | Default | What it does |
|---|---|---|
--quantizer | 100 (255 with --bitrate) | Quantizer index 1–255; lower is higher quality. 0 (lossless) is not implemented and aborts. With --bitrate it is the highest quantizer rate control may use. |
--min-quantizer | 0 | Lowest quantizer (best quality) rate control may use in bitrate mode, 0–255. |
--bitrate, -b | unset (quantizer mode) | Target bitrate in kbit/s. Switches from constant quantizer to rate control. |
--first-pass | unset | Run the first pass of a two-pass encode and write its statistics to this file. Needs --bitrate. |
--second-pass | unset | Run the second pass using statistics from --first-pass. Needs --bitrate and the same input. |
--reservoir-frame-delay | min(240, 1.5 × keyint), at least 12 | Window, in frames, over which rate control spreads its bit reservoir; minimum 12. A longer window lets the bitrate vary more between scenes. |
--speed, -s | 6 | Preset 0–10; 0 is slowest and best. Slower presets search more partition sizes, transform types and motion vectors. Upstream does not recommend 0 or 10. |
--rdo-lookahead-frames | 20 at speed 6 | Frames analysed ahead for rate–distortion decisions. The preset sets 40 at speeds 0–2, 30 at 3–5, 20 at 6–7 and 10 at 8–10. |
--tune | Psychovisual | Psychovisual or Psnr. Psnr optimises for the metric and looks worse. |
Keyframes and frame structure (7 options)
| Option | Default | What it does |
|---|---|---|
--keyint, -I | 240 | Maximum frames between keyframes. 0 removes the limit, leaving only scene-cut keyframes. |
--min-keyint, -i | 12 | Minimum frames between scene-cut keyframes; capped at --keyint. |
--no-scene-detection | off | Turn off scene-cut keyframes. Use it when a chunking tool such as Av1an already splits at scene cuts; on a full encode it costs quality. |
--scd-speed | 0 (1 at speed 10) | Scene-detection mode: 0 standard, 1 fast. |
--switch-frame-interval, -S | 0 (off) | Insert an AV1 switch frame at most every N frames. A player can change to another stream of the same content at a switch frame. |
--low-latency | off | Disable frame reordering so no frame waits for later ones, for real-time use. Compresses much less efficiently. |
--still-picture | off | Encode only the first frame, with the AV1 still-picture sequence header. The output is still IVF; use an AVIF encoder such as avifenc or cavif for images. |
Film grain (2 options)
| Option | Default | What it does |
|---|---|---|
--photon-noise | 0 (off) | Add synthetic luma grain at strength 0–64 (strength × 100 is the simulated ISO, so 8 ≈ ISO 800). The decoder renders it through AV1 film-grain synthesis; it does not model the source’s grain. Cannot combine with a grain table. |
--film-grain-table, --photon-noise-table | unset | Apply grain from a film-grain table file, in the text format aomenc and SVT-AV1 also read. --photon-noise-table is a hidden alias. |
Threading and tiles (5 options)
| Option | Default | What it does |
|---|---|---|
--threads | 0 (logical CPUs) | Maximum worker threads. One encode needs several tiles to keep many threads busy. |
--tile-cols | 0 (automatic) | Number of tile columns: a count (power of two, up to 64), not log2. 0 uses the fewest the frame size allows, and rav1e adjusts other values to fit the frame. |
--tile-rows | 0 (automatic) | Number of tile rows, same rules as --tile-cols. |
--tiles | unset | Minimum total tile count; rav1e picks the rows and columns. Cannot be combined with --tile-rows or --tile-cols. |
--slots | 0 (off) | Encode up to N GOPs in parallel; values above 1 enable it. Requires a build with the unstable feature, and only the rav1e-ch binary (also needing channel-api) uses it. |
Colour and HDR metadata (6 options)
These options only label the stream. They do not convert pixels.
| Option | Default | What it does |
|---|---|---|
--range | Limited | Limited or Full. rav1e does not read the range from the Y4M header, so set Full yourself for full-range input. |
--primaries | Unspecified | BT709, BT470M, BT470BG, BT601, SMPTE240, GenericFilm, BT2020, XYZ, SMPTE431, SMPTE432, EBU3213 or Unspecified. |
--transfer | Unspecified | BT709, BT470M, BT470BG, BT601, SMPTE240, Linear, Log100, Log100Sqrt10, IEC61966, BT1361, SRGB, BT2020_10Bit, BT2020_12Bit, SMPTE2084 (PQ), SMPTE428, HLG or Unspecified. |
--matrix | Unspecified | Identity, BT709, FCC, BT470BG, BT601, SMPTE240, YCgCo, BT2020NCL, BT2020CL, SMPTE2085, ChromatNCL, ChromatCL, ICtCp or Unspecified. |
--mastering-display | unset | HDR mastering display as G(x,y)B(x,y)R(x,y)WP(x,y)L(max,min): CIE xy chromaticities as decimals 0–1, luminance in cd/m². |
--content-light | unset | MaxCLL and MaxFALL in cd/m², as max_cll,max_fall (for example 1000,400). 0,0 writes nothing. |
Frame rate and level (3 options)
| Option | Default | What it does |
|---|---|---|
--frame-rate | from Y4M header | Override the output frame rate’s numerator; needs --time-scale (--frame-rate 24000 --time-scale 1001 is 23.976 fps). Changes timestamps only. |
--time-scale | 0 (unset) | Frame-rate denominator for --frame-rate; use 1 for whole-number rates. Ignored without --frame-rate. |
--level | auto | AV1 level to signal and enforce: 2.0, 2.1, 3.0, 3.1, 4.0, 4.1, 5.0–5.3 or 6.0–6.3. auto and unconstrained both write level 31 (no level). The encode fails if the frame size exceeds the level. |
Statistics and debugging (7 options)
| Option | Default | What it does |
|---|---|---|
--verbose, -v | off | Print statistics for every frame. Cannot combine with --quiet. |
--quiet, -q | off | Print no progress or summary. |
--benchmark | off | Print a timing summary at the end. |
--psnr | off | Report PSNR of the reconstruction against the input. Cannot combine with --metrics. |
--metrics | off | Report PSNR, PSNR-HVS, SSIM, MS-SSIM and CIEDE2000 against the input. Slows the encode. |
--reconstruction, -r | unset | Also write the encoder’s reconstructed frames (what a decoder outputs) to this Y4M file. |
--high-bitdepth | off | Use the high-bit-depth code path for 8-bit input too. For debugging. |
Advanced subcommand (4 options)
| Option | Default | What it does |
|---|---|---|
advanced --completion, advanced -c | unset | Print a shell completion script for bash, elvish, fish, powershell or zsh; zsh panics in 0.8.1. An input and -o are still required (rav1e - -o - advanced -c bash). |
advanced --save-config, advanced -s | unset | Write the encoder configuration to a TOML file. Requires a build with the serialize feature, which default builds lack. |
advanced --load-config, advanced -l | unset | Load the encoder configuration from a TOML file made by --save-config; encoder options on the command line are then ignored. Requires serialize. |
advanced --help, advanced -h | — | Print help for the subcommand. |