Skip to content

Findit-AI/mediatime

Repository files navigation

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.

About

Common Rust types for media file processing.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

Generated from al8n/template-rs