# Encode Wiki full corpus Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf # AV1 Encoding for Dummies Canonical URL: https://encode.wiki/articles/av1-encoding-for-dummies/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: 4ea629cf8d922c9fe9214c4b6fe88b77d2f59c20d19579c754a098f9cad4e3cb > **Note — Editorial correction — 7 September 2026.** > > The original September 2023 aom-av1-lavish example and illustrations are preserved as history. Obsolete installation instructions have been replaced and false technical explanations corrected. The long command is not a current recommendation: its fork-specific flags must not be copied into upstream encoders. No historical encode was rerun. This article documents the authors' September 2023 Av1an/aom-av1-lavish workflow. Standalone encoders and FFmpeg wrappers are valid choices; chunking is not automatically optimal for every source or machine. > **Caution — Historical recipe.** > > For new work, use [AV1 with SVT-AV1](/guides/av1-with-svt-av1/) or the maintained [Av1an guide](/tools/utilities/av1an/). The other “AV1 for Dummies” article also contains a dated tool survey. ![Compare](/img/compare-guide.webp) Av1an can run multiple encoder workers on independent chunks. Parallelism is bounded by CPU, RAM, decoding, and I/O; it is not infinite. Chunk boundaries can affect compression, seeking, and rate control. The original estimate of more than 16 GB for four 4K aomenc workers was a workload-specific warning, not a current resource requirement. ## Installing tools now Use [Av1an's upstream installation documentation](https://github.com/rust-av/Av1an) and the release-specific requirements for its selected decoder backend and encoder. Match VapourSynth to the supported Python version rather than pinning the old Python 3.10/VapourSynth R63 combination. Install maintained FFmpeg and muxing tools, then inspect: ```bash av1an --version av1an --help ffmpeg -version aomenc --help ``` Record the versions and resolved executable paths used for a real job. Avoid copying shared libraries between package-manager prefixes or overwriting several encoder binaries to make an old command work. Configure the build to find the intended dependency versions instead. On Windows, a native build or WSL may be appropriate. WSL2 runs a Linux kernel in a managed virtual machine; the original claim that it runs on bare metal without a VM was incorrect. [Microsoft WSL architecture](https://learn.microsoft.com/en-us/windows/wsl/compare-versions). The old source edits referenced moving line numbers in an aom-av1-lavish branch. Those are not reproducible patches for a current checkout. For historical reproduction, recover the exact fork commit and dependencies from the original source; for new work follow the [upstream aomenc guide](/tools/software-encoders/aomenc/).
Original Windows installer illustration The Python PATH screenshot is retained as historical media, not a recommendation to install that Python version: ![Original Python installer PATH checkbox](/img/python-path.webp)
## Encoding The following is the authors' **historical 3 September 2023 recipe**, retained for provenance. It targets a particular aom-av1-lavish/Av1an combination; no current build is claimed to accept all these flags: ```bash av1an -x 300 -i input.mkv -w 4 -e aom -c mkvmerge --resume -m lsmash --photon-noise=10 --set-thread-affinity=2 --verbose -a " -an " -f " -an " -v " --bit-depth=10 --cpu-used=4 --end-usage=q --cq-level=24 --threads=2 --tile-columns=0 --tile-rows=0 --lag-in-frames=64 --tune-content=psy --tune=ssim --enable-keyframe-filtering=1 --disable-kf --kf-max-dist=9999 --enable-qm=1 --deltaq-mode=0 --aq-mode=0 --quant-b-adapt=1 --enable-fwd-kf=0 --arnr-strength=1 --sb-size=dynamic --enable-dnl-denoising=0 " -o "output.mkv" ``` > **Note — Version-specific parameters.** > > The explanations below describe the historical example. For new commands use the installed encoder's help and release documentation. Community recipes are test candidates, not universal quality settings. Now let's dissect it one-by-one **Av1an parameters:** - ``-i`` Input. - ``-x 300`` Set the historical maximum scene length to 300 frames. Longer chunks can affect compression, parallelism, and seeking; they do not guarantee higher quality. - ``-w 4`` Specifies the amount of "workers" or amount of encoders working on the video. - ``--verbose`` Sets logging to verbose. - ``--resume`` Resumes the encode even when you haven't encoded yet. I strongly recommend leaving this if you resume a lot since you can accidentally delete your whole progress (There's no delete confirmation feature.. yet) if you "resumed" without the parameter in place. - ``-e aom`` Specifies we're using aomenc encoder which should be the default option. - ``-c mkvmerge`` Specifies we're using mkvmerge (MKVToolNix) to concatenate the parts when done, you can specify with ffmpeg if you want to but validate the chosen concatenation method and output streams. - ``-m lsmash`` Selected the historical L-SMASH backend. Backend compatibility, frame accuracy, and speed depend on input and version; this article does not establish that other backends inherently lag or are inferior. - ``-f " -an "`` ``-f`` Stands for ffmpeg parameters, ``-an`` is to remove all audio since its better to encode and merge it separately. To crop use ``-f " -an -vf crop=1920:800 "`` for example to crop the video to 1920x800. - ``-v " "`` Is where you put the encoder's parameters in. - ``-a " -an "`` FFmpeg audio encoding options, we're removing it cause we can always add it later. But if you want to, you can also encode directly. Here's an example for encoding to Opus using libopus assuming stereo: `-a " -c:a libopus -b:a 128k "`. - ``--photon-noise=10`` AV1 grain synthesis, which is a technique where the encoder puts fake grain in so it looks more natural and potentially hiding video artifacts (cause grain is hard to encode and explodes bitrate usage because of their randomness), 5-8 for almost none to little grain, 10-14 for medium, 15+ heavy, 20+ extremely heavy, 30+ for extremely grainy 90s live action films. - ``--set-thread-affinity=2`` Pins the thread to the encoder, aligns with ``--threads=2`` in the encoder parameter so set them accordingly. **aomenc parameters:** - ``--bit-depth=10`` Selected 10-bit coding. It can help precision and banding but does not guarantee smaller files or target compatibility; confirm the output profile and playback path. - ``--cpu-used=4`` Selected the historical CPU-effort setting. Valid ranges and speed/quality tradeoffs depend on encoder build and usage mode; 4 is not a universal sweet spot. - ``--end-usage=q --cq-level=24`` Selected libaom's constant-quality mode and CQ level 24. CQ is not numerically equivalent to x264/x265 CRF 24. - `--threads=2` Sets the amount of threads the encoder can use, aligns with `--set-thread-affinity` in Av1an. - ``--tile-columns=0 --tile-rows=0`` This is the tiles options, where the encoder splits the videos into tiles to encode faster, see the image below (Yellow lines): Tiling > **Note — Tile tradeoffs.** > > Tile row/column controls use logarithmic counts in this interface: 0 means one, 1 means two, and 2 means four. Additional tiles may improve decoder parallelism at a compression cost. Test the intended decoder; resolution alone does not determine the right setting. - ``--lag-in-frames=64`` Similar to x264/x265 `rc-lookahead`. Sets a number of frames to look ahead for frametype and ratecontrol, allowing for better compression decision making. Setting to a value greater than 64 is generally not considered useful. - ``--aq-mode`` adaptive quantization mode; 0 was the author's historical choice, not a demonstrated general optimum - ``--tune-content=psy --tune=ssim`` As the name suggests they are tunes that affect the video output, for the better, and for the worst > **Note — Historical fork tunes.** > > The example's `psy`, `lavish`, and related tuning advice was specific to aom-av1-lavish at the time. These names and the old CQ30 rule are not portable upstream guidance. Inspect the exact fork revision for reproduction; use current encoder documentation for new work. - ``--enable-keyframe-filtering=1`` Used the historical value 1. The old compatibility report was specific to that pipeline; it does not establish a current universal limitation. - ``--sb-size=dynamic`` Allows the encoder to use 128x128 block partitioning besides 64x64 which gives an efficiency boost, ignore it. - ``--deltaq-mode`` was set to 0 in the historical recipe; a universal improvement was not demonstrated. - ``--arnr-strength=1`` Controls how strong the filtering will be, 1 is good for 3D Pixar CGI-like and 2D animation, use 4 if you're doing live action content. Using maximum at higher bitrates would just result in a blurry mess. - ``--disable-kf --enable-fwd-kf=0`` We're disabling keyframes cause **Av1an already did scene detection, so we wont have to.**. And it speeds things up. - ``--kf-max-dist=9999`` Maximum keyframe interval, we're setting it at the highest possible value since av1an's scene detection keyframe interval is already 240 by default - ``--enable-chroma-deltaq=1 --enable-qm=1 --quant-b-adapt=1`` Fork/version-specific choices from the old recipe. Their gains, costs, and interactions require measurement. - ``--enable-dnl-denoising=0`` Disables the encoder's built-in denoising technique when grain synthesis is enabled, you can optionally set it to 1 when you have a pretty noisy video since it works quite well. > **Note — Concatenation Error on Linux.** > > The old guide suggested raising the file-descriptor limit and manually invoking a saved mkvmerge options file. That was a workaround for its historical pipeline, not a general fix. Inspect the actual error, current Av1an resume behavior, and generated files before changing process limits or manually concatenating chunks. ## Merging Everything Verify the output streams explicitly: the historical command disables audio, and subtitles should not be assumed preserved. Use [audio and subtitle mapping](/guides/audio-and-subtitles/) when adding or copying them. Select a compatible container and test playback; MP4 and Matroska have different subtitle and codec mappings. The old blanket statement that Opus support is experimental is not a current compatibility test. ## Additional historical fork settings - `--denoise-noise-level=10` Alternative to `photon-noise`, slower than photon-noise and is the OG grain synthesis method, performs okay and just serves as an alternative. Don't attempt to use it at high values (>12) since it creates noticeable grain patterns. - `--arnr-maxframes` to set max reference frames that will be used to filter the encode, higher values would make the video blurrier at high fidelity but look better at lower bitrates. - `--butteraugli-resize-factor=2` if you use any of the butteraugli-based tunes (lavish, butteraugli) to speed it up without much losses and `--butteraugli-intensity-target=250` to match the content light level. ## Final Thoughts Encoding has always been about experimentation for the best, there is really no "One size fits all" for encoding content, as they differ from scene complexity, how it's captured (2D/Real life), film grain, dark scenes, etc. So experiment away for your specific type of content! > **Guide originally hosted on https://rentry.co/AV1, rewrite and migration by Simulping.** --- # AV1 for Dummies Canonical URL: https://encode.wiki/articles/av1-for-dummies/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: cea45ba42665ef0c17e4b4610b58b9f95a1ecab1e23761fcad81d5a16fe4fa19 > **Note — Editorial correction — 7 September 2026.** > > This guide originated in June 2024. The historical tool-rating tables and credited authorship are retained, but the prose below corrects bit-depth guarantees, encoder capabilities, and project status. The tables record the authors' opinions at publication and are not current compatibility tests or product rankings. Use the linked canonical guides for new encodes. This article introduces AV1 encoding and preserves the authors' 2024 view of the tooling landscape. For a maintained starting workflow, use [AV1 with SVT-AV1](/guides/av1-with-svt-av1/) and [choosing a codec](/guides/choose-a-codec/). ![Compare](/img/av1_for_dummies_guide.avif) ## Introduction [AV1](/codecs/video/av1/) is a royalty-free video codec developed by the Alliance for Open Media. It is designed to replace [VP9](/codecs/video/vp9/) and presently competes with [H.266](/codecs/video/vvc/). AV1 is known for its high compression efficiency, which the marketing will have you believe reduces file sizes by up to 50% compared to [H.264](/codecs/video/avc/) and up to 30% compared to [H.265](/codecs/video/hevc/) across the board. It is supported by several major browsers and is widely used across many streaming services and video platforms. ### Why AV1? Before we dive in, it is important to understand *why* you may want to use AV1 instead of other codecs. The reality is that AV1 is *not* better than H.264/5 in every single scenario; video encoding is a complicated field, and the best codec for you will depend on your specific needs. AV1 excels in: - Low to medium-high fidelity encoding - Higher resolution encoding - Encoding content with very little grain or noise - Slow, non-realtime contexts (e.g. offline encoding) The enumeration above still consists of broad strokes, but the point is to understand that AV1 is not a silver bullet. It will not automatically make your videos smaller while preserving your desired quality. To make things more difficult, the [x264](/tools/software-encoders/x264/) & [x265](/tools/software-encoders/x265/) encoders are very mature, while encoder implementations continue to evolve. Relative performance must be measured with named versions and workloads. This guide focuses almost entirely on tools great for offline, non-realtime encoding for various kinds of content. Streaming is an altogether different application of AV1, and is only covered sparsely here. ### Do's & Don'ts Due to a lot of misunderstandings about codecs and compression, there are a lot of common misconceptions that are held regarding video encoding. We'll start by outlining some bad practices: - **Don't** encode the same video multiple times. This is a common mistake made by people new to video encoding. Repeated **lossy** transcoding can introduce generation loss. Lossless encoding and stream copying are different operations and do not inherently discard decoded sample information. This is why it is important to keep the original video file if you frequently re-encode it. - **Don't** blindly copy settings from others without understanding them. What works for one person's content and workflow may not work for yours. Treat defaults as a starting point to test against your requirements. - **Don't** assume that higher bitrate equates to better quality. Inefficient encoding can waste bits without improving visual quality, and efficient encoding can make lower bitrate video look drastically better than higher bitrate video using the same codec. - **Don't** assume all encoders/presets/settings/implementations are created equal. Even given two encoding frameworks that use the same underlying encoder, you may achieve different results given encoder version mismatches or subtly different settings used under the hood. - **Don't** use unnecessarily slow presets/speeds unless you have a specific need and ample time. While slower presets improve encoding efficiency most of the time, the quality gains reach a point of diminishing returns beyond a certain point. Use the slowest preset you can tolerate, not the slowest preset available. - **Don't** blindly trust metric scores. [VMAF](/reference/metrics/vmaf/) depends on the selected model, viewing assumptions, and preprocessing; this guide does not establish its frequency of agreement with viewers. Even the beloved [SSIMULACRA2](/reference/metrics/ssimulacra2/) is not a perfect one-to-one with the human eye. Now, let's move on to some **good** practices: - Experiment with different settings and compare the results. - Consider your content type when choosing encoding settings. Film, animation, and sports all have different characteristics that benefit from distinct approaches. - Try to use CRF for offline encoding, as opposed to CBR or VBR. While the latter two are effective for precisely targeting a particular bitrate, CRF is more effective at targeting a specific quality level efficiently. - Test 10-bit encoding when the target supports it. It can improve precision and reduce banding, including for some 8-bit sources, but it cannot recover missing source precision or guarantee a smaller or better-looking encode. AV1 Main profile includes 8- and 10-bit coding; profile membership alone does not guarantee that a particular device, browser, container, or playback path supports it. [AV1 specification](https://aomediacodec.github.io/av1-spec/av1-spec.pdf). - Consider using grain synthesis for grainy content, as AV1 can struggle with preserving film grain efficiently. - Keep your encoding software up-to-date; the encoding world moves quickly. ## Tools The following tables preserve the authors' June 2024 tool survey. Platform and bundled-encoder entries describe that historical survey; verify current releases before installation. Dot ratings are editorial opinions without a controlled comparison. ### GUI Here's the key: - **Encoder(s)**: The AV1 encoder(s) the software uses or is able to use. This is between [SVT-AV1](/tools/software-encoders/svt-av1/), [aomenc](/tools/software-encoders/aomenc/), [rav1e](/tools/software-encoders/rav1e/), [SVT-AV1-PSY](/tools/software-encoders/svt-av1-psy/), and various aomenc forks. We'll get into this more later. - **Ease of Use**: How intuitive the software is, especially for beginners. - **Complexity**: How flexible the software can be for advanced users. - **Efficiency**: How "good" the underlying encoder(s) are. This is more subjective, but tools with bad defaults, misleading options, or slow release cycles won't score well here. | Name | Platform(s) | Encoder(s) | Ease of Use | Complexity | Efficiency | |---------|-------------|:----------:|:-----------:|:-----------:|------------| | [Aviator](/tools/utilities/aviator/) | Linux | SVT-AV1-PSY| ●●●●● | ●○○○○ | ●●●●● | | [NMKODER](/tools/utilities/nmkoder/) | Windows | Any | ●●●○○ | ●●●●○ | ●●○○○ | | [Av1ation Station](https://github.com/Av1ation-Association/Av1ation-Creations/releases/) | Any | Any | ●●●○○ | ●●●●● | ●●●●○ | | [StaxRip](https://github.com/staxrip/staxrip) | Windows | Any | ●●○○○ | ●●●●● | ●●●●○ | | [NEAV1E](https://github.com/Alkl58/NotEnoughAV1Encodes) | Windows | Any | ●●●○○ | ●●●○○ | ●●○○○ | | [Handbrake](https://handbrake.fr/) | Any | SVT-AV1 | ●●●●○ | ●●○○○ | ●●○○○ | | [FastFlix](https://github.com/cdgriffith/FastFlix) | Any | Any | ●●●●○ | ●●●○○ | ●●○○○ | | [rAV1ator](/tools/utilities/rav1ator/) | Linux | rav1e | ●●●●○ | ●●●○○ | ●○○○○ | | [Autocompressor](https://autocompressor.net/) | Web | SVT-AV1 | ●●●●● | ●○○○○ | ●●●○○ | For a new GUI workflow, check the tool's current platform support, bundled encoder version, subtitle handling, and color/HDR behavior. The original rankings do not establish current suitability. Consult the [tools index](/tools/) and test a short representative encode before committing to a workflow. ### CLI In the terminal, advanced encoders can explore a much greater degree of complexity than many GUIs allow. That being said, ease of use is still a consideration when managing complex command-line encoding workflows. Let's begin with the key: - We're omitting the "Platform(s)" column here, as this section targets Linux users. As a Windows user, WSL has you covered - as a Mac user, you're likely to experience parity with Linux (most of the time). | Name | Framework(s) | Ease of Use | Complexity | Features | Scene Detection | |------|--------------|:-----------:|:----------:|:--------:|:---------------:| | SvtAv1EncApp | None | ●○○○○ | ●●○○○ | ●○○○○ | No | | [FFmpeg](/tools/utilities/ffmpeg/) | Itself | ●●○○○ | ●●●●● | ●●●●○ | No | | [Av1an](/tools/utilities/av1an/) | FFmpeg | ●○○○○ | ●●●●● | ●●●○○ | Yes | | [rAV1ator CLI](/tools/utilities/rav1ator-cli/) | Av1an | ●●●●○ | ●●●●○ | ●●●●○ | Yes | | [alabamaEncoder](https://github.com/kingstefan26/alabamaEncoder) | FFmpeg | ●●○○○ | ●●●●● | ●●●●● | Yes | For a new CLI workflow, begin with [FFmpeg](/tools/utilities/ffmpeg/) or the [SVT-AV1 guide](/guides/av1-with-svt-av1/). Use [Av1an's current documentation](https://github.com/rust-av/Av1an) when you need scene-based orchestration, and verify its encoder/backend dependencies. The historical table is not an installation matrix. ### Conclusion Choose tooling by supported inputs, target playback, automation needs, and available resources. A GUI and a CLI using the same encoder can still differ through version, settings, stream handling, or preprocessing. ## Encoders **Editorial update:** these descriptions replace the original unconditional rankings and obsolete capability lists. An encoder's speed preset is not a quality guarantee, and lossy AV1 is not an archival substitute for retaining a master. ### SVT-AV1 [SVT-AV1](/tools/software-encoders/svt-av1/) provides a library and `SvtAv1EncApp`, with parallelism aimed at practical throughput. Threads, tiling, preset, and rate control are different controls; “parallel processing is lossless” is not a guarantee that all parallel configurations produce identical bitstreams or quality. Preset ranges and mappings have changed since 2024. Inspect `SvtAv1EncApp --help` and the documentation for the installed release instead of copying the old 0–13 list. Compare speed and size at your desired quality. [Official parameters](https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/Parameters.md). ### rav1e [rav1e](/tools/software-encoders/rav1e/) is an AV1 encoder written in Rust and assembly. Its design emphasizes safety, but language choice alone does not prove crash freedom or superior bitstream correctness. Check supported pixel formats, speed settings, and current release behavior in the [upstream repository](https://github.com/xiph/rav1e). This article supplies no controlled evidence that it universally preserves more detail or is more reliable than other encoders. ### aomenc / libaom [aomenc](/tools/software-encoders/aomenc/) is the command-line encoder from AOMedia's reference implementation. It supports multiple usage modes and many coding controls; valid `--cpu-used` ranges depend on mode and version. Reference-software status does not make it universally slowest, highest quality, or exempt from validation. Its pixel-format support extends beyond common delivery profiles, so verify the intended decoder as well. [Upstream source and documentation](https://aomedia.googlesource.com/aom/). ### SVT-AV1-PSY and successors The original [SVT-AV1-PSY](/tools/software-encoders/svt-av1-psy/) fork announced its end on 20 April 2025. Its repository now points readers toward successor work and upstream integration. The original article's claim that it is an actively maintained universal best choice is no longer applicable. [Project status](https://github.com/psy-ex/svt-av1-psy). Names, tunes, ranges, and defaults differ between upstream SVT-AV1 and forks; a tune number is not portable between them. Variance boost allocates additional precision to low-contrast regions and is not exclusively a PSY feature. HDR metadata handling also requires compatible input, transformation, muxing, and playback: an encoder option alone cannot guarantee Dolby Vision or HDR10+ preservation. See [color and HDR guidance](/guides/preserve-color-and-hdr/). ### Choosing among them Measure named versions on representative content, keep output sizes comparable, and inspect difficult scenes. No evidence in this introductory guide establishes a universal speed/quality winner. Use [quality controls](/guides/quality-controls/) to separate bitrate targets, quality targets, and encoding effort. ## Final Conclusion The AV1 ecosystem has grown to the point where a single comprehensive guide cannot effectively cover the entire extent of the available tools and techniques for AV1 encoding across *every* use case. If you want more detail about a particular tool, where to acquire it, or how to compile an encoder, you can find that information throughout the various wiki entries linked on this page. Reading can get you far, but it is natural to have questions. Please don't hesitate to connect with the team behind the Codec Wiki and many of these tools via our [AV1 for Dummies Discord server](https://discord.gg/bbQD5MjDr3). We're happy to help you with anything you need, and your questions and feedback help the wiki grow and improve. We hope you enjoy your journey into AV1 encoding, and we wish you the best of luck in your encoding endeavors! --- # Codec Wiki: One Year Later Canonical URL: https://encode.wiki/articles/codec-wiki-one-year-later/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: b2ab5aac761f4b7d7526e6323e00c496cb6915d75c3537c21bec402423e1f45a > **Historical community report.** This July 2024 article describes the original Codec Wiki project and its then-current analytics and screenshots. Those visitor totals, hosting locations, tools, and community observations are historical author reports, not measurements of today's Encode Wiki. The original data was not re-audited in October 2026. See the [current privacy notice](/reference/privacy/) for this site's analytics and separate Ask preview. Around a month ago, Codec Wiki celebrates it's very first anniversary as it officially hits one year old (Wow, that's a very long time!). First and foremost, I apologize for this delayed celebration post, I have been very busy for the past month, y'know, real life things. Second of all, I would like to say **THANK YOU** for everyone who helped build this wiki from the ground up and writing down the entries, you know who you are! ## Stats Thanks to everyone's efforts, over the course of 12 months Codec Wiki has grown into the (almost) go-to documentation and guide for newcomers just starting out in the quirky and wild world of multimedia encoding. So here are some pretty graphs to look at our progress so far! ### Plausible As you may know, we ran our own Plausible Analytics instance: self-hosted, open source, and privacy-respecting analytics. It was hosted in Singapore and its former public dashboard is no longer available. Plausible Analytics 7.7K unique total visitors for a whole year may not be much but it's a great start! Let's not forget those who use uBlock Origin or similar to block the analytics script. So the visitor count could be two or three times more! ### Google Search Console For those who are unfamiliar, Google Search Console is used for viewing well.. Google search data for your website. This data is unfortunately private and only the owner and those invited can see the data, no setting available for public view. Probably for the better. Google Search Console



And for our top 10 search queries in the last 28 days: Search Queries page 1 Search Queries page 2



With pretty much zero competition in this niche of a market, it skyrocketed Codec Wiki to the top of search results for everything multimedia related 😅. ## A Brief History Around a year ago, I started work on an unofficial "wiki" for all things encoding, it initially started as a half-serious joke because I was annoyed there were no good documentation available anywhere on the internet on the real application and usage of encoders such as "Should I use tune SSIM in x encoder?". With the search results you'll be presented with being one or more of these: - Doesn't exist. - Mentioned in the FFmpeg mailing list but nothing else. - PDF research papers on IEEE and similar. - Outdated information on Doom9 or Multimedia Wiki. - "The documentation are in the code blocks". - Link rot. - Abandoned, or mostly focused on other topics. - Focused on a specific type of storytelling medium. - Actual good explanation in an old forgotten site (rare). Some or maybe even most of these results still appear up to this day. Frustrated with how scarce information is available on the open internet and combined with the fact that most, if not all of them only exist in non-search-engine-reachable private chat communities such as Discord where you'll have to join and scroll around older conversations. Prone to data erasure as Discord can nuke these servers for whatever reason they please and years of "documentation" is lost in an instant. It is simply not a good platform for a plethora of valuable information. **That's why I took initiative.** ## Bumps in the Road There were also generally a lot of distrust and pushbacks when this project first began, particularly from those who are more experienced with encoding. Which is understandable because everyone who attempted before burned out and never finished it. But Codec Wiki stood the test of time with constant updates through active collaboration of everyone involved, nowadays those voices have mostly subsided or even joined the project themselves. And I am grateful for that. ## Closing Statement Once again, **THANK YOU VERY MUCH** for those who are involved in this project and making the once pipe dream of a one-stop-shop user-friendly documentation for encoding into something that's possible. Let's continue documenting the most crucial yet invisible driving force of internet traffic, pages by pages. Together we are strong, divided we burn out.

> "There are times when a critic truly risks something, and that is the discovery and defense of the *new*. **The world is often unkind to new talent, new creations. The new needs friends**." > > — Anton Ego --- # Embedding the Un-Embeddable Canonical URL: https://encode.wiki/articles/embedding-the-un-embeddable/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: d70fad5878acabe812f59ad29f4626c7226752febfdf33fdc2affcf9a068689a > **Historical Discord behavior, reviewed October 4, 2026.** This article records observations from October 2023. Its helper-site list, account limits, caching, and playback behavior were not retested for current Discord clients or services. [Open Graph](https://ogp.me/) defines metadata such as video URLs and MIME types; it does not guarantee that a platform will fetch, allow, or decode that video. Client codecs, server policy, authentication, and helper availability still matter. Use the [Discord encoding guide](/tools/utilities/discord/) for the wiki's current compatibility guidance. ![Feature image](/img/discord-embed-blog-image.webp) **A 567.14 MB, 12 min 11 s, 2K (2,048 x 858), VP9 + Opus, 6.51 Mbps average, Blender short film "Cosmos Laundromat"** ## A Scenario While chatting in your favorite Discord servers & group chats, you may see a friend send a weird link. You might even consider it suspicious on first glance. It is a video featuring an image of a movie poster with a play button that is almost begging to be clicked. Naturally, you click it. It loads for a second, and to your surprise it is a full-length, 90-minute (sometimes even two hour)-long unauthorized copy of a movie. If you don't know exactly what is going on, you probably sit there dumbfounded as a pixel perfect HD movie plays back. You may have expected a stereotypically muddy, blocky, laggy shitpost, but this has defied your expectations. ![stolen.shoes](/img/stolenshoes-puss.webp) The truth is, there are *multiple* site that do this. Currently, there are five at the time of writing. Below is a list the ones I am currently familiar with: - https://stolen.shoes - https://discord.nfp.is - https://embeds.video - https://x266.mov/discord-embed - https://autocompressor.net/av1 The big question is, **how do they work?** Let's get to dissecting. ## But First, a Quick Disclosure The Codec Wiki unequivocally condemns any form of piracy, including the unauthorized distribution of copyrighted content. This blog post is intended to educate & inform. You may not use the tools discussed to infringe upon the intellectual property rights of content creators without serious legal risk. We encourage our readers to respect copyright laws & use the tools we discuss here appropriately. ## How it Works The entire scheme is actually very simple, as it is all just HTML meta tags (If you are familiar with web development, this is all a walk in the park). The technology's inner working can be divided into two distinct parts. First, let's see how it works on the website's end. ### The Website's End If you view each website's source, you will find this specific line in each one but they may have a different order: ```html ``` These are the `head` parts of HTML, which dictate metadata for the document itself such as what the website title/name is, cosmetic embed, defining the site's icon, etc. They are usually found in between the `` and `` tags. Here's an example of a static HTML site serving one specific video: ```html some embed site

Hi

Just your friendly neighborhood video embed site

``` < br /> These interactive sites usually deploy a live script, like a Javascript framework. Examples are NodeJS, ExpressJS, Svelte, etc. These are used to parse video and thumbnails realtime so they can be embedded on Discord (or potentially other platforms). ### Discord's End Traditionally, Discord's media embedder will impose it's own video embed size limit (50 MiB) when a user sends a direct video link as usual. But in this case Discord will embed the thumbnail first, not the video. You could say the link "tricks" Discord by showing a "false face" first. ## Strengths & Limitations After a combination of countless hours of observation, rigorous testing throughout the period of a year, and conversations with the sites' creators, the current strengths & limitations of this exploit are enumerated below. #### Strengths - You can embed non-web compatible codecs such as [HEVC](/codecs/video/hevc/) in [MP4/MOV](/start-here/terminology/#mp4--m4v), but the user must be using a compatible browser. [Thorium](https://thorium.rocks) or Safari version 13 or greater will work for HEVC playback. - There is no maximum size. You could embed a video the size of a raw Bluray, although I do not condone this unless you have the necessary legal permissions to do so or you're uploading a Creative Commons licensed movie like Big Buck Bunny while adhering to the restrictions of the applicable Creative Commons license. This also means you can send high bitrate gaming clips to your friends without any restrictions, assuming you already have a place to upload them. #### Limitations - You can only use [hotlinks](https://simple.wikipedia.org/wiki/Hotlinking), which means direct linking to the video itself ending in the appropriate file extension such as `.mp4`. Cloud services like Google Drive or OneDrive will not work for storage. - You cannot use Discord's CDN (cdn.discordapp.com) as the video source. I assume this is because of Discord's proxy blocking embeds over 50 MiB, but **only discord.nfp.is can do this**, as it **proxies cdn.discordapp.com** itself. - You cannot embed videos in any resolutions higher than 3840 x 2160, Discord imposes a hard limit for this on all video after it was discovered that some videos could play normally but then be maliciously scaled to ridiculous resolutions during playback to crash Discord. ## Differences between Sites As mentioned before, there are five known sites at the time of writing. They all serve the same function, but one may interest you more than another due to slight differences in features & functionality. Here are the sites, each with one noteworthy special benefit: - https://stolen.shoes - Recognition, as it is the OG. - https://discord.nfp.is - You can use Discord CDN as video source. - https://embeds.video - Immediately input video source into the URL (`https://embeds.video/https://example.com/v/video.mp4`) - https://x266.mov/discord-embed - Attractive domain, simple layout. - https://autocompressor.net/av1 - Lots of info dump, pretty advanced features. That concludes the technical overview! Next, let's cover the history of this exploit. ## The Lore ### Dwayne In around April of 2022, a Reddit user going by the name of u/CreativeGamer03 [posted a video on r/discordapp](https://www.reddit.com/r/discordapp/comments/u96kky/someone_sent_this_in_the_memes_channel_and_bruh) of a link where a GIF of Dwayne "The Rock" Johnson plays caption with "Is this a GIF or is it a video?" When played, a low-quality music video of Rick Astley's "Never Gonna Give You Up" plays. The link used, `archuser.de/the-rock`, has since been removed. ### Discovery On 23rd June 2022, a Discord user *Clybius* on the AV1 Community server asked people for [VP9](/codecs/video/vp9/) or [H.264](/codecs/video/avc/) videos that were over 100 MB in size. At the time the current 500 MB nitro tier did not exist. They then decided to use a 59 minute 1080p sample video of nature scenery from around the world with a thumbnail featuring a GIF of a waterfall to test the exploit. It worked. He tried shortly afterward with [AV1](/codecs/video/av1/). Eureka, it also worked: ![AV1](/img/clybius-av1.webp) Clybius confirmed that this could be patched if discovered. He cites having had the idea from the Dwayne Johnson example above, but forgetting about it for a couple of months. So, it seems this entire concept stemmed from a silly rickroll. ![Dwayne](/img/clybius-dwayne.webp) ### The Experiments & Interactive Site After the discovery of AV1 embedding, experimentation brought about the discovery that *any* video codec will work as long as the user can decode/play the codec and the container/extension is an MP4, MOV, or WebM. These are all traditionally web-compatible containers. If you're interested in learning about containers, please see the [Containers](/start-here/terminology/#container) section on the [Terminology](/start-here/terminology/) page. This applies to HEVC, ProRes, [xHE-AAC](/codecs/audio/aac/#xhe-aac), and other bizarre codecs that are rarely seen on the Web. While experimentating, Clybius converted one their idle domains `stolen.shoes` into an interactive embedder that provided a textbox for a video URL, a thumbnail URL, a width value, & a height value for the desired video. This would be the first website for Discord embedding. ### Virality It's not long before people outside of the AV1 Community discovered `stolen.shoes`, and its popularity increased rapidly. Its use usually involved the illicit distribution of full-length, unauthorized copies of movies; this sometimes happened very shortly after some movies were released. There were a couple notable instances of this happenening that caused quite the stir online each time. - The first instance featured the DreamWorks sequel of "Puss in Boots (2011)", "Puss in Boots: The Last Wish (2022)". A 1080p video sourced from a streaming site was the first wake up call that attracted attention to the existence of these embed sites. This example used `stolen.shoes`. ![puss](/img/stolenshoes-puss.webp) - The second instance was when highly-anticipated animated film "The Super Mario Bros. Movie (2023)" produced by Illumination, Universal Studios, and Nintendo was spread around Discord. It was first spotted as a Cam (A camera recording by someone in theaters), then as it went out on streaming services a different link appeared but spread faster and with upgraded 1080p quality. Both used `stolen.shoes` as the embed site. ![mario](/img/stolenshoes-mario.webp) - The third instance is very recent as of the day this was posted. A streaming-service sourced "Five Nights at Freddy's (2023)" was spread around since the movie released both in theaters and streaming service (Peacock) day one, and it gained steam extremely fast as most people had not seen it yet. Currently, this illegal novelty is gaining [hundreds of upvotes within the r/discordapp subreddit](https://www.reddit.com/r/discordapp/comments/17hx45y/is_discordnfp_an_ip_grabber/). The copy seems to be a compressed 720p encode. This example used `discord.nfp.is`. ![fnaf](/img/discordnfpis-fnaf.webp) Note the ones listed here are the ones that I saw become extremely popular. There may be lesser known links that have been spread around privately or just did not cause enough noise for me to notice. Some less popular examples I've noticed, featuring more illicit copyrighted content distribution: - Top Gun Maverick (2022) - The SpongeBob trilogy (2005/2015/2020) - Spider-Man: Across the Spider-Verse (2023) ## Closing The ability to embed unusually large videos on Discord has enabled both positive and negative use cases. On the one hand, it allows high-quality content to be shared easily among friends. However, it has also facilitated mass copyright infringement by empowering virtually anyone with a Discord accound to freely spread pirated movies. While this is fascinating from a technical perspective, embedding techniques like these tread a fine ethical line. As with anything, it is important to be mindful of how our actions affect others, and I should remind everyone that content creators deserve to be compensated for their work. As users, we should support them by accessing their content via legitimate platforms. It is hard to say how long this exploit will continue to be usable. Instead of enabling piracy, which may cause Discord to be more likely to patch this exploit if they see it as a serious threat, let's instead use these capabilities responsibly to share our own creations, gaming highlights, and other media which we can share legally. Given some thoughtfulness, perhaps we can find a fair balance between respecting copyright law and appeasing Discord's sensibilities while allowing some creative flexibility on the platform. Thank you for reading this blog post, I hope you learned something! --- # Reducing Image Load Online Canonical URL: https://encode.wiki/articles/site-optimization/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: 9bd28d034343f75ee6c21bb82f2062b539e467903a292ffdfe243a5f08fce753 > **Note — Editorial correction — 7 September 2026.** > > The author's image files, scores, sizes, and timings below are preserved as historical observations; no encodes were rerun for this correction. Delivery advice and format claims have been corrected in place. This one-photograph comparison cannot rank formats for all images or encoder versions. A big part of understanding any multimedia codec technology is knowing the application for such technology. For images, a big use case is web delivery. Compared to other multimedia, images are incredibly popular on the Web & knowing how to serve them properly can be a massive boon to your website's traffic as well as less of a headache for users on slower connections or who are under bandwidth constraints. The most disappointing part is that images are often poorly done on the web; all too frequently will you run into a site serving massive photographic PNGs for no reason, or photography sites serving photographs fresh out of the editing software with no thought put into their final delivery. A little effort, patience, & knowledge will go a long way toward improving the user experience for individuals using your site, & this article will illustrate some of the basics. > **Caution.** > > These instructions are for *photographic* images; other kinds of images, like non-photographic, artwork, pixel art, etc. should likely be handled differently. > **Caution — Viewing the historical samples.** > > Some samples require JPEG XL or AVIF decoding and correct ICC color management. Support depends on the browser build and configuration; the original browser list was not a continuing compatibility guarantee. Use the JPEG examples when a format does not display, and test [current image-format guidance](/codecs/images/) on your actual targets. ## Fire & Forget First, we'll illustrate what *not* to do, which is fortunately not incredibly difficult to avoid. Taking an image straight out of your editing software at a massive size will often bloat the size & resolution to something that isn't generally usable for a website regardless of the codec you're using & its quality per bit. It can be argued there are specific use cases that demand incredible resolution & fidelity coexist on the Web, but we won't be covering those here. Here's an example of a bloated image: *exported straight from Darktable at JPEG q90, with no scaling* ![bloated_jpeg](/img/_DSC8466.jpg) **2.2 MB** ## Massive Improvement Reducing unnecessary image dimensions can substantially cut transfer size. Choose source dimensions using both the displayed CSS size and device pixel ratio, and provide responsive candidates for different layouts. A 2× display can need about twice the CSS width in source pixels. Resizing may hide some artifacts but does not recover information lost in a previous JPEG export; resize from the best source available. [HTML responsive images](https://html.spec.whatwg.org/multipage/images.html). ![box-size-mac](/img/box-size-mac.avif) *Inspect Element in Firefox. The Mac used to take this screenshot has a relatively high display resolution of 2560x1664. Because Macs scale things differently, we're probably going to want to double the horizontal resolution here.* The width is the most important value here, so our new image is going to be exported with a width of 1699 pixels. This new image, encoded at JPEG q90 with `cjpegli`, looks like this: ![smaller_jpeg](/img/_DSC8466-smaller.jpg) Obviously, there's lost fidelity compared to the original, but considering this is *so much smaller*, it is worth the trade-off for many. It is also worth noting we are using an improved jpeg encoder in the form of `cjpegli`, although that is secondary to the resize. If it doesn't look as good as you want it to, you can always scale the resolution up a bit, though currently, it looks plenty passable for its size. 2.2 MB -> **233 kB** > **Chart — Page-weight reduction in the article example.** Resizing and re-encoding reduces the example image to roughly one tenth of its original transfer size. Data: Original: 2200 kB; Optimized: 233 kB. ### Lazy Loading Add `loading="lazy"` to the **img** element, including when it is inside **picture**, for images below the initial viewport. It defers fetching until the browser's loading threshold is approached, and **can save bandwidth if the visitor never approaches the image**. It does not reduce the size of an image that is eventually fetched. Avoid lazy loading a prominent image needed for the initial view. [HTML lazy-loading behavior](https://html.spec.whatwg.org/multipage/urls-and-fetching.html#lazy-loading-attributes). ```html alt text ``` ## New Codecs This historical experiment compares JPEG, AVIF, and JPEG XL encodes of one photograph. It does not test WebP or HEIC, so it cannot establish that WebP loses to JPEG, that HEIC has been superseded in every application, or that JPEG XL and AVIF always compress better. Encoding time, fidelity target, alpha, bit depth, color management, and decoder support all matter. Compare representative images with current implementations; see [AVIF](/codecs/images/avif/), [JPEG XL](/codecs/images/jxl/), and [WebP](/codecs/images/webp/). WebP supports both lossy and lossless coding, with different capabilities. [WebP specification](https://www.rfc-editor.org/rfc/rfc9649.html). ### Fallbacks Provide an image the target browser can decode. A `picture` element can offer several formats with a JPEG fallback; the browser selects a supported source according to source order and its selection rules. Support is not a prediction about a format's future adoption. [HTML image selection](https://html.spec.whatwg.org/multipage/images.html). For example: ```html alt text ``` Here the browser can select JPEG XL, AVIF, WebP, or the JPEG fallback in that order. Each extra variant adds encoding and storage work; include formats whose measured savings and target support justify maintaining them. ### Compression Efficacy The following preserved commands document the author's historical encodes, not current CLI recipes; current options are covered in the linked format guides. Let's look at how those image examples compare to the original. We'll be aiming for high visual fidelity, so around the same quality as our initial JPEG encoded with `cjpegli` (which scores ~`83.01` with the [SSIMULACRA2](/reference/metrics/ssimulacra2/) visual fidelity metric). ![smaller_jxl](/img/_DSC8466-smaller.jxl) **137.0 kB** *JPEG-XL image, encoded with `cjxl lossless.png out.jxl -d 1.49 -e 9`. Score: ~`83.04`* *3.06s user time* ![smaller_avif](/img/_DSC8466-smaller.avif) **124.8 kB** *AVIF image, encoded with `avifenc -c aom -s 4 -j 8 -d 10 -y 444 --min 1 --max 63 -a end-usage=q -a cq-level=16 -a tune=ssim lossless.png out.avif`. Score: ~`83.03`* *7.54s user time* JPEG XL can preserve an existing JPEG's coding information so that the original JPEG file can be reconstructed byte-for-byte when reconstruction data is retained. This is distinct from encoding decoded pixels losslessly. The score mismatch reported below is unresolved: it could involve differing decode or color-conversion paths and is not evidence of improved fidelity. Verify reconstruction by decoding back to JPEG and comparing file hashes; do not infer correctness from close metric scores. [cjxl documentation](https://github.com/libjxl/libjxl/blob/main/doc/man/cjxl.txt). ![smaller_jxl_jpeg-recomp](/img/_DSC8466-smaller-recomp.jxl) **189.4 kB** *JPEG-XL image from JPEG, encoded with `cjxl input.jpg input-recomp.jxl -d 0.0 -e 9 --brotli_effort=11`. Score: ~`84.92` (???)* *0.67s user time* The author's XYB JPEG example uses jpegli's `--xyb` mode and its associated ICC profile. Displaying the intended colors requires correct profile handling; decoders that ignore the profile can show incorrect colors. This is not universal display compatibility, and the size/quality result below applies to this sample. [jpegli documentation](https://github.com/google/jpegli). ![smaller_jpeg_xyb](/img/_DSC8466-smaller-xyb.jpg) **208.3 kB** *XYB JPEG, encoded with `cjpegli lossless.png out.jpg --xyb -d 1.155`. Score: ~`83.04`* *0.10s user time* At the author's approximately matched SSIMULACRA2 scores, this AVIF file was smaller than the tested JPEG XL and JPEG files. That supports a result for this image and these settings, not a general ranking or identical perceived quality. The input was 16-bit PNG, but a lossy output accepting that precision does not preserve all original sample information. The reported encoding times are observations from this run. ## Responsive Images Displaying an image that is too large for a viewport is a waste of bandwidth, & displaying an image that's too small for the viewport leaves fidelity to be desired. Luckily, we have the [Responsive Image Linter](https://ausi.github.io/respimagelint/) that can help us figure out which image sizes we should be using. ![responsive_image_linter](/img/responsive_image_linter.avif) In our fire & forget example, we see that we are serving an image that is far too large. We already know that, but now we can see that given various viewport sizes we could be serving images that have respective widths of 270px, 958px, 1350px, 1660px, & 1916px to optimize for delivery to a variety of different devices. Here's how we'd write that in HTML: ```html alt text ``` It is worth noting that this example above & the example below aren't perfect implementations of a responsive image given the conditions of this site, but the general concept still applies. Some things to note: - `srcset` = the images available to your browser to serve, & their respective widths - `sizes` = the conditions given to the browser explaining under what conditions should it serve which image - `(min-width: XXXpx) YYYpx` describes an image slot of YYY CSS pixels when that viewport condition matches. The browser uses the slot size, device pixel ratio, and its selection policy to choose a candidate; it is not an instruction to fetch an exact pixel width. - `calc(100vw - 24px)` = Usually preceded by a (min-width) condition. Specifies a value the browser should calculate on its own to pick the closest option from the srcset. Let's say we have `(min-width: 997px) calc(75vw - 257px)`. This means given the viewport is at least 997px wide, calculate 0.75 \* the current viewport resolution - 257 to find the closest image in the srcset to fit the number of pixel specified. alt text That's all! Massive thanks to Auto-Rez Media Technologies for the inspiration behind this article & explicit permission to use their [Reduce Your Page's Image Load](https://autocompressor.net/blog/reduce-image-load) blog post when writing this entry. I have [confirmed](https://autumn.revolt.chat/attachments/GtFGuwNfeRdcwUN0MWzhDCAiiadWOk88XXC3pQv6RI) with their leadership that this wiki entry can be safely licensed under CC BY-SA 4.0. --- # Encoding Animation with SVT-AV1: A Deep Dive Canonical URL: https://encode.wiki/articles/svt-av1-deep-dive/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: 31e634c5d9f18313946a0ca9c585252b999f5e8853e91b9362b560a9356908b6 # Introduction > **Historical benchmark, reviewed October 4, 2026.** These are the author's December 2023 results for **SVT-AV1 1.8.0**, the listed anime clips, and the stated hardware. The preserved charts were not regenerated. Defaults, parameter availability, and conclusions must not be applied unchanged to current SVT-AV1 or its forks; use the [current encoder reference](/tools/software-encoders/svt-av1/) and test your own content. The linked [Zig VapourSynth metric plugin](https://github.com/dnjulek/vapoursynth-ssimulacra2) is now archived and points to a successor; that does not change which implementation the original experiment reports using. This blog post is based on a series of visual quality benchmarks with SSIMULACRA2 and speed benchmarks of SVT-AV1 1.8.0 on a corpus of animated clips. The resources available will range from ***graphs*** to ~~**image comparisons**~~ (WIP). The ***former*** has the advantage of being easily understandable, showcasing pure efficiency comparisons between encoder parameters using metrics as the reference, while the **latter** are image samples from the encoded files during the tests that enable you to check quality for yourself and add another layer of subjective interpretation to these comparisons. The testing methodology involves using relatively short video samples from a wide range of modern anime genre, which have been either losslessly encoded with `x264 --qp 0` for ease of use or losslessly cut from their source. These lossless files are then pipped into SvtAv1EncApp *directly*, meaning we are measuring the performance of a single encoder instance and not using chunked encoding; chunking is a separate throughput choice with scene-boundary, resource, and rate-control trade-offs. Once an encode is done, SSIMULACRA2 scores are calculated using the [Zig implementation](https://github.com/dnjulek/vapoursynth-ssimulacra2) and lots of useful data are aggregated to make the graphs for this benchmark, including encoding time, encode size (bitrate), and SSIMULACRA2 scores. Bits per pixel scores (BPP) are calculated so that the `Metric / BPP` graphs may represent the closest we have to real efficiency. The clips used in this test were acquired legally. The Codec Wiki and its contributors do not endorse media piracy. SvtAv1EncApp was compiled directly from the [v1.8.0 source code](https://gitlab.com/AOMediaCodec/SVT-AV1/-/releases/v1.8.0) using the provided `Build/linux/build.sh` script, Clang 16.0.6, and Profile-Guided Optimization (PGO). The testing machine is comprised of an i7 8750H running at 35W with 16GB of 2666MHz DDR4 RAM in Arch Linux with kernel 6.6.6 and the performance governor enabled. All encodes have been made in the same session without rebooting. This testing was conducted within the [AV1 Weeb Edition](https://discord.gg/83dRFDFDp7) Discord server, which is focused on encoding animated content in AV1. ## Samples The samples are as follows: - 11s `Blame!` clip which sports 3DCG action with lots of grain, effects and high-contrast elements. Most complex source of this set. - 13s `Blue Lock` clip which sports rapid camera movements and rotations + high-contrast elements. - 15s `Fate/Grand Order: Babylonia` relatively slow-paced clip with lots of effects still. Easiest source of this set but easy sources still give interesting data. - 22s `Jigokuraku (Hell's Paradise)` flashback clip with huge static grain in a very dark scenery and some action. - 14s `Kaguya-sama` opening sequence with lots of effects and fast change of scenery. The resolution of every clip is 1080p, except for the first one which is 1920x804. > **All clips have been encoded in a wide quality range, from `--crf 8` to `--crf 43`.** Without further ado, let's start with the first comparisons! ## Presets comparisons (-1 -> 13) **In the following graphs, you may find comparisons between all SVT-AV1 presets, ranging from the slowest `--preset -1` to the fastest `--preset 13`.** *Please remember that these two extreme presets are meant for development purposes and as such should not be used in normal encoding conditions. You will soon understand why.* `--preset X` is the only parameter used here, in conjunction with the CRF values. That means everything else is default. The defaults worth mentioning are: - `--tune 1`: tune PSNR - `--aq-mode 2`: variance deltaq - `--enable-qm 0`: quantisation matrices disabled - `--irefresh-type 2`: closed GOP - `--enable-tf 1`: temporal filtering enabled And more, like CDEF and restoration enabled, overlays and film-grain disabled... - First of all, here are the efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). This could be too much information. - Now the same graphs but focusing on the "high quality" range (CRF8 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Same again but without presets 9 to 13 for better clarity: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Now for the "low quality" range (CRF28 -> 43): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Same but without presets 9 to 13 for better clarity: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - **Let's now see speed comparisons between all presets:** ![speed_overall](/media/content/8dad638d0e20a9e4-speed_overall.webp) As we can see, preset -1 is so abysmally slow it makes the graph unusable (BTW, notice the `1e6` in the lower right corner, it is obviously not encoding at 1 to 4 ms, but at 1 000 000 to 4 000 000 ms) - Here is what it looks like with a logarithmic scale: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - **Now the speed graphs but with SSIMU2 on the y-axis instead of BPP: (logarithmic scale)** > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Here are speeds graphs for preset 1 to 6 with a linear scale: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). One interpretation we can have is that **presets 2 to 4** have actually pretty close scores (pretty much the same at HQ, 2 points at max in the low quality range) but **preset 2** is **2x slower than preset 4**. The quality gap between **preset 2** and **preset 1** is even narrower but the speed penalty is also ~2x. That makes it hard to recommend **preset 1**, while **preset 3** is in a strange middle ground between **2** and **4** where it makes little sense to choose it over those two: it's better to choose **preset 2** for the higher efficiency at 1.5x slower speeds, or **preset 4** for the 1.33 to 1.5x higher speeds. At least the option exists. A similar observation can be made between **preset 5** and **6**. They can be so close in scores in many samples (especially at HQ) while also being close in speeds that **preset 5** becomes rather obsolete most of the time. ### TLDR **Clear quality gains can be observed as we decrease presets, until the very last one, however the effectiveness of dropping presets becomes less and less impressive the higher in quality you go.** - For instance, in worst-case scenario, we observe that (for the CRF23 to CRF8 range), __**preset 4**__ only loses at maximum **2** SSIMU2 **points** compared to __**preset -1**__ while being 50-60x faster. Though to be fair, the speed loss from __**preset 4**__ to __**preset 0**__ is "only" 5-10x for a maximum SSIMU2 difference close to **1.5 point**. - From CRF43 to CRF28, the difference between __**preset 4**__ and __**preset -1**__ can be as much as **5** SSIMU2 **points**, so lower presets become more attractive. ## Tunes comparisons **In the following graphs, you may find comparisons between SVT-AV1 tunes, from the default `--tune 1` (PSNR) to the other two tunes: `--tune 0` (VQ) and `--tune 2` (SSIM).** Except for the tunes, `--preset 4` is set due to its good balance of quality and speed, in conjunction with the CRF values. That means everything else is default. The defaults have been mentioned earlier above. - **Let's compare the efficiency of every tunes:** > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Now let's focus on the "high quality" range (CRF8 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - And the "low quality" range (CRF28 -> 43): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - And here is the speed difference: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Graphs comparing the tunes individually between each others will be made available soon. - The image comparisons will make the conclusion quite more nuanced, stay tuned (heheh) for that. ### TLDR **SSIMU2 favors __tune 1 and 2__ above __tune 0__. At high quality, __tune 1 and 2__ are matched, while at low quality __tune 2__ takes the edge. __Tune 0__ is sometimes a match for the other two on certain clips and other times fare pretty badly.** **For some reason, __tune 0__ is quite a bit faster now, compared to 1 and 2 which are basically the same.** Keep in mind that I have observed multiple times in the past that __tune 0__ kept more fine detail and was sharper than the other tunes, at the expense of potential artifacting, like ringing and distortion. It may very well explain why the metric doesn't like its results. The image comparisons may give a different interpretation than what we concluded here, please stay *tuned* for these subjective comparisons. ## Parameters comparisons **In the following graphs, you may find comparisons between many SVT-AV1 parameters.** *Additional graphs focusing on the high and low qualities will be made available later down the line* `--preset 4` is used here due to its good balance of quality and speed, in conjunction with the CRF values. That means everything else is default. The defaults have been mentioned earlier above. ### `--tile-rows 1 --tile-columns 1` vs default `--tile-rows 0 --tile-columns 0` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > __tiles__ here are both slightly harmful and slower. ### `--aq-mode 0` vs default `--aq-mode 2` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > Except for the Jigokuraku clip, __aq-mode 0__ is harmful in the eyes of SSIMU2, while being slower at low CRF levels, and sometimes a match or faster at high CRF levels. ### `--aq-mode 1` vs default `--aq-mode 2` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > __aq-mode 1__ fares closer to __aq-mode 2__ than __aq-mode 0__ did, both in quality and speed, but is still overall inferior according to SSIMU2 ### `--enable-cdef 0` vs default `--enable-cdef 1` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > According to SSIMU2, disabling CDEF barely impact efficiency. But as its a pretty demanding tool, there's a slight speed benefit of having it disabled too. I advise you to take these results with a grain of salt until the image comparisons, because in anime particularly, CDEF *can* be beneficial for the line-art. ### `--enable-dg 0` vs default `--enable-dg 1` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > __Dynamic GoP control__ yields bit-perfect results in all clips except for Blue Lock and Jigokuraku. There is no speed benefit to disabling it except in clips where it is in use. Let's not jump to conclusions too easily, the image comparisons will tell if it's "safe" to keep the setting disabled at all times or not. ### `--enable-dlf 0` vs default `--enable-dlf 1` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > In these tested clips, the __deblocking loop filter__ was sometimes slightly beneficial and no harmful result was observed. This limited corpus does not establish that it can never hurt another source. ### `--fast-decode 1` vs default `--fast-decode 0` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > __fast-decode 1__ is pretty harmful in the Fate clip and slightly harmful in the rest. There is a speed benefit of enabling it though. ### `--irefresh-type 1` vs default `--irefresh-type 2` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > Finally something interesting to analyse! - __irefresh-type 1__ is either a match or beneficial compared to __irefresh-type 2__ at high CRF levels. - __irefresh-type 1__ either wins or lose to __irefresh-type 2__ at low CRF levels depending on the clip. As such, it is NOT recommended to blindly set __irefresh-type__ to __1__ at "high quality" as it might be harmful depending on the content. - __irefresh-type 1__ is always slower compared to __irefresh-type 2__, so I might argue it is more safe to leave __irefresh-type__ default at "high quality" than not. - According to the content type of those clips, it appears that __irefresh-type 1__ may benefit *extremely grainy* content while default __irefresh-type 2__ is better suited for *cleanish* content. This needs to be confirmed with *moar* testing though. ### `--lookahead 0` vs default `--lookahead -1` (auto) - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). ### `--lookahead 60` vs default `--lookahead -1` (auto) - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). ### `--lookahead 120` (max) vs default `--lookahead -1` (auto) - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > __lookahead__ seems to behave strangely when set... - __lookahead 0__ shifts quality around a lot and it is difficult to draw conclusions but there's a clear speed drawback of disabling lookahead. - __lookahead 60__ is perfectly bit-perfect to every clips EXCEPT for some damn reason in Jigokuraku at CRF23 - __lookahead 120__ is somehow also bit-perfect, but this time in every clips and every CRF levels. Both 60 and 120 don't see much speed differences. > Soooo.... this behavior is so odd I don't advise to set any lookahead value. Let the encoder decide. ### `--enable-overlays 1` vs default `--enable-overlays 0` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > __overlays__ do not seem to either improve efficiency or performance. ### `--enable-qm 1` vs default `--enable-qm 0` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > Enabling __quantization matrices__ alone increase efficiency at "high quality" with no real speed impact. ### `--enable-qm 1 --qm-min 0` vs `--enable-qm 1` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > Setting __qm-min__ to __0__ on top of enabling __quantization matrices__ can be beneficial in some clips at no added compute time. I will re-tests many QMs ranges in the future, but I doubt it changed much from v1.7.0 where 0 was the most appropriate choice for most content. ### `--enable-restoration 0` vs default `--enable-restoration 1` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > Even though the efficiencies are very similar, nothing is bit-perfect here. So according to SSIMU2, the __loop restoration filter__ isn't necessarily useful. However, just like CDEF, it's a pretty demanding tool, so disabling it yields some performance improvements. Let's take these with a grain of salt until the image comparisons. ### `--scm 0` vs default `--scm 2` (content adaptive) In all the clips, the results are bit-perfect and there is no notable performance difference. ### `--scm 1` vs default `--scm 2` (content adaptive) - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > Interestingly enough, __screen content tools__ seem to improve efficiency according to SSIMU2, at the cost of a huge performance regression. After the image comparisons are published, I will conduct additional testing on this. ### `--enable-tf 0` vs default `--enable-tf 1` - Efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-deep-dive.json). > Disabled __temporal filtering__ *can* sometimes improve efficiency slightly at "high quality", however it is very much clip dependent. It also improves performance slightly. The image comparisons will give another perspective to these results. ### `--enable-tpl-la 0` vs default `--enable-tpl-la 1` In all the clips, the results are bit-perfect and there is no notable performance difference. ### `superres`: Kinda lazy to make, share and comment so much graphs for something that can be told in two lines... All superres variants are freaking useless as they: - do not improve efficiency - decrease encoding speeds - decrease decoding speeds when either bitrate or quality normalized. ### __Early TLDR on parameters results:__ ***For a previous test with SVT-AV1 1.7.0 I did all parameters tests with `--preset 6 --tune 2`, now I did them with `--preset 4 --tune 1`. Mostly everything tested on v1.7.0 still stands today, but now we have more valuable data. Images comparisons are still needed to give more context to some results, so the conclusion presented here remains early as they are 100% based on SSIMU2 results and will require more analysis down the line.*** **Here is a quick run down of how each parameter affect encoding:** - In these SVT-AV1 1.8.0 tests, `--tile-rows` / `--tile-columns` reduced the measured trade-off. Tiles can serve parallelism or delivery requirements; choose them for the actual encoder, decoder, and content rather than treating this corpus as a universal prohibition. - `--aq-mode 2` is the most efficient / fastest - `--enable-cdef 0` *might* improve performance at almost no efficiency loss *(needs more thorough testing)* - `--enable-dg` and `--enable-dlf` barely do anything - `--fast-decode 1` decreases efficiency, improves encoding times, and the decoding gains still need to be determined. - `--irefresh-type` should be kept default at high CRF values and for cleanish content at low CRF values, but can be set to 1 at low CRF values for extremely grainy content - `--lookahead` should be kept default - `--enable-overlays 1` does not improve efficiency, slight speed regression as well - `--enable-qm 1 --qm-min 0` should be set for increased efficiency especially at low CRF values at no perf cost - `--enable-restoration` barely does anything but disabling yields better performance *(needs visual confirmation)* - `--scm 1` screen content tools can improve efficiency with a big performance trade-off *(needs more thorough testing)* - `--enable-tf 0` is a mixed bag efficiency wise but improves performance - `superres & resize` please don't. ## Conclusion The extensive benchmarking reveals that obviously the slower presets provide better efficiency, with diminishing returns past preset 2. However, preset 4 provides a good balance of quality and speed for most use cases. Presets 6 and 8 are good options for the people that find 4 to be too slow for their liking. The default settings tend to provide good results, but some tweaks like enabling quantization matrices can further optimize efficiency. Parameters like tile encoding and super resolution modes are not beneficial. Overall, SVT-AV1 continues to be a competitive option for encoding animation in AV1, with its speed being a notable strength. Further testing with more content samples would help solidify these findings. The image comparisons will also provide additional subjective evaluation to complement the objective metrics used here, and we can discover the potential usefulness of Tune 0 that may betray what the metrics suggest. Overall, this comprehensive deep dive should give encoders a helpful starting point for choosing settings when encoding animation with the tested SVT-AV1 1.8.0. Thanks for reading! {} --- # Deep Dive into SVT-AV1's Evolution (Part 1): Presets Analysis from v2.0 to v3.0 Canonical URL: https://encode.wiki/articles/svt-av1-fourth-deep-dive-p1/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: 8166bc983f698ef6e73b64c53b0a53159483fb976e365db0e10e1a030d93c5d6 > **Note — Editorial correction — 7 September 2026.** > > The author's SVT-AV1 2.0.0–3.0.1 experiments, modified builds, clips, graphs, comparisons, and numerical results are preserved. This is exploratory benchmarking: W-VMAF, W-XPSNR, adjusted Butteraugli, and harmonic SSIMULACRA2 have not been validated here as perceptual video metrics. The methods and conclusions below now state those limits. No benchmark or subjective validation was rerun. # Introduction It's been almost a year since SVT-AV1 v2.0.0 dropped in March 2024, and we finally got v3.0.0 in late February of this year. Minor versions v3.0.1 and v3.0.2 came along afterward with some bug fixes and ARM SIMD improvements, but they didn't meaningfully alter encoding results. So what's actually different between these versions? I've been wanting to run tests across all the major releases from v2.0.0 to v3.0.x to see how the speed vs quality trade-offs have evolved this past year. Using SSIMULACRA2, Butteraugli, XPSNR, and VMAF (plus some methodology tweaks I'll get into), I'll break down what each version brought to the table and in a second part, we'll also deep dive a few specific options that appeared in the encoder since my first blog post release so you can figure out what you may want to use for your projects. That includes variance boost, fast decode, temporal filtering strength and a few others... ## Feedback Although the reception was warm, I got less feedback than usual this time around, but honestly, that hasn't prevented me from wanting more. And better! I'm keeping the stuff that seemed well-received: the diverse test clips, visual comparisons, and my ongoing attempt to stay as objective as possible. In my last post's conclusion, I mentioned some frustrations: XPSNR was acting up, metrics were taking forever to calculate, and there was just too much data to make sense of. Good news is I've tackled all of these. I fixed the XPSNR issue (it expected mod-8 inputs), started using the new [Vship](https://codeberg.org/Line-fr/Vship) to speed up metrics calculation, and found a cleaner way to present all the data points at just two quality levels, like I used to do. Also, it needs to be pointed out I've been way too optimistic about how often I can get these posts out. Especially when I revamp the methodology each time. I'm sorry about that, again. Though, my ambition may also be at fault: the size of this article got so out of hand I eventually decided to split it into two parts for convenience's sake. ## Methodology You'll find both graphs and visual comparisons in this analysis. The graphs give you objective data on encoder efficiency across different settings, using various metrics. The image comparisons show the actual encoded samples so you can judge quality for yourself, adding that subjective element that numbers alone can't capture. This time, I'm using a new tool called [*Metrics*](https://github.com/psy-ex/metrics) from the self-proclaimed Psychovisual Experts group, which provides scripts for measuring and comparing video codecs. I've heavily modified these scripts for my specific needs, but if you want to run your own tests locally, definitely check out the original *Metrics* toolkit! --- Here's how the testing works: I use relatively short video samples covering a wide range of content types, all converted to uncompressed y4m format (if they weren't already!) for consistency. These lossless files go straight into *SvtAv1EncApp*, so we're measuring single-instance encoder performance here. Chunked encoding with a tool such as [Av1an](https://github.com/rust-av/Av1an) is an optional throughput strategy; this single-instance experiment does not test its boundary, rate-control, or resource tradeoffs. The author used Vship for SSIMULACRA2 and Butteraugli, and modified FFmpeg-based processing for VMAF and XPSNR. Using several metrics can expose disagreement; it does not prove that their errors cancel or that the combination tracks human judgments. **Harmonic SSIMULACRA2:** the author pooled frame scores harmonically to emphasize low scores. This is an experimental aggregation of an image metric, not a validated temporal model. SSIMULACRA2 scores can be zero or negative; harmonic pooling becomes undefined at zero and can behave misleadingly across mixed signs. Inspect per-frame values and any exclusions before interpreting these curves. [Reference metric](https://github.com/cloudinary/ssimulacra2). **W-VMAF:** the historical pipeline ran a v0 NEG model separately on Y, U, and V and combined the results as `((4.0 * vmaf_y) + vmaf_u + vmaf_v) / 6.0`, with `motion.motion_force_zero=true`. Running a luma-trained model on chroma planes and selecting a 4:1:1 weight is not validated chroma modeling. Disabling motion also changes the input features from those used for normal prediction. NEG is a documented model variant, but it does not validate these additional changes. This article's W-VMAF is not Netflix VMAF. The old luma-only statement concerned the v0 model used here; newer v1 models include chroma features. [V0 models](https://github.com/Netflix/vmaf/blob/master/resource/doc/models_v0.md), [v1 models](https://github.com/Netflix/vmaf/blob/master/resource/doc/models_v1.md). **W-XPSNR:** the author disabled motion-related code, converted component dB scores back to linear error values, pooled them as `((4.0 * xpsnr_mse_y) + xpsnr_mse_u + xpsnr_mse_v) / 6.0`, and converted back to dB. That defines a modified measurement, not the published XPSNR algorithm. The original instruction to comment out a moving source-code line is not a reproducible patch; exact historical source and patch revisions are needed to reproduce it. For new comparisons use the [built-in XPSNR workflow](/reference/metrics/xpsnr/) and report components before inventing a combined score. **Butteraugli:** the author set intensity to 203 nits rather than the 80-nit default reported for the tested build. Display-intensity assumptions affect scores; a reference-white convention does not validate the resulting video rankings or HDR treatment. Current Vship documentation uses its own default, so record the explicit parameter and implementation version. [Vship Butteraugli API](https://codeberg.org/Line-fr/Vship/src/branch/main/doc/BUTTERAUGLI.md). **Interpretation:** no subjective validation of these transformations is supplied. The plots remain observations of the author's chosen functions, useful for generating hypotheses and selecting visual comparisons. Agreement among them does not establish equal perceived quality, a transparent threshold, or a universal preset ranking. Validating such claims requires independent subjective data and documented viewing conditions; [ITU-R BT.500](https://www.itu.int/rec/R-REC-BT.500) describes relevant assessment methods. The "speed graphs" plot *Constant Rate Factor* (CRF) against encoding time to show speed efficiency at different quality targets. For compression efficiency, I plot metric scores against output file size. Since *Metrics* doesn't use *bits per pixel* (BPP) and I had received feedback a few blog posts back that this metric could be confusing, I decided to drop it this time around. To achieve more accurate efficiency curves with fewer probes, it is more effective to prioritize probes in the higher-quality (lower CRF) range of the quality spectrum, since bitrate will increase quicker. I used the following formula, courtesy of better-vmaf's author, to determine ten CRF values from 10 to 50 to use for the testing: `crfs = [min_q + (max_q - min_q) * ((step / (q_steps - 1)) ** scaling_factor) for step in range(q_steps)]`, then equally split into *High Quality* and *Low Quality* graphs and visual comparisons. How to read the graphs? For the compression efficiency graphs, higher and further left is better, except for Butteraugli, which is a distance metric where lower scores mean better quality, so you want bottom-left instead of top-left. For the encoding speed graphs, further left means faster. One important caveat about speed measurements: reproducing the efficiency curves also requires matching encoder and metric revisions, patches, preprocessing, and settings; GPU and CPU numerical paths can differ. Separately, measuring encoding speed is trickier. The performance numbers you see here will likely differ on your setup depending on your specific hardware configuration. Please take them with a grain of salt. --- The clips used in this test were acquired legally. The Codec Wiki and its contributors do not endorse media piracy. As the testing started a good while ago, about when v3.0.1 released in fact, and many encodes were already completed by the time v3.0.2 was out, I used the following encoder versions for this test: **v2.0.0**, **v2.1.2**, **v2.2.1**, **v2.3.0** and **v3.0.1**. The different *SvtAv1EncApp* binaries were compiled directly from their respective [source codes](https://gitlab.com/AOMediaCodec/SVT-AV1/-/releases/) found on the release section of the SVT-AV1 Gitlab repository, using **Clang 19.1.7** and the provided `Build/linux/build.sh` script with the following command: `build.sh cc=clang cxx=clang++ jobs=$(nproc) enable-lto static native release`. The testing machine is now comprised of an **i7 12700F**, whose E-cores have been disabled to avoid scheduler-related issues, with **2x8GB** of TOTL 3200MHz CL14 DDR4 RAM, in **Arch Linux** with kernel 6.12.17 and the performance governor enabled. I tried my best to run most encodes in the same session without rebooting, but a few issues made it so I had to re-run some in a new session. However, this does not concern this part of the article, so we'll revisit this in the next one. There is an exception to one of my above statement. As you may know, there is a feature that significantly impacted SVT-AV1's competitiveness: [**variance boost**](https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/Appendix-Variance-Boost.md)! This feature can provide good efficiency improvements by increasing quality in low-contrast areas in frames, at little to no performance cost when properly bitrate normalized. This feature was in the work during the v1.7.0 days, but it only got merged to git relatively shortly after v2.0.0 released. As I wanted to enable *varboost* by default for this entire testing (as I had expressed in the conclusion of the last blog post), I decided to manually patch the v2.0.0 source code as provided on the release page with the following two commits: ["Introduce the variance boost feature"](https://gitlab.com/AOMediaCodec/SVT-AV1/-/commit/cb6de1134e9695e48f547a799e3818115f18ae93) and ["Do not adjust picture QP/qindex value with variance boost on"](https://gitlab.com/AOMediaCodec/SVT-AV1/-/commit/128712bf0aa83e4f680352b87c4b75ac3419364d). Of course, the feature slightly evolved since then, but this little modification still allowed me to test the evolution of the encoder performance with this key feature on. We're almost ready to deep dive into an ocean of metrics, graphs, and revelations! (Okay, maybe not revelations... but hopefully a few surprises.) ## Samples The samples are the same as last time: - 17s `Avatar The Way Of Water (trailer 3)` clip sourced from [thedigitaltheater.com](https://thedigitaltheater.com/category/movie-trailers/lossless-movie-trailers/) (1920x808p *with 4 columns and 4 rows of pure black borders to fix XPSNR*, 23.976fps). - 6s `Ducks Take Off` clip sourced from [xiph.org](https://media.xiph.org/video/derf/) (1280x720p, 50fps). - 3s `Fallout 4` clip sourced from another encoder fellow (1920x1080p, 60fps). - 8s `Minecraft` clip sourced from [xiph.org](https://media.xiph.org/video/derf/) (1920x1080p, 60fps). - 8s `Sol Levante` HDR clip sourced from [opencontent.netflix.com](http://download.opencontent.netflix.com/?prefix=SolLevante/) (3840x2160p, 24fps). Its HDR status does not make the custom SDR metric paths valid for HDR. Interpretation requires documented transfer handling and viewing conditions; metadata presence alone does not describe all encoder behavior. - 21s `Suzume (trailer 2)` clip sourced from [thedigitaltheater.com](https://thedigitaltheater.com/category/movie-trailers/lossless-movie-trailers/) *(seems to have been deleted since)* (1920x808p, 23.976fps). - 13s `The Mandalorian (trailer 2)` clip sourced from [thedigitaltheater.com](https://thedigitaltheater.com/category/movie-trailers/lossless-movie-trailers/) (1920x800p, 23.976fps). ## Visual comparisons ![comp_showcase](/img/comp_showcase.webp) Throughout this blog post, you’ll find *slow.pics* links that provide various visual comparisons between presets. The *"High Quality"* (noted HQ) and *"Low Quality"* (noted LQ) links showcase comparisons at two different quality targets. These have been carefully handcrafted to be as size-normalized as possible, given the available encodes. We want to be focusing on encodes with minimal bitrate deviation for a fair comparison. Feel free to double-check the bitrate of each frame or scene (as written in the top-left corner of each screenshot) to make a more informed observation, keeping the size difference in mind when comparing the encodes. Use the arrow keys and numpad to navigate between screenshots. Alternatively, you can click on "Slider comparison" and select two sources if you prefer comparing this way. ## Quality Target & Encoding Settings > **All clips have been encoded in a wide quality range, from `--crf 10` to `--crf 50`, with values determined using the previously described formula.** `--preset X --enable-variance-boost 1` are the only parameters used here, in conjunction with the CRF values. We will compare various varboost parameters' combinations in Part 2 of the article, but for now, the defaults are used. Obviously, it wouldn't be fun without me realizing, as I'm writing these words, that I forgot to use `--hierarchical-levels 4` like last time, but well, it is what it is. Nothing *that* significant. Else, the SVT-AV1 defaults were used. The ones worth mentioning are: - `--tune 1`: tune PSNR - `--aq-mode 2`: variance deltaq - `--enable-qm 0`: quantisation matrices disabled - `--enable-tf 1`: temporal filtering enabled - `--tf-strength 3`: default temporal filtering strength - `--sharpness 0`: default deblock and rate distortion mode decision - `--fast-decode 0`: decode optimizations disabled And more, like CDEF and restoration enabled, overlays and film-grain disabled... Anyway, time to kick things off with the presets comparisons! ## SVT-AV1 v3.0.x Presets Comparisons (-1 -> 10) *If all you care about is what preset to use in the latest available version, this is the section for you!* **In the following graphs, you may find comparisons between all SVT-AV1 v3.0.x presets, ranging from the slowest `--preset -1` to the current fastest `--preset 10`.** > Since **v2.3.0** (and unlike in **v2.1.x** and **v2.2.x**), preset 6 made its return as its own separate preset: it is not mapped to preset 7 anymore. However, the maximum preset has become 10, and anything above it is effectively mapped to 10. ### Efficiency ---> Here are the full efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). Quite a lot of data eh? So much so that readability is impacted. Hence why we'll also focus on two quality targets to better understand what's exactly going on. ---> Thus, let's look at the same data but zooming in on the *"high quality"* range (defined here as CRF10 through 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> And now, let's zoom in on the *"low quality"* range (defined here as CRF28 through 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). As we can see, **presets 9 and 10** can be quite unpredictable depending on the clip. Their efficiency curves are also clearly not monotonic, with unexpected efficiency regressions happening at very low CRFs (high bitrates), especially visible on SSIMU2. This behavior is likely enhanced by the harmonic scoring, but it is also observable on Butteraugli and W-VMAF to a lesser extent. When looking at **preset 10** in the low quality range, the curves can be so chaotic on the SSIMU2 side we can easily conclude there's a quality consistency issue at play, that is to say that certain frames score significantly lower than others. --- ---> Therefore, let's remove **presets 9 and 10** from the equation and have a better look at the "usable" presets, from **8 and below**: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Same, but focusing on the *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> And the *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). Efficiency wise, we instantly notice **presets 2 and below** are grouped together very tightly, while every other presets appear to be more evenly spaced. Consistency, and thus SSIMU2 harmonic scores in particular, tend to get really bad below *CRF38* or *44* depending on the clip, which at least teaches us that SVT-AV1 begins to struggle around these quality targets whatever the chosen preset (in its almost-stock configuration). Something interesting seems to be happening with **preset 8** where it scores better than *preset 7* on certain clips, even going neck and neck with *preset 6* at times according to W-VMAF. That is something worth investigating visually, in the following visual comparisons between the three presets: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/rxAIcuu7) | [Avatar (LQ)](https://slow.pics/c/8LCApWef) | | [Ducks (HQ)](https://slow.pics/c/jIDYwjXn) | [Ducks (LQ)](https://slow.pics/c/K0fQfPew) | | [Fallout (HQ)](https://slow.pics/c/zvLeJCdH) | [Fallout (LQ)](https://slow.pics/c/dsrtj4aN) | | [Minecraft (HQ)](https://slow.pics/c/Yc1tnPhN) | [Minecraft (LQ)](https://slow.pics/c/WSE7zC8B) | | [Sol Levante (HQ)](https://slow.pics/c/zmUvEM6J) | [Sol Levante (LQ)](https://slow.pics/c/kiP6AOYN) | | [Suzume (HQ)](https://slow.pics/c/OepN2y8E) | [Suzume (LQ)](https://slow.pics/c/lvkQehjN) | | [Mandalorian (HQ)](https://slow.pics/c/XknHyTna) | [Mandalorian (LQ)](https://slow.pics/c/M6D29CR1) | Do you agree with W-VMAF's numbers here? I think I do, to an extent. --- ---> Let's take a closer look at **presets 4 and below** to see if we can better observe the differences between the slower modes: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> At *"high quality"* (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> And at *"low quality"* (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). It is better, but still clear the differences are relatively small. Though, we can also put BD-rate numbers to these differences thanks to psy-ex's *metrics*! --- The following table show the BD-rate regressions of preset 0 through 4, with **preset -1** as the reference, when averaged across all four metrics and all seven clips: | Preset | BD-rate regression (vs P-1) | |:-:|:-:| | 0 | 0.97% | | 1 | 3.79% | | 2 | 7.82% | | 3 | 17.08% | | 4 | 22.41% | **Presets 0 through 2** are pretty close to the **reference preset -1** and we notice a huge jump from **preset 2** to **3**, with **preset 4** relatively scoring very close to **preset 3**. We will put these numbers into perspective after having looked at the performance of every presets. ### Speed Efficiency numbers are great, but they only tell half the story. The relative speed differences between presets can paint a drastically different picture of the situation and change our entire interpretation of the results so far. In the following graphs, you may find speed comparisons of the different presets, with either a linear or a logarithmic scale. The latter is useful to better visualize the large speed variations between presets, as it compresses the scale and makes smaller differences more apparent. I must reiterate my previous disclaimer that these numbers should be taken with a grain of salt. They only represent the speed of the given presets at each CRF value *over a single run* on a given machine. Making multiple runs could help eliminate small, undesired variations, but they'd come at the cost of time and electricity. It is not reasonable here considering the scale of this blog post, sacrifices must unfortunately be made. To help mitigate this issue, the processor temperature is closely monitored and the fans actively adjust to prevent overheating. I also make sure no background tasks are running and that only a single encoder instance is running at all times. This won't prevent some outliers from passing through, but they are usually easier to detect. ---> That said, let's begin by comparing the performance of all presets, from **-1 to 10**: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). First thing first, SVT-AV1 scales exceptionally well, from well above realtime speeds, to painfully placebo speeds. Looking at the graphs with logarithmic scales, we can see that encoding speeds, the slower presets we go, tend to increase in an exponential manner. Unfortunately for us, efficiency doesn't usually follow that trend! We do notice a substancial gap between **presets 4 and 5** however. ---> Let's also look at the performance of just **presets -1 through 4**, considered the slower, non-realtime presets: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). On the logarithmic scale, the presets are impressively evenly spaced, except for **preset -1** which is somewhat closer to **preset 0**. Now then, we need to combine what we learned about efficiency and speed to interpret the results in an informative way! ### Interpretation (TLDR) Despite the repeated presets shifting, some things never change. For *good* modes, **presets 2 and 4** still offer the best bang for your buck in balancing efficiency and speed. **Preset 2** is usually slightly more than 2x faster than *preset 1* and about 2x slower than *preset 3* while offering close to *preset 1* efficiency and largely better efficiency than *preset 3*. **Preset 4** happens to be the "slowest" good preset that's still very competitive, with little efficiency differences against *preset 3*, making it a valuable choice for anyone wanting a good balance of quality and speed for non-realtime usecases. For *realtime* modes, **any preset from 5 and above** will do as long as it reaches realtime on your system! However, consistency takes a huge hit at **presets 9 and 10**, rendering those two presets unappealing compared to hardware solutions that are likely to be quite competitive for this usecase. **Preset 8**, which strikes an excellent efficiency to speed ratio for what it is, is the last preset I would deem truly usable in SVT-AV1 v3.0.x. ## SVT-AV1 v2.0.0 -> v3.0.x Initial Presets Comparisons (-1 -> 10) In this section, we will first examine the *presets -1 to 10* range, independently of the presets shifting happening between the tested encoder versions. In a following section, we'll make more targeted comparisons taking into account the shifts. ### `preset -1`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: Efficiency wise, **preset -1** has not improved from v2.0.0 to v3.0.x, rather it has stagnated. At worst, it regressed of exactly 2.0% BD-rate on one metric in one given clip. On average, the regression is closer to 0.5%. The good news though is that the preset became *up to 65% faster vs v2.0.0*! That's the best case scenario, as on average across the studied quality range, it has gotten *faster of about 37.5%*, which is still an amazing trade-off! It is fascinating to see how very different the presets' speed behave with CRF between versions, as at CRF50, the preset is barely faster on v3.0.x than it was on v2.0.0. Now, feel free to look at the following comparisons to see if you can spot much of a difference between the different versions at preset -1! ---> Preset -1 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/7snxpOZv) | [Avatar (LQ)](https://slow.pics/c/h3cE9Pva) | | [Ducks (HQ)](https://slow.pics/c/9Q2mes9k) | [Ducks (LQ)](https://slow.pics/c/VVtIWwgO) | | [Fallout (HQ)](https://slow.pics/c/CmFkc6g5) | [Fallout (LQ)](https://slow.pics/c/xpE2mZiX) | | [Minecraft (HQ)](https://slow.pics/c/i6xsIUa1) | [Minecraft (LQ)](https://slow.pics/c/F3KSC9w2) | | [Sol Levante (HQ)](https://slow.pics/c/pb9UcwUd) | [Sol Levante (LQ)](https://slow.pics/c/yF6fN4b9) | | [Suzume (HQ)](https://slow.pics/c/2ySf85bn) | [Suzume (LQ)](https://slow.pics/c/R8DBurLN) | | [Mandalorian (HQ)](https://slow.pics/c/cl1c54cP) | [Mandalorian (LQ)](https://slow.pics/c/CAWDE2f7) | --- ### `preset 0`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: Here, we have an interesting case where **preset 0** efficiency got slightly better since v2.0.0 (by about 1.75%), though it remained largely unchanged after v2.1.x. There's one funny exception: according to all metrics, it peaked at *HQ* on the Minecraft clip during v2.1.x and regressed ever since. Speed wise, the preset took a hit in v2.1.x, improved a lot in v2.2.x almost closing the gap with v2.0.0, and regressed again in v2.3.0 and especially in v3.0.x. The regressions are not a good look, even though by in large, they're rather insignificant. Can you spot the differences in the comparisons below though? ---> Preset 0 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/u9OZOSxK) | [Avatar (LQ)](https://slow.pics/c/HXc5J1WU) | | [Ducks (HQ)](https://slow.pics/c/sv71x9XV) | [Ducks (LQ)](https://slow.pics/c/feQLSoX6) | | [Fallout (HQ)](https://slow.pics/c/u8KQnRuG) | [Fallout (LQ)](https://slow.pics/c/eYe84LaK) | | [Minecraft (HQ)](https://slow.pics/c/gtL1DkE4) | [Minecraft (LQ)](https://slow.pics/c/bcd8dyr6) | | [Sol Levante (HQ)](https://slow.pics/c/zsXcTpz4) | [Sol Levante (LQ)](https://slow.pics/c/tvaZVwuT) | | [Suzume (HQ)](https://slow.pics/c/XeKhvH4u) | [Suzume (LQ)](https://slow.pics/c/tVrFmswl) | | [Mandalorian (HQ)](https://slow.pics/c/sFL9h8zi) | [Mandalorian (LQ)](https://slow.pics/c/z5zW6yRP) | --- ### `preset 1`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: We start seeing more diverse results with **preset 1**. Versions after v2.0.0 tend to fare better efficiency wise, but each version present different strengths and weaknesses depending on the clip and metric. The speed graphs are quite chaotic, though the preset seems to have consistently gotten slightly slower and slower since the v2.0.0 days. Taking all of this into account, the overall interpretation would still be that the preset behavior is *mostly unchanged* from before. Let's play at "spot the differences"! After looking at the following comps, tell me what you think of the new trade-offs! ---> Preset 1 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/E72LcsSl) | [Avatar (LQ)](https://slow.pics/c/KFuurqAg) | | [Ducks (HQ)](https://slow.pics/c/FPId4Zqe) | [Ducks (LQ)](https://slow.pics/c/qMqqL0Lz) | | [Fallout (HQ)](https://slow.pics/c/vwixXHUX) | [Fallout (LQ)](https://slow.pics/c/k0nicdyT) | | [Minecraft (HQ)](https://slow.pics/c/gyer6fDr) | [Minecraft (LQ)](https://slow.pics/c/BRGkTPoT) | | [Sol Levante (HQ)](https://slow.pics/c/WtxUfd7I) | [Sol Levante (LQ)](https://slow.pics/c/ePf4GiMQ) | | [Suzume (HQ)](https://slow.pics/c/SjuspSWV) | [Suzume (LQ)](https://slow.pics/c/IVDIqGK9) | | [Mandalorian (HQ)](https://slow.pics/c/E2BqCUTc) | [Mandalorian (LQ)](https://slow.pics/c/FuS5w2bn) | --- ### `preset 2`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: On Minecraft, we notice (especially at *HQ*) a trend of **preset 2** progressively becoming worse after v2.1.x, by about 2.5% in fact vs v3.0.x. On other clips, it has either stagnated or slightly improved, except for v3.0.x where it seems to score consistently last or second to last. Relatively, *the differences are small*, so broadly speaking, the preset is again very similar to what it used to be. Well, except for its consistent *speed improvement of 10-40%* since v2.0.0, making the new trade-off considerably more appealing. Does the following comparisons help quantify the speed improvements in the new version? Well, no... they can't, but it's nice to have them anyway! Check them out! ---> Preset 2 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/GmKOaffP) | [Avatar (LQ)](https://slow.pics/c/XsTfILBQ) | | [Ducks (HQ)](https://slow.pics/c/1MapPnXt) | [Ducks (LQ)](https://slow.pics/c/Dr7IoQ6j) | | [Fallout (HQ)](https://slow.pics/c/86DRKP0R) | [Fallout (LQ)](https://slow.pics/c/VZNSVtdy) | | [Minecraft (HQ)](https://slow.pics/c/MKfT4aR7) | [Minecraft (LQ)](https://slow.pics/c/clfDCYS0) | | [Sol Levante (HQ)](https://slow.pics/c/9JkuBBUQ) | [Sol Levante (LQ)](https://slow.pics/c/gKOHHyxj) | | [Suzume (HQ)](https://slow.pics/c/uCTa7ncr) | [Suzume (LQ)](https://slow.pics/c/auIbFheo) | | [Mandalorian (HQ)](https://slow.pics/c/t9x5kOGV) | [Mandalorian (LQ)](https://slow.pics/c/q4kmtobA) | --- ### `preset 3`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: At last, efficiency changes that can be considered significant! The presets shifting is at play here, and it will only become more evident as we progress towards the faster presets. With v3.0.x having fewer presets than some earlier versions, the SVT-AV1 team spread them out more to fill the gaps, completing the shifting initiated in v2.3.0. **Preset 3** in v3.0.x almost consistently scores last, though that is less pronounced at *Low Quality*. On average, *its BD-rate is 2.7% lower* in v3.0.x vs v2.0.0. However, partly thanks to that, it received a hefty *speed boost of about 24%* since! Take a look at the graphs below, does this seem worth it to you? ---> Preset 3 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/bswlVaS9) | [Avatar (LQ)](https://slow.pics/c/bVlBtF5U) | | [Ducks (HQ)](https://slow.pics/c/WMB8HiIa) | [Ducks (LQ)](https://slow.pics/c/MRtHNOAV) | | [Fallout (HQ)](https://slow.pics/c/BEuwKWeU) | [Fallout (LQ)](https://slow.pics/c/CLIwIDQA) | | [Minecraft (HQ)](https://slow.pics/c/6nU4h6Av) | [Minecraft (LQ)](https://slow.pics/c/noTwMunx) | | [Sol Levante (HQ)](https://slow.pics/c/PMWrAwJ6) | [Sol Levante (LQ)](https://slow.pics/c/0yKDNkSG) | | [Suzume (HQ)](https://slow.pics/c/oXePAVWf) | [Suzume (LQ)](https://slow.pics/c/3RPadLsV) | | [Mandalorian (HQ)](https://slow.pics/c/9lwUBV2H) | [Mandalorian (LQ)](https://slow.pics/c/cjyYORDs) | --- ### `preset 4`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: Same goes for **preset 4**! Our slow preset of choice has become *29% faster on average*, at the cost of a *3.0% efficiency loss*. With that in mind and the comps available right below, have your opinion of **preset 4** changed? ---> Preset 4 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/tyQdj3fH) | [Avatar (LQ)](https://slow.pics/c/RTSn1mek) | | [Ducks (HQ)](https://slow.pics/c/TSnz1fH3) | [Ducks (LQ)](https://slow.pics/c/JYB28hs1) | | [Fallout (HQ)](https://slow.pics/c/myrv1Wug) | [Fallout (LQ)](https://slow.pics/c/8RO9hvGH) | | [Minecraft (HQ)](https://slow.pics/c/Z3LOcUlJ) | [Minecraft (LQ)](https://slow.pics/c/jrTsw9Ph) | | [Sol Levante (HQ)](https://slow.pics/c/9rZCYMS6) | [Sol Levante (LQ)](https://slow.pics/c/bnpxfOo8) | | [Suzume (HQ)](https://slow.pics/c/cyUqkiWq) | [Suzume (LQ)](https://slow.pics/c/xTBouY62) | | [Mandalorian (HQ)](https://slow.pics/c/8Fao1kY8) | [Mandalorian (LQ)](https://slow.pics/c/7SVJpFiU) | --- ### `preset 5`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: Unsurprisingly, the spreading continues! The gaming clips are the most affected here, showing an efficiency decrease of 6.1% and 14.3% respectively. Then again, the average across all seven clips is quite a bit lower at *4.5% lower efficiency*. *Speed is improved by 44%*, so the trade-off sounds reasonable. I'm starting to lose inspiration to introduce the comparisons, so simply have a look! ---> Preset 5 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/fwRG6aYK) | [Avatar (LQ)](https://slow.pics/c/93jKW8uB) | | [Ducks (HQ)](https://slow.pics/c/xZq2VS4u) | [Ducks (LQ)](https://slow.pics/c/iHY2I6Pp) | | [Fallout (HQ)](https://slow.pics/c/5k7S6JjP) | [Fallout (LQ)](https://slow.pics/c/VWAZyZLS) | | [Minecraft (HQ)](https://slow.pics/c/XV1if9np) | [Minecraft (LQ)](https://slow.pics/c/N4CugkJp) | | [Sol Levante (HQ)](https://slow.pics/c/pNqh7oLp) | [Sol Levante (LQ)](https://slow.pics/c/ia89EKhf) | | [Suzume (HQ)](https://slow.pics/c/ICbt1UM9) | [Suzume (LQ)](https://slow.pics/c/nJQCjkvK) | | [Mandalorian (HQ)](https://slow.pics/c/DQjLIrE2) | [Mandalorian (LQ)](https://slow.pics/c/6gpzZo9B) | --- ### `preset 6`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: More of the same! Though, the shift seems to have been initiated in v2.1.x, so **preset 6** in v3.0.x is quite different from its older sibling from v2.0.0. **Compared to v2.0.0**, *preset 6* is now both *47% faster* and *8.8% lower efficiency*, while **compared to v2.1.2 instead**, it is roughly *27% faster* and *2.6% lower efficiency*. The gaming clips are the most affected again, showcasing that complex content suffers more as you move to higher presets. Find the visual comparisons right after, if you're interested. ---> Preset 6 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/NfMp2Qxb) | [Avatar (LQ)](https://slow.pics/c/fvRtLfXJ) | | [Ducks (HQ)](https://slow.pics/c/k68hC9TU) | [Ducks (LQ)](https://slow.pics/c/8YpIfbGP) | | [Fallout (HQ)](https://slow.pics/c/936r0JxK) | [Fallout (LQ)](https://slow.pics/c/QXc8lc0V) | | [Minecraft (HQ)](https://slow.pics/c/LhqYPsqK) | [Minecraft (LQ)](https://slow.pics/c/NusQfYg0) | | [Sol Levante (HQ)](https://slow.pics/c/H5TkQgQO) | [Sol Levante (LQ)](https://slow.pics/c/ZF0aLLti) | | [Suzume (HQ)](https://slow.pics/c/lt3HXK9x) | [Suzume (LQ)](https://slow.pics/c/H1qa9TTW) | | [Mandalorian (HQ)](https://slow.pics/c/0mDTEvnx) | [Mandalorian (LQ)](https://slow.pics/c/mRRQt2Ky) | --- ### `preset 7`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: With **preset 7**, it is clear the downward shift in efficiency was progressively set in motion since v2.3.0. **Compared to v2.0.0**, *v3.0.x's preset 7* sees an *11.6% efficiency hit*, traded for a *68% speed improvement*, not too bad. **Versus v2.3.0**, the *new preset 7* has a *5% worse efficiency* and only *14% better speeds*. This difference is arguably the least appealing of every presets so far... How did the preset evolve visually though? The answer is in the following comparisons! ---> Preset 7 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/UVDaSDcb) | [Avatar (LQ)](https://slow.pics/c/zh84Mp6e) | | [Ducks (HQ)](https://slow.pics/c/0DrdFnYu) | [Ducks (LQ)](https://slow.pics/c/86F1oqdy) | | [Fallout (HQ)](https://slow.pics/c/IHZ5zSsa) | [Fallout (LQ)](https://slow.pics/c/PGWRkxiF) | | [Minecraft (HQ)](https://slow.pics/c/MAcpzaop) | [Minecraft (LQ)](https://slow.pics/c/hCwQbbLe) | | [Sol Levante (HQ)](https://slow.pics/c/nSfCm0lW) | [Sol Levante (LQ)](https://slow.pics/c/1CKfXF9T) | | [Suzume (HQ)](https://slow.pics/c/v8GZVrQ8) | [Suzume (LQ)](https://slow.pics/c/V9aFc5d3) | | [Mandalorian (HQ)](https://slow.pics/c/hMmMbBBS) | [Mandalorian (LQ)](https://slow.pics/c/0HgfcQto) | --- ### `preset 8`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: **Preset 8**'s trade-offs are significantly altered in v3.0.x. This is relatively proportionate to the gain in speed, but we may have expected better. Efficiency wise, it is *15.8% lower* and *48% faster* than in v2.0.0. To be fair, as the presets are starting to stray too much from each other, we should probably compare it to a faster v2.0.0 preset like 9. Look up the visual comparisons while keeping that in mind. ---> Preset 8 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/j1HlBkwz) | [Avatar (LQ)](https://slow.pics/c/DTxPsMDM) | | [Ducks (HQ)](https://slow.pics/c/Y5MifaMo) | [Ducks (LQ)](https://slow.pics/c/qQN9QNWU) | | [Fallout (HQ)](https://slow.pics/c/RitaiAEa) | [Fallout (LQ)](https://slow.pics/c/PHsPKE03) | | [Minecraft (HQ)](https://slow.pics/c/N9Gg6dvo) | [Minecraft (LQ)](https://slow.pics/c/rNVmLiEz) | | [Sol Levante (HQ)](https://slow.pics/c/b0LHyz5w) | [Sol Levante (LQ)](https://slow.pics/c/FJH9IhKi) | | [Suzume (HQ)](https://slow.pics/c/mvPN2u37) | [Suzume (LQ)](https://slow.pics/c/Ei7Wbvk9) | | [Mandalorian (HQ)](https://slow.pics/c/g2I52mPH) | [Mandalorian (LQ)](https://slow.pics/c/kz6qcrTm) | --- ### `preset 9`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: Similar to *preset 8*, it is becoming really hard to make a fair comparison between very disparate presets, especially when it is starting to break at extreme CRF values. It is clear **v3.0.x's preset 9** is built differently than *v2.0.0's*, it plays in a completely different league. I will not elaborate further at this point, as we will revisit this preset in the next section. There are still visual comparisons, if you're curious: ---> Preset 9 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/OdUkbCaJ) | [Avatar (LQ)](https://slow.pics/c/l9QdddJH) | | [Ducks (HQ)](https://slow.pics/c/cjgpua5F) | [Ducks (LQ)](https://slow.pics/c/9VCjfwSs) | | [Fallout (HQ)](https://slow.pics/c/T7CeIQxx) | [Fallout (LQ)](https://slow.pics/c/4oWIQ96e) | | [Minecraft (HQ)](https://slow.pics/c/cS9XPPvJ) | [Minecraft (LQ)](https://slow.pics/c/OC42ixqX) | | [Sol Levante (HQ)](https://slow.pics/c/GLY1TNke) | [Sol Levante (LQ)](https://slow.pics/c/O4wQ8qI5) | | [Suzume (HQ)](https://slow.pics/c/g12kkzKH) | [Suzume (LQ)](https://slow.pics/c/XgzXw5do) | | [Mandalorian (HQ)](https://slow.pics/c/roJJVsLE) | [Mandalorian (LQ)](https://slow.pics/c/wSPqbIjf) | --- ### `preset 10`: v2.0.0 -> v3.0.x ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: Unlike the previous two presets, the new **preset 10** can somewhat be compared to its previous iterations. After disregarding *v2.2.1's* which is the one to behave distinctly here, **v3.0.x's preset 10** show similar characteristics across the quality range. For what it's worth, the preset is *38.5% less efficient* but *39.1% faster* compared to v2.0.0. It should be noted that as we go faster, the gap between fast presets is more likely to shrink on shorter clips due to the low encode times (in the order of a few seconds). As the time taken by the encoder to initialize isn't quite negligible anymore, using longer clips would likely increase the lead of **preset 10** in v3.0.x vs v2.0.0 as encoding speeds would have gotten enough time to stabilize. This is obviously out of the scope of this blog post, but still, the analysis in the next section will help shed light on how the fastest preset in v3.0.x compares to the fastest one in v2.0.0. I invite you to take a look at the visual comparisons if you want to see how *preset 10* evolved from v2.0.0 to v3.0.x. ---> Preset 10 Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/TzFCXBiX) | [Avatar (LQ)](https://slow.pics/c/1ynK7ErT) | | [Ducks (HQ)](https://slow.pics/c/phOYk2Un) | [Ducks (LQ)](https://slow.pics/c/vjEFuqlA) | | [Fallout (HQ)](https://slow.pics/c/TTUG4Oha) | [Fallout (LQ)](https://slow.pics/c/BY7pZJdR) | | [Minecraft (HQ)](https://slow.pics/c/7TwJykvh) | [Minecraft (LQ)](https://slow.pics/c/rYIW5Flt) | | [Sol Levante (HQ)](https://slow.pics/c/NJLhXART) | [Sol Levante (LQ)](https://slow.pics/c/5UJnwTuq) | | [Suzume (HQ)](https://slow.pics/c/hlDThBg0) | [Suzume (LQ)](https://slow.pics/c/rmDWXipa) | | [Mandalorian (HQ)](https://slow.pics/c/QqkHhYsk) | [Mandalorian (LQ)](https://slow.pics/c/vwbowkAs) | ## SVT-AV1 v2.0.0 vs v3.0.x Selective Presets Comparisons Some presets cannot be directly compared anymore, as the reduction in presets since v2.0.0 means the gap had to be filled, and the fastest presets were the most affected by this move. I decided to focus on SVT-AV1 v3.0.x's *presets 8*, *9* and *10* here, then we'll proceed do something new for this blog post series... ### v3.0.x's `preset 10` vs v2.0.0's `preset 13` How does v3.0.x's fastest preset fares against v2.0.0's own? ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: Well, the answer is quite nicely! Depending on the clip and metric, v3.0.x is overall either lightly ahead or lightly behind, while staying equally fast! The trade-offs are mildly different, as v3.0.x is capable of being even slightly faster, at the cost of some efficiency. It's fair to say the dev team managed to preserve the performance of the fastest mode despite said reduction in presets. *Preset 13* was always considered an experimental mode reserved for convex hull purposes, so it's my assumption that the dev team had no real intention of making the fastest preset even faster if accuracy was impacted further than it already is. Here are some visual comparisons to visualize the situation! Did you miss them? ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/CeJKaDn9) | [Avatar (LQ)](https://slow.pics/c/gixmjNww) | | [Ducks (HQ)](https://slow.pics/c/uOYxGIh5) | [Ducks (LQ)](https://slow.pics/c/4JxasZSn) | | [Fallout (HQ)](https://slow.pics/c/RYSBtmDW) | [Fallout (LQ)](https://slow.pics/c/paBShIhM) | | [Minecraft (HQ)](https://slow.pics/c/SceyUJPY) | [Minecraft (LQ)](https://slow.pics/c/XqhPRl2m) | | [Sol Levante (HQ)](https://slow.pics/c/S9PRwEUf) | [Sol Levante (LQ)](https://slow.pics/c/3JgTLYcs) | | [Suzume (HQ)](https://slow.pics/c/SFKjq59f) | [Suzume (LQ)](https://slow.pics/c/kZdSkYaw) | | [Mandalorian (HQ)](https://slow.pics/c/VhGBR0G6) | [Mandalorian (LQ)](https://slow.pics/c/qtucNxVy) | --- ### v3.0.x's `preset 9` vs v2.0.0's `presets 11 & 12` ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: In a nutshell, **preset 9** in v3.0.x fares in between v2.0.0's presets 11 and 12 in efficiency, though usually closer to preset 11 overall, while usually being closer in speed to preset 12 (notable exception on the gaming clips)! That is a favorable custom-score/time tradeoff on the tested non-gaming clips, not a guaranteed gain for every other workload. Screenshots... screenshots everywhere! Find them right below: ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/cO94QQdI) | [Avatar (LQ)](https://slow.pics/c/9cjrP2O4) | | [Ducks (HQ)](https://slow.pics/c/AlNsI0Zj) | [Ducks (LQ)](https://slow.pics/c/FtcbLYlh) | | [Fallout (HQ)](https://slow.pics/c/yM0zgRkY) | [Fallout (LQ)](https://slow.pics/c/aKvQww2A) | | [Minecraft (HQ)](https://slow.pics/c/LqYh01UD) | [Minecraft (LQ)](https://slow.pics/c/ZDe8R4de) | | [Sol Levante (HQ)](https://slow.pics/c/nhdlzESm) | [Sol Levante (LQ)](https://slow.pics/c/GRv94zWH) | | [Suzume (HQ)](https://slow.pics/c/JLSRi3aX) | [Suzume (LQ)](https://slow.pics/c/7FnyFHAn) | | [Mandalorian (HQ)](https://slow.pics/c/Fi79eSMN) | [Mandalorian (LQ)](https://slow.pics/c/USPgAC2s) | --- ### v3.0.x's `preset 8` vs v2.0.0's `presets 9 & 10` ---> Compression efficiency graphs, *full* quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). ---> Interpretation: As with *preset 9* previously, **preset 8** in v3.0.x usually competes closer to *v2.0.0's preset 9* in efficiency, while performing one tier higher with speeds comparable to *v2.0.0's preset 10*. The results are more chaotic on the gaming clips but one clear advantage of *preset 8* is its robust consistency, unlike *v2.0.0's preset 10* (and *v3.0.x's two faster presets*). Here's our last set of comps for the day: ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/ldcvqdEf) | [Avatar (LQ)](https://slow.pics/c/NdmLe6Bh) | | [Ducks (HQ)](https://slow.pics/c/lhwMU6m4) | [Ducks (LQ)](https://slow.pics/c/EegUibz1) | | [Fallout (HQ)](https://slow.pics/c/t1gd5pQE) | [Fallout (LQ)](https://slow.pics/c/3P4lmgXC) | | [Minecraft (HQ)](https://slow.pics/c/0XcVB7M0) | [Minecraft (LQ)](https://slow.pics/c/7zo5ZuCT) | | [Sol Levante (HQ)](https://slow.pics/c/gcMqaiP5) | [Sol Levante (LQ)](https://slow.pics/c/B3mjiCJ9) | | [Suzume (HQ)](https://slow.pics/c/ANtnJzta) | [Suzume (LQ)](https://slow.pics/c/91YCoS9b) | | [Mandalorian (HQ)](https://slow.pics/c/YZErMped) | [Mandalorian (LQ)](https://slow.pics/c/nIoc7RN4) | ## SVT-AV1 v2.0.0 -> v3.0.x General BD-rate Evolution Before we wrap up on the presets analysis, I'm going to attempt an exercise widely used for comparing video encoder performance in both academic research and industry benchmarks. *BD-rate* (Bjøntegaard Delta rate) calculates the bitrate savings between two encoders at equivalent quality levels, giving you a single percentage that represents compression efficiency gains. You've already seen these numbers throughout the post. While BD-rate has its limitations (it assumes rate-distortion curves follow specific mathematical models and can struggle with very different encoder behaviors), it remains the most widely accepted metric for encoder comparisons. Psy-ex's *metrics* conveniently outputs BD-rate numbers when running its benchmarking scripts, so this served as the basis for what we're about to do. The graphs in this section plot *BD-rate* (%) against *encoding time* (ms), showing you the classic speed-vs-efficiency trade-off that defines encoder development. The first batch of graphs uses SVT-AV1 *v2.0.0's preset -1* as the reference: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). These combined plots mix two separate quantities: BD-rate is derived from rate–distortion curves, while encoding time forms the other axis. Timing noise does not itself change a correctly computed BD-rate. The original inference that bumpy curves prove timing errors is therefore unsupported. Results also depend on overlap range, interpolation, and non-monotonic or unstable metric curves; averaging across these custom measurements does not validate perceived bitrate savings. Anyway, let's try to interpret these results a bit. The faster presets can be found at the top left of the graph, and the slower ones in the bottom right. We can still generally notice the brighter colors tend to be above the darker ones (representing the newer versions), meaning the trade-offs did in fact improve *overall*. If we take **preset -1** as an easy-to-analyze example, we can confirm our previous findings that it did in fact get faster and faster with versions at little to no efficiency impact. What happens if we take a radically different preset as the reference though? Well, I got you covered with the following graphs, using *SVT-AV1 v2.0.0's preset 10* (the default if unspecified) as the reference: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p1.json). In this case, it tends to straighten the curves and make any sort of analysis harder. It does not help the situation and there's not much more to say with these graphs. At least, it gives a different perspective of the results. All in all, let's just say this was a fine experiment and a good learning opportunity. I'll think of ways I can do this better by next time. ## SVT-AV1 v2.0.0 -> v3.0.x Conclusion So what do you think of SVT-AV1's evolution from v2.0.0 to v3.0.x? Do you find it underwhelming? Well, that's almost expected. The SVT-AV1 dev team has been hard at work to reduce the amount of presets. As that's been a focus for quite some time, I'm not sure the initial reasons for this are still valid today. Anyway, what we're mostly seeing are small but free speed improvements from smart trade-off decisions. It's worth noting that versions 2.0.0 and 3.0.0 weren't actually major feature milestones. The version numbers jumped because of breaking API changes that aren't backward compatible with previous releases. Beyond the incremental performance gains, analysis of the different changelogs reveals a clear development strategy focused on specific areas. The dev team has invested heavily in ARM optimizations and memory requirements reduction, worked on the fast-decode feature to further reduce decoding cycles, and streamlined the architecture by removing the decoder component entirely. While many of these changes might not influence quality metrics, they represent important steps toward broader SVT-AV1 adoption by facilitating integration for actors in the industry and ensuring cross-platform consistency. The biggest changes since v2.0.0 probably lie in the parameters originating from *SVT-AV1-PSY* that were recently introduced. ## Presets Analysis TLDR **Editorially scoped conclusion:** presets 2 and 4 were promising candidates in the author's v3.0.1 corpus and custom-score analysis, while presets 5–8 offered faster measured encoding. The single-run timing limitations and unvalidated quality scales prevent calling them universal efficiency champions. The v2.0.0 baseline also contains variance-boost patches, so this is not a comparison of untouched release defaults. Use these preserved results to choose experiments, then evaluate a current build on representative sources with [documented metrics and visual checks](/guides/compare-encoding-quality/). They do not establish the best preset for another workload or version. ## SVT-AV1 v3.0.x Parameters Revisited This blog post is already pretty long... Although we won't revisiting *every* encoder parameter like we did back in the first deep dive on v1.8.0, we will concentrate on a few important ones, some of them coming straight from the *SVT-AV1-PSY* project! **EDIT:** This section has been developed further in Part 2 of the article, now [available here](/articles/svt-av1-fourth-deep-dive-p2/)! ## Closing Thoughts Today, we tested five SVT-AV1 versions, ranging from v2.0.0 to v3.0.x, to quantify their relative efficiency and speed. New metrics were introduced and the format from the last blog post entry was iterated upon to improve the overall quality and flow of this present article. We used this opportunity to experiment and learn encoding knowledge along the way, I hope it was valuable to you too! This is only the first part of this benchmarking session, as we'll deep dive variance boost and a few other exciting features in the next one. Revisiting certain key parametres in such a context has been on my mind for quite a while, so I hope you will look forward to Part 2! Your feedback and suggestions are always welcome as I work to improve this blog format. Do you have a request for me? Something you'd like to see fixed or added? Let me know what you think on socials or in the different communities I'm active in! Thanks for reading and see you soon! I want to extend my thanks to the people who contributed, directly or indirectly, to the making of this article, including [Gianni Rosato (gb82)](https://github.com/gianni-rosato), [Line (Lumen)](https://codeberg.org/Line-fr), [Soda](https://github.com/GreatValueCreamSoda), [Emre](https://github.com/emrakyz), [Bolu](https://github.com/0xb01u/), [Julio Barba](https://github.com/juliobbv-p), the people behind slow.pics for hosting thousands of screenshots each time I make these articles, the SVT-AV1 dev team for the work on this amazing encoder, and probably others I'm forgetting... --- *Consider supporting me by making a donation on [my Ko-Fi page](https://ko-fi.com/nekotrix), to reward my efforts and to compensate for the electricity bills of weeks of non-stop encoding.* {} --- # Deep Dive into SVT-AV1's Evolution (Part 2): Encoder Parameters Revisited Canonical URL: https://encode.wiki/articles/svt-av1-fourth-deep-dive-p2/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: 32212348d89dde4f21bd17e4405950c115ff3e95123e8e578ffac97e8138e67a > **Note — Editorial correction — 7 September 2026.** > > The author's SVT-AV1 3.0.x samples, graphs, tables, screenshots, and timings remain historical experimental results. Part 2 inherits Part 1's unvalidated custom metric transformations, so quality rankings and pooled BD-rates are exploratory. Visual examples are useful observations but do not validate objective scales. Parameter conclusions below have been narrowed; no encodes or validation study were rerun. # Introduction Welcome to the second part of my SVT-AV1 testing analysis! I received lots of kind words, including constructive feedback to improve on my methodology, I sincerely appreciate it! While I couldn’t incorporate those suggestions for this follow-up, stay tuned, because you’ll likely hear more from me before summer ends. Before we continue, if you haven’t seen Part 1 yet, I recommend giving it a quick look! It covers the test methodology, sample clips, and base encoder settings in detail. The only change to this Part is my decision to remove the *full* graphs in an attempt to cut down on bloat. If you really want to, you can still access them on the repository where we upload pictures for the blog posts [here](https://github.com/av1-community-contributors/images). Now, without further ado, let’s dive right back in where we left off! ## How to interpret this experiment W-VMAF applies a historical luma model to separate color planes and disables motion; W-XPSNR changes motion processing and pools component errors; Butteraugli changes the assumed intensity; SSIMULACRA2 uses harmonic frame pooling. Those outputs must not be treated as standard validated video metrics. Harmonic pooling is particularly problematic for zero or negative scores. Averaging BD-rates from four such functions does not turn them into a perceptual savings estimate. Read the [corrected methodology in Part 1](/articles/svt-av1-fourth-deep-dive-p1/#methodology) before using the plots. Every “efficiency” statement below means efficiency under this historical corpus and scoring pipeline. Version-specific defaults are those of the tested 3.0.x builds; verify current options in the [official parameters](https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/Parameters.md). For new work start with [the current guide](/guides/av1-with-svt-av1/) and [quality-comparison workflow](/guides/compare-encoding-quality/). ## SVT-AV1 v3.0.x Parameters Revisited Today, we are looking at **8 encoder features** present in SVT-AV1 v3.0.x! Although we won't be revisiting *every* encoder parameter like we did back in the first deep dive on v1.8.0, we are going to concentrate on a few important ones, some of them coming straight from the *SVT-AV1-PSY* project! Let's start with the feature you are likely most exciting about: *varboost*! ### Variance Boost The author of variance boost made a highly visual explanation of the feature in the official SVT-AV1 documentation you can find [here](https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/Appendix-Variance-Boost.md). This overview will probably do a better job than me in describing what it does, but in a few words, *varboost* allocates more bits to low-contrast areas in a frame. You can enable varboost via the `--enable-variance-boost` parameter and control its behavior by changing its `--variance-boost-strength` or its `--variance-octile` setting. Basically, the strength controls how much areas are to be boosted, while octile controls how much of the area needs to be deemed low-contrast before being boosted. > *In every graph of this section, you will notice `vbs_o_` in the legend. The `vb` stands for `varboost`, the `s` stands for `strength` and lastly the `o` stands for octile. In the last subsection, you will even see `vbs_o_c_` with the `c` standing for `curve`. To take one example, `vbs1o4c2` means `varboost at strength 1 and octile 4 on the 2nd curve`.* --- #### Varboost Strength We're going to test all 4 available *strengths* values, with *octile* as the variable... ##### ...starting with `--variance-boost-strength 1`! ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). At HQ, on almost all metrics (excepted VMAF which is more inconsistent here), all octile values are more efficient than *varboost disabled*. With one notable exception in *octile 8* which often scores the same or worse than *no varboost* depending on the clip. The lower octiles seem to score increasingly better here. ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). At LQ, the results tend to be the same, however there are more outliers and overall the octile value seem to be more negligible. *No varboost* often scores better than many octile values on VMAF, which is an interesting behavior to observe. ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). In terms of speed, we won't be surprised to learn that the lower octile you go, the slower the encoding instance will be, as the output filesize is bigger and that *tends* to slow down SVT-AV1. By bitrate normalizing, we would get closer performance between all options. ---> Interpretation: `1` is the most conservative strength value, so we expect reasonable results from varboost here. All octile values consistently provide efficiency improvements except for `--variance-octile 8`. It is counter-intuitive to see lower octiles score better in efficiency so far, but we'll see if that changes as we increase the strength. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/mVtRwupm) | [Avatar (LQ)](https://slow.pics/c/Qoa3amhs) | | [Ducks (HQ)](https://slow.pics/c/LpnpWeCh) | [Ducks (LQ)](https://slow.pics/c/Ei6cY7hT) | | [Fallout (HQ)](https://slow.pics/c/HzcmlT95) | [Fallout (LQ)](https://slow.pics/c/H4lJgTSZ) | | [Minecraft (HQ)](https://slow.pics/c/EcRac2q1) | [Minecraft (LQ)](https://slow.pics/c/7zucoraP) | | [Sol Levante (HQ)](https://slow.pics/c/Ra474TKQ) | [Sol Levante (LQ)](https://slow.pics/c/dfo9gMIX) | | [Suzume (HQ)](https://slow.pics/c/HF6ls9AW) | [Suzume (LQ)](https://slow.pics/c/RaZ0Q6SM) | | [Mandalorian (HQ)](https://slow.pics/c/0vwqi52J) | [Mandalorian (LQ)](https://slow.pics/c/9dBsnQaJ) | ##### Let's continue with `--variance-boost-strength 2`, the default *strength* value in every iteration of SVT-AV1: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: The picture is consistent with what we've previously seen, so I won't repeat myself. However, we must keep in mind that the higher strength and the lower octile we go, the more the curve is shifted to the top right, which *may not* paint the most fair picture of the situation and might skew our interpretation in favor of the one end of the graph or another. That being said, except for VMAF which behaves a bit differently with varboost, we see the default of `--variance-boost-strength 2 --variance-octile 6` always increases efficiency over *no varboost* across basically all clips and metrics, which is an observation under these custom metrics, not proof of a perceptual improvement. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/ij7c8xbT) | [Avatar (LQ)](https://slow.pics/c/I8VX0gmb) | | [Ducks (HQ)](https://slow.pics/c/SRIm1hoy) | [Ducks (LQ)](https://slow.pics/c/SR3f3YWp) | | [Fallout (HQ)](https://slow.pics/c/7NeqER2Z) | [Fallout (LQ)](https://slow.pics/c/CQFdBB9C) | | [Minecraft (HQ)](https://slow.pics/c/crBjBTvx) | [Minecraft (LQ)](https://slow.pics/c/hfA0CXrp) | | [Sol Levante (HQ)](https://slow.pics/c/3l2dOaoE) | [Sol Levante (LQ)](https://slow.pics/c/cSDSKnv7) | | [Suzume (HQ)](https://slow.pics/c/pSVfrZSK) | [Suzume (LQ)](https://slow.pics/c/1B0Af0Ta) | | [Mandalorian (HQ)](https://slow.pics/c/t6MEfwHh) | [Mandalorian (LQ)](https://slow.pics/c/UJmCWT1T) | ##### Now for `--variance-boost-strength 3`: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: It's more of the same, varboost at *strength 3* tends to perform better in efficiency at higher quality targets though there can still be gains at lower qualities depending on the content at hand. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/l1PSZy1m) | [Avatar (LQ)](https://slow.pics/c/6XyZa5m2) | | [Ducks (HQ)](https://slow.pics/c/HfgyEtI6) | [Ducks (LQ)](https://slow.pics/c/vNb218sk) | | [Fallout (HQ)](https://slow.pics/c/lTxBGS4h) | [Fallout (LQ)](https://slow.pics/c/Zb1SsMXo) | | [Minecraft (HQ)](https://slow.pics/c/t7pX8SGu) | [Minecraft (LQ)](https://slow.pics/c/dKcQDN48) | | [Sol Levante (HQ)](https://slow.pics/c/q98rqqlx) | [Sol Levante (LQ)](https://slow.pics/c/fiTECJdJ) | | [Suzume (HQ)](https://slow.pics/c/xAcvt1gg) | [Suzume (LQ)](https://slow.pics/c/pZxBf9s9) | | [Mandalorian (HQ)](https://slow.pics/c/0dhkMBkj) | [Mandalorian (LQ)](https://slow.pics/c/ab9AOw54) | ##### And lastly, `--variance-boost-strength 4`, which will print you a warning that this may be too aggressive in some usecases: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: So, what does this unusual varboost strength have in store for us? Well, nothing as dangerous as we're led to believe. In fact, by in large, we observe the same things as the other three strengths. You may have noticed this yourself, as we've increased the strength, Butteraugli has tended to highlight *lower octiles* more and more at high quality and *no varboost* more and more at low quality. Still, *varboost on* often provides great gains and the optimal octile depends a lot on the sample. Octile 6 was the tested default; this experiment does not establish that it is best for every source. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/qUhijQqk) | [Avatar (LQ)](https://slow.pics/c/fLvog0BW) | | [Ducks (HQ)](https://slow.pics/c/DCX9HCno) | [Ducks (LQ)](https://slow.pics/c/M8PcEi4T) | | [Fallout (HQ)](https://slow.pics/c/yfF24i4L) | [Fallout (LQ)](https://slow.pics/c/1aCFxgND) | | [Minecraft (HQ)](https://slow.pics/c/bTHqdZS3) | [Minecraft (LQ)](https://slow.pics/c/0vk3SJ0C) | | [Sol Levante (HQ)](https://slow.pics/c/hYRDUXh1) | [Sol Levante (LQ)](https://slow.pics/c/DcIxPyX2) | | [Suzume (HQ)](https://slow.pics/c/FaTSgkNC) | [Suzume (LQ)](https://slow.pics/c/1exzpYov) | | [Mandalorian (HQ)](https://slow.pics/c/RARbCDOr) | [Mandalorian (LQ)](https://slow.pics/c/SMe5q0Kv) | --- #### Varboost Octile Now, let's do the contrary and test all 8 *octile* values while solely adjusting the *strength*... ##### ...starting with `--variance-octile 1`! ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: For an octile value that supposedly should boost too many blocks in frames, `1` scores pretty consistently better than *no varboost*, especially at high quality. What's more, even though it can be argued all varboost curves are extremely close to one another, higher strengths are ever so slightly better performing than lower ones at high quality, while the contrary is more often observed at low quality though not always! Fallout seems to benefit less from varboost, heck it can be harmful at low quality according to some metrics. You will be unsurprised to hear that the higher the strength the slower encoding tends to be. Again, speed is affected by the resulting output filesize. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/GzZ0xiAW) | [Avatar (LQ)](https://slow.pics/c/ZuIOSRed) | | [Ducks (HQ)](https://slow.pics/c/jUNbTEHV) | [Ducks (LQ)](https://slow.pics/c/bknKSeOY) | | [Fallout (HQ)](https://slow.pics/c/zvc0jqvt) | [Fallout (LQ)](https://slow.pics/c/ongtADY8) | | [Minecraft (HQ)](https://slow.pics/c/NKeFM3q4) | [Minecraft (LQ)](https://slow.pics/c/8LTGKKGa) | | [Sol Levante (HQ)](https://slow.pics/c/CB3GU6g5) | [Sol Levante (LQ)](https://slow.pics/c/h3jJaTAG) | | [Suzume (HQ)](https://slow.pics/c/kCJj6jDP) | [Suzume (LQ)](https://slow.pics/c/fpzkIsUb) | | [The Mandalorian (HQ)](https://slow.pics/c/ZeVlmDlS) | [The Mandalorian (LQ)](https://slow.pics/c/PVvi6EWQ) | ##### Let's look at `--variance-octile 2`: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: **Octile 2**'s results are similar to *1*, that is to say close curves between all strengths, with a tendency for higher strengths to be better at high quality, for lower strengths to be at times preferable at low quality, and for varboost to overall be beneficial over it disabled, except according to VMAF. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/ImqHaKb7) | [Avatar (LQ)](https://slow.pics/c/EhkP5ZaF) | | [Ducks (HQ)](https://slow.pics/c/0CRmG4s9) | [Ducks (LQ)](https://slow.pics/c/lkB0foeJ) | | [Fallout (HQ)](https://slow.pics/c/TlQCQoeH) | [Fallout (LQ)](https://slow.pics/c/ZSxW0PTv) | | [Minecraft (HQ)](https://slow.pics/c/KuqBscxE) | [Minecraft (LQ)](https://slow.pics/c/fZL3hiWK) | | [Sol Levante (HQ)](https://slow.pics/c/eLZy8Fjv) | [Sol Levante (LQ)](https://slow.pics/c/B77FJMuy) | | [Suzume (HQ)](https://slow.pics/c/zvkKQTHO) | [Suzume (LQ)](https://slow.pics/c/5B82eyRP) | | [The Mandalorian (HQ)](https://slow.pics/c/80ofSD0W) | [The Mandalorian (LQ)](https://slow.pics/c/ZWSi8W6G) | ##### Let's test `--variance-octile 3`: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: It can be summarized the same as *octile 1* and *2*. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/WriHrzHL) | [Avatar (LQ)](https://slow.pics/c/bXA4FPus) | | [Ducks (HQ)](https://slow.pics/c/RwggDVq4) | [Ducks (LQ)](https://slow.pics/c/Z8MERQqW) | | [Fallout (HQ)](https://slow.pics/c/Cnsx12Ct) | [Fallout (LQ)](https://slow.pics/c/KUFUrvhX) | | [Minecraft (HQ)](https://slow.pics/c/SxnyNTDr) | [Minecraft (LQ)](https://slow.pics/c/GTydHu65) | | [Sol Levante (HQ)](https://slow.pics/c/iJFd4qzD) | [Sol Levante (LQ)](https://slow.pics/c/gVNXWh7C) | | [Suzume (HQ)](https://slow.pics/c/kYGB1IWf) | [Suzume (LQ)](https://slow.pics/c/yGLJnHAB) | | [The Mandalorian (HQ)](https://slow.pics/c/ryzIi6Ky) | [The Mandalorian (LQ)](https://slow.pics/c/er2a3xNi) | ##### And `--variance-octile 4`: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: I swear it's not just me getting lazy, there's not much more to say than as already been said! ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/bn1iUk8T) | [Avatar (LQ)](https://slow.pics/c/S40uaj7w) | | [Ducks (HQ)](https://slow.pics/c/5auZYNLd) | [Ducks (LQ)](https://slow.pics/c/OH59amm8) | | [Fallout (HQ)](https://slow.pics/c/PppdU8Cp) | [Fallout (LQ)](https://slow.pics/c/LWF9w3KG) | | [Minecraft (HQ)](https://slow.pics/c/Z3Rl51sK) | [Minecraft (LQ)](https://slow.pics/c/UdptXCxk) | | [Sol Levante (HQ)](https://slow.pics/c/ySMBddAM) | [Sol Levante (LQ)](https://slow.pics/c/tNrgSJSR) | | [Suzume (HQ)](https://slow.pics/c/9FVioL5x) | [Suzume (LQ)](https://slow.pics/c/WWCDsBGc) | | [The Mandalorian (HQ)](https://slow.pics/c/pOCex4aG) | [The Mandalorian (LQ)](https://slow.pics/c/2IiO8loM) | ##### And `--variance-octile 5`! ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: Cf. previous interpretations. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/xfux0wc3) | [Avatar (LQ)](https://slow.pics/c/4wUXeENY) | | [Ducks (HQ)](https://slow.pics/c/byPkfKGV) | [Ducks (LQ)](https://slow.pics/c/jhr4SelN) | | [Fallout (HQ)](https://slow.pics/c/XlWDEMlG) | [Fallout (LQ)](https://slow.pics/c/PoElCuV3) | | [Minecraft (HQ)](https://slow.pics/c/gFx0OGXz) | [Minecraft (LQ)](https://slow.pics/c/5mFpmbqq) | | [Sol Levante (HQ)](https://slow.pics/c/XcpyeAfl) | [Sol Levante (LQ)](https://slow.pics/c/elhMkf3h) | | [Suzume (HQ)](https://slow.pics/c/pBXnSGgh) | [Suzume (LQ)](https://slow.pics/c/1ZmKPN5Y) | | [The Mandalorian (HQ)](https://slow.pics/c/xSNu2fAK) | [The Mandalorian (LQ)](https://slow.pics/c/ICwJ27DI) | ##### What about `--variance-octile 6`, the default *octile* value in every iteration of SVT-AV1: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: The default octile value tends, again, to perform better on higher strengths at high quality, and sometimes lower strengths at low quality. We notice it is getting easier to distinct between strengths as we've increased octile, which can be good depending on how you see things. Something we haven't discussed until now is how higher strengths tend to be more inconsistent according to SSIMU2 as you get closer to the *CRF40-50* range, which could be problematic depending on your usecase, and thus something to keep in mind. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/uh1kwBCy) | [Avatar (LQ)](https://slow.pics/c/BhXRytzk) | | [Ducks (HQ)](https://slow.pics/c/45p8EDsI) | [Ducks (LQ)](https://slow.pics/c/7xCXSvO2) | | [Fallout (HQ)](https://slow.pics/c/4xqrsZJ9) | [Fallout (LQ)](https://slow.pics/c/lvmSA3XE) | | [Minecraft (HQ)](https://slow.pics/c/w2OOsRQF) | [Minecraft (LQ)](https://slow.pics/c/VCsRWnKr) | | [Sol Levante (HQ)](https://slow.pics/c/9Cbo7ua5) | [Sol Levante (LQ)](https://slow.pics/c/r1tP3s25) | | [Suzume (HQ)](https://slow.pics/c/oZ61IBgw) | [Suzume (LQ)](https://slow.pics/c/UhzGesBH) | | [The Mandalorian (HQ)](https://slow.pics/c/u5atwJ8W) | [The Mandalorian (LQ)](https://slow.pics/c/eXAZ1p0g) | ##### Following with `--variance-octile 7` tests: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: Cf. previous interpretations. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/dPYDMxXt) | [Avatar (LQ)](https://slow.pics/c/1bOEH4Ts) | | [Ducks (HQ)](https://slow.pics/c/22BsOu46) | [Ducks (LQ)](https://slow.pics/c/gzuNDayw) | | [Fallout (HQ)](https://slow.pics/c/LnrHCX4b) | [Fallout (LQ)](https://slow.pics/c/JOTbCI5m) | | [Minecraft (HQ)](https://slow.pics/c/RfMprkEY) | [Minecraft (LQ)](https://slow.pics/c/whW5d55t) | | [Sol Levante (HQ)](https://slow.pics/c/qcR6vp2Q) | [Sol Levante (LQ)](https://slow.pics/c/cGoytwwE) | | [Suzume (HQ)](https://slow.pics/c/f7cPlcI0) | [Suzume (LQ)](https://slow.pics/c/S20TviAL) | | [The Mandalorian (HQ)](https://slow.pics/c/x736Wk54) | [The Mandalorian (LQ)](https://slow.pics/c/f3hZchK5) | ##### And lastly `--variance-octile 8` testing: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: Well, here we are, *octile 8* barely provides any gains and can be (quite) harmful depending on the clip and metric, especially at low qualities, so it was not a promising candidate on these plots; other content or objectives may differ. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/qsJDQuH9) | [Avatar (LQ)](https://slow.pics/c/sSjtrfV7) | | [Ducks (HQ)](https://slow.pics/c/AkPNi9tB) | [Ducks (LQ)](https://slow.pics/c/Ovc74G5T) | | [Fallout (HQ)](https://slow.pics/c/wftx5BS3) | [Fallout (LQ)](https://slow.pics/c/zhaFrhou) | | [Minecraft (HQ)](https://slow.pics/c/DgxYKGC3) | [Minecraft (LQ)](https://slow.pics/c/QUTIHXJo) | | [Sol Levante (HQ)](https://slow.pics/c/H9IjcZdh) | [Sol Levante (LQ)](https://slow.pics/c/D3gA2BNr) | | [Suzume (HQ)](https://slow.pics/c/OfIcrFq3) | [Suzume (LQ)](https://slow.pics/c/o28ioyrm) | | [The Mandalorian (HQ)](https://slow.pics/c/rdZTAUJn) | [The Mandalorian (LQ)](https://slow.pics/c/RVprUbv4) | --- #### Varboost Curve We will be comparing all 3 available varboost curves... ##### ...with the default settings first: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: We observe that all three curves tend to be blurred together, with the notable exception of *curve 2* scoring non-negligibly better on a few clips, consistently across all metrics. Speed-wise, I would argue it's a tie as all three curves are sometimes situationally slightly slower or faster. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/F44iAZvt) | [Avatar (LQ)](https://slow.pics/c/OsPifnca) | | [Ducks (HQ)](https://slow.pics/c/UdPvmsZd) | [Ducks (LQ)](https://slow.pics/c/MWvE2PhS) | | [Fallout (HQ)](https://slow.pics/c/mE4DPv4b) | [Fallout (LQ)](https://slow.pics/c/imXOhRu3) | | [Minecraft (HQ)](https://slow.pics/c/0M03K6Td) | [Minecraft (LQ)](https://slow.pics/c/vtXMiDX4) | | [Sol Levante (HQ)](https://slow.pics/c/0HkpGRVh) | [Sol Levante (LQ)](https://slow.pics/c/eUFlYP4S) | | [Suzume (HQ)](https://slow.pics/c/4pPMQEHl) | [Suzume (LQ)](https://slow.pics/c/tc6t8142) | | [Mandalorian (HQ)](https://slow.pics/c/CrjP7X1t) | [Mandalorian (LQ)](https://slow.pics/c/hdxcVqCC) | ##### I also conducted the tests with a different combination of varboost settings I have used on occasion: ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: The winner is less clear here, this time we can say it's a tie. Such results are why testing with a different combination of settings can be educative. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/PPInVFpH) | [Avatar (LQ)](https://slow.pics/c/3ddsAMj8) | | [Ducks (HQ)](https://slow.pics/c/r4N2mCXD) | [Ducks (LQ)](https://slow.pics/c/eVvOPXBr) | | [Fallout (HQ)](https://slow.pics/c/6EzFC57R) | [Fallout (LQ)](https://slow.pics/c/EUZWdHKu) | | [Minecraft (HQ)](https://slow.pics/c/Gz32ytoJ) | [Minecraft (LQ)](https://slow.pics/c/UKpTJkzI) | | [Sol Levante (HQ)](https://slow.pics/c/DkIz3Ti1) | [Sol Levante (LQ)](https://slow.pics/c/agKlz4Ul) | | [Suzume (HQ)](https://slow.pics/c/1XL15C39) | [Suzume (LQ)](https://slow.pics/c/daIcH6Bh) | | [Mandalorian (HQ)](https://slow.pics/c/52CQl8aI) | [Mandalorian (LQ)](https://slow.pics/c/gFNSbm5v) | --- #### Varboost Conclusion On the author's tested clips and custom measurements, varboost frequently improved score/rate curves, with different behavior at low and high quality. The recorded default was `--variance-boost-strength 2 --variance-octile 6`; the stronger combinations are experimental candidates, not general recommendations. Changing strength or octile can increase bitrate at a fixed CRF. Raising CRF to restore the file size **can also change visible quality and where bits are spent**. The old claim that this compromises nothing is withdrawn. Match output sizes, inspect low-contrast areas and motion, and test your content before changing defaults. --- ### `--tune` The tested SVT-AV1 3.0.x implementation offered these three tunes: - **`--tune 0` (VQ - Visual Quality)**: Favors sharper decisions, reducing blur but potentially introducing artifacts. - **`--tune 1` (PSNR - Peak Signal-to-Noise Ratio)**: The **default** in mainline SVT-AV1. - **`--tune 2` (SSIM - Structural Similarity Index Measure)**: The previous efficiency champion. Has the dynamics between tunes changed since we last tested them on SSIMULACRA2 almost a year and a half ago? Let's see! ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: In most cases, on most metrics, *tune 1* comes out on top in efficiency, with *tune 2* sometimes trading blows and even winning. Tune 0 is usually quite a bit behind, except on XPSNR. In terms of speed, all tunes seem to perform closely from one another, without a clear winner. Tune 1 scored well in this historical pipeline, but the custom metrics do not establish it as the best balance for most users. Compare tune choices at similar output sizes using playback as well as documented metrics; defaults and available tunes vary by encoder release. >#### **Specialized Tunes in SVT-AV1 Forks** >The SVT-AV1-PSY based forks introduced new tunes to catter to new usecases. We won't be testing these forks today but I'm mentioning them for reference purposes. Note that the following two `--tune 3` modes are entirely different depending on the encoder variant! >- **`--tune 3` (_SVT-AV1-PSY(EX)_ exclusive)**: A psychovisual enhancement of `--tune 2`, borrowing some features from `--tune 0` and other tweaks. A general-purpose psychovisual tune for a wide range of content. >- **`--tune 3` (_SVT-AV1-HDR_)**: Acts as a *grain-optimized* mode, disabling CDEF, restoration, and temporal filtering while applying aggressive psychovisual adjustments. Described by that fork as grain-oriented; this untested feature is not validated by the present experiment. We may want to confirm our findings with a visual analysis on the encoded samples: ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/KoZYGlBL) | [Avatar (LQ)](https://slow.pics/c/CDMgkOVT) | | [Ducks (HQ)](https://slow.pics/c/eiklaXqz) | [Ducks (LQ)](https://slow.pics/c/kLeCUR5k) | | [Fallout (HQ)](https://slow.pics/c/3lzjEFEX) | [Fallout (LQ)](https://slow.pics/c/u9Wx37CU) | | [Minecraft (HQ)](https://slow.pics/c/gQPbq4j0) | [Minecraft (LQ)](https://slow.pics/c/FGGpyjeZ) | | [Sol Levante (HQ)](https://slow.pics/c/9B9lOQ1c) | [Sol Levante (LQ)](https://slow.pics/c/Nr2DBM1m) | | [Suzume (HQ)](https://slow.pics/c/RTlTjyW4) | [Suzume (LQ)](https://slow.pics/c/kV5XUUi1) | | [Mandalorian (HQ)](https://slow.pics/c/CO81FwdN) | [Mandalorian (LQ)](https://slow.pics/c/IxDW70kW) | Lastly, my own opinion regarding the tunes is that it probably does not matter as much as you think. Again, unless you're willing to hyper-tune, which implies testing parameters each time you encode a new source, no one can guess in advance what's going to be best for that content because it depends on an almost infinite amount of variables. The thing with psychovisual approaches is that metrics may be saying something and your eyes something else. Plus it is wildly subjective: my eyes may disagree with yours, or anyone else's. Don't fret too much over the tune. --- Let's continue with the newly introduced parameters of v3.0.0, starting out with an important feature in the context of AV1: luma bias! ### `--luminance-qp-bias` Anyone familiar with AV1 for long enough is aware that its encoders have struggled on dark scenes forever. As the encoder implementations mature, performance in such scenes naturally improve, however in many cases they persist in allocating insufficient bits to these darker scenes. This setting changes (almost) everything! It effectively applies a dumb qp offset to frames of lower overall brightness. The higher the value, the stronger the effect is. This implementation has one advantage and one weakness: it gives the user control over the bitrate balancing between bright and dark frames, however if only parts of the frame are dark and the rest is fairly bright, it may not fix cases of localized detail loss or blurring. So let's see the effect it can have on efficiency and visuals! ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: On the HQ graphs, we can see no luma-bias tends to score last or at least lower than conservative luma-bias values. On the LQ graphs, we usually observe the opposite, that is to say that no luma-bias tends to barely come out on top, with increasing luma-bias values decreasing efficiency ever so slightly. If we look at performance, the impact of luma-bias is negligible at lower *CRF* values, but gradually increases with higher *CRF* values for the simple reason that the frames whose QP will be reduced will take a bit more time to encode, as is the expected behavior of any encoder. The effect on QP, and thus performance, is going to be more important the higher base *CRF* you start with. Let's look at some BD-rate numbers directly, to try and clarify the graphs: | Luma-Bias Effect | LB0 | LB10 | LB20 | LB30 | LB40 | LB50 | LB60 | LB70 | LB80 | LB90 | LB100 | |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| | Avatar | 0% | +0.18% | +0.59% | +0.74% | +0.89% | +1.11% | +1.28% | +1.45% | +1.63% | +1.73% | +1.94% | | Ducks | 0% | +1.33% | +2.34% | +3.04% | +3.76% | +4.43% | +5.02% | +5.74% | +6.29% | +6.82% | +7.43% | | Fallout | 0% | -0.31% | +0.79% | +1.29% | +1.84% | +2.56% | +2.72% | +3.04% | +3.40% | +3.73% | +4.06% | | Minecraft | 0% | +0.69% | +1.43% | +1.99% | +2.64% | +3.10% | +3.47% | +3.87% | +4.26% | +4.59% | +5.06% | | Sol Levante | 0% | -0.09% | -0.12% | -0.02% | +0.21% | +0.29% | +0.44% | +0.42% | +0.53% | +0.60% | +0.75% | | Suzume | 0% | -0.45% | -0.43% | -0.34% | -0.31% | -0.30% | -0.21% | -0.11% | -0.07% | +0.02% | +0.08% | | Mandalorian | 0% | +0.57% | +0.91% | +1.29% | +1.56% | +1.80% | +2.24% | +2.30% | +2.53% | +2.78% | +3.03% | Unfortunately, I couldn't easily separate the BD-rate numbers at low quality and the ones at high quality, so we can't exactly reproduce what I interpreted from the graphs earlier. Still, this gives insightful data, which showcase that the BD-rate across the entire quality range is improved the most on the anime clips and tends to be harmful on live action and gaming clips, again across the entire quality range, not when isolating a smaller range where we could make luma-bias look way more appealing. Luma bias changes quantization allocation according to average frame luminance. A score improvement or regression reflects the chosen objective and distribution of bits; it does not by itself diagnose badly tuned rate control. My advice for choosing a luma-bias value is to simply isolate a test sample in your source and test out a few values (like 10, 30, 50...), look at the bitrate balance between dark and bright frames by checking the impact on visuals and filesizes, and finally decide what you prefer. No value below 50 is guaranteed harmless; even a small bias can alter bitrate distribution and visible detail. Beware that the author of the feature warned me it isn't suited for the PQ transfer used in most UHD blu-rays! Use luma-bias exclusively on SDR and HDR HLG videos. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/NUsH5vl0) | [Avatar (LQ)](https://slow.pics/c/dxkop5sv) | | [Ducks (HQ)](https://slow.pics/c/oWY5nMIr) | [Ducks (LQ)](https://slow.pics/c/Ai0GXaAZ) | | [Fallout (HQ)](https://slow.pics/c/cWT7QhiL) | [Fallout (LQ)](https://slow.pics/c/hskxyERo) | | [Minecraft (HQ)](https://slow.pics/c/yRa03RAb) | [Minecraft (LQ)](https://slow.pics/c/DLp6cOsW) | | [Sol Levante (HQ)](https://slow.pics/c/Z8XcDPxn) | [Sol Levante (LQ)](https://slow.pics/c/kUemyTCw) | | [Suzume (HQ)](https://slow.pics/c/WZPOKhQt) | [Suzume (LQ)](https://slow.pics/c/kc2Zgskv) | | [Mandalorian (HQ)](https://slow.pics/c/D1QSRGhy) | [Mandalorian (LQ)](https://slow.pics/c/eXysNAjI) | --- ### `--sharpness` Sharpness is a straighforward parameter, though it may not do exactly what you'd assume it to do. It does not affect the encodes' clarity but rather impacts the deblocking filter sharpness, which can lead to increased fidelity. ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: Changing deblocking sharpness trades smoothing against retained edges and artifacts; no one setting must suit all viewing objectives. On surface, it looks like there is not much room for improvements. It does depend on the metric and clip, but in many of these, all sharpness values perform extremely closely from each another, apart from 3 (a bit lower or higher) and 4+ (usually noticeably lower). Speed wise, negative sharpness values perform closely to the default of 0, and increasing positive values become slower and slower, but as we can see on the x axis, it's rather negligible. Again, there are so many data points that a BD-rate table will help visualize stuff differently: | Sharpness Effect | -7 | -6 | -5 | -4 | -3 | -2 | -1 | 0 | +1 | +2 | +3 | +4 | +5 | +6 | +7 | |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:| | Avatar | 0% | -0.04% | -0.05% | -0.04% | -0.16% | -0.04% | -0.03% | -0.02% | -0.03% | -0.01% | +1.07% | +3.44% | +6.05% | +8.28% | +9.65% | | Ducks | 0% | -0.05% | -0.09% | -0.10% | -0.14% | -0.10% | -0.09% | -0.06% | +0.04% | +0.06% | +2.14% | +8.94% | +14.24% | +18.19% | +20.74% | | Fallout | 0% | -0.05% | -0.07% | -0.13% | -0.16% | -0.15% | -0.13% | -0.13% | +0.01% | +0.01% | +0.99% | +5.62% | +10.23% | +13.68% | +16.00% | | Minecraft | 0% | -0.04% | -0.08% | -0.12% | -0.17% | -0.11% | -0.08% | -0.01% | +0.21% | +0.26% | -1.14% | +0.88% | +3.88% | +5.60% | +6.83% | | Sol Levante | 0% | -0.03% | -0.07% | -0.10% | -0.02% | -0.01% | -0.17% | -0.06% | -0.05% | +0.04% | -3.61% | -3.61% | -2.65% | -1.89% | -1.53% | | Suzume | 0% | -0.03% | -0.07% | -0.15% | -0.13% | -0.17% | -0.20% | -0.13% | -0.75% | -0.77% | -0.46% | +2.73% | +5.87% | +7.89% | +8.91% | | Mandalorian | 0% | -0.02% | -0.04% | -0.01% | -0.17% | -0.13% | -0.06% | -0.20% | -0.95% | -1.07% | -1.86% | -0.49% | +1.09% | +2.16% | +2.65% | **Editorial clarification:** this table averages BD-rate results from four custom measurement functions across a broad range. That aggregate is preserved as the author's statistic, not validated perceptual bitrate savings. Different overlap ranges, unstable curves, and metric disagreement can change the result. Inspect individual curves and visual samples; their presence does not validate the aggregate. Anyway, on average we can see in the table above that negative sharpness values (-7 to -1) generally show minor BD-rate improvements or neutral effects, while positive sharpness values (+1 to +7) can show decent, consistent BD-rate improvements or neutral effects with 1 & 2, and either bigger gains or significant degradations with 3 and above. We notice that *"Sol Levante"* loves sharpness (any value really), whereas the gaming clips and *"ducks take off"* rather dislike it. So, what effect does sharpness have on visuals: ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/ygCCh0bq) | [Avatar (LQ)](https://slow.pics/c/Y4qtod2v) | | [Ducks (HQ)](https://slow.pics/c/iNLdFEQl) | [Ducks (LQ)](https://slow.pics/c/Ks9N1GI0) | | [Fallout (HQ)](https://slow.pics/c/pI7ijRcy) | [Fallout (LQ)](https://slow.pics/c/E8dfmTz7) | | [Minecraft (HQ)](https://slow.pics/c/gJPslpwr) | [Minecraft (LQ)](https://slow.pics/c/XWc5abmS) | | [Sol Levante (HQ)](https://slow.pics/c/SMMOEbcj) | [Sol Levante (LQ)](https://slow.pics/c/F0invSsk) | | [Suzume (HQ)](https://slow.pics/c/J1esnTPE) | [Suzume (LQ)](https://slow.pics/c/Wc22o61r) | | [Mandalorian (HQ)](https://slow.pics/c/65LP89UX) | [Mandalorian (LQ)](https://slow.pics/c/g0vG4p8B) | --- ### `--tf-strength` Temporal filtering in SVT-AV1 combines information from multiple nearby video frames to create cleaner reference pictures with reduced noise, which helps improve compression quality especially for noisy source material. The feature was often considered too strong and often created unavoidable blocking on keyframes, so we historically disabled temporal filtering. Thankfully, a strength parameter has been introduced which has allowed to tame its effects. ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: On this corpus and custom scoring pipeline, *tf-strength 4* performed poorly; this does not rule it out for all content. Lower strengths than the default 3 tend to score increasingly better, though we seem to hit a ceiling below 2. *No temporal filtering* is competitive with low *tf-strength*s, though it still gets beaten slightly at times. There is an interesting outlier in Minecraft where low strengths and especially no tf perform noticeably worse for some reason. The difference in speed between all options is overall negligible. The historical results suggest testing lower temporal-filter strengths when similar blocking occurs. They do not prove that `--tf-strength 1` eliminates every blocking artifact or is optimal for all sources. Compare keyframes and moving detail at matched sizes, and check the installed version's defaults. > #### **Additional Parameter in SVT-AV1 Forks** > The SVT-AV1-PSY based forks include an additional `--kf-tf-strength` parameter which decouples tf strength on keyframes, and allows the user to concurrently fix the blocking issue and use a stronger tf strength on all other frames if they want. In mainline SVT-AV1, tf-strength is the same between keyframes and other frames, unless you use tune 0 in which case tf-strength on keyframes will be 1 value lower than on other frames (so for example *1* on keyframes if `--tune 0 --tf-strength 2` is set, the strength being capped at a minimum of 0 in any case). ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/SgZuDVbk) | [Avatar (LQ)](https://slow.pics/c/WHh361VL) | | [Ducks (HQ)](https://slow.pics/c/LbanU7Yl) | [Ducks (LQ)](https://slow.pics/c/pbfa7YFg) | | [Fallout (HQ)](https://slow.pics/c/tL86eXXv) | [Fallout (LQ)](https://slow.pics/c/fVKdbsw4) | | [Minecraft (HQ)](https://slow.pics/c/juHcIEFk) | [Minecraft (LQ)](https://slow.pics/c/9M9u6Srw) | | [Sol Levante (HQ)](https://slow.pics/c/DsXaFYfg) | [Sol Levante (LQ)](https://slow.pics/c/Et2cKCt0) | | [Suzume (HQ)](https://slow.pics/c/LIwgjH4w) | [Suzume (LQ)](https://slow.pics/c/nOLPdxus) | | [Mandalorian (HQ)](https://slow.pics/c/CVqDrlrX) | [Mandalorian (LQ)](https://slow.pics/c/zHxREyku) | --- ### `--lossless` SVT-AV1 added its lossless option in v3.0.0. This section examines the author's early 3.0.x results against the available aomenc/x264 workflows; it is not an exhaustive history of every AV1 encoder's capabilities. A zero-valued quality control is not by itself a cross-encoder definition of losslessness. I initially intended this section to compare aomenc to SVT-AV1, but complications quickly arose from my testing as you'll soon be able to see. Obviously, there is no question of efficiency graphs here as the metrics are expected to always be maxed out with lossless enabled. Anyway, no graphs will be needed here. The author's tested 3.0.x pipeline produced small nonzero sample errors for most clips, as recorded below. That observation must be scoped to those builds and conversions; it does not redefine mathematical losslessness or establish that later implementations have the same behavior. The [feature merge request](https://gitlab.com/AOMediaCodec/SVT-AV1/-/merge_requests/2312) provides historical implementation context. For preservation, compare decoded samples exactly in the same pixel format and separately check metadata. Running `--preset 4 --lossless 1` proves it on my test samples: | "Lossless" Test | PSNR (average) | PSNR (min) | PSNR (max) | |:-:|:-:|:-:|:-:| | Avatar | 96.616006 | 86.680008 | inf | | Ducks | inf | inf | inf | | Fallout | 104.378402 | 92.930594 | inf | | Minecraft | 96.263052 | 87.993916 | inf | | Sol Levante | 119.890723 | 106.868980 | inf | | Suzume | 116.226350 | 102.759654 | inf | | Mandalorian | 102.546893 | 91.381363 | inf | > *XPSNR and W-VMAF are not included here as the numbers were nonsensical due to the chroma weighting at play. As for Butteraugli's different intensity multiplier and SSIMULACRA2's harmonic scoring, they are not expected to affect the score of a lossless frame, however the GPU implementation itself isn't 100% score accurate to their original's so they can't be considered reliable for this specific usecase. Therefore, regular ffmpeg's PSNR filter was used here.* Sure, the scores are high, but not lossless-like! Funnily enough, the anime clips' average score a bit higher. That makes SVT-AV1 more lossless on anime than on live action! Is this confirmation that SVT-AV1 is a weeb encoder? You tell me. Anyway, for some reason, *"ducks take off"* is the only clip that is properly lossless out of SVT-AV1 here. What's even more concerning is that even though the outputs are not mathematically lossless, the filesizes are often bigger than `libx264 -preset veryfast -qp 0`, the latter of which is properly lossless: | "Lossless" Test | x264 Filesize | SVT-AV1 Filesize | |:-:|:-:|:-:| | Avatar | 282,198,409 o | 280,441,784 o (-0.6%) | | Ducks | 244,077,992 o | 234,884,891 o (-3.8%) | | Fallout | 272,838,887 o | 278,457,794 o (+2.1%) | | Minecraft | 382,935,638 o | 473,884,851 o (+23.8%) | | Sol Levante | 438,207,769 o | 448,937,567 o (+2.4%) | | Suzume | 372,844,589 o | 384,223,861 o (+3.1%) | | Mandalorian | 182,526,455 o | 185,680,771 o (+1.7%) | Needless to say the AV1 encodes took at least 10x longer to encode as well! Considering that *"Ducks"* is mathematically lossless and a few percents smaller, it shows that the format is in fact capable of compression gains in this department. The reported mismatch needs diagnosis of the exact historical encoder and conversion path; this correction does not attribute intent or assert a current-version defect. While the encodes are not *mathematically* lossless, I doubt anyone can see any difference with our bare eyes, but I still made comps so you can see for yourself. ---> Visual Comparisons: - [Avatar](https://slow.pics/c/B5ITVoCV) - [Ducks](https://slow.pics/c/yAjveP75) - [Fallout](https://slow.pics/c/M9F6GgKB) - [Minecraft](https://slow.pics/c/Hqx6vb5X) - [Sol Levante](https://slow.pics/c/Hqx6vb5X) - [Suzume](https://slow.pics/c/F3wXKV3g) - [Mandalorian](https://slow.pics/c/Makytom1) --- ### `--fast-decode` SVT-AV1 ships with its own built-in method for reducing decoding bottlenecks by smartly tuning down or disabling specific internal tools that trade off some efficiency for decoding performance. The encoder offers two `--fast-decode` levels, with `2` being more aggressive. The default is `0`. Three presets have been tested with the feature to quantify what the effects would be for different usecases. Due to some hardware-related issues, all the encodes in this section were re-run, so the speed numbers of disabled *fast-decode* encodes are different from before, however this ensured there would be no impact on my subsequent analysis. #### Preset 2 ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: The efficiency impact of *fast-decode* is clearly visible, be it at low or high quality targets. Beware of the much different scales on the y-axix between the HQ and LQ graphs, which could mislead you into thinking the effect at low quality is lesser, even though that's not the case. We observe that *fast-decode* can non-negligibly influence the speed of your encoding instances, with **1** appearing slower than *0* and **2** being faster than both. There's an exception in *"Sol Levante"* where *0* and *1* perform the same. Let's look at the effects on decoding speed with data I nicely aggregated into tables! >Decoding speeds were collected using ffmpeg 7.1.0 from Arch's official repository using: `ffmpeg -hide_banner -benchmark -i "" -f null - > /dev/null`. The tests were repeated 5 times and the performance numbers you'll see are the average of these 5 runs. I can say with confidence the speed deviation was *largely* negligible, but better safe than sorry! | Preset 2 Decoding Test (CRF12) | FD0 | FD1 | FD2 | |:-:|:-:|:-:|:-:| | Avatar | 197fps | 204fps *(+3.6%)* | 212fps *(+7.6%)* | | Ducks | 118fps | 126fps *(+6.8%)* | 125fps *(+5.9%)* | | Fallout | 65fps | 67fps *(+3.1%)* | 68fps *(+4.6%)* | | Minecraft | 82fps | 85fps *(+3.7%)* | 91fps *(+11.0%)* | | Sol Levante | 98fps | 105fps *(+7.1%)* | 107fps *(+9.2%)* | | Suzume | 360fps | 401fps *(+11.4%)* | 397fps *(+10.3%)* | | Mandalorian | 326fps | 348fps *(+6.7%)* | 340fps *(+4.3%)* | In our *high quality* target, `--fast-decode 1` provides a `+6%` decoding performance increase on average, while `--fast-decode 2` provides `+7.5%`. | Preset 2 Decoding Test (CRF33) | FD0 | FD1 | FD2 | |:-:|:-:|:-:|:-:| | Avatar | 429fps | 465fps *(+8.4%)* | 482fps *(+12.4%)* | | Ducks | 341fps | 366fps *(+7.3%)* | 342fps *(+0.3%)* | | Fallout | 131fps | 140fps *(+6.9%)* | 140fps *(+6.9%)* | | Minecraft | 182fps | 211fps *(+15.9%)* | 217fps *(+19.2%)* | | Sol Levante | 194fps | 211fps *(+8.8%)* | 210fps *(+8.2%)* | | Suzume | 684fps | 766fps *(+12.0%)* | 770fps *(+12.6%)* | | Mandalorian | 885fps | 912fps *(+3.1%)* | 946fps *(+6.9%)* | At *CRF33*, `--fast-decode 1`'s decoding speeds were faster of about `+8.9%` and `--fast-decode 2` of about `+9.5%`. Sure, `--fast-decode 2` doesn't provide substancial decoding benefits over `1`, heck even over `0` at times, however it also acts as a "fast-encode" parameter, so it can be argued it has its purpose. Before we continue with the visual comparisons, I will add that we are not on a low powered device, so the importance of such gains may not be immediately visible nor perfectly accurate to be honest. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/mHlwNgCj) | [Avatar (LQ)](https://slow.pics/c/3W7ELwA1) | | [Ducks (HQ)](https://slow.pics/c/BeiJQRSs) | [Ducks (LQ)](https://slow.pics/c/rj4jFQGb) | | [Fallout (HQ)](https://slow.pics/c/WPqNeTjN) | [Fallout (LQ)](https://slow.pics/c/ZcKpdvBR) | | [Minecraft (HQ)](https://slow.pics/c/1ElnTugb) | [Minecraft (LQ)](https://slow.pics/c/ODFp1HmP) | | [Sol Levante (HQ)](https://slow.pics/c/E84J2Jdc) | [Sol Levante (LQ)](https://slow.pics/c/xKIDF42q) | | [Suzume (HQ)](https://slow.pics/c/vaQ57EY2) | [Suzume (LQ)](https://slow.pics/c/UJCsXDmV) | | [Mandalorian (HQ)](https://slow.pics/c/Qy1roRVu) | [Mandalorian (LQ)](https://slow.pics/c/vwAg1glu) | --- #### Preset 4 ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: It can be observed the gaming clips's efficiency is less affected by the *fast-decode* feature, if at all. Even then, `--fast-decode 2` continue to provide encoding performance benefits. As we move to faster presets, the resulting streams are expected to be less complex and thus easier to decode. Is that assumption correct? And if so, does it imply that *fast-decode* will have a smaller impact when using preset 4? | Preset 4 Decoding Test (CRF12) | FD0 | FD1 | FD2 | |:-:|:-:|:-:|:-:| | Avatar | 185fps | 202fps *(+9.2%)* | 203fps *(+9.7%)* | | Ducks | 117fps | 126fps *(+7.7%)* | 121fps *(+3.4%)* | | Fallout | 67fps | 71fps *(+6.0%)* | 70fps *(+4.5%)* | | Minecraft | 87fps | 95fps *(+9.2%)* | 94fps *(+8.0%)* | | Sol Levante | 91fps | 100fps *(+9.9%)* | 99fps *(+8.8%)* | | Suzume | 324fps | 372fps *(+14.8%)* | 360fps *(+11.1%)* | | Mandalorian | 312fps | 336fps *(+7.7%)* | 326fps *(+4.5%)* | Looking at the FD0 column of the below and above table, compared to the *preset 2* ones, my claim seems to barely apply and only consistently at low quality levels at that. We'll see how it goes for *preset 6* in the next sub-section. Anyway, the average decoding speed impact at *HQ* is as follow: - `+9.2%` for `--fast-decode 1`, - `+7.1%` for `--fast-decode 2`. | Preset 4 Decoding Test (CRF33) | FD0 | FD1 | FD2 | |:-:|:-:|:-:|:-:| | Avatar | 432fps | 494fps *(+14.4%)* | 499fps *(+15.5%)* | | Ducks | 354fps | 394fps *(+11.3%)* | 375fps *(+5.9%)* | | Fallout | 143fps | 156fps *(+9.1%)* | 146fps *(+2.1%)* | | Minecraft | 197fps | 258fps *(+31.0%)* | 254fps *(+28.9%)* | | Sol Levante | 200fps | 224fps *(+12.0%)* | 217fps *(+8.5%)* | | Suzume | 696fps | 811fps *(+16.5%)* | 763fps *(+9.6%)* | | Mandalorian | 902fps | 981fps *(+8.8%)* | 999fps *(+10.8%)* | `--fast-decode 1` gives a hefty `+14.7%` increase in decoding performance at *lower quality* targets, as certain clips like *"Minecraft"* greatly benefit from it. `--fast-decode 2` brings a more modest `+11.6%` improvement. The trade-offs are quite a bit different than at *preset 2* which is quite fascinating, but `--preset 4` seems to draw more benefit from *fast-decode*! ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/z063QyOe) | [Avatar (LQ)](https://slow.pics/c/fjOkslFE) | | [Ducks (HQ)](https://slow.pics/c/mUdjpzQE) | [Ducks (LQ)](https://slow.pics/c/PJFYyxwC) | | [Fallout (HQ)](https://slow.pics/c/pBUEwMuo) | [Fallout (LQ)](https://slow.pics/c/Rk9yKcOL) | | [Minecraft (HQ)](https://slow.pics/c/0M6hKQxg) | [Minecraft (LQ)](https://slow.pics/c/ZNovZDlt) | | [Sol Levante (HQ)](https://slow.pics/c/sodLtXq2) | [Sol Levante (LQ)](https://slow.pics/c/5Oqc0ljs) | | [Suzume (HQ)](https://slow.pics/c/IdFzXbrh) | [Suzume (LQ)](https://slow.pics/c/pUqrSDSp) | | [Mandalorian (HQ)](https://slow.pics/c/HvpNGjj7) | [Mandalorian (LQ)](https://slow.pics/c/JKLlXygr) | --- #### Preset 6 ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: The efficiency situation here is the same as on *preset 4*, however we notice `--fast-decode 1` is no longer slower than disabled. Instead, it places itself in-between *0* and *2* in terms of performance, offering another kind of trade-off again! What influence on decoding speeds can we expect at `--preset 6`? | Preset 6 Decoding Test (CRF12) | FD0 | FD1 | FD2 | |:-:|:-:|:-:|:-:| | Avatar | 218fps | 216fps *(-0.9%)* | 228fps *(+4.6%)* | | Ducks | 128fps | 127fps *(-0.8%)* | 130fps *(+1.6%)* | | Fallout | 76fps | 74fps *(-2.6%)* | 77fps *(+1.3%)* | | Minecraft | 110fps | 106fps *(-3.6%)* | 112fps *(+1.8%)* | | Sol Levante | 100fps | 104fps *(+4.0%)* | 107fps *(+7.0%)* | | Suzume | 382fps | 381fps *(-0.3%)* | 394fps *(+3.1%)* | | Mandalorian | 343fps | 343fps *(0.0%)* | 357fps *(+4.1%)* | This time, be it at high or low quality, the base decoding speed without fast-decode is almost always faster. At *CRF12*, `--fast-decode 1` and `--fast-decode 2` respectively deliver a `-0.6%` decoding speed regression and a `+3.4%` speed improvement. | Preset 6 Decoding Test (CRF33) | FD0 | FD1 | FD2 | |:-:|:-:|:-:|:-:| | Avatar | 468fps | 480fps *(+2.6%)* | 508fps *(+8.5%)* | | Ducks | 358fps | 364fps *(+1.7%)* | 382fps *(+6.7%)* | | Fallout | 169fps | 168fps *(-0.6%)* | 177fps *(+4.7%)* | | Minecraft | 278fps | 303fps *(+9.0%)* | 335fps *(+20.5%)* | | Sol Levante | 209fps | 215fps *(+2.9%)* | 221fps *(+5.7%)* | | Suzume | 667fps | 694fps *(+4.0%)* | 715fps *(+7.2%)* | | Mandalorian | 878fps | 912fps *(+3.9%)* | 950fps *(+8.2%)* | The gains at low qualities are more appealing, at `+3.4%` for `--fast-decode 1` and `+8.8%` for `--fast-decode 2`. `--preset 6` benefits less from *fast-decode*, especially mode *1*, probably due to a shift in the decoding bottlenecks past this point. ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/P1ghVYLa) | [Avatar (LQ)](https://slow.pics/c/FtUPq8PL) | | [Ducks (HQ)](https://slow.pics/c/sNribSBQ) | [Ducks (LQ)](https://slow.pics/c/MYYl1GBK) | | [Fallout (HQ)](https://slow.pics/c/3GXE1MYP) | [Fallout (LQ)](https://slow.pics/c/YtIF51Xn) | | [Minecraft (HQ)](https://slow.pics/c/ccPFfGsI) | [Minecraft (LQ)](https://slow.pics/c/3hsSuzSD) | | [Sol Levante (HQ)](https://slow.pics/c/0MBOG9TK) | [Sol Levante (LQ)](https://slow.pics/c/NOIjeZkg) | | [Suzume (HQ)](https://slow.pics/c/6ghzI8QM) | [Suzume (LQ)](https://slow.pics/c/ktntjOqm) | | [Mandalorian (HQ)](https://slow.pics/c/0hv7XLQv) | [Mandalorian (LQ)](https://slow.pics/c/kVc5GHuR) | --- #### Fast Decode Conclusion The recorded decode timings can motivate testing fast-decode on a constrained device, but this workstation experiment does not demonstrate an ARM playback benefit. Measure the actual target decoder, frame deadlines, power use, and visible artifacts. The custom-score curves do not establish the size/quality cost for another viewer or device. --- ### Tiles Tiles partition a coded frame to enable independent tile decoding work; AV1 does not require every tile to have identical dimensions. Extra tiles can alter compression and parallelism. The following experiment measures effects on this SVT-AV1 build and decoder, not a guarantee of encoding or playback speed on all devices. > *In the following graphs and tables, `c` refers to `--tile-columns` and `r` refers to `--tile-rows`. For instance, `c2r1` can be read as `--tile-columns 2 --tile-rows 1`.* ---> Compression efficiency graphs, *"high quality"* range (CRF10 -> 23): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Compression efficiency graphs, *"low quality"* range (CRF28 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-fourth-deep-dive-p2.json). ---> Interpretation: Except on *"Suzume"*, and to some extent on *"Mandalorian"* at low qualities, where we see the higher number of tiles start to impact efficiency, the effect of tiles on efficiency is by in large negligible. It does seem like encoding speeds aren't particularly impacted by tiles in this encoder. Let's also look at decoding speeds, as we did with *fast-decode*! What follows are the relative decoding speed improvements relative to `c0r0`, starting with tests at *CRF12*: | Tiles Decoding Test (CRF12) | c0r0 | c1r0 | c1r1 | c2r0 | c2r1 | |:-:|:-:|:-:|:-:|:-:|:-:| | Avatar | 185fps | 335fps *(+81%)* | 446fps *(+141%)* | 477fps *(+158%)* | 487fps *(+163%)* | | Ducks | 117fps | 224fps *(+91%)* | 330fps *(+182%)* | 348fps *(+197%)* | 410fps *(+250%)* | | Fallout | 67fps | 125fps *(+87%)* | 186fps *(+178%)* | 202fps *(+201%)* | 223fps *(+233%)* | | Minecraft | 87fps | 164fps *(+89%)* | 223fps *(+156%)* | 256fps *(+194%)* | 267fps *(+207%)* | | Sol Levante | 91fps | 162fps *(+78%)* | 205fps *(+125%)* | 219fps *(+141%)* | 217fps *(+138%)* | | Suzume | 324fps | 544fps *(+68%)* | 679fps *(+110%)* | 732fps *(+126%)* | 729fps *(+125%)* | | Mandalorian | 312fps | 520fps *(+67%)* | 631fps *(+102%)* | 681fps *(+118%)* | 688fps *(+121%)* | The same tests were conducted at *CRF33* to quantify the differences in impact between two very distinctive quality targets: | Tiles Decoding Test (CRF33) | c0r0 | c1r0 | c1r1 | c2r0 | c2r1 | |:-:|:-:|:-:|:-:|:-:|:-:| | Avatar | 432fps | 698fps *(+62%)* | 780fps *(+81%)* | 816fps *(+89%)* | 758fps *(+75%)* | | Ducks | 354fps | 650fps *(+84%)* | 845fps *(+139%)* | 860fps *(+143%)* | 920fps *(+160%)* | | Fallout | 143fps | 259fps *(+81%)* | 355fps *(+148%)* | 375fps *(+162%)* | 386fps *(+170%)* | | Minecraft | 197fps | 346fps *(+76%)* | 432fps *(+119%)* | 489fps *(+148%)* | 481fps *(+144%)* | | Sol Levante | 200fps | 295fps *(+48%)* | 285fps *(+43%)* | 312fps *(+56%)* | 292fps *(+46%)* | | Suzume | 696fps | 991fps *(+42%)* | 1020fps *(+47%)* | 1082fps *(+55%)* | 1008fps *(+45%)* | | Mandalorian | 902fps | 1183fps *(+31%)* | 1164fps *(+29%)* | 1207fps *(+34%)* | 1128fps *(+25%)* | No, you aren't dreaming! We immediately realize that the impact of tiles is significantly greater than either of the *fast-decode* modes, an especially appealing outcome given their relatively minor effect on compression efficiency. Decoding speeds improve even further at higher quality settings, with the smallest gain reaching **+67%** at *CRF12*. That kind of difference can turn an unplayable file into one that runs smoothly. A single additional tile can have important consequences. *Tile-rows* on average offer less benefit than *tile-columns*, and in some cases even cause slight regressions at lower qualities. Still, seeing up to +250% improvements in decoding speed is nothing to scoff at. [Dav1d](https://code.videolan.org/videolan/dav1d/)’s performance is genuinely impressive, now exceeding **1000fps** on certain clips! ---> Visual Comparisons: | HQ | LQ | |:-:|:-:| | [Avatar (HQ)](https://slow.pics/c/6ZctTOwN) | [Avatar (LQ)](https://slow.pics/c/bHKBXQsC) | | [Ducks (HQ)](https://slow.pics/c/psvcfJR0) | [Ducks (LQ)](https://slow.pics/c/dYIJoDX9) | | [Fallout (HQ)](https://slow.pics/c/9cImaJgO) | [Fallout (LQ)](https://slow.pics/c/lfD5I54d) | | [Minecraft (HQ)](https://slow.pics/c/TG61F71o) | [Minecraft (LQ)](https://slow.pics/c/HVRceUiN) | | [Sol Levante (HQ)](https://slow.pics/c/rWdmd8dP) | [Sol Levante (LQ)](https://slow.pics/c/I9H4Akva) | | [Suzume (HQ)](https://slow.pics/c/uC13Y3J7) | [Suzume (LQ)](https://slow.pics/c/zL4abWSW) | | [Mandalorian (HQ)](https://slow.pics/c/cnUI9sTu) | [Mandalorian (LQ)](https://slow.pics/c/5WlGC4R6) | The author's `--tile-columns 1 --tile-rows 0` and `--tile-columns 2 --tile-rows 0` settings are candidates suggested by these decode runs, not resolution-based rules. These values are logarithmic: they request two and four tile columns respectively, subject to encoder constraints. Compare against `--tile-columns 0 --tile-rows 0` on the intended decoder and content. A workstation throughput gain does not guarantee low-power playback, and additional tiles are not inherently future-proof. Combining fast-decode and tiles requires its own test; the isolated results cannot predict the combined tradeoff. ## Statistics Who doesn't love a bunch of random and useless stats? Well, if you recognize yourself in this, I got you. I compiled a few, though I only included stuff that ended up being used in these two parts. Yes, test encodes, test graphs or test comps figures are *not* included here. Here's this deep dive in numbers: - **10577** total AV1 encodes... - ...which account for a total size of **294GB**... - ...which makes for an average of about **28MB** per file - **3928** total graphs - **2030** total decoding runs - **483** slow.pics comps... - ...for a grand total of about *12000* distinct screenshots uploaded! Even I was flabbergasted when I discovered the actual scope of this benchmarking session! ## Conclusion In this second part, we took a deep dive into several key SVT-AV1 encoding parameters, evaluating them in the article's historical 3.0.x context. The goal was mainly to explore how these settings impact efficiency and encoding speeds, but at times also decoding performance or practical usability. While I could have revisited even more parameters, the sheer time investment required means I had to draw the line somewhere. I made sure to go **really in-depth** with the ones that mattered most in my opinion. As always, your mileage may vary regarding any kind of speed figures. The key is to **test things yourself**, with your own clips, workflows, and goals in mind. What works for one setup might not suit another, and that’s what makes this kind of testing both challenging... and somewhat rewarding too. This wraps up Part 2, but there’s more to come. I'm always thinking about what to explore next, and your feedback helps shape that direction. So if you have suggestions, requests, or thoughts to share, I’d love to hear them, in the usual places. Thanks again for reading, and I hope you found this deep dive insightful! ## Future plans recorded in 2025 ~~First of all, I do not consider this testing complete. I have been told some comps had issues, and while re-generating them, I ended up rate-limited by slow.pics again, though only temporarily fortunately. As you can imagine, even with scripts, preparing and uploading these takes quite a while already, but I'm taking even more precautions to avoid getting banned again. I decided not to delay this Part further, so you wouldn't have to wait more, but I'll ask you to be patient a bit longer for me to add the fixed comps for Part 1 and the varboost octiles comps for this Part. I expect to be able to update both articles before the end of the week.~~ **EDIT (July 4):** These concerns have been addressed. Thanks for your patience. As I alluded to in the last section, I have ideas for future blog posts. First of all, **SVT-AV1 v3.1.0 is right around the corner**, and it is touted to be quite an update especially for VBR and realtime usecases! It could be the occasion for me to do the long awaited *target bitrate* tests and compare efficiency with CRF on our test samples... Second, most of the ideas I proposed in past articles remain valid possibilities and I still want to test other AV1 encoders in this format. AV2 is approaching too so it would be interesting to make some early comparisons of AV1 with AVM, if there's enough time for that. Third, there's still so much that could be improved in my methodology, to make it more robust and precise, so I will continue experimenting as usual to find a better overall formula! Lastly, I’ve also been working on a few AV1-related projects behind the scenes, including one that involves SVT-AV1 directly... I’m looking forward to sharing more about it in the future, so stay tuned! I want to extend my thanks a second time to the people who contributed, directly or indirectly, to the making of this article, including [Gianni Rosato (gb82)](https://github.com/gianni-rosato), [Line (Lumen)](https://codeberg.org/Line-fr), [Soda](https://github.com/GreatValueCreamSoda), [Emre](https://github.com/emrakyz), [Bolu](https://github.com/0xb01u/), [Julio Barba](https://github.com/juliobbv-p), the people behind slow.pics for hosting thousands of screenshots each time I make these articles, the SVT-AV1 dev team for the work on this amazing encoder, and probably others I'm forgetting... --- *Consider supporting me by making a donation on [my Ko-Fi page](https://ko-fi.com/nekotrix).* {} --- # Observing SVT-AV1 v2.1.0's improvements: A New Deep Dive Canonical URL: https://encode.wiki/articles/svt-av1-second-deep-dive/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: 56dbc3778a1456e58fe15c2a2b39655e547d156cfa09cc29bb51cf797f88c32d > **Note — Editorial correction — 7 September 2026.** > > The author's SVT-AV1 2.0.0/2.1.0 experiments, five short anime samples, settings, graphs, and results are preserved. The sample does not represent all modern video, and no completed visual comparison or new benchmark run has been added. The interpretation and conclusion below are limited to this corpus and these versions. # Introduction SVT-AV1, the most scalable AV1 encoder, has received a new update and one may wonder if the old presets recommendation still holds today. We will delve into that in this blog post, based on a series of speed and visual quality benchmarks with SSIMULACRA2 and XPSNR of SVT-AV1 2.1.0 on a corpus of varied animated clips. ## Feedback The planned image comparisons were not completed for this article. Its five clips cover several animation characteristics, including grain, 3DCG, and rapid motion, but that diversity does not make them representative of live action, sports, screen recordings, or full-length encodes. The original claim of universal representativeness is withdrawn. Adding XPSNR provides another view of these samples; it does not replace a broader corpus or controlled subjective evaluation. [ITU-R BT.500 subjective-assessment methodology](https://www.itu.int/rec/R-REC-BT.500). I have also decided to complement this benchmark of another psychovisually-driven metric (XPSNR) so that double-checking is made easier. Thus, each graph possesses a SSIMULACRA2 version and a XPSNR version. Don't hesitate to switch between one another! ## Methodology The resources available will range from ***graphs*** to ~~**image comparisons**~~ (WIP). The ***former*** has the advantage of being easily understandable, showcasing pure efficiency comparisons between encoder parameters using metrics as the reference, while the **latter** are image samples from the files encoded during the tests that enable you to check quality for yourself, adding another layer of subjective interpretation to these comparisons. The testing methodology involves using relatively short video samples from a wide range of modern anime genre, which have been either losslessly encoded with `x264 --qp 0` for ease of use or losslessly cut from their source. These lossless files are then pipped into SvtAv1EncApp *directly*, meaning we are measuring the performance of a single encoder instance and not using chunked encoding. Chunking is an optional workflow with its own resource, boundary, and rate-control tradeoffs. Once an encode is done, SSIMULACRA2 scores are calculated using the [Zig implementation](https://github.com/dnjulek/vapoursynth-ssimulacra2), XPSNR scores on the other hand are calculated using a [ffmpeg filter](https://github.com/fraunhoferhhi/xpsnr), and lots of useful data are aggregated to make the graphs for this benchmark, including encoding time, encode size (bitrate), and metrics scores. Bits per pixel (BPP) is used to compare rate against the selected objective score. Those curves describe this metric/corpus combination, not a direct measurement of perceived quality. The clips used in this test were acquired legally. The Codec Wiki and its contributors do not endorse media piracy. SvtAv1EncApp was compiled directly from the [v2.0.0 and v2.1.0 source code](https://gitlab.com/AOMediaCodec/SVT-AV1/-/releases/) using the provided `Build/linux/build.sh` script, Clang 16.0.6, and Profile-Guided Optimization (PGO). The testing machine is comprised of an i3 12100 with 16GB of 3200MHz CL14 DDR4 RAM in Arch Linux with kernel 6.7.7 and the performance governor enabled. All encodes have been made in the same session without rebooting. ## Samples The samples are as follows: - 11s `Blame!` clip which sports 3DCG action with lots of grain, effects and high-contrast elements. - 13s `Blue Lock` clip which sports rapid camera movements, complex geometry and high-contrast elements. - 5s `Spy x Family` first ending sequence with an extremely high amount of dynamic noise. New most complex source of this set. - 12s `Jigokuraku (Hell's Paradise)` flashback clip with huge static grain in a very dark scenery and some action. - 5s `The Garden of Sinners` clean but fast-paced 3DCG scene with explosions. The resolution of every clip is 1080p, except for the first one which is 1920x804. > **All clips have been encoded in a wide quality range, from `--crf 6` to `--crf 46`, by increments of 4.** Without further ado, let's start with the first comparisons! ## Presets comparisons (-1 -> ~~13~~ 12) **In the following graphs, you may find comparisons between all SVT-AV1 presets, ranging from the slowest `--preset -1` to the fastest `--preset 12`.** > Yes, you heard that right. Preset 7 and 13 are no more in __v2.1.0__. This new update, like the previous one, mostly consisted of optimizing the presets trade-offs. The devs have made the choice to map `preset 7` to `preset 6` and `preset 13` to `preset 12` due to the lack of spacing between the new presets. We will discuss the implications of this further ahead. `--preset X` is the only parameter used here, in conjunction with the CRF values. That means everything else is default. The defaults worth mentioning are: - `--tune 1`: tune PSNR - `--aq-mode 2`: variance deltaq - `--enable-qm 0`: quantisation matrices disabled - `--irefresh-type 2`: closed GOP - `--enable-tf 1`: temporal filtering enabled And more, like CDEF and restoration enabled, overlays and film-grain disabled... ### Efficiency - First of all, here are the full efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). This is all very cool, but visually bloated. - Now the same graphs but focusing on the "high quality" range (CRF6 -> 22): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Same, but now focusing on the "low quality" range (CRF26 -> 46): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - If we now focus on __presets 4__ and below, where it's more difficult to discern the differences between presets, we get this at "high quality": > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - And the following at "low quality": > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). ### Speed - **Let's now see speed comparisons between all presets:** > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Once is not custom, __preset -1__ is so abysmally slow it makes the graph unusable. - Same, but without the placebo __preset -1__: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Lastly, here is what it looks like with a logarithmic scale: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). ### Interpretation **Editorially scoped interpretation:** on this five-clip SVT-AV1 2.1.0 test, presets 2 and 4 appeared to offer useful score/time tradeoffs, with preset 3 between them. The author's graphs show relatively small score gains from slower presets at some quality targets, with substantial time costs. This does not establish that presets 0 or -1 are pointless for every source, or that presets 5–9 satisfy real-time deadlines. The short single-instance runs do not measure live latency, long-duration throughput, or hardware encoders. Similarly, this CRF experiment cannot establish that target-bitrate mode is inherently less efficient. Use the historical curves to form a shortlist for a matching workload, then compare encodes at similar sizes and inspect playback. Recheck presets with the installed encoder version; numbering and defaults change. [Current SVT-AV1 guide](/guides/av1-with-svt-av1/). ### TLDR The same conclusions as the previous blog post can be made: **clear quality gains can be observed as we decrease presets, until __preset 2__, however the effectiveness of dropping presets is noticeably less and less important as quality is increased.** In the next part, we will evaluate the differences in efficiency and speed of every presets when updating from SVT-AV1 2.0.0 to 2.1.0, which should enable an increase of nuance from the previous results alone. ## SVT-AV1 v2.0.0 vs v2.1.0 presets comparisons: In the author's earlier comparison, v2.0.0 presets -1 through 8 appeared similar to v1.8.0 presets 0 through 9 on the selected samples and metrics. That observation is retained. It does not establish a universal regression or explain why upstream release benchmarks differed. Corpus, settings, metrics, hardware, and build configuration can all change measured tradeoffs; the original speculation about developers being misled by metrics was not demonstrated. The next comparisons examine whether the preset tradeoffs changed on this test corpus. ### `preset -1`: v2.0.0 vs v2.1.0 - **Let's start off with a battle of the placebos, with the efficiency at "high quality":** > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - And the efficiency at "low quality": > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Yes, this is a bit underwhelming, but you can't just improve the best an encoder has to offer with just tweaking right? - Now, let's compare their respective speeds: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Let's be grateful it became ever so slightly faster, I guess. ### `preset 0`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Overall, efficiency wise, this new **preset 0** places itself in-between old **preset -1** and **0** - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Interestingly enough, its speed is much closer to the old **preset 0** than to the old **preset -1**. This means **preset 0** was genuinely improved over v2.0.0! ### `preset 1`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). In efficiency, this new **preset 1** is often equal to old **preset 0**, else in-between old **preset 0 and 1**. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). We observe that the new preset is a bit closer to old **preset 1** speeds than it is to old **preset 0** speeds. Good news! ### `preset 2`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Oh well, that's awkward. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Speed was left untouched too, meaning **preset 2** is unchanged in v2.1.0. ### `preset 3`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). The new **preset 3**'s efficiency is the same as the old one. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). However, the preset got slightly faster, so this is a speedup! ### `preset 4`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). We can observe that **preset 4** got slightly to moderately worse efficiency wise. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Fortunately, the consequence of that slight efficiency decrease is a big performance improvement! ### `preset 5`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). **Preset 5** seems to have gotten ever so slightly worse efficiency wise. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Yet it became slightly faster, this is overall a good trade-off. ### `preset 6`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). The new **preset 6** has a huge responsibility: being able to compensate in the absence of its **preset 7** sibling. It seems to performs in-between old **preset 6 and 7**, usually closer to old **7**. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). **Preset 6** is now ever so slightly slower to old **7**, this is an interesting trade-off, overall a win over old **7**. ### `preset 7`: v2.0.0 vs v2.1.0 Again, there is no preset 7. Actually, it's preset 6 that disappeared but I'm not remaking the graphs just for fun. If you select preset 6, you will be granted the following message: `Svt[warn]: Preset M6 is mapped to M7.` ![always_has_been](/img/preset_7_meme.webp) ### `preset 8`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). In efficiency, this new **preset 8** is sometimes equal or slightly worse to the old **8**, and sometimes equal or slightly worse than old **7**... - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Overall, the speed is pretty much unchanged from old **8**. It looks like a slight regression, that's pretty disappointing. ### `preset 9`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). The new **preset 9** is the same as ever, ever so slightly better in some scenario but nothing groundbreaking. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Its speed remains the same, sometimes ever so slightly slower. Basically the preset is pretty much unchanged, which may as well be a relief, as the last usable preset of the encoder. ### `preset 10`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). **Preset 10** is slightly to moderately worse efficiency wise. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Its speed is mostly the same, sometimes ever so slightly faster. It's a wash, avoid this preset at all costs! ### `preset 11`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). **Preset 11**'s efficiency is untouched. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). **Preset 11**'s speed is unchanged as well. ### `preset 12`: v2.0.0 vs v2.1.0 - Efficiency graphs, high quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). - Efficiency graphs, low quality: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). Just as **preset 6**, **preset 12** is now mapped to **13**, and unsurprisingly, its efficiency is equal to old **13**. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-second-deep-dive.json). The speeds seem to be in-between old 12 and 13, so potentially a slight speedup. Still, nothing to get excited at. ### TLDR From these extensive comparisons, it appears that some presets have received genuine improvements in their respective efficiency/speed trade-off. Some presets, like **-1**, **0**, **1** and **3**, received the most significant improvements, followed by **4**, **5** and **6** with overall beneficial new trade-offs. **Preset 12** got slightly faster too. On the other hand, **presets 8 and 10** seemed to have regressed slightly, and **presets 2 and 9** are perfectly unchanged from v2.0.0. ## Conclusion The historical results suggest presets 2–4 as candidates for this animation workload, with faster presets worth measuring when time is constrained. They do not identify universally optimal settings. Parameters not retested here cannot be assumed unchanged. SVT-AV1-PSY was active when the article was written; its original project subsequently announced its end. Its changed defaults and features were not tested by this comparison and should not be described as a free efficiency gain. Consult the [project's status notice](https://github.com/psy-ex/svt-av1-psy) and [current SVT-AV1 guide](/guides/av1-with-svt-av1/) for new work. The [2.1.0 release](https://gitlab.com/AOMediaCodec/SVT-AV1/-/releases/v2.1.0) remains the version context for this article. ## Future plans recorded by the author My plans for the future regarding the blog post include: - polishing this blog post. - a follow-up article in the relatively near future about giving you encoding tips and explaining common AV1 encoding knowlegde, for instance showcasing why film grain synthesis is a game-changer or why chunked encoding can prove beneficial to your encoding pipeline. - an article focused on observing the evolution of SVT-AV1 since the beginning of its development, as well as comparisons with current aomenc, rav1e and SVT-AV1-PSY, including a quick look at the current state of AVM (development ground for AV2) in comparison to VVC's state. Thanks for reading! {} --- # Better late than never: SVT-AV1 v2.2.x Deep Dive Canonical URL: https://encode.wiki/articles/svt-av1-third-deep-dive/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: d4949b79c12e3b1491b1b3d49343c7930ce709c20fde5bbe1faa46f775bb4db1 # Introduction > **Historical benchmark, reviewed October 4, 2026.** The charts and visual comparisons below report the author's 2024 **SVT-AV1 2.1.2 / 2.2.1** experiment, not the current encoder's defaults or performance. They were not rerun for this update. The metric plugin linked in the methodology is now [archived](https://github.com/dnjulek/vapoursynth-ssimulacra2). Consult the [current encoder reference](/tools/software-encoders/svt-av1/) for present controls and use the stated samples, versions, and hardware when interpreting these results. SVT-AV1 v2.2.0 was released in late August and a minor version v2.2.1 followed suit to adress some bugs. This blog post will focus on comparing this new encoder version to the last, on the basis of benchmarks and visual comparisons. We will quantify the new trade-offs between compression efficiency and encoding speed, so you can choose the right balance for your projects. Our metrics of choice today will be SSIMULACRA2 and XPSNR, used in conjonction with a revised methodology. ## Feedback The biggest missed opportunity of the previous SVT-AV1 deep dives was the absence of visual comparisons. Indeed, metrics may be convenient for easily quantifying differences between encoder versions or encoding parameters, but they fail to give the information of how much these differences matter for your eyes. However, making properly useful visual comparisons isn't an easy task. Comparing two encodes of varying bitrates will bias the result against one or the other, which is not desirable. Figuring out the best way to present these comparisons and making the appropriate scripts took me weeks. Gathering all the necessary data, crafting the comparisons and proceeding to a double-checking pass took me another few weeks. These reasons explain why this blog post took so long to release, but I hope it will have been worth the wait! On that note though, I have been uploading thousands of png screenshots to *slow.pics* and I ended up rate-limited. This has prevented me from uploading the visual comparisons for preset 11, 12 and some of 10. I'm actively trying to fix this situation, so please understand. Another reason for this taking so long was my decision to increase the amount of video samples while increasing the amount of CRF values tested. A grand total of 3682 encodes were done for this blog post alone, in the span of around two weeks, where my PC would be exclusively encoding 24/7. Send help. The charts use the author's harmonic-mean pooling alongside SSIMULACRA2 standard deviation. For positive scores, harmonic pooling weights low values more strongly than the arithmetic mean; neither mean alone describes the full distribution. **This is a study-specific aggregation choice, not a default metric definition.** SSIMULACRA2 can produce zero or negative scores: a zero score makes reciprocal pooling undefined, and mixed signs undermine its usual interpretation. The preserved article does not document how such frames were handled, so the graphs near that region cannot establish a generally valid pooling rule. The original score series was not reprocessed; inspect scene/frame scores and report a defined zero/negative-score policy in new experiments. [Upstream SSIMULACRA2 score implementation](https://github.com/libjxl/libjxl/blob/main/tools/ssimulacra2.cc). Lastly, the biggest complaint I have received is me exclusively using anime clips. The reason for that is pretty simple: I mostly encode anime content on my free time and am myself very little interested in other types of media. However, these blog posts have grown in exposure and I understand a majority of people is more concerned about the performance of encoders on live action content or gaming clips. Thus, this new blog post is comprised of 3 live action clips, 2 gaming clips and 2 anime clips! See the sacrifices I'm making for y'all? ## Methodology The resources provided will include both graphs and image comparisons. Graphs offer a straightforward, objective look at efficiency across encoder parameters, using metrics as benchmarks for performance. In contrast, image comparisons display actual samples from encoded files, allowing you to assess quality firsthand. This adds a subjective dimension to the comparisons, giving you a more nuanced understanding of each preset's impact on visual quality. The testing methodology involves using relatively short video samples with a wide range of content types, uncompressed to the y4m file format for ease of use. These lossless files are *directly* fed to SvtAv1EncApp, implying the performance of a single encoder instance is what's being measured here. Chunked encoding is a separate throughput option, especially on high-core-count systems, and introduces its own boundary, resource, and rate-control trade-offs. Once an encode is done, SSIMULACRA2 scores are calculated using the [Zig implementation](https://github.com/dnjulek/vapoursynth-ssimulacra2), XPSNR scores on the other hand are calculated using a [ffmpeg filter](https://github.com/fraunhoferhhi/xpsnr), and the data is then aggregated into a final Harmonic or Standard Deviation score to create the graphs for this benchmark. The Constant Rate Factor (CRF) is plotted against encoding time, and the metrics scores against encode size (bitrate). The former may represent the efficiency as defined by the speed achieved at a certain quality target. For the latter, Bits Per Pixel scores (BPP) are calculated so that the `Metric / BPP` graphs may represent the compression efficiency, normalized by resolution. How to read the graphs? For the compression efficiency ones, the closer to the top left the better. For the encoding speed ones, the closer to the left the faster. For the standard deviation ones, the closer to the bottom left the better. The clips used in this test were acquired legally. The Codec Wiki and its contributors do not endorse media piracy. SvtAv1EncApp was compiled directly from the [v2.1.2 and v2.2.1 source code](https://gitlab.com/AOMediaCodec/SVT-AV1/-/releases/) using Clang 18.1.8 and the provided `Build/linux/build.sh` script with the following command: `build.sh cc=clang cxx=clang++ jobs=$(nproc) enable-lto static native release`. The testing machine is comprised of an i3 12100 in its stock configuration, with 2x8GB of 3200MHz CL14 DDR4 RAM, in Arch Linux with kernel 6.9.12 and the performance governor enabled. All encodes have been made in the same session without rebooting. I want to give a disclaimer concerning encoding speeds. Contrary to the efficiency results which should be reproducible independantly of the machine, measuring speed is a pretty difficult endeavor, with increased risks for errors. The performance numbers I mention may differ for you depending on the hardware configuration at hand. ## Samples & Encoding Settings The samples are as follows: - 17s `Avatar The Way Of Water (trailer 3)` clip sourced from [thedigitaltheater.com](https://thedigitaltheater.com/category/movie-trailers/lossless-movie-trailers/) (1916x804p, 23.976fps). - 6s `Ducks Take Off` clip sourced from [xiph.org](https://media.xiph.org/video/derf/) (1280x720p, 50fps). - 3s `Fallout 4` clip sourced from another encoder fellow (1920x1080p, 60fps). - 8s `Minecraft` clip sourced from [xiph.org](https://media.xiph.org/video/derf/) (1920x1080p, 60fps). - 8s `Sol Levante` HDR clip sourced from [opencontent.netflix.com](http://download.opencontent.netflix.com/?prefix=SolLevante/) (3840x2160p, 24fps). This one is pretty educative as SVT-AV1's behavior isn't influenced by the existence (or lack thereof) of HDR metadata in a source. - 21s `Suzume (trailer 2)` clip sourced from [thedigitaltheater.com](https://thedigitaltheater.com/category/movie-trailers/lossless-movie-trailers/) (1920x808p, 23.976fps). - 13s `The Mandalorian (trailer 2)` clip sourced from [thedigitaltheater.com](https://thedigitaltheater.com/category/movie-trailers/lossless-movie-trailers/) (1920x800p, 23.976fps). > **All clips have been encoded in a wide quality range, from `--crf 10` to `--crf 50`, by increments of 2, with the exception of preset -1 that uses increments of 4.** `--preset X --hierarchical-levels 4` are the only parameter used here, in conjunction with the CRF values. I have been asked to use `--hierarchical-levels 4` by fellow SVT-AV1-PSY developers to force smaller mini GOPs, more appropriate for testing. Else, the SVT-AV1 defaults were used. The ones worth mentioning are: - `--tune 1`: tune PSNR - `--aq-mode 2`: variance deltaq - `--enable-qm 0`: quantisation matrices disabled - `--irefresh-type 2`: closed GOP - `--enable-tf 1`: temporal filtering enabled And more, like CDEF and restoration enabled, overlays and film-grain disabled... ## Visual comparisons ![comp_showcase](/img/comp_showcase.webp) Throughout this blog post, you’ll find *slow.pics* links that provide various visual comparisons between presets. - The “full” links offer comparisons across the entire quality range for each source. - The HQ (High Quality), MQ (Medium Quality), and LQ (Low Quality) links showcase more targeted comparisons. These have been carefully handcrafted to be as size-normalized as possible, given the available encodes. We want to be focusing on encodes with minimal bitrate deviation for a fair comparison. Feel free to double-check the bitrate of each frame or scene to make a more informed observation, keeping the size difference in mind when comparing the encodes. Use the arrow keys and numpad to navigate between screenshots. Alternatively, you can click on "Slider comparison" and select two sources if you prefer comparing this way. Without further ado, let's start with the first comparisons! ## Presets comparisons (-1 -> 12) **In the following graphs, you may find comparisons between all SVT-AV1 presets, ranging from the slowest `--preset -1` to the fastest `--preset 12`.** > Just like in __v2.1.x__, preset 6 and 13 do not exist in __v2.2.x__ and are instead mapped to preset 7 and 12 respectively. ### Efficiency - First of all, the complete efficiency graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). You may notice something odd going on with the Avatar results using XPSNR. I have tried to understand the cause, without success. For the remainder of this blog post, the Avatar XPSNR results will be omitted. I will continue investigating and aim to have a workaround in place for next time. Anyway, this graph may be impressive, but difficult to read. So let's analyse different quality targets. - The same graphs but focusing on the "high quality" range (CRF10 -> 22): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Same, but now focusing on the "medium quality" range (CRF24 -> 36): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - And lastly, focusing on the "low quality" range (CRF38 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - If we now focus on __presets 4__ and below, where it's more difficult to discern the differences between presets, we get this at "high quality": > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - This at "medium quality": > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - And the following at "low quality": > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). ### Speed - **Let's now compare the speed of all presets:** > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Unusable, right? - Then, here is what it looks like with a logarithmic scale: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). ### Interpretation It appears as if once again **preset 2** through **preset 4** remain the most balanced presets all-around in an efficient encoding scenario, with **preset 3** not offering much improvements over **preset 4** in average scores but nicely improving on consistency instead, and **preset 2** offering a nice efficiency and consistency uplift on top. In this release again, the quality gap between **preset 2** and **preset 1** is pretty narrow, and the speed penalty from **preset 1** onward continuously increases, ending up close to ~2x. In comparison, the penalty of going from **preset 3** to **preset 2** is closer to ~1.5x. As such, using **preset 1** is entering placebo territory and it is usually not recommended to waste precious encoding resources on **preset 0** and **preset -1**. This especially applies at medium to high quality, though at extremely low quality targets, like the CRF40-50 range, we can still see appreciable gains from these placebo presets in some clips. As for the faster presets, **presets 5 to 10** are usually grouped on the graphs focusing on average scores and the ones focusing on consistency. They tend to stand apart from their slower counterparts by just a bit. Though **preset 10** can be worryingly close to **preset 11** on some occasions. They are all viable for your real-time needs. The rule is the same as usual: **go the slowest you can bear that still achieves your goal!** **Presets 11 and 12** are especially inefficient and inconsistent, and to be avoided at all costs. If possible, forget they even exist, as it's probably better to use a comparably fast (or faster) competing codec. They could still be of use in a convex-hull scenario, but in the case of realtime transcoding, you will be better off with some hardware solution like the ones found in RTX 4000 or Arc GPUs. ### TLDR The same conclusions as the previous blog posts can be made: **clear quality gains can be observed as we decrease presets, until __preset 2__, however the effectiveness of dropping presets is noticeably less and less important as quality is increased.** ## SVT-AV1 v2.1.x vs v2.2.x presets comparisons: In this section, we’ll examine the efficiency and speed differences across presets when upgrading from SVT-AV1 2.1.x to 2.2.x. This comparison should bring a new level of nuance to our results, highlighting both incremental improvements and any notable shifts in performance. SVT-AV1 __v2.1.x__ brought some nice improvements over __v2.0.0__, but does __v2.2.x__ bring appreciable improvements in the presets trade-offs this time around as well? Let's find out! ### `preset -1`: v2.1.x vs v2.2.x - **Let's start things off with the battle of the placebos, with the Compression efficiency & consistency at "high to medium-ish quality" (CRF10 -> 30):** > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Along with the Compression efficiency & consistency at "medium-ish to low quality" (CRF34 -> 50): > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Basically no changes at all, except a slight regression on Minecraft. - What about their speeds though?: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Well **preset -1** basically became 15 to 25% faster, not bad at all! - Preset -1 visual comparisons: [Avatar (full)](https://slow.pics/c/LdIsYSua), [Avatar (HQ)](https://slow.pics/c/2a4aILcQ), [Avatar (LQ)](https://slow.pics/c/zT82h9rX) [Ducks (full)](https://slow.pics/c/BpxD7oZd), [Ducks (HQ)](https://slow.pics/c/vQfwqoid), [Ducks (LQ)](https://slow.pics/c/1hSeoXlp) [Fallout (full)](https://slow.pics/c/EOIoOoAQ), [Fallout (HQ)](https://slow.pics/c/GAfLlWLl), [Fallout (LQ)](https://slow.pics/c/nXGUeEyI) [Minecraft (full)](https://slow.pics/c/XRHmsQOw), [Minecraft (HQ)](https://slow.pics/c/UpCRq43R), [Minecraft (LQ)](https://slow.pics/c/835PVO4r) [Sol Levante (full)](https://slow.pics/c/AQC1xzLS), [Sol Levante (HQ)](https://slow.pics/c/tLv4zf68), [Sol Levante (LQ)](https://slow.pics/c/x8r8YUvF) [Suzume (full)](https://slow.pics/c/Ab6bkcpS), [Suzume (HQ)](https://slow.pics/c/lsGgf2pL), [Suzume (LQ)](https://slow.pics/c/KPNiucZk) [The Mandalorian (full)](https://slow.pics/c/BAF89tjA), [The Mandalorian (HQ)](https://slow.pics/c/tI50zGYS), [The Mandalorian (LQ)](https://slow.pics/c/V2q6DHYT) ### `preset 0`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Efficiency wise, this new **preset 0** is close to unchanged from the old **preset 0**, but its consistency improved slightly in a few clips at high quality and decreased in one clip at low quality. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). **Preset 0**'s speed sees an improvement of about 20% at best. Overall, **preset 0** got a proper upgrade! - Preset 0 visual comparisons: [Avatar (full)](https://slow.pics/c/7n5bAB2d), [Avatar (HQ)](https://slow.pics/c/AHmNT8Pw), [Avatar (MQ)](https://slow.pics/c/VC6lZr6D), [Avatar (LQ)](https://slow.pics/c/97SAuLaO) [Ducks (full)](https://slow.pics/c/m9iPnqqW), [Ducks (HQ)](https://slow.pics/c/gBXawmpH), [Ducks (MQ)](https://slow.pics/c/7dRVJzXD), [Ducks (LQ)](https://slow.pics/c/qshRSgnZ) [Fallout (full)](https://slow.pics/c/aq9eTZf5), [Fallout (HQ)](https://slow.pics/c/xu99HM0j), [Fallout (MQ)](https://slow.pics/c/eC0gzO7y), [Fallout (LQ)](https://slow.pics/c/pB9Ps3a6) [Minecraft (full)](https://slow.pics/c/aWbIxmgr), [Minecraft (HQ)](https://slow.pics/c/3jVGagWZ), [Minecraft (MQ)](https://slow.pics/c/MlYl7i4e), [Minecraft (LQ)](https://slow.pics/c/7MImyYc0) [Sol Levante (full)](https://slow.pics/c/SmDGEAPx), [Sol Levante (HQ)](https://slow.pics/c/ZiCgjlxE), [Sol Levante (MQ)](https://slow.pics/c/4GbaSzv6), [Sol Levante (LQ)](https://slow.pics/c/EPTFWHQI) [Suzume (full)](https://slow.pics/c/oVZqCWsl), [Suzume (HQ)](https://slow.pics/c/LqadqVGG), [Suzume (MQ)](https://slow.pics/c/TnD6CAyF), [Suzume (LQ)](https://slow.pics/c/CDuu3SOK) [The Mandalorian (full)](https://slow.pics/c/x8Sot0wg), [The Mandalorian (HQ)](https://slow.pics/c/idbPz3uh), [The Mandalorian (MQ)](https://slow.pics/c/OpFzXtjr), [The Mandalorian (LQ)](https://slow.pics/c/3d8gpuoo) ### `preset 1`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). **Preset 1** is mostly unchanged but sees another slight regression in Minecraft at high quality. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Depending on the clip, speed is mostly unchanged or ever so slighty improved. **Preset 1** is a bit stagnant this release. - Preset 1 visual comparisons: [Avatar (full)](https://slow.pics/c/BnOX37oJ), [Avatar (HQ)](https://slow.pics/c/bWjBtTyR), [Avatar (MQ)](https://slow.pics/c/6UQKyNac), [Avatar (LQ)](https://slow.pics/c/NpyxU3uF) [Ducks (full)](https://slow.pics/c/KVX4piAj), [Ducks (HQ)](https://slow.pics/c/EsEpbKVY), [Ducks (MQ)](https://slow.pics/c/8AxTTvKw), [Ducks (LQ)](https://slow.pics/c/ZgW8715d) [Fallout (full)](https://slow.pics/c/xQprIMbB), [Fallout (HQ)](https://slow.pics/c/qRvBez7k), [Fallout (MQ)](https://slow.pics/c/taXnNGUx), [Fallout (LQ)](https://slow.pics/c/s6fbIqvr) [Minecraft (full)](https://slow.pics/c/cE86n2Gb), [Minecraft (HQ)](https://slow.pics/c/eOyUxHhq), [Minecraft (MQ)](https://slow.pics/c/tKPYsd9K), [Minecraft (LQ)](https://slow.pics/c/evfzJDjc) [Sol Levante (full)](https://slow.pics/c/BSzecR9N), [Sol Levante (HQ)](https://slow.pics/c/mWIoU45b), [Sol Levante (MQ)](https://slow.pics/c/geYXLoIY), [Sol Levante (LQ)](https://slow.pics/c/QzSjaYXF) [Suzume (full)](https://slow.pics/c/pBVidgiB), [Suzume (HQ)](https://slow.pics/c/5KtTXd3q), [Suzume (MQ)](https://slow.pics/c/lb0yMDhZ), [Suzume (LQ)](https://slow.pics/c/TipcRRJr) [The Mandalorian (full)](https://slow.pics/c/4ouGFV9s), [The Mandalorian (HQ)](https://slow.pics/c/oxPNsHdU), [The Mandalorian (MQ)](https://slow.pics/c/EPju5ULC), [The Mandalorian (LQ)](https://slow.pics/c/e58LmgFm) ### `preset 2`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). **Preset 2**'s efficiency has regressed at high quality on some clips, improved in some and stayed the same in others. Except in one clip, consistency seems to have improved all around. At low to medium quality targets, efficiency is mostly unchanged, same for consistency. Not exactly noteworthy. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Speed was improved by about 10-20%. Not a bad showcase, for sure. - Preset 2 visual comparisons: [Avatar (full)](https://slow.pics/c/CJg3dsFg), [Avatar (HQ)](https://slow.pics/c/71wpH5eB), [Avatar (MQ)](https://slow.pics/c/AN0syhNv), [Avatar (LQ)](https://slow.pics/c/NRocyEay) [Ducks (full)](https://slow.pics/c/NyGfMRpQ), [Ducks (HQ)](https://slow.pics/c/OAqs5b8k), [Ducks (MQ)](https://slow.pics/c/tQSF50Ro), [Ducks (LQ)](https://slow.pics/c/gJjm3BGl) [Fallout (full)](https://slow.pics/c/snQuTi1f), [Fallout (HQ)](https://slow.pics/c/0rLG3TUT), [Fallout (MQ)](https://slow.pics/c/MMX6DgNz), [Fallout (LQ)](https://slow.pics/c/lwoIkLfm) [Minecraft (full)](https://slow.pics/c/5OYsrhGY), [Minecraft (HQ)](https://slow.pics/c/kCwbA7Ir), [Minecraft (MQ)](https://slow.pics/c/1nnyrvjD), [Minecraft (LQ)](https://slow.pics/c/F1RTfQf7) [Sol Levante (full)](https://slow.pics/c/xduJGoTU), [Sol Levante (HQ)](https://slow.pics/c/8SdKLegQ), [Sol Levante (MQ)](https://slow.pics/c/uHNR7DNz), [Sol Levante (LQ)](https://slow.pics/c/wgZgH7w6) [Suzume (full)](https://slow.pics/c/zC4AEMLt), [Suzume (HQ)](https://slow.pics/c/kGip9wuY), [Suzume (MQ)](https://slow.pics/c/aoQ0m9ms), [Suzume (LQ)](https://slow.pics/c/7ZMT3inc) [The Mandalorian (full)](https://slow.pics/c/8BKkJ4du), [The Mandalorian (HQ)](https://slow.pics/c/XQeD7vfY), [The Mandalorian (MQ)](https://slow.pics/c/6rQMASQR), [The Mandalorian (LQ)](https://slow.pics/c/Jl2Fh5wE) ### `preset 3`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Practically, it's a wash. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Still, **preset 3** got slightly faster, I'm happy to report this is a speedup! - Preset 3 visual comparisons: [Avatar (full)](https://slow.pics/c/Vql4MJWQ), [Avatar (HQ)](https://slow.pics/c/Iuqp0Zbz), [Avatar (MQ)](https://slow.pics/c/MuTOEHE9), [Avatar (LQ)](https://slow.pics/c/poiDDJRQ) [Ducks (full)](https://slow.pics/c/mqWOgsYF), [Ducks (HQ)](https://slow.pics/c/16L6HyaH), [Ducks (MQ)](https://slow.pics/c/KaoPy7ae), [Ducks (LQ)](https://slow.pics/c/0L84OWnI) [Fallout (full)](https://slow.pics/c/JuXAjSY6), [Fallout (HQ)](https://slow.pics/c/mR5rJfsU), [Fallout (MQ)](https://slow.pics/c/Zpy7Hzds), [Fallout (LQ)](https://slow.pics/c/GeQrpfhp) [Minecraft (full)](https://slow.pics/c/rBCbaJkx), Minecraft (HQ comparison unavailable), [Minecraft (MQ)](https://slow.pics/c/MYLA8KPH), [Minecraft (LQ)](https://slow.pics/c/aEMnRk7D) [Sol Levante (full)](https://slow.pics/c/F7rmPiaW), [Sol Levante (HQ)](https://slow.pics/c/PYO4K4sy), [Sol Levante (MQ)](https://slow.pics/c/viWYsgX7), [Sol Levante (LQ)](https://slow.pics/c/4NBaUoEX) [Suzume (full)](https://slow.pics/c/d15XbowQ), [Suzume (HQ)](https://slow.pics/c/eS6EQKng), [Suzume (MQ)](https://slow.pics/c/IJtLW35Z), [Suzume (LQ)](https://slow.pics/c/zf352iox) [The Mandalorian (full)](https://slow.pics/c/UrAekqg6), [The Mandalorian (HQ)](https://slow.pics/c/WWgygRS4), [The Mandalorian (MQ)](https://slow.pics/c/ry5sPqmB), [The Mandalorian (LQ)](https://slow.pics/c/6wI4wexZ) ### `preset 4`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). **Preset 4** sees a consistent though small improvement in average scores and standard deviation across the entire quality range on basically all clips. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Unfortunately, it got slower as a result. If you remember, **v2.1.0** did the exact contrary over **v2.0.0**, I wonder if **preset 4** simply took back the place it previously had... - Preset 4 visual comparisons: [Avatar (full)](https://slow.pics/c/ArdO4K7R), [Avatar (HQ)](https://slow.pics/c/88ikqaZn), [Avatar (MQ)](https://slow.pics/c/rM6LRBg0), [Avatar (LQ)](https://slow.pics/c/ofmHWCkv) [Ducks (full)](https://slow.pics/c/HVkqo5G3), [Ducks (HQ)](https://slow.pics/c/w44DNiqe), [Ducks (MQ)](https://slow.pics/c/GlRLCaBt), [Ducks (LQ)](https://slow.pics/c/Lkzi1VBU) [Fallout (full)](https://slow.pics/c/44jtBEqw), [Fallout (HQ)](https://slow.pics/c/G9YPifBb), [Fallout (MQ)](https://slow.pics/c/86m4exaw), [Fallout (LQ)](https://slow.pics/c/m4KHBihZ) [Minecraft (full)](https://slow.pics/c/n9OP2sht), [Minecraft (HQ)](https://slow.pics/c/JohJ3MzJ), [Minecraft (MQ)](https://slow.pics/c/e6b8R24h), [Minecraft (LQ)](https://slow.pics/c/xNwNlmAG) [Sol Levante (full)](https://slow.pics/c/vB7ndGZI), [Sol Levante (HQ)](https://slow.pics/c/R5uENbD5), [Sol Levante (MQ)](https://slow.pics/c/i7eV72sl), [Sol Levante (LQ)](https://slow.pics/c/zUMYarNf) [Suzume (full)](https://slow.pics/c/rgmuB5xB), [Suzume (HQ)](https://slow.pics/c/y9rxWVre), [Suzume (MQ)](https://slow.pics/c/4GhRL8gZ), [Suzume (LQ)](https://slow.pics/c/F3Hq8V9z) [The Mandalorian (full)](https://slow.pics/c/3BAR5P80), [The Mandalorian (HQ)](https://slow.pics/c/s2xzApJd), [The Mandalorian (MQ)](https://slow.pics/c/Ihjks1JO), [The Mandalorian (LQ)](https://slow.pics/c/JjGKUO1r) ### `preset 5`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Both metrics say **preset 5** regressed slightly to moderately, though surprisingly its consistency is basically unchanged. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). The result of this regression is an impressive speedup of up to 25%. - Preset 5 visual comparisons: [Avatar (full)](https://slow.pics/c/Lc8HjJBK), [Avatar (HQ)](https://slow.pics/c/r3gJkCv3), [Avatar (MQ)](https://slow.pics/c/k2TwNLHN), [Avatar (LQ)](https://slow.pics/c/cMlNo17a) [Ducks (full)](https://slow.pics/c/X4EZFJcM), [Ducks (HQ)](https://slow.pics/c/zKLphp19), [Ducks (MQ)](https://slow.pics/c/dYs1snV3), [Ducks (LQ)](https://slow.pics/c/JFtne5WV) [Fallout (full)](https://slow.pics/c/9ye1q9Rm), [Fallout (HQ)](https://slow.pics/c/zhEuOjRc), [Fallout (MQ)](https://slow.pics/c/YmZ3aRLO), [Fallout (LQ)](https://slow.pics/c/9ye1q9Rm) [Minecraft (full)](https://slow.pics/c/kyjcJWxt), [Minecraft (HQ)](https://slow.pics/c/UTWgYc3P), [Minecraft (MQ)](https://slow.pics/c/FtOxX3RH), [Minecraft (LQ)](https://slow.pics/c/jNyqLPgP) [Sol Levante (full)](https://slow.pics/c/ipyfREjA), [Sol Levante (HQ)](https://slow.pics/c/73V8CGKk), [Sol Levante (MQ)](https://slow.pics/c/z8P9UokS), [Sol Levante (LQ)](https://slow.pics/c/OPwerF86) [Suzume (full)](https://slow.pics/c/xfsYGM5C), [Suzume (HQ)](https://slow.pics/c/dL2J923D), [Suzume (MQ)](https://slow.pics/c/OhZNMzjx), [Suzume (LQ)](https://slow.pics/c/XFCnEebJ) [The Mandalorian (full)](https://slow.pics/c/xrO227rQ), [The Mandalorian (HQ)](https://slow.pics/c/m7Yky6EK), [The Mandalorian (MQ)](https://slow.pics/c/pN0cH6Yn), [The Mandalorian (LQ)](https://slow.pics/c/vB9zK9iz) ### ~~`preset 6`: v2.1.x vs v2.2.x~~ **Preset 6** is mapped to **preset 7** in **v2.2.x**. ### `preset 7`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). **Preset 7** is close to unchanged in **v2.2.x**. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). It still got some slight to moderate speedups though, which can be appreciated. - Preset 7 visual comparisons: [Avatar (full)](https://slow.pics/c/YtvMG9X6), [Avatar (HQ)](https://slow.pics/c/P0gF7nbQ), [Avatar (MQ)](https://slow.pics/c/syT6uiVt), [Avatar (LQ)](https://slow.pics/c/zkkv1ePp) [Ducks (full)](https://slow.pics/c/pyVQmAWj), [Ducks (HQ)](https://slow.pics/c/eXSNnqV7), [Ducks (MQ)](https://slow.pics/c/ja7d0sFU), [Ducks (LQ)](https://slow.pics/c/JCTFfcMu) [Fallout (full)](https://slow.pics/c/S6SbCW8x), [Fallout (HQ)](https://slow.pics/c/bWCLQWwV), [Fallout (MQ)](https://slow.pics/c/hvauusst), [Fallout (LQ)](https://slow.pics/c/04LVSbGD) [Minecraft (full)](https://slow.pics/c/mh8VUfrO), [Minecraft (HQ)](https://slow.pics/c/P0pIx6XP), [Minecraft (MQ)](https://slow.pics/c/vnrXVajs), [Minecraft (LQ)](https://slow.pics/c/8WKQdw2N) [Sol Levante (full)](https://slow.pics/c/kH9LcEzG), [Sol Levante (HQ)](https://slow.pics/c/1DWCNq2B), [Sol Levante (MQ)](https://slow.pics/c/clxjB7Uw), [Sol Levante (LQ)](https://slow.pics/c/52wLF7NR) [Suzume (full)](https://slow.pics/c/3VlVk3O9), [Suzume (HQ)](https://slow.pics/c/FKel5bhI), [Suzume (MQ)](https://slow.pics/c/XXiyyCNN), [Suzume (LQ)](https://slow.pics/c/rrBoua68) [The Mandalorian (full)](https://slow.pics/c/unxuKHEK), [The Mandalorian (HQ)](https://slow.pics/c/GMXnxSdA), [The Mandalorian (MQ)](https://slow.pics/c/v8wSN90W), [The Mandalorian (LQ)](https://slow.pics/c/fswh5kCT) ### `preset 8`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). The efficiency and consistency of **preset 8** has improved at high quality. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). And we can observe a speed increase of around 10%. Some crazy speed deviations can be noticed in Sol Levante. - Preset 8 visual comparisons: [Avatar (full)](https://slow.pics/c/8tKOAvGN), [Avatar (HQ)](https://slow.pics/c/YLWgqmxU), [Avatar (MQ)](https://slow.pics/c/pDg4gLry), [Avatar (LQ)](https://slow.pics/c/ADFSsXmP) [Ducks (full)](https://slow.pics/c/ug0TVcoF), [Ducks (HQ)](https://slow.pics/c/WiDmtcVZ), [Ducks (MQ)](https://slow.pics/c/ERVfuYHH), [Ducks (LQ)](https://slow.pics/c/I0N97rQw) [Fallout (full)](https://slow.pics/c/MqVzmFIi), [Fallout (HQ)](https://slow.pics/c/jUoB0PGo), [Fallout (MQ)](https://slow.pics/c/hXGIfwVj), [Fallout (LQ)](https://slow.pics/c/QUy3iX2H) [Minecraft (full)](https://slow.pics/c/frkuJR97), [Minecraft (HQ)](https://slow.pics/c/GayEkyrn), [Minecraft (MQ)](https://slow.pics/c/S36Ha8LP), [Minecraft (LQ)](https://slow.pics/c/lxoYsv8k) [Sol Levante (full)](https://slow.pics/c/YupMFGeu), [Sol Levante (HQ)](https://slow.pics/c/evfWqxZ9), [Sol Levante (MQ)](https://slow.pics/c/Juh027Eq), [Sol Levante (LQ)](https://slow.pics/c/ETPf9ppU) [Suzume (full)](https://slow.pics/c/oeFUWMHd), [Suzume (HQ)](https://slow.pics/c/01vzYfnq), [Suzume (MQ)](https://slow.pics/c/BIL4g7zk), [Suzume (LQ)](https://slow.pics/c/boxyyeZN) [The Mandalorian (full)](https://slow.pics/c/57M6RHM0), [The Mandalorian (HQ)](https://slow.pics/c/8WJcnZfU), [The Mandalorian (MQ)](https://slow.pics/c/M7q5PYz8), [The Mandalorian (LQ)](https://slow.pics/c/ctoke6p1) ### `preset 9`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Efficiency and consistency stayed mostly the same. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Speed improved by a few percents at most. **Preset 9** has stagnated over **v2.1.x**. - Preset 9 visual comparisons: [Avatar (full)](https://slow.pics/c/P3zZKVF0), [Avatar (HQ)](https://slow.pics/c/sL4HPZLa), [Avatar (MQ)](https://slow.pics/c/QOxyI9h0), [Avatar (LQ)](https://slow.pics/c/RfLKIRjj) [Ducks (full)](https://slow.pics/c/aj6SVcIZ), [Ducks (HQ)](https://slow.pics/c/UpnejngN), [Ducks (MQ)](https://slow.pics/c/KJRzl3FY), [Ducks (LQ)](https://slow.pics/c/4mMq9sz3) [Fallout (full)](https://slow.pics/c/vHqlIJBK), [Fallout (HQ)](https://slow.pics/c/XHoe9Udp), [Fallout (MQ)](https://slow.pics/c/tukibDud), [Fallout (LQ)](https://slow.pics/c/cV57jRF9) [Minecraft (full)](https://slow.pics/c/XRT1OYnX), [Minecraft (HQ)](https://slow.pics/c/HqtoRlvV), [Minecraft (MQ)](https://slow.pics/c/Ml2rLjvO), [Minecraft (LQ)](https://slow.pics/c/EGCsqcSl) [Sol Levante (full)](https://slow.pics/c/8URvlnba), [Sol Levante (HQ)](https://slow.pics/c/jPFT5hMG), [Sol Levante (MQ)](https://slow.pics/c/92EZO3U3), [Sol Levante (LQ)](https://slow.pics/c/bWgcvUtj) [Suzume (full)](https://slow.pics/c/yA2y0v92), [Suzume (HQ)](https://slow.pics/c/pAPBbl7r), [Suzume (MQ)](https://slow.pics/c/7hTvbMy1), [Suzume (LQ)](https://slow.pics/c/arrDGAd9) [The Mandalorian (full)](https://slow.pics/c/KQHqkAVZ), [The Mandalorian (HQ)](https://slow.pics/c/UzdN0rSC), [The Mandalorian (MQ)](https://slow.pics/c/dxKpfcvs), [The Mandalorian (LQ)](https://slow.pics/c/FPJAf74J) ### `preset 10`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). **Preset 10** received the most efficiency and consistency improvements out of all presets in this release. What will be the cost of such drastic change though? - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Well, not that much all things considered! **Preset 10**'s speed did decrease from barely anything to 20% in the most extreme situation, but its improvements well outshine its speed regression. Overall, **preset 11** went from borderline unusable to becoming an interesting new fast real-time preset. This is pretty huge in my opinion, as it offers a new kind of trade-off no other AV1 encoder or prior SVT-AV1 versions did. - Preset 10 visual comparisons: [Avatar (full)](https://slow.pics/c/8GjtQQAm), [Avatar (HQ)](https://slow.pics/c/FriwG6rw), [Avatar (MQ)](https://slow.pics/c/vqau9jk1), [Avatar (LQ)](https://slow.pics/c/WQTbcWvH) [Ducks (full)](https://slow.pics/c/xYotraaP), [Ducks (HQ)](https://slow.pics/c/HHlwCvwc), [Ducks (MQ)](https://slow.pics/c/bgV6MoQz), [Ducks (LQ)](https://slow.pics/c/bOAyMVUk) [Fallout (full)](https://slow.pics/c/MrYTMHoQ), [Fallout (HQ)](https://slow.pics/c/qL9xmCfI), [Fallout (MQ)](https://slow.pics/c/dwdE0pWt), [Fallout (LQ)](https://slow.pics/c/uo7Ztb5f) [Minecraft (full)](https://slow.pics/c/fICToF3E), [Minecraft (HQ)](https://slow.pics/c/cGBhBsaS), [Minecraft (MQ)](https://slow.pics/c/w1P4LAu5), [Minecraft (LQ)](https://slow.pics/c/rNqRWd61) [Sol Levante (full)](https://slow.pics/c/UyMpDhx0), [Sol Levante (HQ)](https://slow.pics/c/b0B7ndsZ), [Sol Levante (MQ)](https://slow.pics/c/3H4ewpMI), [Sol Levante (LQ)](https://slow.pics/c/wpCnz72u) [Suzume (full)](https://slow.pics/c/ZYoFdtdS), [Suzume (HQ)](https://slow.pics/c/L2z8yEd5), [Suzume (MQ)](https://slow.pics/c/DEphKnbY), [Suzume (LQ)](https://slow.pics/c/Dm3OP4xO) [The Mandalorian (full)](https://slow.pics/c/NhYFWBzc), [The Mandalorian (HQ)](https://slow.pics/c/MFMQjVRD), [The Mandalorian (MQ)](https://slow.pics/c/pTt74iCi), [The Mandalorian (LQ)](https://slow.pics/c/e6VwtFfU) ### `preset 11`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). The new **preset 11** places itself between the old **preset 11** and the old **preset 12** efficiency and consistency wise. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Unsurprisingly, its speed is also in-between the old **preset 11** and the old **preset 12**. I'm unsure this new trade-off helps in anything. ### `preset 12`: v2.1.x vs v2.2.x - Compression efficiency & consistency graphs, high quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, medium quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). - Compression efficiency & consistency graphs, low quality range: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). **Preset 12** is almost unchanged from the previous release. - Speed graphs: > **Interactive comparison:** [Open the complete media manifest](/media/articles/svt-av1-third-deep-dive.json). Same speed wise. So, no improvements at all for the two fastest presets. They remain all around very bad performers. In hindsight, it doesn't matter that I couldn't upload the **preset 11 & 12** visual comparisons, because there is literally nothing to see. ### ~~`preset 13`: v2.1.x vs v2.2.x~~ **Preset 13** is mapped to **preset 12** in **v2.2.x**. ### TLDR With **v2.2.x**, we observed new efficiency/speed trade-offs for a good amount of presets. Some presets, like **-1** and **0**, received significant speed improvements at no efficiency cost. **Presets 3 and 7** received more reasonable speedups. **Presets 2, 8 and 11** have seen new trade-offs that are mostly beneficial. **Preset 10** was deeply revamped and replaces **preset 9** in my book as the fastest, still viable, real-time preset. **Preset 4** seems to have returned to the state it was in **v2.0.0**. On the other hand, **preset 5** seemed to have regressed slightly, and **presets 1, 9 and 12** are basically unchanged from **v2.1.x**. ## Conclusion The release of SVT-AV1 **v2.2.x** brings some welcome speed improvements. **Presets 2 through 4** continue to lead in efficiency for AV1 encoding, delivering top-tier quality and compression. Meanwhile, **presets 5 through 10** offer solid alternatives for those who find **presets 2 through 4** too slow, balancing quality with noticeably faster encoding times. Hopefully, this comprehensive third deep dive has given you a helpful starting point for choosing settings when encoding with ~~the latest~~ SVT-AV1(-PSY) v2.2.x. ## Future Once more, this testing focused on establishing the new presets dynamics, however I haven't revisited the different SVT-AV1 parameters since **v1.8.0**. A few meaningful features have been added since, like variance boost, and with this overhauled methodology, the conclusion made in that blog post may be different now. I think it will be worth to revisit this in the future, maybe in the next blog post for **v2.3.0**? Yes, I'm fully aware I'm late because **v2.3.0** has already been out for two whole weeks. Even if the frontend of this blog post doesn't seem to have radically changed, my entire workflow has tremendously evolved since last time. It may have taken me since mid-August to manage to complete this blog post, but my efforts should allow me to produce a follow-up faster. I am conscious of this blog post's limitations. First of all, I observed some odd behaviors from XPSNR on certain clips which I haven't been able to pinpoint yet. It would also give me nonsensical standard deviation results, which is the reason why only the standard deviation in SSIMU2 scores was given. Second of all, SVT-AV1's own behavior starts to get messy when you approach the SSIMULACRA2 0 score, rendering all the data in that region pretty much useless. Plus, aggregating these metrics scores take forever, so I'm looking into ways to accelerate the process, for instance by offloading the work to my GPU using [turbo-metrics](https://github.com/Gui-Yom/turbo-metrics). Also, I'm stuck between wanting to increase the amount of data points in each graphs to get more detailed results and having to keep everything readable. This time around I had to seperate each graph into three quality levels, but that's already too much for my liking. I will look into improving myself on the data presentation front. I feel like I have to streamline this formula to make it more digestible for everyone. Please, I'm open to **your** remarks and suggestions to improve on this blog post formula. That said, here are my plans for future blog posts: - a follow-up v2.3.0 article that also revisits the useful SVT-AV1 parameters. *__I'm planning for this to release before 2025.__* - an article focused on giving you encoding tips and explaining common AV1 encoding knowlegde is still planned for *someday*. - a *future* article focused on observing the evolution of all software AV1 encoders since the beginning of their development, as well as comparisons with vpxenc, AVM (development ground for AV2) and VVenC. - and many more... Thanks for reading! *Support me by making a donation on [my Ko-Fi page](https://ko-fi.com/nekotrix), as a reward for my efforts and to compensate for the electricity bills of two whole weeks of non-stop encoding.* {} --- # Fast Computation of SSIMULACRA2 on GPUs: A Performance Evaluation Canonical URL: https://encode.wiki/articles/turbo-metrics-performance/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: 0ddb5d5e7700f119988a48247e40f14f62d4061e7032eed180ec0029244de0a2 > **Note — Editorial correction — 7 September 2026.** > > This is the author's 2024 timing experiment, preserved with its hardware, tables, graphs, and preliminary scoring observations. It establishes measured throughput on those workloads, not perceptual validity or equivalence to reference SSIMULACRA2. No validation rerun has been performed. Corrections below withdraw the general stride and quality-assessment recommendations. # Introduction In this blog entry, we will evaluate the performance of [TurboMetrics](https://github.com/Gui-Yom/turbo-metrics), a software which provides a GPU-accelerated implementation of SSIMULACRA2, and promises to save a lot of time in its computation. Video encoding is a time-consuming task by itself. When it comes to assessing the resulting encodes, objective quality metrics are often used, providing advantages over subjective measurements, e.g., faster evaluation processes. Nevertheless, the computation of some of these metrics is still somewhat slow. This is the case for [SSIMULACRA2](/reference/metrics/ssimulacra2/), one of the most popular objective metrics for image and video assessment. ## Basics Before we start with the evaluation, we will first cover some fundamental (and not-so-fundamental) concepts. ### SSIMULACRA2 SSIMULACRA2, which is sometimes abbreviated as "ssimu2", is a perceptual metric for images, based on the concept of the multi-scale structural similarity index measure ([MS-SSIM](https://en.wikipedia.org/wiki/Structural_similarity_index_measure)). In the words of its developer, it is "[based on MS-SSIM], computed in a perceptually relevant color space, adding two other (asymmetric) error maps, and aggregating using two different norms". A total of 54 error maps are computed over multiple downscalings (from 1:1 to 1:32) of the image to assess (_distorted_) and its source image (_reference_). These error maps are then added using a weighted sum to produce the final SSIMULACRA2 score. The weight of each error map is tuned based on a large set of subjective scores from different image benchmarks. SSIMULACRA2 scores are in the range [-inf, 100]. They are reported to correlate to subjective visual quality scores as follows: * 30 = low quality * 50 = medium quality * 70 = high quality * 90 = very high quality; likely impossible to distinguish from the original when viewed at 1:1 from a normal viewing distance **Editorial correction:** there is no validated universal video-transparency threshold of 80 established here. Image-score interpretations do not automatically transfer to pooled video scores; motion can mask some defects and reveal others. The reference project describes image measurements, not a guarantee for every viewer or video. [SSIMULACRA2 reference](https://github.com/cloudinary/ssimulacra2). The reference implementation for SSIMULACRA2 can be found [here](https://github.com/cloudinary/ssimulacra2). Other popular implementations include [the Rust implementation](https://docs.rs/crate/ssimulacra2_rs/latest), and [the Zig implementation](https://github.com/dnjulek/vapoursynth-zip). SSIMULACRA2 can be applied independently to corresponding video frames. Means, percentiles, and per-frame traces summarize those image measurements, but they do not model temporal artifacts. A low standard deviation also does not guarantee consistently good quality. This article does not establish that SSIMULACRA2 universally outperforms PSNR, SSIM, or VMAF for video. As stated previously, SSIMULACRA2 computes 54 error maps per image assessed. This entails a high amount of computation, especially for videos, which usually contain tens of thousands of frames (images). That explains its rather slow execution time. Speeding up these computations would be very much desired, if possible. --- #### In-depth: SSIMULACRA2 computation The summary of the algorithm for SSIMULACRA2 is the following, as [reported here](https://github.com/Gui-Yom/turbo-metrics/blob/master/crates/ssimulacra2-cuda/README.md#computing-ssimulacra2): 1. Get the frame pair (reference and distorted). 2. Convert the frames to linear RGB (using 32-bit floating-point). 3. For each scale (1:1 to 1:32, downsampling by 2 every step: 6 different scales): 1. Downscale by the scale number (if needed). 2. Convert the frames to XYB color space. 3. Blur the following pictures, using a recursive Gaussian blur: (reference * reference), (distorted * distorted), (reference * distorted), (reference), (distorted). 4. Compute 1-SSIM, artifact and detail\_loss error scores from the 5 blurred images and the original frame pair; this yields 3 error maps. 5. The error maps are reduced to a single number using the 1-norm and 4-norm. 4. From this, we get 6 scores for each scale (6) and color component (3), totaling 108 scores. 5. The scores are added using a weighted sum. 6. The final value is processed through a non-linear function and clipped to render a score between 100 and -infinite. #### SSIMULACRA2 subsampling Given that the metric is quite slow to compute, it is often computed over a subset (subsample) of the video frames, instead of over all of them. For example, a _stride_ of 3 could be used, to compute SSIMULACRA2 scores for 1 frame out of every 3 in the video, skipping the computation for the other 2 frames. This is expected to speedup the computation by a factor of ×3. Skipping frames changes the sampled population. Its error can grow or shrink with stride depending on the content and phase; it is not necessarily monotonic. Prime strides such as 3 or 5 do not guarantee unbiased coverage of temporal layers, periodic motion, scene cuts, or short defects. Compare several offsets with a full-frame run on representative material before adopting subsampling, and retain full-frame checks for brief failures. The timing results below measure speed, not sampling accuracy. ### TurboMetrics [TurboMetrics](https://github.com/Gui-Yom/turbo-metrics) is a WIP software suite developed by the very talented [Gui-Yom/LimelioN](https://github.com/Gui-Yom). It is "a collection of video related libraries and tools oriented at performance and hardware acceleration". It comes as a collection of Rust libraries/crates, and some include command-line applications to interact with them. There are currently no public releases of the suite in the dedicated "Releases" page of its GitHub repository, but you can download the code and compile it yourself. The latest tagged version of the software, at the moment of writing, is v0.2.2. TurboMetrics focuses mainly on **NVIDIA GPUs** using CUDA. However, the developer is actively working on adding support for other hardware (e.g., AMD and Intel GPUs). Nevertheless, I only have experience with NVIDIA GPUs, so I cannot tell how the progress is going on that front. Among the tools, there is a working SSIMULACRA2 implementation that uses CUDA to leverage GPU acceleration, ssimulacra2-cuda. We will focus exclusively on it from now on. We will use this tool to compute SSIMULACRA2 scores for certain video samples. However, it is worth noting that the tool is also able to compute other metrics, such as SSIM and PSNR. It can even compute multiple metrics on the same rum. ssimulacra2-cuda is [stated to be](https://github.com/Gui-Yom/turbo-metrics/tree/master/crates/ssimulacra2-cuda) "close to the original implementation, and with close results". Also, the developer has said that "[r]ight now, [it] can compute SSIMULACRA2 orders of magnitude faster than the ssimulacra2\_rs implementation". Therefore, we can expect the tool to compute SSIMULACRA2 scores for videos much faster than any CPU implementation out there, but provide scores that are not quite the same as the ones those CPU implementations would give, including the reference one. In this blog entry, we will test that second claim, concerning the speed of TurboMetrics in computing SSIMULACRA2. --- #### In-depth: Implementation differences from the reference As [reported here](https://github.com/Gui-Yom/turbo-metrics/blob/master/crates/ssimulacra2-cuda/README.md#differences-from-the-reference-implementation), the GPU implementation of SSIMULACRA2 provided in TurboMetrics differs from the reference implementation in the following ways that can affect the accuracy of the reported scores: * The conversion from YUV to linear RGB might not be yielding the same results as other tools. * Explicit Fused Multiply-Add (FMA) operations are used when possible, as the GPU can leverage them for higher performance. * The order of operations might not be the same, as some calculations have been rearranged. * Floating-point operations might not yield the same results, especially with the approximated math functions used in the GPU (like `powf`). Additionally, the differences in scores are amplified by the following features of the SSIMULACRA2 computation: * The original weights were computed by fitting the error scores to Mean Opinion Score (MOS), and deviation in the error scores is amplified by them. * The final non-linear function is rather steep (it is a cubic function, x³), and, thus, score variations are amplified again. ## Performance evaluation ### Setup In this experiment, we will evaluate TurboMetrics in terms of performance; that is, the amount of ssimu2 scores computed per unit of time. For that, an episode of an animated series (~25 minutes), encoded with H.264, has been chosen as sample video. The selected clip has 1080p resolution (1920×1080), 8 bits per sample, and YUV 4:2:0 chroma subsampling. These properties affect the metric workload, while codec, encoding settings, I/O, and decoder paths can also affect end-to-end throughput. The experiment does not isolate GPU kernel speed. The video source and example distorted encode have been compared using **ssimulacra2\_rs**, **vszip**, and **TurboMetrics**. ssimulacra2\_rs and vszip are both CPU implementations of SSIMULACRA2, the former written in Rust and the latter in Zig (but invoked from VapourSynth/Python scripts). It has been reported that the Zig implementation is considerably faster than the Rust one, and we can check that out as well! The CPU implementations have been executed on an Intel i5-11400 CPU (base frequency of 2.60 GHz, turbo frequency of 4.40 GHz), using 6 CPU cores (`-f 6` parameter in ssimulacra2\_rs, `-t 6` parameter in ssimulacravszip.py). TurboMetrics has been executed both on an NVIDIA GTX 1060 GPU and an NVIDIA RTX 4060 GPU. The three programs have been executed for the same video pair with **varying frame strides: 1, 3, 5, 7, 11, 13, 17, 19, and 23** (not skipping frames, plus every prime number lower than 24 frames / 1 second, excluding 2). For the CPU and RTX 4060 executions, the distorted video was a custom AV1 encode of the reference video. For the GTX 1060, as it does not have AV1 decoding hardware support, the H.264 reference video was compared to itself **This is a different decode workload from the H.264/AV1 pair used elsewhere, so the GTX and RTX timings are not a controlled GPU-only comparison.** ### Results and discussion The exact results of this experiment are shown in the following table: | Stride | ssimulacra2\_rs FPS | vszip FPS | GTX 1060 GPU FPS | RTX 4060 GPU FPS | |:-:|:-:|:-:|:-:|:-:| | 1 | 3.37 | 14.63 | 46.70 | 85.64 | | 3 | 9.55 | 37.67 | 133.86 | 245.73 | | 5 | 15.15 | 49.34 | 164.34 | 350.01 | | 7 | 20.45 | 56.37 | 197.17 | 400.94 | | 11 | 30.23 | 64.46 | 222.98 | 458.61 | | 13 | 34.54 | 66.65 | 239.17 | 488.83 | | 17 | 40.51 | 69.23 | 249.58 | 520.30 | | 19 | 42.82 | 69.99 | 258.71 | 525.44 | | 23 | 45.43 | 88.60 | 264.85 | 546.14 | Here they are in graph form, for better visualization: ![CPU vs GPUs decoded FPS](/img/blog_turbo-metrics_11-2024/ssimu2_cpu-gpu_dec.svg) On a superficial level, we can already make some observations: * SSIMULACRA2 computation with ssimulacra2\_rs is quite slow: 3.37 frames per second (without skipping frames) when using 6 threads. That is like 0.56 frames per second per thread. I know the CPU used is no beast by any measure, but beast CPUs are quite expensive and not that common (that is something to keep in mind). Those processing speeds are comparable to some of the slower-ish presets of SVT-AV1. - vszip is, in fact, considerably faster: Between ×4.34 (full video computation) and ×1.63 (stride of 19) with the same amount of threads. However, it seems that vszip does not scale as well as the other implementations (except for that weird performance boost with a stride of 23). * GPU computation of SSIMULACRA2 scores is impressive, considering the CPU performances: - Compared to ssimulacra2\_rs: Speedups for the GTX 1060 (an 8-year-old GPU) are between ×14.01 (stride of 3) and ×5.83 (stride of 23). Speedups for the RTX 4060 are between ×25.73 (stride of 3) and ×12.02 (stride of 23). - Compared to vszip: Speedups for the GTX 1060 are between ×3.70 (stride of 19) and ×2.99 (stride of 23). Speedups for the RTX 4060 are between ×7.51 (stride of 17) and ×5.85 (stride of 1 / full video computation). - It is amazing seeing how GPUs not only achieve real-time SSIMULACRA2 computation of entire videos, but more than ×1.94 and ×3.56 real-time processing, even (GTX and RTX, respectively). Nevertheless, the most interesting observation is made when we use computation strides bigger than 1: The performance does _not_ scale linearly with the stride, as it would be expected. This happens with both the CPU and GPUs, although it is more noticeable in the case of the GPUs due to their higher performance. Why is that? Well, there is actually a good explanation: The reported FPS are _decoded_ FPS. That is, the speed in which the software is decoding and processing all the video frames. All the frames in the video bitstream are decoded and reconstructed as images, but the SSIMULACRA2 score is only computed for some of them. SSIMULACRA2 computation affects decoding speed in that the decoding of each frame only starts after the processing of the previous has finished (kind of, this is not be entirely true for multithreaded CPU implementations, but we can ignore that). The faster the SSIMULACRA2 processing is done, the sooner the next frame starts decoding. And there is no faster processing than not doing any processing at all, that is, skipping the frame! However, **the decoding itself is a process that has to be done regardless**, and the time it takes should not be disregarded. Although decoding as a process is considerably faster than SSIMULACRA2 computation, it starts becoming the bottleneck when you both compute SSIMULACRA2 so fast, and skip computing frames. ### Considerations about video decoding performance [NVIDIA's Video Codec SDK 13.0 application note](https://docs.nvidia.com/video-technologies/video-codec-sdk/13.0/nvdec-application-note/index.html#nvdec-performance) gives these indicative per-NVDEC figures for 1080p YUV 4:2:0 decoding: * Pascal architecture decodes H.264 at up to 694 frames per second. * Ada architecture decodes H.264 at up to 903 frames per second. * Ada architecture decodes AV1 at up to 1,018 frames per second. Being proprietary NVIDIA technology, served as a black box through their API, we cannot be sure how the NVDEC engines are implemented and what exactly are their limitations under scenarios such as these (i.e., concurrent decoding of multiple video streams of same or different codecs). We can only trust the information NVIDIA provides. NVDEC engine count and capability are product-specific; the statement that all GeForce products have one engine is not a current hardware rule. The ratios below are the author's comparison against indicative SDK figures, not measurements of decoder utilization. In our case, considering two videos are being decoded at the same time: * The GTX 1060 decodes up to 529.7 H.264 (2×264.85) frames per second when using a stride of 23 frames, which corresponds to 75% of its reported peak decoding performance for H.264. * The RTX 4060 decodes up to 546.14 H.264 + 546.14 AV1 (1092.28 total) frames per second when using a stride of 23 frames, which corresponds to 61.85% and 54.34% of its reported peak decoding performance for H.264 and AV1 respectively. Notice how, even though the NVDEC hardware resources are reportedly being shared between the two decodes, both are able to reach more than 50% peak performance **at the same time**. We can just focus on _processed_ FPS, that is, only not-skipped frames processed per second, or SSIMULACRA2 scores computed per second, to see how the processing performance degrades with increasing strides. | Stride | ssimulacra2\_rs FPS | vszip FPS | GTX 1060 GPU FPS | RTX 4060 GPU FPS | |:-:|:-:|:-:|:-:|:-:| | 1 | 3.37 | 14.63 | 46.70 | 85.64 | | 3 | 3.18 | 12.56 | 44.62 | 81.91 | | 5 | 3.03 | 9.87 | 32.87 | 70.00 | | 7 | 2.92 | 8.05 | 28.17 | 57.28 | | 11 | 2.75 | 5.86 | 20.27 | 41.69 | | 13 | 2.66 | 5.13 | 18.40 | 37.60 | | 17 | 2.38 | 4.07 | 14.68 | 30.61 | | 19 | 2.25 | 3.68 | 13.62 | 27.65 | | 23 | 1.98 | 3.85 | 11.52 | 23.75 | Here they are in graph form, for better visualization: ![CPU vs GPUs processed FPS](/img/blog_turbo-metrics_11-2024/ssimu2_cpu-gpu_comp.svg) It can be seen how the actual SSIMULACRA2 processing performance quickly decreases, as more and more relative time gets dedicated to decoding the videos. **Editorial correction:** these measurements do not justify a GPU purchase recommendation or a claim that increasing stride has insignificant scoring error. Decoder throughput depends on the GPU model, clocks, stream characteristics, and software pipeline; generation alone does not guarantee identical end-to-end performance. Profile the intended workload before deciding whether decoding, conversion, transfer, or metric computation is the bottleneck. Sampling error and implementation error require separate validation. ### Conclusions As a quick summary of the experiment, we can highlight: * **GPU processing greatly accelerates SSIMULACRA2 computation**, with modern GPUs enabling speeds **faster than real-time** on the tested RTX 4060 workload (~85 fps), while the GTX 1060's different H.264 self-comparison workload reached ~46 fps. * As SSIMULACRA2 computations accelerate, **video decoding speed becomes a relevant factor, to the point of being the main bottleneck when the computation stride is large enough**. It is not worthwhile to increase the computation stride too much, as you will quickly get diminishing returns in performance. --- ### Further discussion: Possible improvements One may think that a possible solution to the decoding speed bottleneck, which does not require waiting until the next-generation GPUs implement faster decoding hardware, would be to **make the software decode only the frames that are going to be processed**. Nevertheless, that approach comes with significant caveats: Inter-predicted frames require their reference dependencies to be decoded, but not necessarily every frame in the entire GOP. Savings from selective decoding depend on the dependency graph, random-access points, and decoder API; this experiment did not measure such a pipeline. (Aside from the possible accuracy/representativeness concerns associated to using such big strides.) Additionally, when leveraging GPU programming, the actual hardware is often treated like a black box, and the available APIs may limit considerably the control the user has over it. Another, more useful approach one may think of, would be to exploit **computation overlapping**: To keep decoding frames while the SSIMULACRA2 scores are being computed, storing the decoded frames that are to be processed in a buffer. This seems to be partially implemented in TurboMetrics already, but only to some extent. Without any modification to the SSIMULACRA2 computations, the overlap in computation and decoding would still have limited effect for low strides (where SSIMULACRA2 computation is still the bottleneck), as every time the decoded frame buffer fills completely, the decoder would have to wait for it to have free space again. In theory, the SSIMULACRA2 computations could be sped up further (maybe requiring faster but more imprecise approximations). And, ideally, TurboMetrics should aim to approach the theoretical decode FPS limit in the computation of the SSIMULACRA2 scores, thus perfectly overlapping computing and decoding. In such scenario, skipping the computation of any frames would not make sense anymore, as no speed advantage would be obtained from it. However, this is still far from being a reality, as a speedup of at least ×10.31 is needed for an RTX 4060 to match its decoding speeds with a computation stride of 1. ## Short discussion on scoring error My original idea for this blog entry was to evaluate TurboMetrics both in terms of performance and scoring error. By "scoring error" I mean "the difference between the scores a CPU reference provides, and the ones TurboMetrics provides". However, once the first draft for that original version of this blog entry was completed, I realized I was not satisfied with the methodology followed and conclusions extracted from that second experiment. Therefore, I am putting off that evaluation for a second blog entry, that I will write once I make a new, bigger, and better, evaluation of the error. The main concern about the error the GPU computation incurs on SSIMULACRA2 scores is that SSIMULACRA2 scores have been tuned mathematically to correlate with visual quality, while the GPU implementation's scores _try to mimic_ those scores, but have not undergone any kind of mathematical tuning or assessment themselves. The GPU scores could be seen as "SSIMULACRA2 + random error", and that "random error" might break the desired correlation, thus reducing the reliability of the metric. Nevertheless, it is worth noting that SSIMULACRA2 is not by any means a kind of "perfect metric" or "absolute truth" about video quality assessment. **SSIMULACRA2 still is unreliable in some situations, and it does not always present a perfect correlation with visual observations**. You may find here and there specific examples of SSIMULACRA2 scores that do not accurately reflect the (perceived) quality of a compressed image or video. Besides, we should keep in mind that quality is a subjective matter. In that regard, and as an example, people who do not care much about film grain might give denoised videos higher quality scores than those that SSIMULACRA2 gives. (Other metrics, such as VMAF, are more tolerant to denoising.) Calling the output an “alternative metric” does not validate it. A changed implementation needs agreement checks against the reference with identical preprocessing, and a changed perceptual model needs testing against independent subjective data. The preliminary findings below are reasons to investigate, not proof of either perceptual validity or universal invalidity. Just to give a preview on the error evaluation thus far, I will share the following: The preliminary results I obtained from that now-scraped evaluation seem to indicate that: * The scores provided by the GPU implementation of SSIMULACRA2 are **statistically different** to the real scores (provided by the CPU implementations). * **No linear correlation** between the real scores and the GPU scores has been found. * TurboMetrics **might tend to under-score**, compared to the real scores (i.e., the results for the frames tend to be lower than those a CPU implementation gives). This has yet to be assessed over a larger sample size to prove if it is really true, though. I am looking for help with the error evaluation for the follow-up blog entry. Mainly, I need a considerably larger sample of SSIMULACRA2 scores for videos, computed both in CPU and GPU. I myself do not have enough material (encoded videos and/or the SSIMULACRA2 scores for all their frames) yet to do a sufficiently good evaluation, and it would take me quite some time to get it. Thus, I am looking for anyone who has saved the SSIMULACRA2 scores for all the frames of any video they had assessed, and is able to re-assess those same videos using TurboMetrics. If you think you can help, and are willing to, please contact me through the [AV1 for Dummies Discord server](https://discord.gg/bbQD5MjDr3). ## Overall conclusions and final thoughts In this blog entry, we have tested the GPU implementation of SSIMULACRA2 available through TurboMetrics, in terms of performance (i.e., scores computed per unit of time). The main conclusions are the following: * All in all, TurboMetrics provides **impressive acceleration** of the SSIMULACRA2 computation. * **The performance of TurboMetrics does not scale linearly with the computational stride/frame skipping**. When increasing the stride, a point of diminishing returns is reached rather soon. - This is caused by the time taken to decode the video frames, which is non-negligible, and becomes the bottleneck when computing SSIMULACRA2 so fast and only for some of the frames. Hardware acceleration of computationally-intensive tasks is an important topic nowadays in several fields, especially considering how powerful current-day GPUs are; and I would hope for the teams developing these quality assessment metrics to consider it as an existing option. So far, only [XPSNR](https://github.com/fraunhoferhhi/xpsnr) has seemed to be concerned about computational complexity from the beginning, and the developers' response was not to consider hardware acceleration, but rather to simplify the design of their metric. **Editorial correction to the recommendation:** the reported speedups justify considering TurboMetrics for further evaluation, but this article does not establish it as a substitute for reference SSIMULACRA2 quality scores. Do not transfer reference score thresholds to it or assume stride 3 or 5 is harmless. First match color conversion and frame alignment, quantify score and ranking differences on representative distortions, and validate sampling separately. Use [quality-comparison guidance](/guides/compare-encoding-quality/) and the [reference implementation](https://github.com/cloudinary/ssimulacra2) for a reproducible baseline. ## Future plans recorded in November 2024 TurboMetrics' development is still ongoing, and I know Gui-Yom has tons of ideas for it. To begin with, I know the following ideas are being worked on: * Support for GPUs of other vendors (AMD, Intel). * Support for FFmpeg piping, to enable working with videos of any codec. * GPU acceleration of XPSNR. All these features would improve TurboMetrics significantly, while also opening the door for more tests to be performed. Additionally, as it has been mentioned in this blog entry, the SSIMULACRA2 computation can still be optimized further, including overlapping computation and decoding. Gui-Yom knows this, and plans to tackle that issue eventually. A list of features to improve TurboMetrics' computation of SSIMULACRA2, written by the main developer, can be found [here](https://github.com/Gui-Yom/turbo-metrics/blob/master/crates/ssimulacra2-cuda/README.md#how-to-do-better-). As I said earlier, I also plan to write a follow-up blog entry evaluating the scoring error incurred in the GPU implementation, to test the reliability of the scores provided by TurboMetrics. Additionally, it may be insightful to evaluate the error for GPU implementations of other video metrics, such as [VMAF CUDA](https://github.com/Netflix/vmaf/blob/master/libvmaf/README.md), and see if we find any similarities. I do not recall reading any analysis on the matter for other metrics, either. Nevertheless, I cannot give a date yet for when that follow-up blog entry might come out. I reckon it will take quite some time to perform the required experimentation, as well as processing and analyzing the results. Also, this blog entry is heavily missing information on 4K video, which I believe to be of high interest. The main reason for it is that most 4K content is served using HEVC, and TurboMetrics still does not support that codec. When support for it gets added, experiments with 4K video should be conducted. If you like TurboMetrics and have knowledge about programming, please consider [contributing to it](https://github.com/Gui-Yom/turbo-metrics) to the best of your ability. Together, we can make it even more awesome than it already is! And, lastly, thank you very much for reading! #### Special thanks * **Gui-Yom**, for developing TurboMetrics, and also for proofreading and green-lighting this blog entry. * **Trix**, for linking me to the Python script to easily compute SSIMULACRA2 using vszip (ssimulacravszip.py), and for helping me to get it to work the way I needed. {} --- # Welcome to Encode Wiki Canonical URL: https://encode.wiki/articles/welcome/ Collection: articles Status: current License: CC BY-SA 4.0 Checksum: 68e71c4247dec11538d72fa96b5b2e6303c5c1e8b792dab4cce25649e5973bab Encode Wiki is a community-maintained home for practical information about codecs and encoding tools. It combines durable reference documentation with reproducible guides, experiments, and benchmark articles. The initial corpus comes from the AV1 Community Contributors' [Codec Wiki](https://github.com/av1-community-contributors/codec-wiki). Its pages will be migrated with source provenance and modification notices under CC BY-SA 4.0. The application and deployment code written for Encode Wiki is separately licensed under MIT. The public site is designed to remain useful without accounts, analytics, or an AI service. Clean machine-readable editions will also make the reviewed corpus easier to use from other tools. --- # Codecs Canonical URL: https://encode.wiki/codecs/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 7f384091cef782dd5174114ad208ed679fbe7c200b55f5d5b89d464aa7d08444 Each codec page describes a format: what its bitstreams can express, the profiles and containers it uses, and where implementations differ. Use these pages to choose a format, then the tool pages to pick the encoder that writes it. --- # Audio codecs overview Canonical URL: https://encode.wiki/codecs/audio/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: ac5b6b4c63041cced59b08640034ea5aac9f5c55c1a43b7bf8273fd9a22a93ee New to audio coding? Start with the [intro](/codecs/audio/intro/). Otherwise, this is the short version of what to pick. ## Which codec should I use? | You want | Use | Notes | | --- | --- | --- | | Lossy audio for most things — music, speech, video soundtracks | [Opus](/codecs/audio/opus/) | Best quality per bit across the whole range, from low-bitrate speech to near-transparent music. Ogg, WebM, Matroska, MP4. | | Lossy audio that has to play on everything, including hardware players, TVs and old phones | [AAC](/codecs/audio/aac/) in MP4/M4A | The safe choice for MP4 video and streaming. | | Lossy audio for really old devices | [MP3](/codecs/audio/mp3/) | Needs more bitrate than AAC or Opus for the same quality, but plays on anything. | | Lossless archive or lossless delivery | [FLAC](/codecs/audio/flac/) | Open, fast, supported nearly everywhere. | | Lossless in an Apple-only library | [ALAC](/codecs/audio/alac/) | Same idea as FLAC; Apple's ecosystem prefers it. | | Lossless with a lossy-plus-correction hybrid mode | [WavPack](/codecs/audio/wavpack/) | Niche; the hybrid mode is its selling point. | | Surround on Blu-ray, TVs and receivers | [Dolby](/codecs/audio/dolby/) (AC-3, E-AC-3, TrueHD) | Keep the original track when remuxing; re-encoding costs quality. | | Object-based or immersive audio | [Spatial audio](/codecs/audio/spatial-audio/) | Atmos, MPEG-H, IAMF and so on are metadata systems on top of codecs. | [Vorbis](/codecs/audio/vorbis/) and [Speex](/codecs/audio/speex/) are both superseded by Opus. Keep them only for existing files or devices that require them. ## Comparison | Codec | Type | Typical channels | Containers | Encoders | | --- | --- | --- | --- | --- | | Opus | Lossy | Mono and stereo; multichannel via channel mapping families | Ogg, WebM, Matroska, MP4 | libopus (`opusenc`, FFmpeg `libopus`) | | AAC | Lossy | Up to 5.1 and 7.1 in common profiles | MP4/M4A, MPEG-TS, ADTS, Matroska | Apple, Fraunhofer FDK, FFmpeg native | | MP3 | Lossy | Mono and stereo only | Raw MP3, Matroska, MP4 | LAME | | Vorbis | Lossy | 1–255 | Ogg, WebM, Matroska | libvorbis | | FLAC | Lossless | 1–8 | Native FLAC, Ogg, Matroska | `flac`, FFmpeg | | ALAC | Lossless | 1–8 | MP4/M4A, MOV | Apple, FFmpeg | | WavPack | Lossless or hybrid | Many (hundreds supported) | Native WavPack, Matroska | `wavpack`, FFmpeg | | Speex | Lossy, speech only | Mono and stereo | Ogg | `speexenc` | FLAC stores 4–32-bit integer PCM. ALAC stores 16, 20, 24 and 32-bit integer PCM, though FFmpeg's encoder writes only 16 and 24-bit. WavPack also stores 32-bit float and DSD. ## Browser support MP3, AAC in MP4 and FLAC play in every current browser. Opus and Vorbis in Ogg or WebM play in Chrome, Edge and Firefox, and Safari 18.4 added Ogg Opus and Vorbis on recent Apple operating systems. ALAC is effectively Safari-only, AC-3 and E-AC-3 play only where the operating system supplies a licensed decoder (Apple platforms, some Windows and TV browsers), and Speex and WavPack need an application-supplied decoder. The [image and audio support guide](/reference/image-audio-support/) has the detection code. ## Channels versus spatial audio More channels is not the same as spatial audio. Immersive systems describe objects, scenes and speaker layouts in metadata that a renderer interprets; the actual samples are carried by an ordinary codec. See [spatial and immersive audio](/codecs/audio/spatial-audio/). --- # AAC Canonical URL: https://encode.wiki/codecs/audio/aac/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 1229335095fdc1dbb2e05df9d5a84114ed04375f79dd322e0249be13267a5a56 AAC is a family of lossy MPEG audio profiles. "AAC" on its own almost always means **AAC-LC**, the profile every phone, player, TV and browser can decode. It is the right default whenever the file has to play everywhere: MP4 video, iTunes/Apple Music, Bluetooth, broadcast. If compatibility is not a constraint, [Opus](/codecs/audio/opus/) is usually the better lossy codec. ## Profiles | Profile | What it is | When to use it | | --- | --- | --- | | **AAC-LC** | The standard profile. | Default for everything from about 96 kbit/s stereo up. | | **HE-AAC (v1)** | LC core at half the sample rate plus Spectral Band Replication (SBR), which rebuilds the high frequencies from side data. | Stereo below roughly 64 kbit/s, e.g. streaming and spoken word. Above ~96 kbit/s, plain LC is as good or better. | | **HE-AAC v2** | HE-AAC plus Parametric Stereo (PS), which codes stereo as a mono downmix plus spatial parameters. | Stereo at 32 kbit/s and below. Stereo only. | | **AAC-LD / AAC-ELD** | Low-delay variants for conferencing. | Real-time use. Almost no file or player support; encoded by FDK-AAC and Apple's encoder. | | **xHE-AAC (USAC)** | MPEG-D USAC with MPEG-D DRC loudness metadata; handles speech and music well at very low rates. | Low-rate streaming where you control the player. [exhale](/tools/software-encoders/exhale/) is the only free encoder. | ### xHE-AAC xHE-AAC is natively decodable on current Android, Apple (iOS, macOS, tvOS, watchOS) and Windows 11 platforms, but not in most other players, and FFmpeg's decoder does not handle every stream (see [exhale](/tools/software-encoders/exhale/#decoding-in-ffmpeg)). Keep an AAC-LC version if you cannot control the player. In MP4, the profile is signalled by the codec string: `mp4a.40.2` (LC), `mp4a.40.5` (HE-AAC), `mp4a.40.29` (HE-AAC v2), `mp4a.40.42` (xHE-AAC). HE-AAC decoders output at double the core sample rate, which matters if you handle the decoded audio yourself. ## Which encoder to use | Encoder | Profiles | Notes | | --- | --- | --- | | **Apple Core Audio** | LC, HE-AAC, LD, ELD (FFmpeg's `aac_at` also requests HE-AAC v2; qaac has no v2 mode) | Generally regarded by the Hydrogenaudio community as the best AAC encoder. Use [qaac](/tools/software-encoders/qaac/) on Windows, `afconvert` or FFmpeg's `aac_at` on macOS. | | **FDK-AAC** (`fdkaac`, `libfdk_aac`) | LC, HE-AAC, HE-AAC v2, LD, ELD | Close to Apple at typical rates and available everywhere. Its license is GPL-incompatible: an FFmpeg build that also uses `--enable-gpl` (as any build with x264 or x265 does) needs `--enable-nonfree` and cannot be redistributed, so most downloadable builds leave it out. The standalone [`fdkaac`](https://github.com/nu774/fdkaac) tool avoids building FFmpeg yourself. | | **FFmpeg native `aac`** | LC | Free and built into every FFmpeg. Behind Apple and FDK, most noticeably at low bitrates; give it more bitrate (160–192 kbit/s stereo) to compensate. Use `-b:a`: its `-q:a` VBR mode works but has no calibrated scale. | | **exhale** | xHE-AAC | See above. | FAAC and the discontinued Nero encoder still turn up in old guides; there is no reason to use either today. ## Starting points For stereo music the usual targets are 128 kbit/s for small files, 160–192 kbit/s for a comfortable margin, and 256 kbit/s as overkill insurance. Bitrate is the total for all channels. ```sh # FFmpeg native encoder ffmpeg -i input.flac -c:a aac -b:a 192k output.m4a # FDK-AAC through the standalone tool: VBR 4 is roughly 150 kbit/s for stereo fdkaac -m 4 -o output.m4a input.wav # FDK-AAC through an FFmpeg build that includes libfdk_aac ffmpeg -i input.flac -c:a libfdk_aac -vbr 4 output.m4a # Apple encoder through qaac (Windows), true VBR around 190 kbit/s qaac64 --tvbr 91 -o output.m4a input.wav ``` FDK's VBR modes 1–5 target roughly 32, 40, 48–56, 64 and 80–96 kbit/s per channel; FFmpeg documents its `libfdk_aac` VBR as experimental, and it is only dependable with AAC-LC. For HE-AAC, use a plain bitrate: ```sh fdkaac -p 5 -b 64000 -o he-aac.m4a input.wav fdkaac -p 29 -b 32000 -o he-aac-v2.m4a input.wav ``` `fdkaac` reads WAV or raw PCM (`-R`), not FLAC; pipe from FFmpeg with `ffmpeg -i input.flac -f wav - | fdkaac -m 4 -o output.m4a -`. Its `-b` takes bit/s, and `-m 1`–`5` selects VBR and overrides `-b`. > **Caution.** > > FFmpeg's native encoder only makes AAC-LC. Passing `-profile:a aac_he` to it fails; HE-AAC needs `libfdk_aac` or an Apple encoder. ## Containers and files | Container | Notes | | --- | --- | | **MP4/M4A** | The normal choice. Stores the profile and encoder delay, so gapless playback works. Add `-movflags +faststart` for web delivery. | | **ADTS (`.aac`)** | Raw frames with a header on each. Needed by some hardware and streaming tools; carries no tags or gapless information. `fdkaac -f 2` writes it. | | **LATM/LOAS** | Broadcast transport (`fdkaac -f 10`, `libfdk_aac -latm 1`). | | **MPEG-TS, Matroska** | Fine for video; check the player. | Neither `.aac` nor `.m4a` tells you the profile. Run `ffprobe` on the file if you need to know. For gapless playback in iTunes-style players, keep the encoder-delay metadata (`fdkaac -G 2` writes both the iTunes and ISO forms; qaac does this by default). Do not trim decoded samples by hand. ## Pitfalls - Re-encoding an AAC (or any lossy) source stacks artefacts. Encode from the lossless original. - Downmixing with `-ac 1` or `-ac 2` can cause phase cancellation on some mixes; check by ear. ## Related [Opus](/codecs/audio/opus/) for open, royalty-free lossy audio. [FLAC](/codecs/audio/flac/) for lossless. [Vorbis](/codecs/audio/vorbis/) in older Ogg/WebM workflows. ## Full option reference Every option of the encoders above in FFmpeg 9.0.2 and `fdkaac` 1.0.9 (with FDK-AAC 2.0.3). Defaults are what you get when the option is omitted. ## FFmpeg native AAC parameter reference Private options of the native [`aac` encoder](https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/aacenc.c). The `anmr` coder and the `aac_pred`/`aac_ltp` options in older guides no longer exist. | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `-aac_coder` | `twoloop` | `twoloop`, `fast` | Quantizer search. `twoloop` gives the best quality; `fast` is quicker and worse. | | `-aac_ms` | `auto` | `auto`, `0`, `1` | Mid/side stereo. `auto` decides per band, `1` forces M/S on every band, `0` disables it. Always off for more than three channels. | | `-aac_is` | `1` | `0`/`1` | Intensity stereo: codes some high bands as one channel plus a position. Saves bits at low bitrates. | | `-aac_pns` | `1` | `0`/`1` | Perceptual noise substitution: replaces noise-like bands with synthesized noise. Turned off for `-profile:a mpeg2_aac_low`. | | `-aac_tns` | `1` | `0`/`1` | Temporal noise shaping; reduces pre-echo on transients. | | `-aac_pce` | `0` | `0`/`1` | Signal the channel layout with a Program Config Element even for standard layouts. Non-standard layouts always get one. | ### Generic audio controls used by AAC encoders | Parameter | Native `aac` | `libfdk_aac` | Notes | | --- | --- | --- | --- | | `-profile:a` | `aac_low` (default), `mpeg2_aac_low` | `aac_low` (default), `aac_he`, `aac_he_v2`, `aac_ld`, `aac_eld`, `mpeg2_aac_low`, `mpeg2_aac_he` | The native encoder can't do HE-AAC or xHE-AAC. | | `-b:a` | 128k per channel pair, 69k per single channel, 16k per LFE (128k stereo) | About 96k mono or 128k stereo at 44.1 kHz, scaled with sample rate; halved for HE-AAC | Total bitrate for all channels. | | `-q:a` | Constant quality: fixed quantizer, no rate control | `1`–`5`, same as `-vbr` | Selects VBR instead of `-b:a`. Higher means more bits. | | `-cutoff` | Encoder chooses | Library chooses; at most 20000 Hz | Low-pass in Hz. | | `-ar` | 7350–96000 Hz (the 13 AAC rates) | Depends on profile | FFmpeg resamples to a supported rate. | | `-sample_fmt` | `fltp` | `s16` | Input format; FFmpeg converts automatically. | ## FFmpeg `libfdk_aac` parameter reference Private options of the [FFmpeg 9.0.2 `libfdk_aac` wrapper](https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/libfdk-aacenc.c). It needs FFmpeg built with `--enable-libfdk-aac` (non-free, so not in most distributed builds). | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `-afterburner` | `1` | `0`/`1` | Extra analysis for better quality at some CPU cost. Leave it on. | | `-eld_sbr` | `0` | `0`/`1` | Enable SBR with `-profile:a aac_eld`. HE-AAC gets SBR from `-profile:a aac_he`/`aac_he_v2`. | | `-eld_v2` | `0` | `0`/`1` | ELDv2 (LD-MPS) for stereo AAC-ELD. Only present when FFmpeg is built against fdk-aac 2.0 or later. | | `-signaling` | `default` | `default`, `implicit`, `explicit_sbr`, `explicit_hierarchical` | How SBR/PS are signalled. `default` uses `explicit_hierarchical` when the muxer stores a global header (MP4, Matroska) and `implicit` for ADTS/LATM. | | `-latm` | `0` | `0`/`1` | Write LOAS/LATM instead of ADTS when the muxer doesn't use a global header. No effect for MP4 or Matroska. | | `-header_period` | `0` | `0`–`65535` frames | With `-latm 1`, repeat the StreamMuxConfig/PCE every N frames. `0` keeps the library default. | | `-vbr` | `0` | `0`–`5` | `0` uses `-b:a`. `1`–`5` are FDK's VBR modes; its documented stereo averages are about 32 (HE-AAC v2), 72 (HE-AAC), 112, 148 and 228 kbit/s. FFmpeg warns that VBR only works with some parameter combinations. | | `-drc_profile` | `0` | `0` none, `1` film standard, `2` film light, `3` music standard, `4` music light, `5` speech | MPEG-4 DRC profile written as metadata for the decoder; the encoded audio is unchanged. | | `-drc_target_ref` | `0` | Integer dB, `-31`–`0` | Target reference level for `-drc_profile`. | | `-comp_profile` | `0` | Same as `-drc_profile` | ETSI heavy-compression profile; only written when `-drc_profile` is non-zero. | | `-comp_target_ref` | `0` | Integer dB, `-31`–`0` | Target reference level for `-comp_profile`. | | `-prog_ref` | `0` | Integer dB, `-31`–`0` | Programme (dialogue) reference level metadata. `0` means it is not written. | | `-frame_length` | `-1` | `1024` (LC, HE), `512`/`480` (LD, ELD), `256`/`240`/`128`/`120` (downscaled ELD) | Core frame length in samples. `-1` keeps the profile default. | ## Standalone `fdkaac` 1.0.9 parameter reference [`fdkaac`](https://github.com/nu774/fdkaac/blob/v1.0.9/src/main.c) is a separate command-line frontend to FDK-AAC; its options and units differ from FFmpeg's wrapper. Its help lists `--header-period` as `-h`, but the working short form is `-P` (`-h` prints help). ### Coding and transport | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `-p`, `--profile N` | `2` | `2` AAC-LC, `5` HE-AAC, `29` HE-AAC v2, `23` AAC-LD, `39` AAC-ELD | Audio object type. | | `-b`, `--bitrate N` | None; required unless `-m` is 1–5 | bit/s; values below 10000 are read as kbit/s | CBR target. `-b 128` and `-b 128000` are the same. | | `-m`, `--bitrate-mode N` | `0` | `0` CBR, `1`–`5` VBR | VBR modes ignore `-b`. Mode 1 is tuned for HE-AAC v2, 2 for HE-AAC, 3–5 for AAC-LC; FDK's documented stereo averages are about 32, 72, 112, 148 and 228 kbit/s. | | `-w`, `--bandwidth N` | `0` (auto) | Hz | Low-pass frequency, AAC-LC only. At most 20 kHz or half the sample rate; the automatic choice is usually better. | | `-a`, `--afterburner N` | `1` | `0`/`1` | Extra analysis for better quality. Leave it on. | | `-L`, `--lowdelay-sbr N` | `0` | `-1` auto, `0` off, `1` on | SBR for AAC-ELD. | | `-s`, `--sbr-ratio N` | `0` (library default) | `0`, `1` downsampled, `2` dual-rate | SBR sampling ratio. The library defaults to downsampled SBR for ELD+SBR and dual-rate for HE-AAC. | | `-f`, `--transport-format N` | `0` (M4A) | `0` M4A, `1` ADIF, `2` ADTS, `6` LATM MCP=1, `7` LATM MCP=0, `10` LOAS/LATM | Anything other than `0` writes a raw AAC stream (default extension `.aac`) instead of M4A. | | `-C`, `--adts-crc-check` | Off | Flag | Add CRC protection to ADTS headers. | | `-P`, `--header-period N` | `0` (library default) | Frames | StreamMuxConfig/PCE repetition period for LATM/LOAS. | | `-o FILE` | Input name with `.m4a`, or `.aac` if `-f` is not `0` | Filename; `-` (stdout) only when `-f` is not `0` | Output file. M4A output must be seekable. | | `-G`, `--gapless-mode N` | `0` | `0` iTunSMPB, `1` ISO (`edts` + `sgpd`), `2` both | How encoder delay and padding are signalled in M4A. | | `--include-sbr-delay` | Off | Flag | Count the SBR decoder delay in the signalled encoder delay. This is FDK's own convention but is not iTunes-compatible. | | `--moov-before-mdat` | Off | Flag | Put the `moov` index before the audio data, for progressive playback. | | `--no-timestamp` | Off | Flag | Write zero creation/modification times, for reproducible output. | ### Input and reporting | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `-h`, `--help` | — | Flag | Print the version and help, then exit. | | `-I`, `--ignorelength` | Off | Flag | Ignore the WAV data-chunk length, for WAV piped from tools that write a placeholder length. | | `-S`, `--silent` | Off | Flag | No progress output. | | `-R`, `--raw` | Off | Flag | Read headerless PCM described by the `--raw-*` options instead of WAV or CAF. | | `--raw-channels N` | `2` | Channel count | Raw channel count. | | `--raw-rate N` | `44100` | Hz | Raw sample rate. | | `--raw-format SPEC` | `S16L` | `S` or `U` with 8–32 bits, or `F` with 32/64; then `L` or `B` | Raw sample format, case-insensitive (`S24L`, `F32L`). Endianness defaults to little. | ### Metadata M4A tags. Tags from the input file are copied; these options set or override them. | Parameter | Default | Values / syntax | Effect | | --- | --- | --- | --- | | `--title TEXT` | — | Text | Title. | | `--artist TEXT` | — | Text | Artist. | | `--album TEXT` | — | Text | Album. | | `--genre TEXT` | — | Text | Genre. | | `--date TEXT` | — | Text | Date. | | `--composer TEXT` | — | Text | Composer. | | `--grouping TEXT` | — | Text | Grouping. | | `--comment TEXT` | — | Text | Comment. | | `--album-artist TEXT` | — | Text | Album artist. | | `--track N[/TOTAL]` | — | `N` or `N/TOTAL` | Track number. | | `--disk N[/TOTAL]` | — | `N` or `N/TOTAL` | Disc number. | | `--tempo N` | — | Integer | Tempo (BPM). | | `--tag FCC:VALUE` | — | `FCC:VALUE` | Set an iTunes atom by four-character code; a three-character code gets the `©` prefix (`day` → `©day`). | | `--tag-from-file FCC:FILE` | — | `FCC:FILE` | As `--tag`, with the value read from a file. | | `--long-tag NAME:VALUE` | — | `NAME:VALUE` | Custom iTunes (`----`) tag. | | `--tag-from-json FILE[?PATH]` | — | `FILE` or `FILE?dotted.path` | Read tags from a JSON object, e.g. `ffprobe -print_format json -show_format` output with `?format.tags`. | --- # ALAC Canonical URL: https://encode.wiki/codecs/audio/alac/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 7ca856682988da8c455c2b2f2c6384eafe5aa1a4943347cb9dfb9d62f90ae600 ALAC (Apple Lossless Audio Codec) is Apple's lossless format. It compresses about as well as [FLAC](/codecs/audio/flac/) and decodes back to identical samples, but it lives in MP4/`.m4a` files that iPhones, iPods, Macs, Apple TV and iTunes/Music play natively. Use ALAC when the destination is an Apple library; use FLAC for everything else. Apple's reference implementation is open source (Apache 2.0). ALAC stores integer PCM at 16, 20, 24 or 32 bits with 1–8 channels. It cannot store floating-point audio. ## Encoding ```sh ffmpeg -i input.flac -c:a alac output.m4a ``` FFmpeg's `alac` encoder is the usual route off a Mac. It writes **16-bit or 24-bit** ALAC only: a 32-bit integer source is stored as 24-bit, so the lowest eight bits are lost. Apple's reference encoder handles all four bit depths. `-compression_level` only goes 0–2 (default 2) and the result changes size, not fidelity. The extra `-min_prediction_order` and `-max_prediction_order` options (defaults 4 and 6) are rarely worth touching. ## Converting to and from FLAC ALAC and FLAC are both lossless, so converting between them loses nothing as long as the bit depth is preserved: ```sh ffmpeg -i input.m4a -c:a flac output.flac ffmpeg -i input.flac -c:a alac output.m4a ``` ## Compatibility - Apple hardware and software play ALAC natively, as does Safari. Chrome, Edge and Firefox do not list ALAC as a supported browser audio format. - Outside Apple's ecosystem, support is software-only (FFmpeg-based players such as mpv and VLC); hardware players and car stereos are far less likely to handle it than FLAC. - ALAC also appears in `.caf` files, mainly as an Apple tool format. For anything web-facing, publish FLAC (or a lossy codec) instead. --- # Dolby audio codecs and Atmos Canonical URL: https://encode.wiki/codecs/audio/dolby/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 4440ff69888514cbedbed74caccb8ecc1cdc15421a8d9646a55b9f79e4325a40 Dolby has several unrelated-looking things under one name: AC-3 and E-AC-3 are lossy surround codecs, TrueHD is a lossless one, AC-4 is a newer lossy one, and Atmos is an immersive-audio system that rides on top of E-AC-3, TrueHD and AC-4. If you work with Blu-rays, streaming rips or home theatre files you will meet all of them. The practical rule: **copy Dolby tracks rather than re-encoding them**, because FFmpeg can only make plain channel-based AC-3, E-AC-3 and (experimentally) TrueHD, with no Atmos. ## The codecs | Codec | Type | What it is | | --- | --- | --- | | **AC-3** (Dolby Digital) | Lossy | The original 5.1 codec: DVD, broadcast, Blu-ray core tracks. Up to 640 kbit/s. Every surround device plays it. | | **E-AC-3** (Dolby Digital Plus) | Lossy | AC-3's successor: more efficient, 32 kbit/s to 6 Mbit/s, up to 7.1 discrete channels. The main surround codec of streaming services; also how Atmos reaches streaming. Not bitstream-compatible with AC-3, but E-AC-3 decoders also decode AC-3. | | **TrueHD** | Lossless | MLP-derived lossless codec used on Blu-ray: 44.1–192 kHz, up to 24-bit, up to 16 channels in the format. Blu-ray limits it to eight channels at 96 kHz or six at 192 kHz. Carries Atmos on disc. | | **AC-4** | Lossy | Newer broadcast and streaming codec with multiple presentations (languages, dialogue enhancement) and Atmos support. Not compatible with AC-3 or E-AC-3. | On Blu-ray, a TrueHD track is interleaved with an AC-3 version in the same stream for players that cannot decode TrueHD. FFmpeg and eac3to expose the two as separate tracks, so you can keep just the lossless one. ## Atmos is not a codec Atmos is a production and rendering system. A mix is a channel bed (for example 7.1.2) plus positioned audio objects and metadata, and the player's renderer maps that to whatever speakers or headphones are present. That payload is carried by a normal Dolby codec: - **TrueHD Atmos** on Blu-ray: the usual lossless 7.1/5.1/stereo presentations, rendered from the full mix, plus an extra substream with the object data. - **E-AC-3 with JOC** (Joint Object Coding) on streaming: a lossy 5.1 or 7.1 mix rendered from the full mix, plus side data from which an Atmos decoder reconstructs the objects. Decoders without Atmos support play the channel mix. - **AC-4** for broadcast and some streaming. So an E-AC-3 or TrueHD file is not necessarily Atmos; check the profile. `ffprobe` reports Atmos streams as "Dolby Digital Plus + Dolby Atmos" or "Dolby TrueHD + Dolby Atmos" in the `profile` field. ## What FFmpeg can and cannot do | Task | FFmpeg | | --- | --- | | Copy any Dolby track into another container | Yes (`-c copy`). Atmos survives. | | Encode plain AC-3 or E-AC-3 from PCM | Yes: `ac3` and `eac3`, up to 5.1. A 7.1 input is silently downmixed to 5.1. | | Encode TrueHD from PCM | Experimental: `truehd`, up to 5.1, needs `-strict -2`. Bit-exact on decode. | | Encode AC-4 | No. | | Create Atmos | No. Needs Dolby's Atmos tools and licensed encoders. | | Decode Atmos | Decodes the backward-compatible 7.1 or 5.1 mix and ignores the object data, so height and object positioning are lost. | Re-encoding an Atmos track with FFmpeg to AC-3, E-AC-3, AAC or Opus permanently discards the object data. If you need a compatibility copy, make it additionally and keep the original track. ## Commands Copy a Dolby track into a new file without touching the audio: ```sh ffmpeg -i input.mkv -map 0:a:0 -c:a copy output.mka ``` Encode a 5.1 PCM master to AC-3 or E-AC-3: ```sh ffmpeg -i input.wav -c:a ac3 -b:a 640k output.ac3 ffmpeg -i input.wav -c:a eac3 -b:a 640k output.eac3 ``` Use 448 kbit/s for 5.1 AC-3 if the target doesn't need the maximum. Stereo is typically 192 kbit/s. The encoder has a lot of metadata options (`-dialnorm`, `-dmix_mode`, `-center_mixlev` and others) that matter for broadcast delivery and rarely otherwise; the defaults are fine for a compatibility track. Encode lossless TrueHD (5.1 or fewer channels): ```sh ffmpeg -i input.wav -c:a truehd -strict -2 output.thd ``` This is experimental and rarely worth it; if you just want lossless surround, use [FLAC](/codecs/audio/flac/). AC-3, E-AC-3 and TrueHD go into MP4 (E-AC-3 and AC-3) or Matroska (all). MP4 labels them `ac-3` and `ec-3`. Most TVs and receivers want a bitstream passthrough over HDMI to get Atmos, which means copying the track, not decoding it. ## When to choose what - **Remuxing a disc or streaming rip:** keep the original track. - **A surround compatibility copy for a TV:** E-AC-3 or AC-3 at 448–640 kbit/s. For most people [AAC](/codecs/audio/aac/) or [Opus](/codecs/audio/opus/) are better codecs, but only the Dolby ones pass through to an AV receiver. - **Lossless surround you encode yourself:** [FLAC](/codecs/audio/flac/). - **Authoring Atmos:** professional Dolby tools; see [spatial and immersive audio](/codecs/audio/spatial-audio/) for the open alternatives. --- # FLAC Canonical URL: https://encode.wiki/codecs/audio/flac/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 0968a68dc25dce115ebc6643375888691fbb25d736e54fb627581926c934113e FLAC (Free Lossless Audio Codec) compresses PCM audio to roughly half its size and decodes back to identical samples. It is open, fast to decode, plays almost everywhere, has good tagging, and is the default choice for music archives and lossless downloads. Use it unless you are locked into Apple's ecosystem ([ALAC](/codecs/audio/alac/)) or need something FLAC lacks, such as [WavPack](/codecs/audio/wavpack/)'s float support or hybrid mode. FLAC holds 4–32-bit integer PCM with 1–8 channels. It cannot store floating-point audio or DSD. Encoding a lossy source (MP3, AAC, Opus) to FLAC only preserves the damage at several times the size, so don't. ## Encoding With the reference encoder: ```sh flac -8 -V input.wav -o output.flac ``` Or with FFmpeg: ```sh ffmpeg -i input.wav output.flac ``` `-V` verifies the encode by decoding it as it goes. Use `flac -t file.flac` any time to test a file; it checks the MD5 of the audio stored in the header. ### Compression levels The levels only trade encoding time against file size. Every level decodes to the same samples, and decoding speed barely changes. | Tool | Levels | Default | Notes | | --- | --- | --- | --- | | `flac` | `-0` … `-8` | `-5` | `-8` is `--best`. Add `-e` for an exhaustive model search, which is very slow for a tiny gain. | | FFmpeg | `-compression_level 0` … `12` | 5 | 0–8 roughly mirror `flac`'s levels. 11 and 12 allow LPC orders up to 32, which takes the file outside the streamable subset at 48 kHz and below. | The gap between `-5` and `-8` is typically a percent or two, so the default is fine for most work. FLAC 1.5.0 can use several threads (`-j`) when encoding. ## Tags, cover art and metadata FLAC stores tags in a Vorbis comment block, cover art in a PICTURE block and seek points in a SEEKTABLE. `metaflac` edits these without touching the audio: ```sh metaflac --list output.flac metaflac --set-tag="ARTIST=Name" --import-picture-from=cover.jpg output.flac ``` ## Containers and compatibility Plain `.flac` is the normal form. FLAC can also live in Ogg (`flac --ogg`, usually `.oga`), Matroska/`.mka`, and MP4. Native FLAC plays in all current browsers and most hardware; Ogg FLAC and FLAC in MP4 are less widely supported. The format has a "streamable subset" that restricts block sizes, LPC order and sample-rate signalling so hardware decoders can cope. `flac` stays inside it unless you pass `--lax`, and FFmpeg does up to `-compression_level 10`; stay there if the files are headed for hardware players. Check 5.1 and 7.1 files on the device you care about, since some players ignore the channel layout. ## Decoding and converting ```sh flac -d input.flac -o output.wav ffmpeg -i input.flac output.wav ``` To get the original WAV back byte for byte, including non-audio chunks, pass `--keep-foreign-metadata` to both the encode and the decode. ## See also - [ALAC](/codecs/audio/alac/) and [WavPack](/codecs/audio/wavpack/) for the other lossless options - [Opus](/codecs/audio/opus/) and [AAC](/codecs/audio/aac/) for lossy delivery from a FLAC master --- # Intro Canonical URL: https://encode.wiki/codecs/audio/intro/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 94260ef96c9ef739265d8720c13e129cc2a98fa637a9eb2cc389adf81b5c0b78 Digital audio is a waveform stored as a series of numbers. Everything else in this section — codecs, containers, spatial formats — is about storing or compressing those numbers. ## The basics - **Sample rate** is how many measurements per second are taken. CDs use 44.1 kHz; video and most production work use 48 kHz. A sampled signal can represent frequencies up to half the sample rate (the Nyquist frequency), so 44.1 kHz already covers everything people can hear. Higher rates mainly matter for production headroom, not playback. - **Bit depth** is the precision of each sample. 16 bits gives roughly 96 dB of dynamic range and 24 bits far more than any real recording needs. Dropping to a lower depth should be done with dither, which replaces correlated quantization distortion with low-level noise. - **Channels** are the separate signals in a stream: mono, stereo, 5.1 and so on. A channel count says nothing about speaker positions — two channels can be stereo or two unrelated mono tracks — so layout and channel order matter for surround. - **Bitrate** is the size of the stream per second. Uncompressed PCM is sample rate × bit depth × channels: stereo 48 kHz/24-bit is 2,304 kbit/s. Compressed bitrate depends on the codec and settings. Upsampling or converting to a higher bit depth adds no detail. A 48 kHz file made from a 22 kHz source still contains nothing above 11 kHz. ## Lossless versus lossy **Lossless** codecs ([FLAC](/codecs/audio/flac/), [ALAC](/codecs/audio/alac/), [WavPack](/codecs/audio/wavpack/), Dolby TrueHD) shrink PCM typically to around half its size and decode back to identical samples. Use them for masters, archives and anything you may edit or re-encode later. See [lossless compression](/start-here/lossless/) for how they work. **Lossy** codecs ([Opus](/codecs/audio/opus/), [AAC](/codecs/audio/aac/), [MP3](/codecs/audio/mp3/), [Vorbis](/codecs/audio/vorbis/), AC-3) discard information to reach much smaller files, often a tenth of the PCM size or less. They are built on perceptual coding: a transform (usually an MDCT) splits the signal into frequency bands, and a psychoacoustic model decides which components are masked by louder neighbours and can be quantized coarsely or dropped. At a sufficient bitrate the result is transparent, meaning indistinguishable from the source in a blind test. Where "sufficient" lies depends on the codec, encoder and material. See [lossy compression](/start-here/lossy/). Never re-encode lossy files if you can avoid it. Each generation adds new artifacts on top of the old ones, and transcoding a lossy file to a lossless format only preserves its flaws at a larger size. Keep a lossless master and make delivery copies from that. ## Inspecting a file ```sh ffprobe -v error -select_streams a -show_entries stream=codec_name,sample_rate,channels,channel_layout,bit_rate input.mka ``` Check this before and after any conversion, and listen for clipping, downmix cancellation and timing problems. The [audio overview](/codecs/audio/) compares the codecs and [image and audio support](/reference/image-audio-support/) covers browser playback. --- # MP3 Canonical URL: https://encode.wiki/codecs/audio/mp3/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: b2c8db27fb9ca3bc902d99f375414a2272746ea8dc288d463ecefbd5080eaeb8 MP3 (MPEG-1/2 Audio Layer III) is a lossy codec from the early 1990s. It is far less efficient than [AAC](/codecs/audio/aac/) or [Opus](/codecs/audio/opus/): at the same bitrate it sounds worse, and it cannot do surround. It stays relevant for one reason, which is that everything can play it — old hardware, car stereos, DJ gear, cheap players. Use it only when you need that. Otherwise use Opus or AAC. The MP3 patent licensing program ended in 2017, so patents are no longer a practical concern. MP3 is mono or stereo only. Sample rates run from 8 to 48 kHz, split across MPEG-1 (32, 44.1, 48 kHz), MPEG-2 (16, 22.05, 24 kHz) and an unofficial MPEG-2.5 extension (8, 11.025, 12 kHz) that some players reject. Bitrates run from 8 to 320 kbit/s depending on the generation. ## Encoding with LAME LAME is the only MP3 encoder worth using. Always encode from a lossless source, with variable bitrate (VBR) quality mode: ```sh lame -V 2 input.wav output.mp3 ``` `-V` goes from 0 (best) to 9 (smallest). Without `-V`, `lame` encodes 128 kbit/s CBR, and `-V` without a number means 4; both are lower quality than most people want. Approximate averages for music, which vary with the material: | Setting | Average bitrate | Use | | --- | --- | --- | | `-V 0` | ~245 kbit/s | Highest VBR quality; the sensible choice if you want margin. | | `-V 2` | ~190 kbit/s | The usual recommendation: transparent for most listeners on most music. | CBR 320 (`-b 320`) is the only fixed-rate setting worth using, and only when a device demands CBR. It is larger than `-V 0` for no audible benefit. LAME reads WAV and AIFF directly. For FLAC and other formats, pipe the decode through: ```sh ffmpeg -i input.flac -f wav - | lame -V 2 - output.mp3 ``` ## Encoding with FFmpeg FFmpeg uses LAME through `libmp3lame` and needs no pipe. `-q:a` is the same scale as LAME's `-V`: ```sh ffmpeg -i input.flac -c:a libmp3lame -q:a 2 output.mp3 ``` For a fixed bitrate use `-b:a 320k`, and add `-abr 1` to ask for average-bitrate mode instead of CBR. FFmpeg's separate `-compression_level` (0–9) affects only encoder effort and speed, not bitrate. Don't copy options between `lame` and FFmpeg; the spellings differ. ## Pitfalls - **Don't transcode.** Encoding a lossy file to MP3 stacks artifacts on artifacts. Keep a lossless master. - **Gapless playback.** The encoder adds delay and padding at the start and end. Players need the LAME/Xing tag, which LAME and FFmpeg write, to trim it. Never join MP3s by byte-concatenating them for gapless albums. - **VBR seeking.** Some old players seek or show duration incorrectly with VBR files because they ignore the Xing header. CBR avoids that. - **Low-rate files.** Below ~128 kbit/s MP3 degrades quickly; switch to Opus or AAC. - **Tags.** MP3 uses ID3v2. Cover art is stored in the tag, so it appears as a video stream when FFmpeg reads it. --- # Opus Canonical URL: https://encode.wiki/codecs/audio/opus/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: f9105752d54c46a4476df916bc0aed6e878cd1103c2bc7865b2cda8ca1354ef3 Opus is an open, royalty-free lossy audio codec standardised as [RFC 6716](https://datatracker.ietf.org/doc/rfc6716/). It combines Skype's SILK (speech) and Xiph's CELT (general audio) and switches between them automatically, so one codec covers voice calls, podcasts and music. It is the default recommendation for lossy audio unless you need MP4/Apple-device compatibility, where [AAC](/codecs/audio/aac/) is still the safe choice. For web video it is the standard companion to [VP9](/codecs/video/vp9/) and [AV1](/codecs/video/av1/) in WebM. At the same bitrate Opus generally sounds better than AAC-LC, Vorbis and MP3, and it stays usable far lower. Stereo music is near-transparent at around 128 kbit/s VBR. It is lossy: encode from the lossless original, never from another lossy file. ## Recommended bitrates Bitrates are for the whole stream, not per channel. These are the [Xiph recommended settings](https://wiki.xiph.org/Opus_Recommended_Settings): | Content | Channels | kbit/s | | --- | --- | --- | | Voice over IP | Mono | 10–24 | | Podcast / audiobook | Mono | 24 | | Podcast / audiobook | Stereo | 32 | | Music streaming | Stereo | 64–96 | | Music archive / storage | Stereo | 96–128 | | Music | 5.1 | 128–256 | | Music | 7.1 | 256–450 | Below about 19 kbit/s the encoder starts folding stereo to mono. Opus covers 6–510 kbit/s. For archiving, keep a lossless copy ([FLAC](/codecs/audio/flac/)) instead. ## Encoding with opusenc `opusenc` (from [opus-tools](https://gitlab.xiph.org/xiph/opus-tools)) is the reference encoder. Its defaults are already the right ones for stored audio: VBR, complexity 10, 20 ms frames, automatic speech/music detection. It reads WAV, AIFF and FLAC and resamples 44.1 kHz material itself. ```sh opusenc --bitrate 128 input.flac output.opus opusenc --speech --downmix-mono --bitrate 24 interview.wav interview.opus ``` `--bitrate` is in kbit/s, unlike FFmpeg's bit/s. `--speech` and `--music` override the automatic speech/music detection and only matter at low bitrates. `--cvbr` and `--hard-cbr` exist for transports with a strict rate limit; leave VBR on for files. ## Encoding with FFmpeg ```sh ffmpeg -i input.flac -c:a libopus -b:a 128k output.opus ``` Everything else defaults sensibly: `-vbr on`, `-application audio`, 20 ms frames, complexity 10. The options worth knowing: | Option | Use | | --- | --- | | `-application voip` | Speech intelligibility tuning for voice recordings. `audio` (default) is right for music; `lowdelay` is only for real-time work. | | `-vbr constrained` | Limits rate swings for streaming. `-vbr off` is hard CBR. | | `-frame_duration` | Leave at 20. Longer frames only help at very low bitrates; shorter ones cost quality and are for latency. | | `-mapping_family 1` | Surround layouts, see below. | | `-ac 1` | Mono downmix for speech. | `-q:a` is not supported by `libopus`; control quality with `-b:a`. `-packet_loss` and `-fec` are for real-time links and do nothing useful in a stored file. ### Sample rate Opus works at 48 kHz internally, and players and FFmpeg decode to 48 kHz (8, 12, 16 and 24 kHz are also accepted as input rates). A 44.1 kHz source is resampled by `opusenc` or FFmpeg automatically; do not force `-ar 44100`. The original rate is stored only as informational metadata. Audible bandwidth tops out around 20 kHz regardless of the input rate. ### Surround Opus carries mono and stereo directly (mapping family 0). For 3–8 channels it uses mapping family 1, which defines the channel order and enables surround-specific bit allocation. FFmpeg writes a family 1 header by default but only uses libopus's surround-aware encoder when you ask for it: ```sh ffmpeg -i surround.mkv -c:a libopus -b:a 256k -mapping_family 1 output.mka ``` `libopus` rejects the `5.1(side)` layout that many Blu-ray and AC-3 sources use ("Invalid channel layout 5.1(side) for specified mapping family"). Convert it to plain 5.1 first: ```sh ffmpeg -i input.mkv -af aformat=channel_layouts=5.1 -c:a libopus -b:a 256k -mapping_family 1 output.mka ``` `aformat` relabels the side channels as back channels; nothing is downmixed. `-af` applies to every audio output stream, so when a command encodes several audio tracks, target the surround one with `-filter:a:N` instead (see [audio and subtitles](/guides/audio-and-subtitles/)). To handle unknown inputs in one command, offer several layouts and let FFmpeg pick the closest: `-af aformat=channel_layouts=7.1|5.1|stereo -mapping_family 1`. More than 8 channels needs mapping family 255 (unmapped channels), which most players will not render as surround. `opusenc` handles 5.1 WAV files directly. ### FFmpeg's native encoder FFmpeg also has its own `opus` encoder (CELT-only, mono/stereo, 48 kHz). It is experimental, needs `-strict -2`, and is not better than libopus; the only reason to reach for it is a build without libopus. ## Containers and playback **Opus container mappings** | Relationship | Project or format | Evidence and scope | Status | | --- | --- | --- | --- | | Carried By | [Ogg](/containers/ogg/) | Ogg Opus uses OpusHead and OpusTags headers with 48 kHz granule-position semantics. Scope: Container Mapping. Sources: [RFC 7845: Ogg Encapsulation for the Opus Audio Codec](https://datatracker.ietf.org/doc/rfc7845/). | Normative | | Carried By | [Matroska](/containers/matroska/) | Uses the A_OPUS Codec ID and stores the Opus identification header in CodecPrivate. Scope: Container Mapping. Sources: [Matroska codec mappings](https://www.matroska.org/technical/codec_specs.html). | Normative | | Carried By | [WebM](/containers/webm/) | Opus is one of the audio codecs listed by the WebM Project. Scope: Container Mapping. Sources: [WebM container guidelines](https://www.webmproject.org/docs/container/). | Documented | | Carried By | [ISO Base Media File Format](/containers/isobmff/) | The public Opus binding defines the Opus sample entry and dOps box, but remains an old incomplete draft. Scope: Container Mapping. Sources: [Encapsulation of Opus in ISO Base Media File Format](https://www.opus-codec.org/docs/opus_in_isobmff.html), [MP4 Registration Authority codec registry](https://mp4ra.org/registered-types/codecs). | Registered | [Open the complete typed relationship catalog](/api/v1/catalog.json). - **Ogg Opus** (`.opus`, [RFC 7845](https://datatracker.ietf.org/doc/rfc7845/)) is the standard file format for audio. Safari supports it from 18.4 (macOS 15.4, iOS 18.4). - **WebM / Matroska** is the usual choice with video; `-c:a copy` between them is lossless. - **MP4** can carry Opus, but player support is patchier than for the other two. Opus is also one of the codecs IAMF/Eclipsa Audio can use; see [spatial audio](/codecs/audio/spatial-audio/#iamf-and-eclipsa-audio). ## Full option reference Every option of `opusenc` 0.2 (with libopus 1.6.1 and libopusenc 0.3) and of FFmpeg 9.0.2's two Opus encoders. Defaults are what you get when the option is omitted. ### Complete `opusenc` 0.2 parameter reference #### Rate, signal, and latency | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `--bitrate N` | Auto: 64 kbit/s mono, 96 stereo | kbit/s for the whole stream, decimals allowed; 6–256 per channel is the useful range | Target bitrate. The automatic value is 64 kbit/s per stream plus 32 per coupled pair (5.1 gets 320), scaled down for inputs below 44.1 kHz (16 kHz mono gets 33). Capped at 256 kbit/s per channel. | | `--vbr` | On | Flag | Unconstrained VBR: the bitrate follows the content around the target. The right mode for files. | | `--cvbr` | Off | Flag | Constrained VBR: packet sizes vary but stay close to the target, like CBR with a small reservoir. For streaming over constant-rate links. | | `--hard-cbr` | Off | Flag | Every packet the same size, at a quality cost. Only for transports that need it. The last of `--vbr`, `--cvbr` and `--hard-cbr` wins. | | `--music` | Auto-detected | Flag | Treat the input as music, overriding speech/music detection. Mainly matters at low bitrates. | | `--speech` | Auto-detected | Flag | Treat the input as speech, favouring the SILK modes at low bitrates. The last of `--music` and `--speech` wins. | | `--comp N`, `--complexity N` | `10` | `0`–`10` | Encoder effort; 10 is slowest and best. Lower it only for real-time encoding on weak CPUs. | | `--framesize N` | `20` | `2.5`, `5`, `10`, `20`, `40`, `60` ms | Maximum frame duration. 20 ms suits almost everything; 40 or 60 ms save a little overhead for low-bitrate speech. Frames under 10 ms can only use CELT and cost efficiency. | | `--expect-loss N` | `0` | `0`–`100` % | Expected packet loss. Makes frames more robust to loss at some quality cost. It does not turn on in-band FEC; add `--set-ctl-int 4012=1` for that. | | `--downmix-mono` | Off | Flag | Downmix to mono before encoding. | | `--downmix-stereo` | Off | Flag | Downmix inputs with more than two channels to stereo. | | `--no-downmix` | Off | Flag | Disable the automatic downmix: with more than two channels and `--bitrate` below 16 kbit/s per channel, opusenc otherwise downmixes to stereo (3–8 channels) or mono (more than 8). Not listed by `--help`. | | `--no-phase-inv` | Off | Flag | Disable intensity-stereo phase inversion. Slightly lowers stereo quality, but avoids artefacts if the decoded audio is later downmixed to mono. | | `--max-delay N` | `1000` | `0`–`1000` ms | Maximum Ogg muxing delay: how long packets may wait before a page is written. Lower it for live streaming. | #### Input interpretation | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `--raw` | Off | Flag | Read headerless PCM instead of detecting WAV, AIFF or FLAC. Any `--raw-*` option implies it. | | `--raw-bits N` | `16` | `8`, `16`, `24` | Raw sample size; 8-bit is unsigned, 16- and 24-bit are signed. | | `--raw-rate N` | `48000` | Hz, `100`–`768000` | Raw sample rate. Opus always codes at 48 kHz internally; opusenc resamples any other input rate. | | `--raw-chan N` | `2` | `1`–`255` | Raw channel count. More than eight channels are coded as discrete channels (mapping family 255). | | `--raw-endianness N` | `0` | `0` little, `1` big | Raw byte order. | | `--ignorelength` | Off | Flag | Ignore the WAV data-chunk length, for WAV piped from tools that write a placeholder length. | #### Tags, pictures, and padding Tags and pictures from the input file are copied unless you discard them; command-line tags are added to them. | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `--title TEXT` | Copied from input | Text | Title. | | `--artist TEXT` | Copied from input | Text; repeatable | Artist. | | `--album TEXT` | Copied from input | Text | Album. | | `--tracknumber N` | Copied from input | Text | Track number. | | `--genre TEXT` | Copied from input | Text; repeatable | Genre. | | `--date TEXT` | Copied from input | `YYYY`, `YYYY-MM` or `YYYY-MM-DD` | Date. | | `--comment TAG=VALUE` | — | `NAME=value`; repeatable | Add any Vorbis comment. | | `--picture FILE` | Input pictures copied | JPEG, PNG or GIF file, or `[TYPE]\|[MIME]\|[DESC]\|[WxHxD]\|FILE`; repeatable | Attach cover art. The type defaults to `3` (front cover); `--help-picture` lists the types. | | `--padding N` | `512` | Bytes | Spare room in the comment header so tags can be edited later without rewriting the file. | | `--discard-comments` | Off | Flag | Don't copy tags or pictures from the input (implies `--discard-pictures`). Tags given on the command line are still written. | | `--discard-pictures` | Off | Flag | Don't copy pictures from the input. | #### Diagnostics and advanced controls | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `-h`, `--help` | — | Flag | Print help and exit. | | `-V`, `--version` | — | Flag | Print the opus-tools and libopus versions and exit. | | `--version-short` | — | Flag | Same output as `--version` in 0.2. Not listed by `--help`. | | `--help-picture` | — | Flag | Print the `--picture` syntax and picture types `0`–`20`. | | `--quiet` | Off | Flag | Suppress progress and the final statistics. | | `--serial N` | Random | Integer | Ogg stream serial number. | | `--save-range FILE` | Off | Filename | Write per-frame range-coder check values, for decoder conformance testing. | | `--set-ctl-int [S:]X=Y` | — | `X=Y`, or `S:X=Y` to target stream `S` of a multistream file; repeatable | Pass an integer encoder control, applied after all other settings. Only the requests in the next table are accepted. | #### Allowed advanced integer requests `--set-ctl-int` accepts only these requests. Numbers are from the [libopus 1.6.1 headers](https://github.com/xiph/opus/blob/v1.6.1/include/opus_defines.h) and [libopusenc 0.3](https://github.com/xiph/libopusenc/blob/v0.3/include/opusenc.h); defaults are what opusenc sets, which differ from bare libopus in places. Use the named option where one exists. | Request X | opusenc default | Values Y | Control | | --- | --- | --- | --- | | `4000` | `2049` (audio) | `2048` VoIP, `2049` audio, `2051` low delay | Application. | | `4002` | From `--bitrate` | bit/s; `-1000` auto, `-1` maximum | Bitrate. Without `S:` it is the total for all streams; with `S:` it sets one stream. | | `4004` | `1105` (fullband) | `1101`–`1105` = 4, 6, 8, 12, 20 kHz | Maximum bandwidth the encoder may choose. | | `4006` | `1` | `0`/`1` | VBR. | | `4008` | `-1000` (auto) | `-1000` or `1101`–`1105` | Force a bandwidth. | | `4010` | `10` | `0`–`10` | Complexity. | | `4012` | `0` | `0` off, `1` on, `2` on without forcing SILK for music | In-band FEC; also set `--expect-loss`. | | `4014` | `0` | `0`–`100` % | Expected packet loss. | | `4016` | `0` | `0`/`1` | DTX. | | `4020` | `0` (unconstrained) | `0`/`1` | Constrained VBR; ignored with hard CBR. Bare libopus defaults to `1`. | | `4022` | `-1000` (auto) | `-1000`, `1` mono, `2` stereo | Force the coded channel count of a stream. | | `4024` | `-1000` (auto) | `-1000`, `3001` voice, `3002` music | Signal type. | | `4036` | Input bit depth, clamped to `8`–`24` | `8`–`24` | Significant bits in the input. | | `4042` | `0` | `0`/`1` | Disable inter-frame prediction. | | `4046` | `0` | `0`/`1` | Disable intensity-stereo phase inversion. | | `14000` | `96000` (2 s) | 48 kHz samples, at most `96000` | libopusenc decision lookahead. | | `14002` | `48000` (1 s) | 48 kHz samples | Ogg muxing delay; `--max-delay` sets the same thing in ms. | | `14004` | `512` | Bytes | Comment padding. | | `14006` | Random | Integer | Ogg stream serial. | | `14010` | `0` | 1/256 dB, signed 16-bit | Output gain stored in the Opus header and applied by the player. | ### Complete FFmpeg `libopus` private options The private options of the [FFmpeg 9.0.2 `libopus` wrapper](https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/libopusenc.c). | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `-application` | `audio` | `audio`, `voip`, `lowdelay` | `audio` for music and general content; `voip` favours speech intelligibility; `lowdelay` uses CELT only for minimum latency. Frames under 10 ms force `lowdelay`. | | `-frame_duration` | `20` | `2.5`, `5`, `10`, `20`, `40`, `60`, `80`, `100`, `120` ms | Frame length. Other values are rejected, although help shows a continuous 2.5–120 range. 80–120 ms need libopus 1.2 or later. | | `-packet_loss` | `0` | `0`–`100` % | Expected packet loss. Makes frames more loss-robust and sets how much FEC to send when `-fec 1`. | | `-fec` | `0` | `0`/`1` | In-band forward error correction (SILK and hybrid modes). Needs `-packet_loss` above 0. | | `-vbr` | `on` | `off`, `on`, `constrained` | Hard CBR, VBR or constrained VBR. `on` is the right choice for files. | | `-mapping_family` | `-1` | `-1`, `0`, `1`, `255` | `-1`: family 0 for mono/stereo; for 3–8 channels a family 1 header, but without libopus's surround analysis. `1`: the surround encoder with inter-channel masking, up to 8 channels; use it for 5.1 and 7.1. `0`: mono/stereo only. `255`: up to 254 discrete channels. | | `-dtx` | `0` | `0`/`1` | Discontinuous transmission: send almost nothing during silence. For VoIP. | | `-apply_phase_inv` | `1` | `0`/`1` | Intensity-stereo phase inversion. Set `0` if the output will be downmixed to mono. Only present when built against libopus 1.2 or later. | Generic FFmpeg options the wrapper also reads: | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `-b:a` | 64k per stream + 32k per coupled pair (64k mono, 96k stereo) | `500`–`256000 × channels` bit/s | Total bitrate. Unlike opusenc, the default does not drop for low input sample rates. | | `-compression_level` | `10` | `0`–`10` | Complexity. | | `-cutoff` | `0` (auto) | `4000`, `6000`, `8000`, `12000`, `20000` Hz | Maximum coded bandwidth. Other values are ignored with a warning. | | `-ar` | Input rate if supported | `8000`, `12000`, `16000`, `24000`, `48000` | Other input rates, such as 44.1 kHz, are resampled. | | `-ac`, `-ch_layout` | Input layout | Channel count or layout name | Output channels. | | `-q:a` | — | Not supported | Rejected; use `-b:a` with `-vbr`. | ### FFmpeg native `opus`: a separate interface FFmpeg's own [Opus encoder](https://github.com/FFmpeg/FFmpeg/blob/n9.0.2/libavcodec/opus/enc.c) is experimental (`-strict -2`), CELT-only, and takes 48 kHz mono or stereo. Its default bitrate is 48k mono or 96k stereo. The `libopus` options above don't apply; it has two of its own. | Parameter | Default | Values / units | Effect | | --- | --- | --- | --- | | `-opus_delay` | `360` | `2.5`–`360` ms | Maximum encoder delay. Values below 20 ms also shorten the frame size. | | `-apply_phase_inv` | `1` | `0`/`1` | Intensity-stereo phase inversion; set `0` if the output will be downmixed to mono. | --- # Spatial and immersive audio Canonical URL: https://encode.wiki/codecs/audio/spatial-audio/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 647bbadafb0d0aa50e8200ec73aa93b868fbbdb7c1331f9663afbbf470881116 "Spatial audio" covers several different layers, and most confusion comes from mixing them up: - A **codec** compresses audio samples: [Opus](/codecs/audio/opus/), AAC-LC, FLAC. - An **immersive format** describes channels, objects, ambisonics and rendering metadata on top of a codec: IAMF, Dolby Atmos, MPEG-H. - A **renderer** turns that description into output for a particular speaker layout or headphones. - **Binaural** is a headphone rendering method, not a codec or container. Converting the underlying codec usually throws away the object or scene metadata, even though a channel mix still plays. Keep the original immersive track and make any compatibility mix in addition. See [Dolby](/codecs/audio/dolby/) for what FFmpeg can and cannot do with Atmos. ## Comparison | System | What it is | Carried by | Openness | | --- | --- | --- | --- | | IAMF / Eclipsa Audio | Open immersive format (channels, objects, ambisonics, mix metadata); Eclipsa is the consumer brand | Opus, AAC-LC, FLAC or LPCM in ISOBMFF | Open AOMedia specification, with a reference decoder and the Open Audio Renderer | | MPEG-H 3D Audio | ISO standard for channels, objects and higher-order ambisonics, with interactivity and accessibility metadata | Its own codec | International standard; licensed | | Sony 360 Reality Audio | Sony's object-based music format | Built on MPEG-H 3D Audio | Proprietary ecosystem | | Dolby Atmos | Channel bed plus objects and metadata | E-AC-3 JOC, TrueHD, AC-4 | Proprietary, licensed | | DTS:X | DTS's object-based format | An extension of DTS-HD Master Audio on Blu-ray | Proprietary | | Auro-3D | Layered height-channel format | Height channels folded into a 5.1 or 7.1 PCM signal, on Blu-ray usually inside DTS-HD Master Audio | Proprietary | | Binaural | HRTF-filtered stereo derived from a spatial scene | Any stereo codec | A technique, not a format | ## IAMF and Eclipsa Audio IAMF (Immersive Audio Model and Formats) is the open option from the Alliance for Open Media; the current specification is version 2.0. It is codec-agnostic: Opus, AAC-LC, FLAC and LPCM are the allowed codecs, and Opus is just one of them. It supports channel layouts such as 5.1.2 and 7.1.4, objects and ambisonics. Streams carry the coded audio plus metadata for mixing, loudspeaker rendering and binaural rendering, packaged in ISOBMFF (MP4). AOMedia publishes a reference decoder (`libiamf`) and the Open Audio Renderer. Eclipsa Audio is the consumer brand and certification program built on IAMF, backed by Google and Samsung. Device support is still limited. **IAMF's sourced codec and ecosystem relationships** | Relationship | Project or format | Evidence and scope | Status | | --- | --- | --- | --- | | Permits Codec | [Opus](/codecs/audio/opus/) | IAMF defines an Opus codec configuration alongside AAC-LC, FLAC, and LPCM configurations. Scope: Codec Binding. Sources: [Immersive Audio Model and Formats v1.1](https://aomediacodec.github.io/iamf/v1.1.0.html). | Normative | | Renders To | [Binaural rendering](/codecs/audio/spatial-audio/) | IAMF mix presentations can be rendered to binaural headphone output. Scope: Renderer. Sources: [Immersive Audio Model and Formats v1.1](https://aomediacodec.github.io/iamf/v1.1.0.html), [Open Audio Renderer 1.0.0](https://aomedia.org/specifications/oar/1.0.0/). | Normative | | Based On by | [Eclipsa Audio](/codecs/audio/spatial-audio/) | Eclipsa Audio builds consumer tools, certification, and device interoperability around IAMF. Scope: Ecosystem. Sources: [Eclipsa Audio ecosystem and certification](https://eclipsamedia.org/), [Immersive Audio Model and Formats v1.1](https://aomediacodec.github.io/iamf/v1.1.0.html). | Documented | [Open the complete typed relationship catalog](/api/v1/catalog.json). ## MPEG-H and Sony 360 Reality Audio MPEG-H 3D Audio supports channels, objects and higher-order ambisonics with flexible layouts and headphone output. Sony describes 360 Reality Audio as an object-based music experience whose distribution format is based on MPEG-H 3D Audio. ## Dolby Atmos, DTS:X and Auro-3D Atmos is covered on the [Dolby page](/codecs/audio/dolby/). DTS:X and Auro-3D tracks on Blu-ray are backward compatible: a player without the decoder plays the ordinary DTS-HD MA or PCM surround mix. FFmpeg decodes only that mix. Copy these tracks if you want to keep the immersive version. ## Binaural A binaural renderer filters a spatial scene with head-related transfer functions to make a two-channel headphone mix. Quality depends on the HRTF and whether head tracking is used. The resulting stereo file plays anywhere, but it no longer contains the original scene. ## Playback No browser or OS exposes a single "spatial audio" capability. Playing the 5.1 mix of an E-AC-3 Atmos stream, or running a Web Audio `PannerNode`, does not mean an authored scene or its objects are being rendered. The [image and audio support guide](/reference/image-audio-support/) covers detection. --- # Speex Canonical URL: https://encode.wiki/codecs/audio/speex/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: b6bc199bad22994e1de430a91b40b7e4a8fe128bd80be4c1ef2408d3b3152bb2 Speex is a lossy speech codec from Xiph, designed for VoIP and other low-bitrate voice. Xiph's own site says it has been obsoleted by [Opus](/codecs/audio/opus/), which is better in every respect, and the last release (1.2.1) dates from 2022. Don't use Speex for new work. The only reasons to touch it are playing or converting old `.spx` files and talking to legacy VoIP equipment. Speex works at three sampling rates: narrowband (8 kHz), wideband (16 kHz) and ultra-wideband (32 kHz). It handles speech, not music, and its quality is poor outside that. SpeexDSP, the companion library with resampling, echo cancellation and noise suppression, is separate and still used. ## Encoding and decoding With the reference tools: ```sh speexenc --wideband --quality 8 input.wav output.spx speexdec output.spx output.wav ``` `--narrowband`, `--wideband` and `--ultra-wideband` say which rate the input is (8, 16 or 32 kHz); resample first, since speexenc warns about other rates. `--quality` goes 0–10. With FFmpeg (needs `libspeex`): ```sh ffmpeg -i speech.wav -ar 16000 -c:a libspeex -b:a 24k speech.spx ``` FFmpeg's wrapper also exposes `-vad` and `-dtx` (voice activity detection and discontinuous transmission), `-abr 1` (average bitrate), `-frames_per_packet` (1–8) and `-compression_level` (0–10, default 3). It accepts mono or stereo at 8, 16 or 32 kHz. ## Migrating to Opus Re-encoding Speex to Opus decodes and recompresses lossy audio, so keep the originals and expect some extra loss. Opus handles speech well at 24–32 kbit/s mono. `.spx` files use the Ogg container. Browsers do not play them natively. --- # Vorbis Canonical URL: https://encode.wiki/codecs/audio/vorbis/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: f1c6354ccbbe1b367b6bf021b6adcd9be00ce055bc3cf2c598c8bcdeba7abb6e Vorbis is a free lossy audio codec from Xiph.Org, finalised in 2002 (Vorbis I) as an open alternative to MP3. It was widely used in games (Minecraft's sounds and music are Ogg Vorbis) and in Ogg and WebM media. [Opus](/codecs/audio/opus/) is its successor and is more efficient, especially at low bitrates, so choose Opus for anything new. Use Vorbis when a game engine, device or existing library needs it. Vorbis is almost always found in Ogg (`.ogg`, `.oga`), WebM or Matroska. The `.ogg` extension alone does not tell you the codec, since Ogg also carries Opus, FLAC and Speex. ## Encoding Use libvorbis through FFmpeg: ```sh ffmpeg -i input.flac -c:a libvorbis -q:a 5 output.ogg ``` Or `oggenc` from vorbis-tools, which uses the same encoder: ```sh oggenc -q 5 input.wav -o output.ogg ``` `-q` is a VBR quality scale from -1 to 10 (FFmpeg's default is 3). The nominal stereo bitrates are about 112 kbit/s at 3, 160 at 5 and 224 at 7, but the actual rate varies with the content. Quality 5 is a good starting point for music; go higher only if you can hear a difference. Don't use FFmpeg's built-in `vorbis` encoder. It is flagged experimental and its quality is below libvorbis. Make sure your FFmpeg has `--enable-libvorbis`. ### Other options | Option | Effect | | --- | --- | | `-b:a 128k` | Managed (ABR-like) bitrate instead of quality VBR. | | `-cutoff` | Lowpass frequency in Hz. Off by default (0). | | `-iblock` | Impulse block bias, -15 to 0 (default 0). More negative keeps transients crisper at a higher bitrate. | ## Compatibility Vorbis in Ogg or WebM plays in Chrome, Edge and Firefox. Safari 18.4 added Ogg Vorbis and Ogg Opus on macOS 15.4, iOS/iPadOS 18.4 and visionOS 2.4; older versions do not play Ogg. Hardware players are less consistent than for AAC or MP3. Vorbis supports 1–255 channels. It defines channel order for up to eight, so multichannel files are portable only up to 7.1; check the order in your player for anything above that. ## Pitfalls - **Don't transcode Vorbis to Opus.** Both are lossy; encode from the lossless master. - **Keep all three headers** (identification, comment, setup) if you ever repack the raw packets. - **Chained Ogg streams** (several files joined end to end) confuse some players and seek poorly. --- # WavPack Canonical URL: https://encode.wiki/codecs/audio/wavpack/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: a76ad99aab04332737ab3e82170dba9a5208a0284201fa76d83ef5cbd891fe01 WavPack is an open lossless audio codec by David Bryant, dating from 1998. It compresses about as well as [FLAC](/codecs/audio/flac/), with slower high-compression modes, handles integer PCM, 32-bit float and DSD, supports a very large number of channels, and has a hybrid mode that stores a lossy file plus a separate correction file. Player and hardware support is much narrower than FLAC's, which is why most people use FLAC. Choose WavPack when you need floating-point or DSD stored losslessly, or want the hybrid mode. ## Encoding Defaults are lossless, so for archiving just run it: ```sh wavpack input.wav -o output.wv wvunpack output.wv -o restored.wav ``` For smaller files at the cost of speed: ```sh wavpack -hh -x4 -m input.wav -o output.wv ``` | Option | Effect | | --- | --- | | `-f` | Fast: quicker encode and decode, larger files. | | `-h` / `-hh` | High and very high: better compression, slower to encode and decode. | | `-x0` … `-x6` | Extra encoder-side search (default 1). Only costs encoding time. 4–6 build custom filters and are very slow. | | `-m` | Store an MD5 of the audio so `wvunpack -v` can check integrity. | | `-v` | Verify the file right after encoding (not possible with pipes). | | `--threads=n` | Up to 12 threads; on by default on multicore machines, but not used in hybrid mode except for multichannel files. | `-h` and `-x` change effort and size, not fidelity. DSD input is always lossless and ignores `-x` and the hybrid options. Check the [WavPack manual](https://www.wavpack.com/wavpack_doc.html) for the full list. ## Hybrid mode Hybrid mode writes a lossy `.wv` file. With `-c` it also writes a `.wvc` correction file; playing both gives the exact original, and the `.wv` alone plays as a lossy file. ```sh # lossy .wv only, targeting 256 kbit/s wavpack -b256 input.wav -o lossy.wv # lossy .wv plus a .wvc correction file that makes it lossless, at 4 bits per sample wavpack -b4 -c input.wav -o hybrid.wv ``` `-b` takes either a bitrate in kbit/s (24–9600) or, below 24, bits per sample (2.0–23.9). So `-b4` is four bits per sample, not 4 kbit/s. The floor of 2 bits per sample is about 200 kbit/s for CD stereo, which is high. WavPack's lossy mode has no psychoacoustic model, so [Opus](/codecs/audio/opus/) or [AAC](/codecs/audio/aac/) sound better at far lower rates. Hybrid is mainly useful if you want a portable lossy copy and a lossless archive from a single encode. `-cc` squeezes the pair further, at some cost to lossy quality and decode speed. Always keep each `.wvc` next to its `.wv`. ## FFmpeg FFmpeg has its own WavPack encoder and decoder: ```sh ffmpeg -i input.flac -c:a wavpack output.wv ``` The encoder does lossless only, with no lossy or hybrid mode, and `-compression_level` (0–8) trades speed for size. The decoder ignores `.wvc` files, so a hybrid file plays as the lossy version. Use the native `wavpack` and `wvunpack` for anything hybrid or DSD. ## Compatibility - Foobar2000, mpv, VLC and FFmpeg-based players handle ordinary WavPack. Browsers do not play it natively, and few hardware players do. - Many players ignore hybrid correction files, DSD, or float WavPack. - Matroska can hold lossless WavPack. - Tagging uses APEv2 (or ID3v1); `wvtag` edits tags and `wvgain` calculates ReplayGain. For web or general distribution, keep the WavPack archive and deliver FLAC or a lossy codec. --- # 7z Canonical URL: https://encode.wiki/codecs/data/7z/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: c99de4744622b3edb7f8b598ef8f49982876144c22fcd20457b25fe1660cfc31 7z is the native format of [7-Zip](https://7-zip.org/), Igor Pavlov's open-source archiver. It uses LZMA2 (the algorithm behind [xz](/codecs/data/xz/)) with large dictionaries, and by default compresses all files together as one **solid** block, so similar files share context. For collections of many similar files, it is typically the smallest common archive format, well ahead of [ZIP](/codecs/data/zip/). It also does AES-256 encryption (including file names) and applies filters that help executables and some binary data. 7-Zip is also a general archive reader: it opens ZIP, tar, gz, xz, bz2, RAR, ISO, WIM, disk images and many others, and since 24.01 it can unpack `.zst` files. ## Install On Windows use the 7-Zip installer. On Linux, use your distribution's `7zip` package or the official `7zz` build from 7-zip.org; the old `p7zip` is unmaintained. The command is `7z` or `7zz`. ## Common commands ```sh 7z a archive.7z dir/ # create (LZMA2, level 5) 7z a -mx=9 archive.7z dir/ # maximum compression 7z a -mx=9 -md=256m archive.7z dir/ # bigger dictionary 7z x archive.7z -oout/ # extract with paths into out/ 7z l archive.7z # list 7z t archive.7z # test 7z a -p -mhe=on secret.7z dir/ # AES-256, encrypt file names too (prompts for password) ``` The options that matter: | Switch | Effect | | -------------------------------------------- | ------------------------------------------------------------------------------------------------ | | `-mx=0…9` | Level; default 5. 9 is "ultra" | | `-md=Nm` | LZMA2 dictionary size; bigger finds more repeats but needs that much RAM to compress and extract | | `-ms=on` | Solid archive (default); `-ms=off` allows fast extraction of single files at a worse ratio | | `-mmt=N` | Thread count; all cores by default | | `-mhe=on` | Encrypt file names as well as data (needs a password) | | `-t7z`, `-tzip`, `-txz`, `-tbzip2`, `-tgzip` | Output format | Use `-bso0 -bsp0` to silence output in scripts. ## Pitfalls - **Solid archives are slow to extract from.** Pulling one file out of a solid 7z means decoding everything before it in the same block. Use `-ms=off` or smaller solid blocks (`-ms=100m`) when you need random access. - **Not for Unix backups.** 7z does not preserve Unix owner/group, ACLs or extended attributes, so use [tar](/codecs/data/tar/) with xz or zstd for system backups and preserve permissions. - **No recovery data.** A damaged 7z can often be partly extracted, but there is no built-in repair; keep a second copy or use PAR2. - **Compatibility:** not built into macOS or most Linux file managers without a 7-Zip/p7zip install. Choose ZIP for strangers. - **Large dictionaries** require the same memory on extraction; `-md=1536m` archives can fail on small devices. --- # brotli Canonical URL: https://encode.wiki/codecs/data/brotli/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 0b7bcbd64a864d940a1a5d13cfb8c6695a265b103d6bf29c85028e3774a869cf Brotli is a compression format from Google ([RFC 7932](https://www.rfc-editor.org/rfc/rfc7932)) designed for the web. It combines LZ77, Huffman coding and a built-in dictionary of common words and markup from HTML, CSS, JavaScript and natural language. That dictionary is why it beats [gzip](/codecs/data/gzip/) by a clear margin on small text assets. It is also the format inside WOFF2 fonts and the `br` HTTP content coding. As a general archive compressor it is unusual; use [zstd](/codecs/data/zstd/) or [xz](/codecs/data/xz/) for that. ## Common commands ```sh brotli -q 11 file # file.br, maximum quality (the CLI default) brotli -q 5 file # fast, good for on-the-fly use brotli -d file.br # decompress brotli -t file.br # test brotli -c file > file.br # to stdout ``` Unlike gzip and xz, `brotli` **keeps** the input (`-j`/`--rm` deletes it). Quality runs 0–11, and the default of 11 is very slow (many times slower than zstd or gzip at similar size gains), which is fine for static files compressed once but too slow for dynamic responses. For responses compressed per request, servers use qualities 4–5. | Option | Effect | | ------------------ | ---------------------------------------------------------------------------------------------------- | | `-q N` | Quality 0–11 | | `-w N` | Window size `2^N − 16` bytes, N from 10 to 24; the CLI uses 24 (16 MiB), shrunk to fit smaller files | | `--large_window=N` | Non-standard window up to 2^30; only decodable by decoders that support it | | `-D file` | Custom raw dictionary (both sides must have it) | ## Use it on the web Browsers send `Accept-Encoding: br` over HTTPS, so serve precompressed files: ```sh brotli -q 11 app.js app.css index.html # then serve app.js.br with Content-Encoding: br ``` nginx (`ngx_brotli`), Apache (`mod_brotli`) and CDNs such as Cloudflare can compress responses on the fly at a low quality; Caddy serves precompressed `.br` files with `file_server { precompressed br }`. Precompress static assets at 11 and let the server handle dynamic responses at 4–5. Brotli does not help already-compressed data (images, video, WOFF2 itself). Serving `Content-Encoding: br` to browsers that did not ask for it breaks the page; keep a gzip fallback. ## Limits - **Not an archive format.** There is no directory support, and tools such as GNU tar do not auto-detect it: use `tar -I brotli -cf dir.tar.br dir/` and `tar -I brotli -xf dir.tar.br`. - **Large windows** (`--large_window`) are not RFC 7932 and are not valid for HTTP. - Decompression is fast (comparable to gzip), so the cost is entirely at compression time. --- # bzip2 Canonical URL: https://encode.wiki/codecs/data/bzip2/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 625f9d783511d8ba7a82f7d95c83dafe8fcb3d52f800f69f823b10abe2e1fa22 bzip2, by Julian Seward, compresses with the Burrows–Wheeler transform in independent blocks of 100–900 kB. It beats [gzip](/codecs/data/gzip/) on ratio, particularly for text, but is slow in both directions, single-threaded, and is outperformed on speed, and usually on ratio, by [xz](/codecs/data/xz/) and [zstd](/codecs/data/zstd/). Today it is mainly something you decompress: old source tarballs (`.tar.bz2`) and some datasets. For new files, use zstd or xz. ## Common commands ```sh bzip2 -k file # file.bz2, 900k blocks, keep the original bzip2 -1 file # 100k blocks: faster, less memory, worse ratio bzip2 -d file.bz2 # decompress (or bunzip2); bzcat to stdout bzip2 -t file.bz2 # test integrity ``` bzip2 **deletes** the input unless you pass `-k`. The `-1` … `-9` options set the block size to 100 kB … 900 kB; the default is `-9`, and smaller blocks only help when memory is limited. Compression at `-9` needs about 7.6 MB of memory and decompression about 3.7 MB (`-s` reduces it to at most 2.5 MB, at some cost in speed). ## Archives and parallelism ```sh tar -cjf backup.tar.bz2 dir/ tar -xf backup.tar.bz2 ``` The reference `bzip2` uses a single thread. Because blocks are independent, parallel implementations such as `pbzip2` and `lbzip2` can speed it up and also decompress `.bz2` files in parallel. 7-Zip can also create bzip2 with multiple threads (`7z a -tbzip2`). ## Pitfalls - **Block independence helps recovery.** Damage to one block loses only that block, and `bzip2recover` can extract the intact ones. gzip has no equivalent. - **Poor on binary or already-compressed data** and slower than modern alternatives; the gain over gzip rarely justifies the time. - **`.bz2` is a single stream,** not an archive. Combine it with [tar](/codecs/data/tar/) for directories. --- # gzip Canonical URL: https://encode.wiki/codecs/data/gzip/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: a8fc53196c7251ca17fc1599e513a6a5f99e8a71c05de8bbf5ca95f2fdbced64 gzip is the oldest and most universally readable general-purpose compressor. It uses DEFLATE (32 KiB window), the same algorithm inside ZIP and PNG, and every Unix system, browser, programming language and CDN reads it. Its ratio is the weakest of the common tools, but it is fast, needs almost no memory, and works everywhere. Use it when compatibility matters more than size; otherwise prefer [zstd](/codecs/data/zstd/). ## Common commands ```sh gzip -k file # file.gz, level 6, keep the original gzip -9 -k file # best ratio; slower, usually a few % smaller gzip -d file.gz # decompress (or gunzip) zcat file.gz | less # to stdout (gzip -dc) gzip -t file.gz # test integrity gzip -l file.gz # sizes and ratio ``` Like xz, gzip **replaces** the input file unless you pass `-k`. Levels run 1–9, default 6; `-9` buys little over 6, and zopfli-style optimisers (`pigz -11`) can squeeze a few percent more for files that are compressed once and served often. For reproducible output, add `-n`, which stops gzip storing the original file name and timestamp in the header: the same input then gives the same bytes. `--rsyncable` makes the stream friendlier to rsync, at a small cost in size. ## pigz: parallel gzip pigz is a drop-in multithreaded gzip that writes standard `.gz` files: ```sh pigz -p 8 -9 -k file pigz -dc file.gz | tar -x tar -I pigz -cf backup.tar.gz dir/ ``` Compression scales with cores; decompression of a normal `.gz` is mostly single-threaded, since DEFLATE blocks depend on each other. It is not part of most base installs. ## Directories gzip compresses one stream. For a tree use [tar](/codecs/data/tar/): ```sh tar -czf backup.tar.gz dir/ tar -xzf backup.tar.gz ``` Concatenating `.gz` files produces a valid multi-member `.gz` that decompresses to the concatenated data, which is useful for appending to compressed logs. ## HTTP and web delivery `gzip` is the fallback content coding supported by every client. Servers compress responses on the fly at a low-to-medium level; for static assets, precompress once at `-9` (or with `pigz -11`) and serve it with `Content-Encoding: gzip`. [Brotli](/codecs/data/brotli/) compresses text assets noticeably smaller, but gzip remains the compatibility baseline. ## Pitfalls - **Already-compressed data** (JPEG, MP4, ZIP, video) does not shrink; gzip may make it slightly larger. - **`.gz` is not `.zip`.** gzip stores one file stream with no directory structure; ZIP stores many entries. See [ZIP](/codecs/data/zip/). - **Corruption:** the CRC detects damage but gzip has no recovery; a damaged stream is lost from the bad point onward. --- # tar Canonical URL: https://encode.wiki/codecs/data/tar/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 5452489501a14d08ea6c9c662a16aba2a947c3cfa3c46fd94a15cea7f9fb6dac tar ("tape archive") packs a directory tree into one stream, keeping names, permissions, owners, timestamps, symlinks and (optionally) ACLs and extended attributes. It does not compress; compression is a separate layer that tar runs for you, giving `.tar.gz`, `.tar.xz`, `.tar.zst` and so on. Combined with a good compressor, tar is the right tool for Unix backups and source distribution, and the compressor sees the whole archive as one stream, so it can exploit redundancy across files, unlike [ZIP](/codecs/data/zip/). ## Common commands ```sh tar -cf archive.tar dir/ # create tar -tf archive.tar # list tar -xf archive.tar -C out/ # extract (into out/, which must exist) tar -xf archive.tar path/in/archive # extract one member ``` Reading is automatic: `tar -xf` detects gzip, xz, bzip2, zstd and others by content. For creating, pick the compressor by flag or suffix: | Flag | Compression | | ------------------------ | ----------------------------------------------------------- | | `-z` | [gzip](/codecs/data/gzip/) | | `-J` | [xz](/codecs/data/xz/) | | `-j` | [bzip2](/codecs/data/bzip2/) | | `--zstd` | [zstd](/codecs/data/zstd/) | | `-a` (`--auto-compress`) | chosen from the archive suffix: `tar -caf out.tar.zst dir/` | | `-I 'prog args'` | any program: `tar -I 'zstd -19 -T0' -cf out.tar.zst dir/` | Use `-I` for options such as threads and levels; `-I pigz` gives parallel gzip. For compressors tar does not know, such as brotli, pass `-I` for extraction as well: `tar -I brotli -xf out.tar.br`. ## Backups and restores To preserve everything you will need on restore: ```sh tar --xattrs --acls --numeric-owner -I 'zstd -T0' -cpf backup.tar.zst /path/to/dir sudo tar --xattrs --acls --numeric-owner -xpf backup.tar.zst -C /restore ``` `-p` keeps permissions exactly (extraction as root does this by default). Owner restore only works as root, and `--numeric-owner` restores by UID/GID instead of names, which matters when restoring on a different system. `--one-file-system` stops tar crossing mount points, and `--exclude='pattern'` skips paths. ### Reproducible archives Tar embeds timestamps, ordering and owner names. To get identical bytes from identical content: ```sh tar --sort=name --mtime='2026-01-01 00:00Z' --owner=0 --group=0 --numeric-owner -cf - dir/ | zstd -T0 > dir.tar.zst ``` ## Formats and tools GNU tar writes the GNU format by default. `--format=pax` (POSIX.1-2001) supports long paths and sub-second times without the GNU extensions, and `--format=ustar` is the oldest and most limited. bsdtar (libarchive, the default on macOS and Windows) reads all of them. Because tar archives are a plain stream, there is no index: listing or extracting one file means reading through the archive, and a damaged stream loses everything after the damage unless the compressor limits it. ## Pitfalls - **Absolute paths:** GNU tar strips the leading `/` on creation, so `tar -xf` will not overwrite system files. Use `-C /` for a full restore. - **Compression flags and `-f`:** `-f` takes the next argument, so `tar -cfz out.tgz dir` creates a file named `z`. Put `-f` last (`-czf out.tgz`). - **Symlinks and hard links** are stored as links; use `-h` to follow symlinks instead. --- # xz Canonical URL: https://encode.wiki/codecs/data/xz/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: d637ea08e9c3efd9c4224ed33c2c703db4c310b19cc31283734fdd269c2a8192 `xz` compresses with LZMA2, the algorithm behind 7z. It produces some of the smallest files of any common tool, decompresses reasonably fast, and is the standard for source tarballs (`.tar.xz`) and many package formats. Compression is slow and memory-hungry. If you compress once and distribute widely, xz is a good choice; if you compress often, use [zstd](/codecs/data/zstd/). ## Common commands ```sh xz file # file.xz, preset 6; deletes file xz -9e -k file # maximum compression, keep the original xz -d file.xz # decompress (or unxz) xz -dc file.xz | less xz -t file.xz # test integrity xz -l file.xz # sizes and ratio ``` Note that xz **deletes the input** after success unless you pass `-k`. ## Presets `-0` … `-9` select dictionary size and match-finder effort. The default is `-6`. Appending `-e` (`-6e`, `-9e`) searches harder for a little extra compression at significant extra time. | Preset | Dictionary | Compress memory | Decompress memory | | ------ | ---------- | --------------- | ----------------- | | `-1` | 1 MiB | 9 MiB | 2 MiB | | `-3` | 4 MiB | 32 MiB | 5 MiB | | `-6` | 8 MiB | 94 MiB | 9 MiB | | `-9` | 64 MiB | 674 MiB | 65 MiB | A dictionary larger than the input is wasted memory, so `-9` on a 5 MB file is slower than `-6` for no gain. The decompressor needs memory proportional to the dictionary, which matters for small devices and installers: a `-9e` file needs ~65 MiB to unpack. Since XZ Utils 5.6.0, xz compresses multithreaded by default, using all cores. It splits the input into independent blocks, which slightly reduces the ratio and multiplies memory by the thread count, but lets the file be decompressed multithreaded too. Use `-T1` for the single-threaded compressor when you need the smallest possible output or memory is tight. Older versions were single-threaded unless given `-T0`. ## Archives and pipelines xz compresses one stream. Use [tar](/codecs/data/tar/) for directories: ```sh tar -cJf backup.tar.xz dir/ XZ_OPT='-9e' tar -cJf backup.tar.xz dir/ tar -xf backup.tar.xz ``` `-J` uses the default preset; set others through `XZ_OPT` or `-I 'xz -9e'`. ## Other notes - **Integrity check:** xz stores a CRC64 by default (`--check=crc32|crc64|sha256|none`). `xz -t` verifies it. - **`.lzma` and `lzip`:** the older raw LZMA format (`xz --format=lzma`) is obsolete. lzip is a separate format. - **Not for HTTP:** there is no `xz` HTTP content coding. Use [brotli](/codecs/data/brotli/), [zstd](/codecs/data/zstd/) or [gzip](/codecs/data/gzip/). - **Memory limit errors** while decompressing only happen when a limit is set (for example `XZ_DEFAULTS=--memlimit=150MiB`); xz has none by default. Raise it with `--memlimit-decompress=…`. --- # ZIP Canonical URL: https://encode.wiki/codecs/data/zip/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: c5e214ac78213f167063e617bac6aca28cbaf40539f4ab275f98410d41b9871b ZIP is an archive format: one file holding many entries, each compressed on its own and listed in a central directory at the end. That makes extracting a single file fast and appending cheap, and every operating system opens `.zip` natively. The price is a weaker ratio than [7z](/codecs/data/7z/) or `.tar.xz`, because entries are compressed independently (no shared dictionary across files). Use ZIP when the recipient might be anyone; also remember that `.docx`, `.jar`, `.apk`, `.epub` and `.cbz` are ZIP files. ## Common commands ```sh zip -r archive.zip dir/ # Deflate, recurse zip -r -9 archive.zip dir/ -x '*.tmp' # best Deflate, exclude pattern zip -r -y archive.zip dir/ # store symlinks as links unzip -l archive.zip # list unzip -t archive.zip # test unzip archive.zip -d out/ # extract into out/ ``` Running `zip` on an existing archive adds and replaces entries (`-u` only updates changed ones); `-0` stores without compression, which is the right choice for already-compressed content such as video or JPEGs. The Info-ZIP `zip`/`unzip` tools are on most Linux systems; macOS and Windows ship their own, and `7z a -tzip` also works. ## Compression methods The default is Deflate (method 8), and that is the only one you can count on everywhere. The format also defines others, which built-in OS tools and Info-ZIP `unzip` often cannot read: | Method | Notes | | -------------- | --------------------------------------------------------------------- | | Deflate | Universal; the default | | Deflate64 | Larger window variant; 7-Zip writes it, Info-ZIP `unzip` 6.0 reads it | | bzip2 | `zip -Z bzip2` or 7-Zip; `unzip` 6.0 reads it | | LZMA, xz, PPMd | 7-Zip and similar tools only; `unzip` 6.0 skips these entries | | Zstandard (93) | Added in APPNOTE 6.3.8; 7-Zip 24.01+ can read it | For anything but Deflate, check that the other side's tool supports it. If you want better compression, use 7z or `.tar.zst` instead. ## Encryption and limits - **Classic ZipCrypto** (`zip -e`) is weak and can be broken with known plaintext. AES-256 ZIP (`7z a -tzip -mem=AES256 -p`) is secure but unreadable to Info-ZIP `unzip` and to some built-in OS tools. File names stay readable either way. - **ZIP64** removes the old 4 GiB and 65,535-entry limits; current tools write it automatically when needed. Very old extractors may not read it. - **Metadata:** ZIP stores modification time and basic permissions but not Unix owner/group or xattrs. For system backups use [tar](/codecs/data/tar/). - **File names:** non-ASCII names are the usual cross-platform problem. Modern tools write UTF-8 names with the correct flag; older ones use the local code page and show mojibake. --- # zpaq Canonical URL: https://encode.wiki/codecs/data/zpaq/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: a0bf0274f8d40a875a67e83c91cef5b76f749ffcc6ff02ab71f84bd96dea2dbf ZPAQ is a format and journaling archiver by Matt Mahoney. Where other tools overwrite or rewrite archives, `zpaq` only ever **appends**: each run adds a new version containing the changes since the last one, with identical data deduplicated across files and versions. Every earlier state remains restorable. That makes it a good fit for incremental backups of a directory that changes slowly, such as projects, VM images or databases, where it often beats everything else on stored size. The ZPAQ format is self-describing: each archive embeds the decompression program for its own data, so any compliant reader can open archives written with any compression model, including ones that did not exist at the time. The reference tool is `zpaq` 7.15 from 2016, and the format has been stable since. ## Common commands ```sh zpaq a backup.zpaq dir/ # add (first run: full; later runs: only changes) zpaq a backup.zpaq dir/ -m5 # slower, better compression zpaq l backup.zpaq # list the current contents zpaq l backup.zpaq -all # list every version zpaq x backup.zpaq dir/ -to restore/ # restore the latest version into restore/ zpaq x backup.zpaq dir/ -until 3 -to old/ # restore as of version 3 zpaq x backup.zpaq -test # verify without writing ``` Put the options **after** the file names. Options that matter: | Option | Effect | | --------------- | --------------------------------------------------------------------------------------- | | `-m0` … `-m5` | Method: 0 stores (deduplication only), 1 is default and fast, 5 is the slowest and best | | `-t N` | Number of threads (default: all cores) | | `-key password` | Encrypt the archive | | `-until N` | List or extract as of version N (or `-N` counting from the end) | | `-to path` | Extract into a different location | | `-f` | Add files whose contents changed even if dates did not | By default `zpaq a` decides what changed by file modification dates, so a file touched without changes is re-checked cheaply through deduplication. ## What it is good and bad at - **Good:** incremental backup, deduplication, high ratios on text, source trees and disk images, restoring any past version, and appending without rewriting. - **Bad:** speed at high `-m` levels (compression and decompression speed are about the same, and slow), and wide availability: it is not installed by default anywhere and there is no native OS support or HTTP coding. Extraction needs the `zpaq` tool or a compatible library. - **No in-place deletion.** Removed files are tracked as deletions; the data remains until you rewrite the archive (`-repack`, or extract and re-add). - **Single file by design.** An archive name with `????` (quote it in the shell), such as `'backup_????.zpaq'`, writes numbered parts, and you must keep every part. For archives you write once and read widely, use [7z](/codecs/data/7z/), [xz](/codecs/data/xz/) or [zstd](/codecs/data/zstd/). --- # zstd Canonical URL: https://encode.wiki/codecs/data/zstd/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 7784754cbce9e3f7a91a4246d719229609c5d23a7b3d6edd5aed5415dec61eef Zstandard (zstd) is Yann Collet's compressor, developed at Facebook (now Meta) and specified in [RFC 8878](https://www.rfc-editor.org/rfc/rfc8878). It compresses and decompresses faster than gzip at a better ratio, its high levels approach xz, and decompression speed barely depends on the level. That makes it the sensible default for archives, backups, logs, container images and intermediate files. Arch Linux packages are zstd-compressed, and the Linux kernel, btrfs, SquashFS and OpenZFS all support it. ## Common commands ```sh zstd file # file.zst, level 3, source kept zstd -19 -T0 file # slower, much smaller, all cores zstd --ultra -22 -T0 file # maximum; needs lots of memory zstd -d file.zst # decompress zstd -dc file.zst | less # to stdout zstd -t file.zst # test integrity ``` Unlike gzip and xz, zstd **keeps** the input file by default (`--rm` deletes it). Output has a `.zst` extension. | Option | Effect | | ----------------- | ---------------------------------------------------------------------------------------------------------------------------- | | `-1` … `-19` | Compression level; default 3. `-19` is about the useful limit | | `--ultra -20…-22` | Even slower and memory-hungry, with small gains; the decoder also needs more memory | | `--fast=N` | Negative levels, faster than `-1` with worse ratios | | `-T0` | Use all cores (default is 1); also speeds up higher levels a lot | | `--long[=27]` | Long-distance matching with a 128 MiB window; helps on big files with distant repeats (VM images, tarballs of similar trees) | | `--adapt` | Change the level on the fly to match how fast the output is being consumed (good for piping over a network) | | `-D dict` | Use a trained dictionary; `zstd --train files…` builds one. Big wins on many small similar files | Levels 3–9 are the sweet spot for logs, backups and anything compressed repeatedly. Use 19 for things compressed once and read many times. ### Larger windows need matching decompression settings With `--long=N` for N above 27, the decompressor must be given `--long=N` too (or `--memory=…`), otherwise it refuses the file to protect itself from huge allocations. Archives made with the default window decompress anywhere. ## Archives and other formats zstd compresses one stream, not a directory, so combine it with [tar](/codecs/data/tar/): ```sh tar --zstd -cf backup.tar.zst dir/ tar -I 'zstd -19 -T0' -cf backup.tar.zst dir/ tar -xf backup.tar.zst ``` The `zstd` binary can also read and write gzip, xz and lzma streams (`--format=gzip`). [7-Zip](/codecs/data/7z/) can unpack `.zst` files since 24.01 but does not create them. ## HTTP `zstd` is a registered HTTP content coding. Chrome and Edge 123, Firefox 126 and Safari 26.3 (iOS, or macOS 26.3 and later) advertise it in `Accept-Encoding`; see [Can I use](https://caniuse.com/zstd). HTTP zstd limits the window to 8 MiB ([RFC 9659](https://www.rfc-editor.org/rfc/rfc9659)), so do not serve files compressed with `--long` or `--ultra` levels (20–22) as `Content-Encoding: zstd`. Level 19 and below stay within the limit. Brotli ([brotli](/codecs/data/brotli/)) is the established alternative for static web assets and has wider browser support. ## Compared with others | vs. | zstd | | ------------------------------ | ----------------------------------------------------------------------------- | | [gzip](/codecs/data/gzip/) | Faster at a similar or better ratio, and multithreaded | | [xz](/codecs/data/xz/) | Slightly worse ratio at max, but decompresses several times faster | | [brotli](/codecs/data/brotli/) | Faster; brotli wins on small text/web files thanks to its built-in dictionary | --- # Image codecs overview Canonical URL: https://encode.wiki/codecs/images/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 7edbfb58214bf78149cd3885ff801d0b43fe1469399143ea77140353ccb5ed18 Pick a format by what the image is and where it has to be displayed. This page gives the short answer; each format page covers encoders, settings and pitfalls. ## Which format should I use? | You have... | Use | Why | | --- | --- | --- | | **Photos for the web** | [AVIF](/codecs/images/avif/) or [WebP](/codecs/images/webp/), with a [JPEG](/codecs/images/jpeg/) fallback | AVIF compresses best and has wide browser support; WebP encodes faster and is supported everywhere current; JPEG opens on anything | | **Photos where quality matters most**, or HDR and wide gamut | [JPEG XL](/codecs/images/jxl/) | Excellent at high quality, supports HDR, lossless and progressive decoding. Supported in Safari 17+ and Chrome 155+; Firefox 158 (due 13 October 2026) enables it | | **Existing JPEGs you want smaller** | [JPEG XL](/codecs/images/jxl/) lossless transcode, or `jpegtran` / MozJPEG | JPEG XL keeps the original JPEG recoverable bit for bit | | **Screenshots, UI, logos, line art** | [PNG](/codecs/images/png/) (optimised with oxipng), or lossless [WebP](/codecs/images/webp/) | Lossless and sharp; `pngquant` makes a lossy palette version much smaller | | **Transparency** | PNG, WebP, AVIF or JPEG XL | JPEG and GIF can't do soft alpha | | **Lossless masters and archives** | PNG or TIFF; [JPEG XL](/codecs/images/jxl/) lossless for smaller files; [JPEG 2000](/codecs/images/jpeg2000/) in institutions that already use it | Keep a lossless master and export delivery files from it | | **Animation** | A looping muted video, animated [WebP](/codecs/images/webp/) or AVIF; [GIF](/codecs/images/gif/) only where nothing else works | GIF is the largest and has 256 colours; see the [GIF page](/codecs/images/gif/) | | **Phone and Apple-camera files** | [HEIC](/codecs/images/heic/) | Common camera output, but convert before sharing: licensing and support are patchy | | **Fast lossless in a game or tool** | [QOI](/codecs/images/qoi/) | Trivial to implement and very fast, but larger files and no browser support | ## At a glance | Format | Compression | Bit depth | Alpha | Animation | Browser support (October 2026) | | --- | --- | --- | --- | --- | --- | | [JPEG](/codecs/images/jpeg/) | Lossy | 8 | No | No | Everywhere | | [PNG](/codecs/images/png/) | Lossless | Up to 16 | Yes | APNG | Everywhere | | [GIF](/codecs/images/gif/) | Lossless, 256 colours | 8 (palette) | 1-bit | Yes | Everywhere | | [WebP](/codecs/images/webp/) | Lossy or lossless | 8 | Yes | Yes | All current browsers | | [AVIF](/codecs/images/avif/) | Lossy or lossless | 8, 10, 12 | Yes | Yes | All current browsers | | [JPEG XL](/codecs/images/jxl/) | Lossy or lossless | Up to 32 | Yes | Yes | Safari 17+ (stills only), Chrome 155+, Firefox 158+ | | [HEIC](/codecs/images/heic/) | Lossy or lossless (HEVC) | 8, 10 and up | Yes (auxiliary) | Image sequences | Safari 17+ only | | [JPEG 2000](/codecs/images/jpeg2000/) | Lossy or lossless | 1–38 in the standard (tools mostly handle ≤16) | Yes (JP2 channels) | MJ2 only | None (Safari dropped it in 18.0) | | [QOI](/codecs/images/qoi/) | Lossless | 8 | Yes | No | None | Browser support changes quickly; the [image and audio support guide](/reference/image-audio-support/) is kept up to date, and the [guide to the option tables](/reference/encoder-parameters/) lists every command-line option for the tools on these pages. ## Tips that apply to all of them - **Always encode from a lossless master.** Re-encoding a lossy file stacks errors. - **Compare by eye.** For automatic comparison across formats use [SSIMULACRA2](/reference/metrics/ssimulacra2/) or [Butteraugli](/reference/metrics/butteraugli/); PSNR and SSIM reward blur and mislead on perceptually tuned encoders. - **Check metadata and colour.** Orientation, ICC profiles and HDR signalling are the first things converters drop. Test one image from your pipeline in each target viewer. - **Quality numbers are per encoder.** `-q 80` in `cjpeg`, `cwebp`, `avifenc` and `cjxl` gives four different quality levels; compare outputs, not settings. --- # AVIF Canonical URL: https://encode.wiki/codecs/images/avif/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: 6649f626c8ccebb5f8e813163a9928a12fcd593643fd26f72a73841ac515f97f AVIF is AV1 intra-frame coding stored in a HEIF/ISO-BMFF container. It is the format to reach for when you want the smallest lossy images that every current browser can display, and it also gives you 10- and 12-bit depth, HDR signalling, alpha and animation. It is a poor choice for lossless archival, and encoding is slower than JPEG or WebP. The container is the same family as [HEIC](/codecs/images/heic/); the payload is the [AV1](/codecs/video/av1/) video codec, so any AV1 encoder can in principle produce AVIF images. ## Strengths and weaknesses **Strengths** - Very good lossy compression on photos and on flat graphics. At low and medium bitrates it beats [JPEG](/codecs/images/jpeg/) and [WebP](/codecs/images/webp/) by a wide margin; against [JPEG XL](/codecs/images/jxl/) it usually produces smaller files at web-delivery quality, while JPEG XL pulls ahead at very high quality and in lossless. - 8-, 10- and 12-bit, 4:2:0 / 4:2:2 / 4:4:4 / monochrome, wide gamut and HDR signalling (PQ, HLG), ICC or CICP colour, and a separate alpha plane. - Animation using real inter-frame video coding, which makes it a far better animated format than GIF or animated WebP for most clips. - Royalty-free, and supported by every current browser. **Weaknesses** - Slower encoding than JPEG, WebP or JPEG XL. libaom at its slowest speeds (`-s 0`–`3`) and on large images takes seconds to minutes per file. - Weak lossless mode. It is usually larger than lossless WebP or JPEG XL, and sometimes larger than PNG. - No JPEG-style progressive decode: a plain AVIF shows nothing until enough of the file has arrived. Layered "progressive" files exist in the AVIF 1.2 spec and `avifenc --progressive` can write them, but check your target decoders before relying on them. - Smooth gradients can band and fine texture can smear at low bitrates, and 4:2:0 bleeds saturated colour edges and small coloured text. - Very large images need tiling or a grid, which costs a little efficiency and can leave faint seams. ## Support | Platform | Still AVIF | Notes | | --------------------------- | --------------------------------------------------------- | ------------------------------------------------- | | Chrome | 85+ | Other Chromium browsers follow their Chromium version | | Firefox | 93+ | Animated AVIF from Firefox 113 | | Edge | 121+ | | | Safari | 16.4+ on macOS, 16.1+ on iOS | Safari 16.1–16.3 on macOS worked only on Ventura | | Android system decoder | Android 12+ (8-bit) | 10-bit decoding is optional per device | Browser versions are from [MDN's AVIF data](https://github.com/mdn/browser-compat-data/blob/main/mediatypes/image/avif.json) and Android's [supported media formats](https://developer.android.com/media/platform/supported-formats). Desktop OS thumbnailers, editors and messaging apps are patchier than browsers; see [image and audio support](/reference/image-audio-support/) for how to check a given file. Profiles matter less than they used to, but they still bound what a conservative decoder accepts. The Baseline brand (`MA1B`) is AV1 Main profile (8/10-bit, 4:2:0 or monochrome) at level 5.1 or lower; the Advanced brand (`MA1A`) is High profile (adds 4:4:4) up to level 6.0. Larger images are built from a grid of tiles. ## Encode with avifenc `avifenc` from [libavif](https://github.com/AOMediaCodec/libavif) is the standard encoder. It takes PNG, JPEG or Y4M input and calls an AV1 backend (libaom, SVT-AV1 or rav1e, whatever your build includes). ```sh avifenc -q 65 -s 4 input.png output.avif ``` `-q` and `-s` are the two knobs you will actually turn. The defaults are `-q 60` and `-s 6`. Pick the quality by eye at a fast speed, then encode the final file at `-s 4` or slower; speeds below 4 cost a lot of time for a small gain. | Option | What it does | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `-q 0..100` | Colour quality; 100 is lossless AV1 coding. Not comparable between backends or libavif releases. | | `--qalpha 0..100` | Alpha quality, inherited from `-q` unless set. Use `--qalpha 100` if the alpha edge must stay clean. | | `-s 0..10` | Speed; lower is slower and smaller. Default 6. | | `-d 8/10/12` | Output bit depth; follows 8-bit input by default. Use 10 for HDR and high-bit-depth sources. `-d 10` is also common for 8-bit sources because it reduces banding in smooth gradients. | | `-y 444/422/420/400` | Chroma format. `auto` gives 4:4:4 for PNG, keeps the subsampling of a JPEG and uses 4:0:0 for greyscale PNG. | | `--sharpyuv` | Sharper RGB→4:2:0 conversion; only does anything with `-y 420`. | | `-c aom/svt/rav1e` | Choose the backend. | | `-j N` | Worker threads (default `all`). | | `-a KEY=VALUE` | Pass a backend option, e.g. `-a tune=iq`. libaom keys can be limited to one plane with `color:` or `alpha:`. | | `-l` | Lossless: sets RGB-identity, full-range, 4:4:4 defaults. | | `--cicp P/T/M`, `--icc` | Signal colour primaries/transfer/matrix or attach an ICC profile. | ### Chroma: 4:4:4 or 4:2:0 `avifenc` keeps 4:4:4 for PNG input, and libaom handles 4:4:4 well, so the extra chroma usually costs little. Keep it for screenshots, UI, line art and coloured text, where 4:2:0 visibly bleeds colour. Use `-y 420` (plus `--sharpyuv`) when you need the smallest photo files or files that stay within the Baseline brand and AV1 Main profile that hardware decoders support. ### Tuning Since libavif 1.4.0, `avifenc` with libaom 3.13 or newer encodes still images (YUV, not RGB-matrix) with `tune=iq` by default, and maps `-q` to quantizers with a formula designed for it. `tune=iq` is libaom's still-image mode, added in 3.12: it was developed with [SSIMULACRA2](/reference/metrics/ssimulacra2/) as a guide and checked visually, and uses Variance Boost, adaptive CDEF and quantization matrices. Alpha is encoded with `tune=psnr`, because `tune=ssim` causes ringing on alpha. The older recipe of `-a tune=ssim -a end-usage=q -a cq-level=…` is obsolete: use `-q` and leave the tune alone. Because `tune=iq` was shaped around SSIMULACRA2, check comparisons against other tunes by eye as well. ### Backends | Backend | Notes | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | libaom | The default and the usual best choice for stills: full chroma and bit-depth support, `tune=iq`, and the most intra-coding work behind it. | | SVT-AV1 | Faster, but libavif's SVT adapter is 4:2:0 only, 8/10-bit. A PNG defaults to 4:4:4, so `-c svt` without `-y 420` fails with "Only support 420 now". The libaom `-a` keys do not apply. | | rav1e | Works, but is slow for stills and lacks libaom's still-image tuning. | libheif's `heif-enc --avif` is a second frontend with the same backends and its own defaults (quality 50); its plugin parameter tables are in the reference below. AVIF is also writable from FFmpeg and ImageMagick, which go through libavif or libheif. ## Alpha, HDR and animation - **Alpha** is stored as a separate monochrome AV1 image, so it has its own quality (`--qalpha`). Use `-p` only if you intend premultiplied (associated) alpha. - **HDR**: keep the source's real transfer function and primaries (`--cicp 9/16/9` for PQ BT.2020, `9/18/9` for HLG) and encode at 10 bit or more. Tagging SDR pixels as PQ does not make them HDR. In builds with gain-map support, `avifenc` converts gain maps embedded in JPEG input (`--qgain-map`, `--ignore-gain-map`). - **Animation**: pass several PNGs with `--fps`, or pipe Y4M from FFmpeg: `ffmpeg -i in.mp4 -pix_fmt yuv420p -f yuv4mpegpipe - | avifenc --stdin out.avif`. Firefox plays animated AVIF from version 113. ## Pitfalls - A lossless AV1 stream does not make the file lossless: RGB→YUV conversion and 4:2:0 are lossy unless you use `-l`. - `avifenc` copies Exif, XMP and ICC from PNG and JPEG input and turns the Exif orientation into AVIF `irot`/`imir` transforms. Use `--ignore-exif`, `--ignore-xmp` or `--ignore-icc` to drop them; dropping the ICC profile of a wide-gamut source changes its colours. - Re-encoding an AVIF from a previous lossy AVIF compounds loss; keep the original source. ## Other encoders Any AV1 encoder can produce AVIF; see [aomenc](/tools/software-encoders/aomenc/), [SVT-AV1](/tools/software-encoders/svt-av1/) and [rav1e](/tools/software-encoders/rav1e/). Rachel Barker's [tinyavif](https://github.com/rachelplusplus/tinyavif) is a minimal AVIF encoder written to show how AVIF and AV1 work, not for production. ## Related pages - [AV1](/codecs/video/av1/) is the video codec underneath. - [JPEG XL](/codecs/images/jxl/) has lossless JPEG recompression and a stronger lossless and high-quality story. - [WebP](/codecs/images/webp/) is the older, faster, 8-bit-only alternative. - [HEIC](/codecs/images/heic/) uses the same container with HEVC. ## Full option reference The tables below are the full `avifenc` and libheif AVIF plugin parameter references. [Reading option tables](/reference/encoder-parameters/) explains the Default column. ## avifenc 1.4.2 complete parameter reference
INPUT to --target-size | Parameter / aliases | Type or accepted values | Default | Purpose and constraints | | ---------------------------------------------------------------------- | ------------------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------- | | `INPUT` | path(s) | required | JPEG, PNG or Y4M input. Several inputs make an animated sequence, or the layers/cells with --layered/--grid. | | `OUTPUT` | path | required, unless --output is used | Output .avif. Taken from the last positional argument unless --output is given. | | `--help`, `-h` | action | not requested | Print usage and the compiled-in codec versions. | | `--version`, `-V` | action | not requested | Print the libavif and codec library versions. | | `--qcolor`, `-q`, `--qcolor:u`, `--qcolor:update`, `-q:u`, `-q:update` | integer 0–100 | 60 | Colour quality, 0–100. 100 is lossless AV1 coding, though RGB→YUV conversion can still be lossy. The :u forms apply only to the inputs after them. | | `--qalpha`, `--qalpha:u`, `--qalpha:update` | integer 0–100 | same as qcolor | Alpha quality, 0–100. Follows --qcolor unless set. | | `--speed`, `-s` | 0–10, default or d | 6 | Encoder speed, 0 (slowest) to 10, or default/d for the codec's own default. Slower is smaller. | | `--jobs`, `-j` | positive integer or all | all detected CPUs | Worker threads, or all. What it controls depends on the codec. | | `--no-overwrite` | flag | false | Fail instead of replacing an existing output file. | | `--output`, `-o` | path | final positional filename | Output path, instead of the last positional argument. | | `--lossless`, `-l` | flag | false | Set lossless defaults: quality 100, full range, 4:4:4 and identity matrix. Warns when the input can't be stored losslessly. | | `--depth`, `-d` | D[,extension] | input-dependent | Output bit depth, 8, 10 or 12. A second value (8,8 / 12,4 / 12,8) adds a hidden extension image for 16-bit output. Y4M keeps its own depth. | | `--yuv`, `-y` | auto, 444, 422, 420, 400 | auto | Chroma format: auto, 444, 422, 420 or 400. auto keeps a JPEG's subsampling, uses 400 for greyscale PNG and 444 otherwise; Y4M keeps its format. | | `--premultiply`, `-p` | flag | false | Multiply colour by alpha before encoding and mark alpha as premultiplied. Changes pixel values. | | `--sharpyuv` | flag | false | Sharper RGB→4:2:0 conversion (needs libsharpyuv). No effect on Y4M or non-4:2:0 output. | | `--stdin` | flag | false | Read one stream (Y4M by default) from standard input. No other input paths are allowed; the output path is still required. | | `--input-format` | auto, jpg, jpeg, png, y4m | auto for paths; y4m for stdin | Force the input type: jpeg/jpg, png, y4m or auto. Needed only when the extension is misleading. | | `--cicp`, `--nclx` | P/T/M integers | 2/2/6 before input-specific handling | Colour primaries/transfer/matrix as three numbers (H.273); 2 means unspecified. Tags the file; samples are not converted. | | `--range`, `-r` | full/f or limited/l | full for JPEG/PNG; retained for Y4M | YUV range, full or limited. Y4M input keeps its own range. | | `--target-size` | positive bytes | disabled | Aim for this file size in bytes by searching over quality. Up to 7× slower; conflicts with fixed --qcolor/--qalpha. |
--progressive to --irot | Parameter / aliases | Type or accepted values | Default | Purpose and constraints | | ---------------------------------- | ------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | `--progressive` | flag | false | Write a two-layer image that can render progressively from one input. Needs --qcolor of at least 10; support is limited. | | `--layered` | flag | false | Encode two to four inputs as layers of one image. Not an animation. | | `--grid`, `-g` | columns x rows | disabled | Write a grid of COLSxROWS cells, from identical inputs or one image split evenly. | | `--codec`, `-c` | build-specific encoder ID | auto | Pick the AV1 encoder, for example aom, rav1e or svt. Decoder-only IDs can't encode. | | `--exif` | payload path | preserve input metadata if present | Use this Exif payload instead of any embedded Exif. | | `--xmp` | payload path | preserve input metadata if present | Use this XMP payload instead of any embedded XMP. | | `--icc` | profile path | preserve input profile if present | Use this ICC profile instead of any embedded one. Tags the image; samples are not converted. | | `--timescale`, `--fps` | positive integer | 30; may inherit Y4M timing | Sequence ticks per second. With one-tick frames this is the frame rate. Y4M frame rate is used if unset. | | `--creation-time` | nonnegative Unix seconds | 0: use modification time | Sequence creation time in Unix seconds. 0 uses the modification time. | | `--modification-time` | nonnegative Unix seconds | 0: use current time | Sequence modification time in Unix seconds. 0 uses the current time. | | `--keyframe`, `-k` | integer | 0: disabled | Maximum keyframe interval for sequences, in frames. 0 disables the limit. | | `--ignore-exif` | flag | false | Drop embedded Exif. | | `--ignore-xmp` | flag | false | Drop embedded XMP. | | `--ignore-icc`, `--ignore-profile` | flag | false | Drop the embedded ICC profile. | | `--ignore-gain-map` | build-gated flag | false | Drop an embedded JPEG gain map. Needs a libavif built with gain-map conversion. | | `--qgain-map` | build-gated integer 0–100 | 60 | Gain map quality, 0–100. Needs a gain-map build; takes no :u form. | | `--pasp` | H,V positive spacing | absent | Pixel aspect ratio as H,V. Metadata only. | | `--crop` | x,y,width,height | absent | Clean-aperture crop as x,y,width,height. Applied at display time; pixels are not removed. | | `--clap` | eight rational components | absent | Clean aperture as eight numerator/denominator values: width, height, horizontal offset, vertical offset. | | `--irot` | integer 0–3 | absent | Rotation in 90° steps anticlockwise (0–3). Stored as a transform. |
--imir to -- | Parameter / aliases | Type or accepted values | Default | Purpose and constraints | | ---------------------------------------------------------------------------- | ------------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------- | | `--imir` | 0 or 1 | absent | Mirror axis: 0 top-to-bottom, 1 left-to-right. Stored as a transform. | | `--clli` | MaxCLL,MaxPALL | absent | MaxCLL,MaxPALL content light level metadata. Doesn't make the image HDR. | | `--repetition-count` | nonnegative integer or infinite | infinite | How many times a sequence plays, or infinite. | | `--tilerowslog2`, `--tilerowslog2:u`, `--tilerowslog2:update` | integer 0–6 | 0 before automatic tiling | log2 of the number of tile rows (0–6). Setting it switches to manual tiling. | | `--tilecolslog2`, `--tilecolslog2:u`, `--tilecolslog2:update` | integer 0–6 | 0 before automatic tiling | log2 of the number of tile columns (0–6). Setting it switches to manual tiling. | | `--autotiling`, `--autotiling:u`, `--autotiling:update` | flag | true | Choose AV1 tiling automatically. This is the starting mode; it is separate from a HEIF grid. | | `--min`, `--min:u`, `--min:update` | deprecated quantizer 0–63 | 0 | Deprecated minimum quantizer (0–63). Use --qcolor. | | `--max`, `--max:u`, `--max:update` | deprecated quantizer 0–63 | 63 | Deprecated maximum quantizer (0–63). Use --qcolor. | | `--minalpha`, `--minalpha:u`, `--minalpha:update` | deprecated quantizer 0–63 | 0 | Deprecated minimum alpha quantizer (0–63). Use --qalpha. | | `--maxalpha`, `--maxalpha:u`, `--maxalpha:update` | deprecated quantizer 0–63 | 63 | Deprecated maximum alpha quantizer (0–63). Use --qalpha. | | `--scaling-mode`, `--scaling-mode:u`, `--scaling-mode:update` | positive N[/D] | 1/1 | Frame or layer scaling as N[/D], for example 1/2. | | `--duration`, `--duration:u`, `--duration:update` | positive clock ticks | 1; may inherit Y4M timing | Frame duration in timescale ticks for the following inputs. Applies with or without :u. | | `--advanced`, `-a`, `--advanced:u`, `--advanced:update`, `-a:u`, `-a:update` | KEY[=VALUE], repeatable | none | Pass KEY[=VALUE] straight to the codec, for example -a tune=ssim. Repeatable. Keys are the codec's own. | | `--mini` | build-gated flag | false | Compact-header writer. Needs a build with AVIF_ENABLE_EXPERIMENTAL_MINI; not in current binaries. | | `--` | separator | not used | End of options; later arguments are filenames. |
## libheif AVIF plugin references Plugin parameters for `heif-enc --avif -e aom|rav1e|svt`, set with `-p NAME=VALUE`. The full `heif-enc` frontend reference is on the [HEIC page](/codecs/images/heic/#heif-enc-1236-complete-frontend-reference). ### libheif AOM plugin parameters | Parameter / aliases | Type or accepted values | Default | Purpose and constraints | | ------------------- | ----------------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------- | | `realtime` | boolean | false | Use libaom's realtime mode instead of good-quality mode. Faster, larger. | | `speed` | integer 0–9 | 6 | libaom cpu-used, 0 is slowest. Realtime mode changes what the values mean. | | `threads` | integer 1–64 | CPU count, max 64 (4 if undetectable) | Worker threads. | | `quality` | integer 0–100 | 50 | Colour quality. | | `lossless` | boolean | false | Lossless colour coding. | | `chroma` | 420, 422 or 444 | 420 | Chroma subsampling. Lossless RGB needs 444. | | `tune` | auto, psnr, ssim or iq | auto | auto picks by image type (still, sequence, alpha). iq can't be combined with lossless. | | `min-q` | integer 0–63 | 0 | Lowest quantizer index the encoder may use. | | `max-q` | integer 0–63 | 63 | Highest quantizer index the encoder may use. | | `alpha-quality` | integer 0–100 | same as quality | Alpha quality. Follows the colour quality if unset. | | `alpha-min-q` | integer 0–63 | same as min-q | Lowest alpha quantizer. Follows min-q if unset. | | `alpha-max-q` | integer 0–63 | same as max-q | Highest alpha quantizer. Follows max-q if unset. | | `lossless-alpha` | boolean | false | Code alpha losslessly while colour stays lossy. | | `auto-tiles` | boolean | false | Let libaom choose the tile layout. | | `enable-intrabc` | boolean | true | Allow intra block copy, which helps screen content. | ### libheif rav1e plugin parameters | Parameter / aliases | Type or accepted values | Default | Purpose and constraints | | ------------------- | ---------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | `speed` | integer 0–10 | 8 | rav1e speed, 0 is slowest. | | `threads` | integer 1–16 | 4 | Worker threads. | | `tile-rows` | 1, 2, 4, 8, 16, 32, 64 | 4 | Number of tile rows (a count, not the log2 value avifenc uses). | | `tile-cols` | 1, 2, 4, 8, 16, 32, 64 | 4 | Number of tile columns (a count, not log2). | | `chroma` | 420, 422 or 444 | 420 | Chroma subsampling. | | `min-q` | integer 0–255 | 0 | Lowest quantizer rav1e may use. | | `quality` | integer 0–100, -q only | 50 (set by heif-enc) | Set with heif-enc -q and mapped to a 0–255 quantizer. Not in the parameter list, so -p quality= is rejected. | | `lossless` | not settable | unsupported | No lossless mode: -L falls back to lossy with a warning, and -p lossless= is rejected. | ### libheif SVT-AV1 plugin parameters | Parameter / aliases | Type or accepted values | Default | Purpose and constraints | | ------------------- | --------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------- | | `speed` | integer 0–13 | 12 | SVT-AV1 preset. Lower is slower and smaller. | | `threads` | integer 1–16 | 4 | Thread hint, not a guaranteed worker count. | | `tile-rows` | 1, 2, 4, 8, 16, 32, 64 | 4 | Number of tile rows. | | `tile-cols` | 1, 2, 4, 8, 16, 32, 64 | 4 | Number of tile columns. | | `quality` | integer 0–100 | 50 | Quality, converted to a QP unless qp is set. | | `lossless` | boolean, SVT ≥3 | false | Lossless coding, SVT-AV1 3 or newer. heif-enc -L on RGB input (PNG, JPEG) exits with 'Unsupported encoder parameter' because it also sets chroma=444, which this plugin lacks. | | `qp` | integer 0–63 | unset: derived from quality | Quantizer. Overrides quality when set. | | `min-q` | integer 0–63 | 0 | Lowest quantizer SVT-AV1 may use. | | `max-q` | integer 0–63 | 63 | Highest quantizer SVT-AV1 may use. | | `tune` | vq, psnr, ssim, iq, ms-ssim | psnr | SVT-AV1 tune: vq, psnr, ssim, iq, ms-ssim. iq and ms-ssim need SVT-AV1 4 or newer. | | `chroma` | fixed 420 | 420 | Not a parameter: the plugin always encodes YCbCr 4:2:0, and -p chroma= is rejected. | --- # GIF Canonical URL: https://encode.wiki/codecs/images/gif/ Collection: docs Status: current License: CC BY-SA 4.0 Checksum: fa89d1006799b36de31293503e09d0f277124101b15a6c274cd16320d8ff3f92 GIF (CompuServe, 1987) is an indexed-colour format with LZW compression: at most 256 colours per frame, one fully transparent colour at most, no partial alpha. It survives because every chat app, forum and browser plays it without asking. Compression is poor by modern standards, so GIFs of video-like content are many times larger than the same clip as video, animated [WebP](/codecs/images/webp/), animated [AVIF](/codecs/images/avif/) or [APNG](/codecs/images/png/). | Property | Value | | ------------ | -------------------------------------------------------------------- | | Compression | Lossless LZW of palette indices (making the palette is the lossy step) | | Colours | 256 per frame (a global table plus optional per-frame tables) | | Transparency | One fully transparent palette index, no partial alpha | | Animation | Yes, frame delays in hundredths of a second, loop count | | Royalty-free | Yes | ## When to use it - Short loops that must work in apps that accept nothing else: chat, forums, issue trackers, email. - Small flat-colour animations, pixel art and UI demos with few colours and little motion. - **Don't use it for screen recordings or clips of film or games** if you control the page. A muted, looping `