COOLJAPAN
← All posts

OxiMedia 0.2.1 Released — Honest Loudness Metering, Pure-Rust Camera Capture, and Bit-Exact VP8/VP9 Inter-Frame Decode

OxiMedia 0.2.1 fixes a ±35 dB K-weighting bug in its EBU R128 loudness stack, ships a new Pure-Rust oximedia-capture crate for AVFoundation/V4L2/Media Foundation camera input, and brings VP8/VP9 to bit-exact inter-frame decode against libvpx — plus a full RFC 9639 FLAC rebuild. The sovereign media layer for the COOLJAPAN ecosystem.

release oximedia ffmpeg opencv vp9 vp8 flac loudness camera-capture pure-rust

A loudness meter that’s quietly wrong by 3 decibels is worse than no meter at all — it tells you the audio passed when it didn’t. OxiMedia 0.2.1 goes looking for exactly that kind of bug, in its own code, and fixes what it finds.

Today we released OxiMedia 0.2.1 — a release built on four things: an EBU R128 / K-weighting loudness stack that was measurably wrong and is now standards-accurate, a new Pure-Rust oximedia-capture crate that brings live camera and device input into the framework without linking a single C library, VP8 and VP9 decoders that now handle inter frames bit-exactly instead of just key frames, and a workspace-wide sweep that took nine crates from fabricated success to real work or an honest error.

No C. No C++. No Fortran. That held for the decode/transcode core since 0.1.9, and 0.2.1 extends it to the one place a “sovereign” media framework usually cheats: camera input. oximedia-capture talks to AVFoundation on macOS through objc2, to Video4Linux2 on Linux through raw rustix syscalls, and to Media Foundation on Windows through windows-rs COM calls — zero -sys crates, zero compiled C, on any of the three. It still compiles to one static binary (or to wasm32-unknown-unknown for the browser) and installs with one cargo add.

Why OxiMedia 0.2.1 is a game changer

Loudness measurement, camera capture, and inter-frame video decode are three places where media tooling quietly cuts corners:

OxiMedia 0.2.1 ends all four.

Technical Deep Dive: how the loudness, capture, and codec work fit together

  1. Loudness layer — oximedia-metering and oximedia-audio. ebu_r128_impl.rs and filters.rs now carry the exact ITU-R BS.1770-4 Table 1 biquad coefficients at 48 kHz and correct bilinear-transform designs at every other rate; complete_hop sums per-channel weighted power instead of averaging it; true_peak_dbtp() returns the maximum across every channel’s 4×-oversampled detector, not just channel 0. New conformance tests pin the chain magnitude to within 0.1 dB at 100 Hz, 997 Hz, and 4 kHz.
  2. Capture layer — the new oximedia-capture crate. Three platform backends behind one enumerate()/open() entry point, delivering raw pixel formats or an untouched MJPEG bitstream only — never a decode of an encumbered codec. New PixelFormat::{Yuyv422, Uyvy422} back the two most common UVC/AVFoundation raw formats end to end, from bits_per_pixel through frame_buffer_size.
  3. Codec layer — oximedia-codec’s vp8/dec/ and vp9/dec/. VP8’s near-MV survey (NEAREST/NEAR/ZERO/NEWMV, SPLITMV sub-partitioning), six-tap and bilinear sub-pixel motion compensation, and sequential last/golden/altref reference updates; VP9’s persistent cross-frame state (four probability contexts, an eight-slot MI-aligned reference DPB), vpx_convolve8 motion compensation, and find_mv_refs with sign-bias flipping — every function a cited port of libvpx v1.15.2, diff-verified against a fresh fetch of the tagged upstream before use. Five hollow VP9 modules (~4,800 lines) that had zero real consumers were deleted in the same pass.
  4. The honesty sweep, crate by crate. oximedia-videoip’s dummy encoders/decoders and oximedia-mam’s fake cloud backends were deleted outright rather than patched; oximedia-server’s CdnUploader::new() — which produced an uploader with an empty bucket and a worker that silently dropped every packet — is gone, replaced by CdnUploader::with_config(...), which fails fast instead.

Getting Started

cargo add oximedia

or pin the version and pick features in Cargo.toml:

[dependencies]
oximedia = { version = "0.2.1", features = ["full"] }

Measure loudness the standards-accurate way — straight from the crate’s own conformance tests:

use oximedia::prelude::*;

// Probe a media file
let data = std::fs::read("video.webm")?;
let result = probe_format(&data)?;
println!("Format: {:?}, Confidence: {:.1}%",
    result.format, result.confidence * 100.0);

// Transcode with quality control
let pipeline = TranscodePipeline::builder()
    .input("input.mkv")
    .video_codec(VideoCodec::Vp9)
    .audio_codec(AudioCodec::Flac)
    .output("output.webm")
    .build()?;

pipeline.run().await?;

Or open a camera with the new capture crate directly:

use oximedia_capture::{CaptureConfig, CaptureEncoding, DeviceSelector};
use oximedia_core::PixelFormat;

fn main() -> Result<(), oximedia_capture::CaptureError> {
    let devices = oximedia_capture::enumerate()?;
    let Some(device) = devices.first() else {
        eprintln!("no capture device found");
        return Ok(());
    };

    let config = CaptureConfig::default()
        .with_device(DeviceSelector::Id(device.id.clone()))
        .with_size(1280, 720)
        .with_fps(30.0)
        .with_preferred([CaptureEncoding::Raw(PixelFormat::Nv12)]);
    let mut session = oximedia_capture::open(config)?;

    if let Some(mut stream) = session.take_stream() {
        while let Ok(Some(frame)) = stream.recv() {
            println!("frame {} at {:?}", frame.sequence, frame.timestamp);
        }
    }
    Ok(())
}

What’s New in 0.2.1

Tips

This is the foundation

OxiMedia is the pure-Rust media and computer-vision layer of the COOLJAPAN ecosystem, leaning on its siblings directly:

Repository: https://github.com/cool-japan/oximedia

Star the repo if you think a loudness meter that’s wrong by 3 decibels is a worse failure mode than a codec that refuses to run at all — and that a media framework should go looking for both kinds of bug in its own code before anyone else finds them.

The era of media tooling that measures loudness approximately, captures video through a C shim, and calls a key-frame-only decoder “done” is over. Pure Rust media is here — bit-exact where it counts, standards-accurate where it’s measured, and honest everywhere else.

KitaSan at COOLJAPAN OÜ August 13, 2026

↑ Back to all posts