Skip to content

SVT-AV1-PSY

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

The Scalable Video Technology for AV1 (SVT-AV1 Encoder and Decoder) with perceptual enhancements for psychovisually optimal AV1 encoding

Latest release
v3.0.2
Last commit
License
BSD-3-Clause-Clear
Stars
396

SVT-AV1-PSY was a community fork of SVT-AV1 aimed at the best perceptual quality per bit rather than better metric scores. It was developed by Gianni Rosato, Julio Barba, Clybius and BlueSwordM, with SSIMULACRA2 and XPSNR as guide metrics and visual testing as the final check. It became widely used for quality-focused AV1 encoding and was bundled by tools such as Aviator, rAV1ator CLI and StaxRip.

The project has ended. The lead maintainer announced its end on 20 April 2025, alongside the final release, v3.0.2 “Supernova” (based on mainline SVT-AV1 3.0.2). The repository, now at psy-ex/svt-av1-psy, is archived and read-only. Its README names SVT-AV1-HDR as the official continuation.

  • Mainline SVT-AV1 now contains most of PSY’s important features (see below) plus over a year of upstream speed and efficiency work. Use --tune 0 and enable variance boost.
  • SVT-AV1-HDR is the actively developed successor. It is based on current mainline and keeps several PSY-only options.
  • SVT-AV1-PSYEX continued PSY directly but has been put on hold in favour of SVT-AV1-HDR.

At its end, the project named merging into mainline as its sole mission. Mainline’s changelog credits SVT-AV1-PSY for most of these:

PSY featureMainline status
Variance boost (--enable-variance-boost, --variance-boost-strength, --variance-octile, later --variance-boost-curve)Since v2.1.0; off by default
--sharpness, --tf-strength, --luminance-qp-bias (--frame-luma-bias in earlier PSY releases), --qp-scale-compress-strength, --fgs-table, --enable-dlf 2, --enable-tf 2In mainline
CRF up to 70 in quarter stepsRange in mainline; quarter steps since v4.0.0
--chroma-qm-min / --chroma-qm-maxSince v3.1.0
Adaptive film grain block size (--adaptive-film-grain)Toggle since v4.0.0; on by default
Tune 4 “Still Picture”Became tune IQ in libaom and mainline --tune 3 (IQ, v4.0.0)
--max-32-tx-size 1Mainline --max-tx-size 32 (v4.0.0)
No film-grain denoising by defaultMainline default is now --film-grain-denoise 0
--psy-rd, --spy-rd, --sharp-tx, --noise-norm-strength, --kf-tf-strength, tune 3 “Subjective SSIM”, presets -2 and -3, --dolby-vision-rpu, --hdr10plus-jsonNever merged. PSYEX keeps all of them; SVT-AV1-HDR keeps --sharp-tx, --noise-norm-strength, --kf-tf-strength and the Dolby Vision/HDR10+ inputs, but not --psy-rd/--spy-rd

Mainline v4.0.0 also added --ac-bias, a psy-rd-like texture-energy bias credited to PSY work.

PSY changed many defaults, so a bare PSY command line does not mean the same thing on mainline. Its tune numbers also differ: in PSY, tune 3 is Subjective SSIM and tune 4 is Still Picture. In mainline, tune 3 is IQ (still images only), tune 4 is MS-SSIM and tune 5 is VMAF.

SettingPSY v3.0.2 defaultMainline v4.2.0 default
--tune2 (SSIM)1 (PSNR)
--enable-variance-boost / --variance-octile1 / 60 / 5
--enable-qm / --qm-min1 / 20 / 8
--tf-strength13
--sharpness10
--qp-scale-compress-strength10
--keyint default~10 s, rounded up to whole mini-GOPs~5 s, rounded up to whole mini-GOPs
--psy-rd / --sharp-tx0.5 / 1not available

To carry the merged PSY defaults over to mainline, set them on the command line. Tune 0 replaces PSY’s tune 2 here because it is mainline’s visual-quality tune:

Terminal window
SvtAv1EncApp -i input.y4m --preset 4 --crf 30 --tune 0 --enable-variance-boost 1 --variance-octile 6 \
--enable-qm 1 --qm-min 2 --tf-strength 1 --sharpness 1 --qp-scale-compress-strength 1 --keyint 10s -b output.ivf

This reproduces the defaults that exist in mainline, not PSY’s output: psy-rd, sharp-tx and PSY’s tune changes have no mainline equivalent.

Only build PSY to reproduce an old encode. It builds like mainline:

Terminal window
git clone --depth 1 --branch v3.0.2 https://github.com/psy-ex/svt-av1-psy.git
cd svt-av1-psy/Build/linux
./build.sh release

The encoder is written to Bin/Release/SvtAv1EncApp, so keep it apart from a mainline binary of the same name.

Every option SVT-AV1-PSY v3.0.2 accepts, grouped by purpose; aliases share a row. “auto” defaults are resolved from the preset, tune and input.

Input, output and application (17 options)
OptionDefaultDescription
--help—Print the option list and exit.
--version—Print the library version and exit.
--input, -irequiredInput file, Y4M or raw YUV; - or stdin reads from a pipe. Raw YUV also needs --width, --height, the frame rate and --input-depth.
--output, -bnoneOutput IVF file; - or stdout writes to a pipe.
--config, -cnoneRead options from a configuration file of Name : value lines (the config-file names, e.g. EncoderMode).
--errlogstderrWrite warnings and errors to this file.
--recon, -ononeWrite the reconstructed (decoded) frames as raw YUV, for debugging or metrics.
--stat-filenoneWrite per-frame PSNR and SSIM to this file; needs --enable-stat-report 1.
--progress1Progress output: 0 none, 1 normal, 2 aomenc-style, 3 detailed.
--no-progress0--no-progress 1 is the same as --progress 0.
--svtav1-paramsnoneColon-separated key=value list using option names without --, e.g. tune=0:enable-variance-boost=1. Handy when a wrapper passes a single parameter string.
--frames, -n0 (all)Number of frames to encode; 0 encodes to the end of the input. A count longer than the input loops back to the start.
--skip0Skip this many frames at the start of the input.
--nb-1 (off)Preload this many frames into memory and encode only those, for benchmarking without I/O.
--inj0Feed frames to the encoder at a fixed rate (--inj-frm-rt) to simulate live input.
--inj-frm-rt60Injection rate in frames per second (0–240) for --inj 1.
--enable-stat-report0Compute PSNR and SSIM against the source and print a summary at the end; per-frame values go to --stat-file. Slows encoding.
Source format, profile and level (12 options)
OptionDefaultDescription
--width, -w0 (from Y4M)Frame width in pixels, 4–16384. Required for raw YUV; Y4M headers supply it.
--height, -h0 (from Y4M)Frame height in pixels, 4–8704. Required for raw YUV.
--forced-max-frame-width0 (input width)Maximum frame width written to the sequence header (4–16384), for streams whose frame size changes later.
--forced-max-frame-height0 (input height)Maximum frame height written to the sequence header (4–8704).
--color-format1 (4:2:0)Chroma format of raw input: 0 4:0:0, 1 4:2:0, 2 4:2:2, 3 4:4:4. Mainline encodes 4:2:0 only.
--profile0 (main)AV1 profile: 0 main, 1 high, 2 professional. Main covers 8- and 10-bit 4:2:0, which is all mainline can encode.
--level0 (auto)AV1 level to signal, 2.0–7.3 (e.g. 5.1); 0 derives it from the input.
--fps60Integer frame rate for raw input, 1–240; Y4M headers override it. Use --fps-num/--fps-denom for fractional rates.
--fps-num60000Frame-rate numerator for raw input; Y4M headers override it.
--fps-denom1000Frame-rate denominator; the default pair means 60 fps.
--input-depth10Bit depth of raw input and of the encode, 8 or 10; Y4M headers supply it. Raw input defaults to 10-bit.
--tier0 (main)AV1 tier: 0 main, 1 high (higher bitrate limits for levels 4.0 and up). Accepted but not listed in --help.
Preset, tune and threading (8 options)
OptionDefaultDescription
--preset8Speed/efficiency trade-off, −3–13; lower is slower and more efficient. −2 and −3 are extremely slow research modes. Presets above 10 run as 10, and 8K inputs need preset 2 or faster.
--asmmaxHighest instruction set to use. x86: c, mmx, sse … sse4_2, avx, avx2, avx512, max; Arm: c, neon, crc32, neon_dotprod, neon_i8mm, sve, sve2, max. Lower it only to debug or compare.
--lp0 (auto)Level of parallelism, 1–6: higher levels create more threads and picture buffers and use more memory. 0 picks a level from the core count. It is not a thread count.
--pin0 (off)Pin the encoder to the first N logical cores; 0 disables pinning.
--ss-1 (any)CPU socket to run on: −1 any, 0 or 1 a specific socket of a two-socket system.
--fast-decode0Decoder-speed optimizations, 0–2 (2 decodes fastest) at a small efficiency cost. Try it before tiles.
--tune2 (SSIM)0 VQ, 1 PSNR, 2 SSIM, 3 Subjective SSIM (tune 2 with psychovisual tweaks: worse metrics, better looks), 4 Still Picture (all-intra images).
--hbd-mds0 (preset)Precision of mode decision for 10-bit input: 0 preset default, 1 10-bit, 2 hybrid 8/10-bit, 3 8-bit.
Rate control and passes (21 options)
OptionDefaultDescription
--rc0Rate-control mode: 0 CRF (or CQP with --aq-mode 0), 1 VBR, 2 CBR, both with --tbr.
--qp, -q35Base QP, 1–63: the fixed QP in CQP and the starting point otherwise. For constant quality use --crf.
--crf35Constant rate factor, 1–70 in 0.25 steps; lower is higher quality and larger. Equivalent to --rc 0 --aq-mode 2 --qp N on a finer scale.
--tbr2000 kbpsTarget bitrate for VBR and CBR in kbps (1–100000); b, k and m suffixes are accepted, e.g. --tbr 3.5m.
--mbr0 (off)Maximum bitrate for capped CRF, in kbps (same suffixes). Dropped with a warning when TPL is off: --aq-mode 0, all-intra or low-delay.
--max-qp63Highest QP rate control may use, 0–63; mainly for VBR and CBR.
--min-qpauto (0 for CRF, 4 for VBR/CBR)Lowest QP rate control may use, 0–63; mainly for VBR and CBR.
--undershoot-pctauto (50 for VBR, 25 for CBR)How far below the target VBR/CBR may undershoot, in percent (0–100).
--overshoot-pctauto (25)How far above the target VBR/CBR may overshoot, in percent (0–100).
--mbr-overshoot-pct50Allowed overshoot of --mbr in capped CRF, in percent (0–100).
--gop-constraint-rc0Make VBR hit the target within each GOP instead of over the whole clip; useful for chunked or segmented encoding.
--buf-sz1000CBR decoder buffer size in milliseconds (20–10000).
--buf-initial-sz600CBR initial buffer level in milliseconds (20–10000); must be below --buf-sz.
--buf-optimal-sz600CBR target buffer level in milliseconds (20–10000).
--recode-loop4 (preset-based)Re-encode frames that miss the rate target: 0 off, 1 key frames and oversized frames, 2 key/alt-ref/golden frames, 3 all frames, 4 preset-based.
--minsection-pct0VBR: lowest bitrate a GOP may get, as a percentage of the target (0–100).
--maxsection-pct2000VBR: highest bitrate a GOP may get, as a percentage of the target (0–10000).
--pass0Run one pass of a two-pass encode: 0 single pass, 1 first pass, 2 second pass (VBR only). Use the same --stats file in both.
--statssvtav1_2pass.logStatistics file written by the first pass and read by the second.
--passes1--passes 2 runs both passes of a VBR two-pass encode in one command.
--enable-tpl-la1Temporal dependency (TPL) model. The library forces it on for CRF/CQP, so 0 only matters in VBR/CBR.
Quantization offsets and matrices (20 options)
OptionDefaultDescription
--use-q-file0Take per-frame QPs from --qpfile instead of the encoder’s own assignment.
--qpfilenoneFile with one QP per line, one line per frame, for --use-q-file 1.
--aq-mode2Adaptive quantization: 0 off (constant QP), 1 variance-based segments, 2 delta-q from TPL prediction efficiency.
--use-fixed-qindex-offsets0Override per-layer QP assignment: 1 use the base q-index plus --qindex-offsets and --key-frame-qindex-offset, 2 add those offsets on top of the encoder’s own assignment.
--key-frame-qindex-offset0Q-index offset for key frames, −64–63, used with --use-fixed-qindex-offsets. Q-index runs 0–255, about four steps per QP.
--key-frame-chroma-qindex-offset0Chroma q-index offset for key frames, −64–63.
--qindex-offsets0 per layerComma-separated luma q-index offsets, one per temporal layer (each −64–63), for --use-fixed-qindex-offsets.
--chroma-qindex-offsets0 per layerComma-separated chroma q-index offsets, one per temporal layer (each −64–63).
--luma-y-dc-qindex-offset0Luma DC quantizer offset in q-index steps (−64–63); positive values quantize DC more coarsely.
--chroma-u-dc-qindex-offset0Cb DC quantizer offset in q-index steps (−64–63).
--chroma-u-ac-qindex-offset0Cb AC quantizer offset in q-index steps (−64–63).
--chroma-v-dc-qindex-offset0Cr DC quantizer offset in q-index steps (−64–63).
--chroma-v-ac-qindex-offset0Cr AC quantizer offset in q-index steps (−64–63).
--lambda-scale-factors128 for every frame typeComma-separated RD lambda multipliers per frame-update type, in units of 1/128 (128 = 1.0). A research control.
--enable-qm1Use quantization matrices, which quantize high frequencies more coarsely than low ones.
--qm-min2Lowest (steepest) luma QM level the encoder may pick, 0–15; 15 is flat.
--qm-max15Highest (flattest) luma QM level, 0–15.
--roi-map-filenoneRegion-of-interest file giving per-block QP offsets for chosen frames.
--chroma-qm-min8Lowest chroma QM level, 0–15.
--chroma-qm-max15Highest chroma QM level, 0–15.
GOP structure and keyframes (11 options)
OptionDefaultDescription
--keyint-2 (about 10 s)Maximum keyframe interval in frames, or seconds with an s suffix. −2 is about 10 seconds; −1 or 0 means no periodic keyframes (CRF only).
--irefresh-type2 (closed GOP)Keyframe type at each interval: 1 forward keyframe (open GOP), 2 key frame (closed GOP). Open GOP is slightly more efficient; closed GOP makes every keyframe a clean seek point.
--scd0Scene-change detection. The encoder switches it back off with a warning: scene changes are handled inside mode decision and no keyframe is inserted.
--lookahead-1 (auto)Frames of extra look-ahead for rate control and TPL, 0–120, beyond the mini-GOP and temporal-filter window.
--hierarchical-levelsauto (5; 4 above preset 12)Temporal layers above the base layer, 0–5; 5 gives 32-frame mini-GOPs. Fewer levels lower latency and memory use.
--pred-struct2 (random access)Prediction structure: 1 low delay, 2 random access (normal for files). 0 all-intra is also accepted.
--force-key-framesnoneComma-separated keyframe positions: a number followed by f for frames or s for seconds (e.g. 0f,120f,30.5s).
--startup-mg-size0 (off)Use a smaller mini-GOP right after each keyframe: 2, 3 or 4 temporal layers (4, 8 or 16 frames). CRF only, and not above --hierarchical-levels.
--startup-qp-offset0QP offset (−63–63) for that startup mini-GOP.
--enable-dg1Dynamic mini-GOP: adapt the hierarchical structure to the content.
--intra-period-2Deprecated form of --keyint, counted as keyint − 1. Not listed in --help.
Filters and coding tools (14 options)
OptionDefaultDescription
--tf-strength1Alt-ref temporal filter strength, 0–4; each step doubles it. The default 1 is 4× weaker than mainline’s 3, which keeps more detail and grain.
--tile-rowsautoTile rows as log2 (0–6; 2 means 4 rows). Tiles help decoder threading at a small efficiency cost; the encoder does not need them for its own threading.
--tile-columnsautoTile columns as log2 (0–4); at most 128 tiles in total.
--enable-dlf1Deblocking filter: 0 off, 1 on, 2 more accurate and slower.
--enable-cdefauto (on)CDEF deringing filter, 0 or 1.
--enable-restorationauto (on)Loop restoration filter (Wiener and self-guided), 0 or 1.
--enable-mfmv-1 (auto)Motion-field motion vector projection, 0 or 1; −1 lets the preset decide.
--enable-tf1Temporal filtering of alt-ref frames: 0 off, 1 on, 2 adaptive strength per 64×64 block (overrides --tf-strength).
--enable-overlays0Insert overlay frames after filtered alt-refs as extra references. Not supported with low delay or multi-pass.
--scm2 (detect)Screen-content tools (palette, intra block copy): 0 off, 1 on, 2 detect per frame.
--lossless0Lossless coding.
--avif0Still-picture mode for AVIF and single images: better efficiency and less memory.
--max-32-tx-size0Limit transforms to 32×32 (0 or 1); can help detail at high-fidelity CRFs.
--kf-tf-strength1Temporal filter strength on key frames, 0–4; each step doubles it (1 is 4× weaker than mainline). Removes keyframe artifacts from strong filtering.
Super-resolution, resizing and switch frames (13 options)
OptionDefaultDescription
--superres-mode0 (off)Super-resolution (code at reduced width, upscale in the decoder): 0 off, 1 fixed, 2 random, 3 by QP threshold, 4 auto. Not available with two-pass.
--superres-denom8Mode 1 scale: width × 8/denom, 8–16 (8 none, 16 half width).
--superres-kf-denom8Mode 1 scale for key frames, 8–16.
--superres-qthres43Mode 3: frames with QP above this (0–63) use super-resolution.
--superres-kf-qthres43Mode 3 threshold for key frames, 0–63.
--sframe-dist0 (off)Insert a switch frame every N frames; S-frames let a decoder switch between streams.
--sframe-mode2S-frame placement: 1 only if that frame is an alt-ref, 2 the next alt-ref.
--resize-mode0 (off)Reference scaling (resize frames inside the codec loop): 0 off, 1 fixed, 2 random, 3 dynamic, 4 per-event list.
--resize-denom8Mode 1 scale 8/denom, 8–16.
--resize-kf-denom8Mode 1 scale for key frames, 8–16.
--frame-resz-eventsnoneMode 4: comma-separated frame numbers (0-based) where a new scale starts.
--frame-resz-kf-denomsnoneMode 4: key-frame denominators (8–16), one per event.
--frame-resz-denomsnoneMode 4: denominators (8–16), one per event.
Film grain (3 options)
OptionDefaultDescription
--film-grain0 (off)Film-grain synthesis, 1–50: estimate grain from the source and signal it for the decoder to add back. Saves a lot of bitrate on grainy sources; the encoder warns about the compute cost above preset 6.
--film-grain-denoise01 also codes a denoised picture at the --film-grain strength; 0 codes the source picture and only adds the grain parameters.
--fgs-tablenoneUse a pre-made grain table file (aomenc --film-grain-table format) instead of estimating grain.
Colour and HDR metadata (10 options)
OptionDefaultDescription
--color-help—Print the colour-metadata reference (primaries, transfer and matrix names, mastering-display syntax) and exit.
--color-primaries2 (unspecified)Colour primaries, 0–12 or 22, by number or name (bt709, bt2020…); see --color-help. Signalling only: pixels are not converted.
--transfer-characteristics2 (unspecified)Transfer function, 0–22 (bt709, smpte2084 for PQ, hlg…).
--matrix-coefficients2 (unspecified)YUV matrix, 0–14 (bt709, bt2020-ncl…). 0 (identity) needs 4:4:4.
--color-range0 (limited)0 limited (studio) range, 1 full range.
--chroma-sample-positionunknownChroma siting: unknown, vertical/left or colocated/topleft.
--mastering-displaynoneSMPTE ST 2086 mastering display as G(x,y)B(x,y)R(x,y)WP(x,y)L(max,min): CIE xy chromaticities and luminance in cd/m².
--content-lightnoneContent light level as MaxCLL,MaxFALL in cd/m², e.g. 1000,400.
--dolby-vision-rpunoneDolby Vision RPU file to embed, frame-aligned with the encode. Requires a build with libdovi.
--hdr10plus-jsonnoneHDR10+ JSON metadata file to embed. Requires a build with hdr10plus support.
Psychovisual tuning (11 options)
OptionDefaultDescription
--luminance-qp-bias0Spend more bits on dark frames: lowers frame QP based on average luma, strength 0–100.
--sharpness1Bias deblocking and RD decisions toward sharpness (positive) or smoothness (negative), −7–7.
--enable-variance-boost1Variance Boost: lower QP in low-contrast superblocks to prevent banding and blocking in flat and dark areas, at some bitrate cost.
--variance-boost-strength2Variance Boost strength: 1 mild, 2 gentle, 3 medium, 4 aggressive. Upstream suggests 1 for smooth animation and 3 for stills or very contrasty films.
--variance-octile6How much of a superblock must be low-contrast before it is boosted, 1–8 (1 boosts readily, 8 only uniform blocks). Lower values spend more bits; upstream recommends 4–7.
--variance-boost-curve0Variance Boost curve: 0 default, 1 low-to-medium contrast boost, 2 still-picture curve.
--qp-scale-compress-strength1Compress QP differences between temporal layers, 0–3, for steadier quality within a mini-GOP; helps grain and fast motion.
--noise-norm-strength1Noise normalization, 0–4: boosts some AC coefficients so fine texture survives in otherwise flat areas. Upstream suggests 3 for tune 3 and difficult content.
--psy-rd0.5Psychovisual RD strength, 0.0–6.0: tries to keep the energy of high-frequency detail and texture. At 0.6 and above with presets ≤6 it also enables a slower high-quality mode.
--spy-rd0Alternative psychovisual RD pathways that favour sharpness and detail, at some risk of blocking and banding: 0 off, 1 full (most aggressive), 2 partial.
--sharp-tx1Skip conventional transform optimizations and let other metrics such as psy-rd decide, which makes psy-rd much stronger. Upstream suggests turning it off if you set --psy-rd 0.