Skip to content

rav1e

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

The fastest and safest AV1 encoder.

Latest release
v0.8.1
Last commit
License
BSD-2-Clause
Stars
4,160

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.

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.

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:

Terminal window
cargo install --locked rav1e

Or build the tagged release from source:

Terminal window
git clone --branch v0.8.1 https://github.com/xiph/rav1e.git
cd rav1e
cargo build --release

The 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.

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.

Terminal window
rav1e input.y4m -o output.ivf --quantizer 80 --speed 6

Pipe from FFmpeg to encode anything else. 10-bit output is more efficient and bands less, even from 8-bit sources:

Terminal window
ffmpeg -i input.mkv -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | \
rav1e - -o output.ivf --quantizer 80 --speed 6 --photon-noise 8

FFmpeg 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:

Terminal window
ffmpeg -i input.mkv -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | \
rav1e - -o output.ivf --quantizer 72 --speed 6 --tile-cols 2 --photon-noise 8
Terminal window
rav1e input.y4m -o /dev/null --bitrate 3000 --first-pass stats.bin
rav1e 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.

OptionDefaultNotes
--quantizer N100Constant 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, -s60 (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 N0 (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 NautomaticTile 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 Nall logical CPUsThread 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, -i240 / 12Maximum and minimum keyframe distance in frames. Scene-cut keyframes are on by default.
--tunePsychovisualPsnr optimises for the metric and looks worse. Leave the default.
--bitrate N, --first-pass, --second-passquantizer modeBitrate targeting, single or two-pass.
--no-scene-detectionoffFor chunked encoders that place keyframes themselves.
--primaries, --transfer, --matrix, --rangeunspecified, limited rangeColour signalling written into the stream. It labels the colour; it does not convert it.
--mastering-display, --content-lightunsetHDR10 static metadata.

For HDR10, signal the colour and static metadata from your source:

Terminal window
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,400

Replace 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.

Terminal window
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.

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)
OptionDefaultType and rangeWhat it does
-qp-1int, -1–255Constant quantizer, same scale as --quantizer. -1 leaves rav1e’s default of 100. Takes priority over -b:v if both are given.
-speed-1int, -1–10Speed 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.
-tiles0int, ≥ -1Minimum 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-rows0int, ≥ -1Number of tile rows: a count (power of two), not log2. 0 or -1 leaves it automatic.
-tile-columns0int, ≥ -1Number of tile columns, same rules as -tile-rows. The FFmpeg name is -tile-columns, not -tile-cols.
-rav1e-paramsunsetdictionarykey=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.

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)
OptionDefaultWhat it does
INPUTrequiredY4M input file, or - for stdin. It is positional: -i is --min-keyint, not an input flag.
--output, -orequiredIVF output file, or - for stdout. A file name must end in .ivf or have no extension.
-yoffOverwrite an existing output file. Without it rav1e asks for confirmation on stdin, so an encode with piped input exits instead.
--limit, -l0 (all frames)Stop after this many frames. --still-picture allows at most 1.
--skip0Read 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)
OptionDefaultWhat it does
--quantizer100 (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-quantizer0Lowest quantizer (best quality) rate control may use in bitrate mode, 0–255.
--bitrate, -bunset (quantizer mode)Target bitrate in kbit/s. Switches from constant quantizer to rate control.
--first-passunsetRun the first pass of a two-pass encode and write its statistics to this file. Needs --bitrate.
--second-passunsetRun the second pass using statistics from --first-pass. Needs --bitrate and the same input.
--reservoir-frame-delaymin(240, 1.5 × keyint), at least 12Window, in frames, over which rate control spreads its bit reservoir; minimum 12. A longer window lets the bitrate vary more between scenes.
--speed, -s6Preset 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-frames20 at speed 6Frames 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.
--tunePsychovisualPsychovisual or Psnr. Psnr optimises for the metric and looks worse.
Keyframes and frame structure (7 options)
OptionDefaultWhat it does
--keyint, -I240Maximum frames between keyframes. 0 removes the limit, leaving only scene-cut keyframes.
--min-keyint, -i12Minimum frames between scene-cut keyframes; capped at --keyint.
--no-scene-detectionoffTurn 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-speed0 (1 at speed 10)Scene-detection mode: 0 standard, 1 fast.
--switch-frame-interval, -S0 (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-latencyoffDisable frame reordering so no frame waits for later ones, for real-time use. Compresses much less efficiently.
--still-pictureoffEncode 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)
OptionDefaultWhat it does
--photon-noise0 (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-tableunsetApply 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)
OptionDefaultWhat it does
--threads0 (logical CPUs)Maximum worker threads. One encode needs several tiles to keep many threads busy.
--tile-cols0 (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-rows0 (automatic)Number of tile rows, same rules as --tile-cols.
--tilesunsetMinimum total tile count; rav1e picks the rows and columns. Cannot be combined with --tile-rows or --tile-cols.
--slots0 (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.

OptionDefaultWhat it does
--rangeLimitedLimited or Full. rav1e does not read the range from the Y4M header, so set Full yourself for full-range input.
--primariesUnspecifiedBT709, BT470M, BT470BG, BT601, SMPTE240, GenericFilm, BT2020, XYZ, SMPTE431, SMPTE432, EBU3213 or Unspecified.
--transferUnspecifiedBT709, BT470M, BT470BG, BT601, SMPTE240, Linear, Log100, Log100Sqrt10, IEC61966, BT1361, SRGB, BT2020_10Bit, BT2020_12Bit, SMPTE2084 (PQ), SMPTE428, HLG or Unspecified.
--matrixUnspecifiedIdentity, BT709, FCC, BT470BG, BT601, SMPTE240, YCgCo, BT2020NCL, BT2020CL, SMPTE2085, ChromatNCL, ChromatCL, ICtCp or Unspecified.
--mastering-displayunsetHDR 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-lightunsetMaxCLL and MaxFALL in cd/m², as max_cll,max_fall (for example 1000,400). 0,0 writes nothing.
Frame rate and level (3 options)
OptionDefaultWhat it does
--frame-ratefrom Y4M headerOverride the output frame rate’s numerator; needs --time-scale (--frame-rate 24000 --time-scale 1001 is 23.976 fps). Changes timestamps only.
--time-scale0 (unset)Frame-rate denominator for --frame-rate; use 1 for whole-number rates. Ignored without --frame-rate.
--levelautoAV1 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)
OptionDefaultWhat it does
--verbose, -voffPrint statistics for every frame. Cannot combine with --quiet.
--quiet, -qoffPrint no progress or summary.
--benchmarkoffPrint a timing summary at the end.
--psnroffReport PSNR of the reconstruction against the input. Cannot combine with --metrics.
--metricsoffReport PSNR, PSNR-HVS, SSIM, MS-SSIM and CIEDE2000 against the input. Slows the encode.
--reconstruction, -runsetAlso write the encoder’s reconstructed frames (what a decoder outputs) to this Y4M file.
--high-bitdepthoffUse the high-bit-depth code path for 8-bit input too. For debugging.
Advanced subcommand (4 options)
OptionDefaultWhat it does
advanced --completion, advanced -cunsetPrint 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 -sunsetWrite the encoder configuration to a TOML file. Requires a build with the serialize feature, which default builds lack.
advanced --load-config, advanced -lunsetLoad 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.