Skip to main content

Crate mediatime

Crate mediatime 

Source
Expand description

mediatime

Exact-integer rational time types for media pipelines — FFmpeg-style Timebase, Timestamp, and TimeRange for Rust. no_std by default, zero dependencies, const fn throughout.

github LoC Build codecov

docs.rs crates.io crates.io license

§Overview

mediatime provides the same three primitives every media pipeline reinvents, done once with integer-exact semantics:

  • Timebase — a rational num/den (both u32, non-zero denominator). Directly mirrors FFmpeg’s AVRational. Common values: 1/1000 (ms PTS), 1/90000 (MPEG-TS), 30000/1001 (NTSC frame rate).
  • Timestamp — an i64 PTS tagged with a Timebase. Two timestamps compare by the instant they represent, not by their raw (pts, timebase) tuple, so Timestamp(1_000, 1/1000) equals Timestamp(90_000, 1/90_000). Cross-timebase comparison uses a 128-bit cross-multiply — no division, no rounding.
  • TimeRange — a half-open [start, end) interval sharing a single Timebase. Carries the endpoints as raw PTS; returns Timestamp on demand.

Everything is const fn. The crate only uses core — no allocation, no dependencies. Use it as the time layer for scene detectors, demuxers, NLE timelines, or anywhere you’d otherwise pass f64 seconds around and pay for rounding drift later.

§Why not f64 seconds?

Floating-point seconds accumulate drift: 0.1 + 0.2 != 0.3. Real video timestamps are already integer PTS in an integer timebase — converting to f64 for arithmetic only to convert back on output introduces rounding error. mediatime keeps the representation that the stream actually carries, and does exact rational arithmetic on it.

Equality semantics show the win:

f64 seconds:              0.1 + 0.2 == 0.3       → false
mediatime::Timestamp:     100 ms    == 9000 ticks @ 1/90000 → true

§Features

  • Value-based equality and ordering. 1/2 == 2/4 == 3/6; Timestamp(1000, 1/1000) == Timestamp(90_000, 1/90_000). Cross-timebase cmp uses 128-bit cross-multiply — exact for any u32 numerator/denominator with any i64 PTS.
  • Hash agrees with Eq. Hashes the reduced-form rational, so equal rationals hash identically and you can use these types as HashMap keys.
  • FFmpeg-style utilities. rescale_pts (a.k.a. av_rescale_q), frames_to_duration, duration_to_pts, duration_since, saturating_sub_duration.
  • TimeRange interpolation. Linear midpoint (interpolate(t)) for placing an event somewhere between fade-out and fade-in frames, with t ∈ [0, 1] clamped.
  • no_std + no_alloc library. The library builds without std and alloc; tests use std.
  • const fn throughout. Build Timebase / Timestamp / TimeRange in const context.

§Example

use core::num::NonZeroU32;
use core::time::Duration;
use mediatime::{Timebase, Timestamp, TimeRange};

// FFmpeg-style rational timebases.
let ms     = Timebase::new(1, NonZeroU32::new(1000).unwrap());
let mpegts = Timebase::new(1, NonZeroU32::new(90_000).unwrap());

// Same instant in two different timebases — they compare equal.
let a = Timestamp::new(1_000, ms);
let b = Timestamp::new(90_000, mpegts);
assert_eq!(a, b);
assert_eq!(a.duration_since(&b), Some(Duration::ZERO));

// `av_rescale_q`-style conversion, rounding toward zero.
assert_eq!(ms.rescale(500, mpegts), 45_000);

// Frame rate helpers — treat `Timebase` as fps and count frames.
let ntsc = Timebase::new(30_000, NonZeroU32::new(1001).unwrap());
assert_eq!(ntsc.frames_to_duration(30_000), Duration::from_secs(1001));

// A half-open [start, end) range with interpolation.
let r = TimeRange::new(100, 500, ms);
assert_eq!(r.interpolate(0.5).pts(), 300);
assert_eq!(r.duration(), Some(Duration::from_millis(400)));

§Installation

[dependencies]
mediatime = "0.1"

§MSRV

Rust 1.85.

§License

mediatime 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.

Structs§

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