Skip to main content

Crate mediadecode

Crate mediadecode 

Source
Expand description

mediadecode

Generic, no_std-friendly type-and-trait spine for media decoders.

github LoC Build codecov

docs.rs crates.io crates.io license

The backend-agnostic core of the mediadecode workspace. Defines the unified Packet / Frame types, VideoAdapter / AudioAdapter / SubtitleAdapter traits, and the matching push-style *StreamDecoder traits that concrete decoder backends implement.

This crate ships no decoder code and no FFmpeg dependency. It’s no_std-clean (with optional alloc / std features) and zero heavy deps — downstream crates (colconv, scenesdetect, …) program against this vocabulary regardless of which backend produced the bytes. Adapter implementations live in sibling crates such as mediadecode-ffmpeg.

§What’s in the box

  • Pixel and sample formatsPixelFormat (~270 variants covering every FFmpeg n9.0 AVPixelFormat slug plus cinema-RAW additions; sourced from videoframe and re-exported here so consumers keep their mediadecode::PixelFormat import). Unknown(u32) preserves the raw wire identifier for lossless round-trip via from_u32 / to_u32. H.273-aligned color enums (ColorMatrix, ColorPrimaries, ColorTransfer, ColorRange, ChromaLocation) and BayerPattern for RAW are similarly re-exported from videoframe.
  • Generic packet / frame typesVideoPacket<A, B>, AudioPacket<A, B>, SubtitlePacket<A, B>, VideoFrame<A, B>, AudioFrame<A, B>, SubtitleFrame<A, B> parameterized over an adapter’s per-item extras type A and buffer type B. Plane<B> is the generic plane carrier.
  • Adapter traitsVideoAdapter, AudioAdapter, SubtitleAdapter. A backend implements these on a zero-sized type to fix A and B once for the whole pipeline.
  • Decoder traitsVideoStreamDecoder, AudioStreamDecoder, SubtitleStreamDecoder. Push-style send_packet / receive_frame / send_eof / flush shape; mirrors FFmpeg’s decoder API while staying backend-agnostic.
  • Time primitives — re-exported Timebase / Timestamp / TimeRange from mediatime, so consumers don’t need a separate dep.

§API style

Mirrors the mediatime idioms the rest of the findit-studio workspace uses:

  • All public fields are private; access is via field() getters, consuming with_field(value) builders, and in-place set_field(value) mutators that return &mut Self.
  • const fn everywhere the field type allows.
  • Panicking constructors come with try_* fallible counterparts (empty / try_empty, clone / try_clone, …).
  • Errors via thiserror over the stable core::error::Error, so failures still implement the Error trait under --no-default-features.

§Cargo features

FeatureDefaultEffect
stdyesEnable the standard library and mediatime/default.
allocEnable owning collections (Vec, String) without std.
serdeEvery type below on the wire, plus mediatime.
arbitraryArbitrary impls for fuzzing, same coverage.
quickcheckThe same coverage again, for quickcheck.

The three optional matrices cover the same types, and each type’s wire shape follows what it is:

TypeTierserde wire shape
channel::ChannelLayoutKindanycanonical slug — "5.1", "7.1-wide-back"
channel::AudioChannelOrderKindanycanonical slug — "native", "ambisonic"
channel::AudioChannelSpecallocmap of its accessor names
channel::AudioChannelLayoutallocmap of its accessor names
packet::PacketFlagsanythe raw bits, as a number

A name vocabulary travels as its name: an unrecognised slug is a deserialization error, where an unrecognised u32 code would decode to Unknown / Unspecified and invent a value. A bit set travels as a number, because every bit pattern is meaningful and bits this build has no constant for still have to survive the round trip. A record travels as its fields, each in its own shape.

no_std builds: disable defaults and pick alloc if you need Vec-backed payloads:

[dependencies]
mediadecode = { version = "0.5", default-features = false, features = ["alloc"] }

§Usage

This crate defines the surface; concrete decoding happens in adapter crates. A backend-agnostic consumer programs against the traits:

use mediadecode::{
  decoder::VideoStreamDecoder,
  frame::VideoFrame,
  packet::VideoPacket,
};

fn decode_one<D: VideoStreamDecoder>(
  decoder: &mut D,
  packet: &VideoPacket<
    <D::Adapter as mediadecode::adapter::VideoAdapter>::PacketExtra,
    D::Buffer,
  >,
  dst: &mut VideoFrame<
    <D::Adapter as mediadecode::adapter::VideoAdapter>::PixelFormat,
    <D::Adapter as mediadecode::adapter::VideoAdapter>::FrameExtra,
    D::Buffer,
  >,
) -> Result<(), D::Error> {
  decoder.send_packet(packet)?;
  decoder.receive_frame(dst)
}

For an end-to-end example using the FFmpeg adapter, see mediadecode-ffmpeg.

§Build requirements

  • Rust ≥ 1.95, edition 2024.
  • No system dependencies — mediadecode is FFmpeg-free and builds anywhere Rust does, including no_std targets with optional alloc.

§License

mediadecode is under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE, LICENSE-MIT for details.

Copyright (c) 2026 FinDIT Studio authors.

Modules§

adapter
Adapter traits — the per-kind backend “vocabulary.”
cfa
Color-filter-array (Bayer) descriptions: re-exported from mediaframe::frame (mediaframe 0.2 dropped the cfa module and moved BayerPattern under frame::bayer, re-exported via frame::*).
channel
Audio channel layout types.
color
Color metadata: re-exported from mediaframe::color.
decoder
Decoder traits — push-style streams (FFmpeg / WebCodecs / ProRes RAW via VTDecompressionSession) and pull-style frame sources (R3D / BRAW / ARRIRAW / X-OCN / Canon RAW Light).
frame
Frame types and supporting building blocks.
futurefuture
Async variants of the decoder / frame-source traits — gated behind the future feature.
packet
Compressed Packet types and PacketFlags.
pixel_format
Pixel format identifier: re-exported from mediaframe::pixel_format.
subtitle
Decoded subtitle payload.

Structs§

TimeRange
A half-open time range [start, end) in a given Timebase.
Timebase
A media timebase represented as a rational number: a non-negative numerator over a strictly positive denominator.
Timestamp
A presentation timestamp, expressed as a PTS value in units of an associated Timebase.

Enums§

PixelFormat
Pixel format identifier covering FFmpeg + Bayer + cinema-RAW.