rusty_mp3
A complete MP3 (MPEG-1, MPEG-2 and MPEG-2.5 Audio Layer III) decoder and encoder in pure Rust. No C, no FFI, and no runtime dependencies.
- Conformant. The decoder passes all 16 ISO 11172-4 / 13818-4 Layer III conformance vectors and matches FFmpeg bit for bit on a 678-stream corpus.
- Complete. Encoding covers CBR (8–320 kbps) and VBR, mono, stereo and joint stereo, a psychoacoustic model, transient block switching, per-band noise shaping, the bit reservoir, and Xing/Info headers.
- Fast. On one x86-64 core, decoding runs at about 800× real time and encoding at about 120× real time. The decoder is faster than FFmpeg's.
- Safe. The only
unsafecode is explicit SIMD, each kernel paired with a safe scalar reference that produces identical output. The crate is fuzzed, and its tests pass under Miri and the Address, Thread and Memory sanitizers. - Portable. It builds for every Rust target. It uses AVX on x86-64 and NEON on AArch64, and WebAssembly builds produce bit-identical output to native.
MP3's patents expired in 2017, so the format is royalty-free worldwide.
Installation
[]
= "1"
Decoding
use ;
Mp3Decoder is a streaming decoder. Push bytes as they arrive and pull frames
as they become available. Each frame reports its sample rate and channel count.
For a complete in-memory file, decode_pipelined runs the entropy and transform
stages on two threads. Its output is identical to the streaming decoder's.
Encoding
use ;
PCM can be pushed as f32 or i16 slices, or directly as little-endian bytes
with push_pcm_f32le / push_pcm_s16le, the layout of a WAV data chunk.
The encoder converts its input in one pass and buffers at most one frame,
however much audio each call delivers.
API overview
| Type / function | Purpose |
|---|---|
Mp3Decoder |
Streaming decoder: push, next_frame, flush |
decode_pipelined |
Two-thread decode of a complete byte slice |
Mp3Encoder, Mp3EncoderConfig |
Streaming encoder: push_pcm_*, next_packet, finish |
vbr_quality_index |
Maps an FFmpeg/LAME-style -q:a value (0 = best, 9 = smallest) to a VBR target |
Error |
Typed errors; Again and Eof follow FFmpeg's drain protocol |
header, decode, encode |
Frame-level building blocks: header parsing, per-frame decode and encode |
Conformance and quality
Decoder. All 16 Layer III vectors from ISO/IEC 11172-4 and 13818-4 pass, including mixed blocks and both forms of intensity stereo. On a 678-stream corpus (streams from three encoders across nine sample rates, mono and stereo, CBR and VBR) the output matches FFmpeg bit for bit. There is one deliberate divergence: for MPEG-2 intensity stereo at positions FFmpeg does not implement, rusty_mp3 follows the standard and the ISO reference output.
Encoder. Perceptual quality, measured with PEAQ against LAME at the same bitrate (ODG difference; positive means LAME scores higher). The clips are three 24-second CC0 music recordings, 44.1 kHz mono:
| Clip | 96 kbps | 128 kbps | 160 kbps | 192 kbps |
|---|---|---|---|---|
| Guitar | +0.054 | +0.020 | −0.034 | +0.030 |
| Piano | +0.564 | +0.322 | +0.134 | +0.096 |
| Vocal | +0.295 | +0.334 | +0.174 | +0.125 |
| Mean | +0.304 | +0.225 | +0.091 | +0.084 |
At 160 kbps and above, rusty_mp3 is within about 0.1 ODG of LAME, and it is ahead on the guitar clip at 160 kbps. The regeneration command and the full methodology are in the development history.
Performance
Measured on one desktop x86-64 core with AVX, using a 412.9-second 44.1 kHz stereo track:
| Operation | Time | Speed |
|---|---|---|
| Decode (192 kbps CBR) | 0.50 s | ~830× real time |
| Encode (192 kbps CBR) | 3.4 s | ~120× real time |
Against FFmpeg's native decoder (a 27.5-minute stream, both sides discarding their output, pinned to the same cores, 15 paired runs):
| Cores | rusty_mp3 | FFmpeg | Result |
|---|---|---|---|
| 1 | 1,952 ms | 2,431 ms | rusty_mp3 1.24× faster |
2 (decode_pipelined) |
1,017 ms | 1,455 ms | rusty_mp3 1.39× faster |
Those figures predate later decoder optimizations, so current releases are at least as fast.
Platform support
| Target | Kernels | Status |
|---|---|---|
| x86-64 | AVX (runtime-detected), portable fallback | Primary; all measurements above |
| AArch64 | NEON | Bit-identical to the portable path (verified under emulation) |
WebAssembly (wasm32-unknown-unknown, wasm32-wasip1) |
Portable | Bit-identical to native, with no host imports |
| Any other Rust target | Portable | Supported |
Setting MP3_ISA=scalar in the environment forces the portable kernels, for
A/B testing.
Security
The decoder treats every input byte as hostile, and a panic on malformed input is treated as a bug.
- Threat model: assets, adversaries, entry points, and a STRIDE analysis.
UNSAFE.md: everyunsafeblock and the bounds argument for each.- Hardening audit: gate-by-gate status, summarized at the end of this page.
- Continuous fuzzing of the decoder, the frame-level decoder and the encoder.
The supply chain is checked with
cargo audit,cargo denyandcargo vet; the crate has no runtime dependencies. - Report vulnerabilities privately; see
SECURITY.md.
Compatibility
- Minimum supported Rust version: 1.85 for the library. The test suite and examples need Rust 1.88 or later, because of a development dependency.
- Semantic versioning. The 1.x public API is stable. Decoder output is bit-exact and stable across releases. Encoder output may change in minor releases when encoding quality improves; such changes are noted in the changelog.
Not supported: free-format bitrate streams (the decoder rejects them) and MPEG Layers I and II. The encoder does not produce intensity stereo or mixed blocks. It uses the bit reservoir for MPEG-1 CBR up to 256 kbps, and a fixed per-frame budget elsewhere.
Part of Remade With Rust
This crate is the MP3 engine of
remade_ffmpeg_rs, a
ground-up, permissively licensed Rust rebuild of FFmpeg: a drop-in
ffmpeg/ffprobe CLI on pure-Rust codecs, with no copyleft. Related crates
include rusty_h264,
rusty_h265,
rusty_vp9,
rusty_aac,
rusty_flac and
rusty-opus. See also
FFAI, media for an AI-first world.
About Mata Network
Mata Network builds sovereign, self-hostable infrastructure. Remade With Rust is our open-source home for the permissively-licensed building blocks that work depends on.
License
Apache-2.0. See the workspace LICENSE.
Hardening status
Tier critical-path · Audited 2026-10-04 (deep) · v1.0.0 gates 13/15 · Full checklist
█████████████████░░░ 88% · 30 Completed · 0 Scheduled · 4 Incomplete · 21 N/A
| Phase | ✅ Completed | 🗓 Scheduled | ⬜ Incomplete | · N/A |
|---|---|---|---|---|
| 0 — Threat modeling | 2 | 0 | 0 | 0 |
| 1 — Toolchain | 3 | 0 | 1 | 0 |
| 2 — Supply chain | 8 | 0 | 0 | 0 |
| 3 — Code level | 6 | 0 | 0 | 1 |
| 4 — Static analysis | 1 | 0 | 0 | 0 |
| 5 — Dynamic analysis | 3 | 0 | 0 | 0 |
| 6 — Fuzzing and properties | 3 | 0 | 1 | 0 |
| 7 — Formal verification | 0 | 0 | 1 | 0 |
| 8 — Build and binary | 0 | 0 | 0 | 2 |
| 9 — Runtime privilege | 0 | 0 | 0 | 1 |
| 10 — Cryptography | 0 | 0 | 0 | 3 |
| 11 — CI/CD, release, and operations | 4 | 0 | 1 | 0 |
| 12 — Compliance controls | 0 | 0 | 0 | 14 |
| Total | 30 | 0 | 4 | 21 |
Architect — Tim Almond