Multimedia and computer vision, reconstructed in one pure-Rust framework — and as of today, the royalty-free codecs are real, end to end.
Today we released OxiMedia 0.1.4 — a focused codec-and-container release that turns MJPEG and APV from mere codec IDs into fully wired encoders, decoders, and muxers, while adding OpenDML AVI, animated JPEG-XL, and low-latency CMAF streaming to the pipeline.
No C. No C++. No FFmpeg binaries. No OpenCV. No libavcodec to link, no swscale to patch, no system packages to chase across platforms. OxiMedia is a single static binary — or a WASM module — that carries its own codecs, containers, filters, and vision routines. Every codec we ship is royalty-free by design, and the entire stack is written in safe Rust with zero unsafe in the core paths. Your media pipeline becomes one artifact you can drop anywhere.
Why OxiMedia 0.1.4 is a game changer
Anyone who has shipped a media pipeline knows the FFmpeg/OpenCV tax: pinning the right libav* ABI, rebuilding when a distro bumps a shared library, juggling -sys crates that wrap C that wraps assembly, and discovering at runtime that a “supported” codec was compiled out. Patent-encumbered codecs add a legal tax on top of the engineering one.
OxiMedia 0.1.4 attacks that head-on with concrete wins:
- MJPEG and APV are now real, end-to-end codecs — not just identifiers in a table. Both have a working encoder, decoder, and container plumbing, so you can mux them into MP4/MOV and Matroska and transcode straight to them.
- OpenDML AVI handles captures larger than 1 GB. The AVI v3 / OpenDML path lifts the classic 1 GB RIFF ceiling, so long ingest files just work.
- Low-latency CMAF lets you stream with sub-second chunks. The CMAF-LL chunked DASH emitter is built for live delivery where latency matters.
- More real FFmpeg command lines just work. The compat layer now understands
-crf,-b:v,-maxrate,-bufsize,-vf,-af, and two-pass (-pass 1/-pass 2), so existing scripts translate instead of breaking.
And a correctness milestone worth calling out: the JPEG encoder fix in this release lifts the MJPEG round-trip PSNR from 6.16 dB to 32.53 dB at Q85. The DQT table is now serialized in zigzag order per the JPEG spec, the EOB marker is emitted only when a trailing-zero AC run actually exists, and the dequantization ordering is corrected — turning a visibly broken round-trip into a clean one.
Technical Deep Dive
Codec wiring across the stack. The MJPEG and APV work threads cleanly through oximedia-codec (encoder/decoder), the container crates, and oximedia-transcode (dispatch). FourCC routing is explicit: jpeg and apv1 sample entries in MP4/MOV, V_MJPEG for MJPEG in Matroska, and V_MS/VFW/FOURCC with a BITMAPINFOHEADER CodecPrivate for APV. The proxy codec in oximedia-multicam and the compat-ffmpeg pass-through both recognize these royalty-free codecs now, and the MP4 muxer validation accepts them rather than rejecting them.
Typed codec identity in the core. oximedia-core gains a FourCc struct with 31 predefined constants and a CodecId::FromStr implementation covering 24 aliases plus canonical_name(). That means string-to-codec resolution (the kind FFmpeg command lines rely on) is now a typed, centralized operation instead of scattered matching.
Container breadth. Beyond AVI OpenDML, this release adds an AJXL ISOBMFF animated container — AnimatedJxlEncoder::finish_isobmff() emits a spec-conformant ftyp + jxll + jxlp* box chain per ISO/IEC 18181-2 — plus a memory-bounded streaming decoder, JxlStreamingDecoder<R: Read>: Iterator<Item = CodecResult<JxlFrame>>, that auto-detects ISOBMFF vs the OxiMedia native format and keeps one frame in flight. The MP4 muxer gains a Mp4FragmentMode enum (Progressive/Fragmented) and AV1 av1C config emission, and the Matroska demuxer gains seek_sample_accurate().
Streaming and WASM. A DASH MPD manifest emitter and the CMAF-LL chunked emitter share a cross-format seek_sample_accurate() trait. Meanwhile, WASM32 support is hardened across several crates: mio, tokio, tonic, and rusqlite dependencies are target-gated, GPU/graphics accelerators are Send + Sync cfg-gated for WASM, and oximedia-batch, oximedia-convert, oximedia-colormgmt, oximedia-workflow, and oximedia-farm all pass cargo check --target wasm32-unknown-unknown cleanly.
This release lands at 108 crates (107 stable), roughly 2,670,000 lines of Rust, 81,150+ tests passing, zero clippy warnings, Apache-2.0, MSRV Rust 1.85+.
Getting Started
Add OxiMedia and transcode to a royalty-free intra codec in two lines:
# Add the crate
cargo add oximedia
# Transcode to MJPEG (royalty-free, intra-only)
cargo run --bin oximedia -- transcode -i input.mkv -o output.mkv --codec mjpeg
# APV is also a valid target now:
cargo run --bin oximedia -- transcode -i input.mkv -o output.mkv --codec apv
# The AV1 path is unchanged:
cargo run --bin oximedia -- transcode -i input.mkv -o output.webm --codec av1
From the library, build a pipeline and pick the new codec variant:
use oximedia::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
let pipeline = TranscodePipeline::builder()
.input("input.mkv")
.video_codec(VideoCodec::Mjpeg) // or VideoCodec::Apv
.output("output.mkv")
.build()?;
pipeline.run().await?;
Ok(())
}
What’s New in 0.1.4
- MJPEG end-to-end wiring — encoder, decoder, MP4/MOV
jpegsample entry, MatroskaV_MJPEG, proxy-codec integration, and transcode dispatch. - APV end-to-end wiring — Advanced Professional Video (royalty-free): encoder, decoder, MP4
apv1sample entry, MatroskaV_MS/VFW/FOURCCwith BITMAPINFOHEADER CodecPrivate, compat-ffmpeg pass-through, and transcode dispatch. - AVI container (Wave 3) — AVI v3 / OpenDML support for files over 1 GB, PCM audio muxing, H264/RGB24 codec arms in the RIFF-AVI muxer and demuxer, with
hdrl+movi+idx1index. - Animated JPEG-XL container —
finish_isobmff()emits a spec-conformantftyp+jxll+jxlp*chain (ISO/IEC 18181-2) via a shared ISOBMFF helper module. - AJXL streaming decoder —
JxlStreamingDecoder<R: Read>with ISOBMFF/native auto-detection, lazyjxlpparsing, and one-frame-in-flight memory bounding. - FourCc + CodecId::FromStr — 24-alias
FromStrandcanonical_name()for every codec ID, plus aFourCcstruct with 31 predefined constants inoximedia-core. - CLI MJPEG/APV support —
VideoCodec::{Mjpeg, Apv}withis_intra_only(),default_crf(), andvalidate_crf(), plus an intra-codec fast path inTranscodePipeline. - WASM32 gating —
mio/tokio/tonic/rusqlitetarget-gated, GPU/graphics acceleratorsSend + Synccfg-gated, and several more crates checking clean underwasm32-unknown-unknown. - MP4 muxer fragment modes (Wave 3) —
Mp4FragmentMode(Progressive/Fragmented), AV1av1Cconfig emission, and MJPEG/APV sample-entry arms. - Matroska enhancements —
seek_sample_accurate()in the demuxer,preroll_samples/padding_samplesin the MP4elstbox, andBlockAdditionMappingin the MKV muxer. - DASH/CMAF streaming — a DASH MPD manifest emitter and a CMAF-LL chunked DASH emitter for low-latency delivery, behind a cross-format
seek_sample_accurate()trait. - FFmpeg compat extensions (Wave 3) —
-filter_complexgraph parser, FFmpeg stream specifiers, duration parsing, and anffprobe-style output struct. - FFmpeg compat quality flags (Wave 4) —
OnceLock-cached codec map,-crf/-b:v/-maxrate/-bufsizetranslated toEncoderQuality,-vf/-affilter-chain parsing, and two-pass encoding. - Dolby Atmos channel layouts (Wave 4) — 7.1.2, 5.1.4, 7.1.4, 9.1.6, and binaural variants in
oximedia-core. - Color metadata types (Wave 4) —
ColorPrimaries,TransferCharacteristics,MatrixCoefficientsenums and aColorMetadatastruct. - Timestamp arithmetic (Wave 4) — Add/Sub/Mul/Div operator impls on
Timestamp. - JPEG encoder PSNR fix — zigzag DQT serialization, conditional EOB emission, and corrected dequantization lift MJPEG round-trip PSNR from 6.16 dB to 32.53 dB at Q85; Matroska MJPEG/APV codec IDs and MP4 codec validation corrected too.
- Docs and cleanup — a documentation sweep across many crates with 20 TODO markers resolved.
Tips
- Choose MJPEG or APV for intra-only editing and proxy workflows. Every frame is independently decodable, which is exactly what scrubbing-heavy editorial and multicam proxies want — check
is_intra_only()and start fromdefault_crf()when wiring quality. - Use OpenDML AVI for large ingest. If your capture files cross the 1 GB RIFF boundary, the AVI v3 / OpenDML path handles them without splitting.
- Reach for CMAF-LL when latency matters. For live and near-live delivery, the CMAF-LL chunked DASH emitter is built for sub-second chunking.
- Bring your existing FFmpeg scripts. Command lines using
-crf,-b:v,-maxrate,-bufsize,-vf,-af, and two-pass (-pass 1/-pass 2) now translate through the compat layer. - Target WASM with confidence. The newly gated crates —
oximedia-batch,oximedia-convert,oximedia-colormgmt,oximedia-workflow,oximedia-farm— check clean underwasm32-unknown-unknown, so browser and edge targets build without surprises. - Resolve codecs from strings the typed way. Use
CodecId::FromStrandcanonical_name()instead of hand-rolled matching when you accept codec names from config or the command line.
Part of the COOLJAPAN ecosystem
OxiMedia stands on pure-Rust COOLJAPAN foundations: it builds on SciRS2 (scirs2-core) for tensor and signal math under its codecs and filters, and on OxiARC (oxiarc-archive) for pure-Rust compression — no C compression libraries linked anywhere. It is one piece of the broader COOLJAPAN effort to rebuild the systems stack in safe, sovereign Rust.
Repository: https://github.com/cool-japan/oximedia
Star the repo if you want a media and vision stack with no C dependencies, no patent traps, and no system packages to chase. Pure Rust media and computer vision is here — fast, safe, and sovereign.
— KitaSan at COOLJAPAN OÜ April 20, 2026