# Encode Wiki documentation corpus
Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf
# Codecs
Canonical URL: https://encode.wiki/codecs/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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/
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 `