Skip to main content

Crate vtome

Crate vtome 

Source
Expand description

Show an image or a video on a specific monitor — or on a specific quadrilateral of one — without FFmpeg and without a codec anyone charges for.

file.mp4 ──demux──▶ H.264 ──platform decode──▶ ┌─────────┐ ──▶ GPU ──▶ corner-pinned quad
                                               │  Frame  │            on monitor 2
file.webm ─demux──▶ AV1 ──────software────────▶ │ (YUV +  │
                                               │  colour)│ ──▶ AV1 out (transcode)
image.png ──────────────image─────────────────▶└─────────┘

§What this is for

Putting a picture where you want it: on the second monitor, in a rectangle of the third, or into four arbitrary corners because the projector is not square to the wall. geometry::Quad is that last one, and it is perspective-correct — see its documentation for why the obvious implementation leaves a crease down the diagonal.

Audio is deliberately absent. atome is the audio engine; a player here slaves its clock to one (see clock) rather than opening a device.

§Royalty-free, which is a design constraint rather than a preference

vtome writes AV1 and VP9, both AOMedia/Google royalty-free. It never writes H.264 or HEVC. It reads them through the decoder the operating system already ships and already licensed — VideoToolbox, Media Foundation, MediaCodec, VA-API — which is also the fastest path, since those are the hardware decoders. identify::Encoding::is_royalty_free is the same rule in code.

§Everything heavy is optional

A build that only decodes frames and hands them to somebody else’s renderer must not compile a windowing library, a GPU abstraction, or a C toolchain.

FeatureWhat it adds
demuxMP4 and Matroska/WebM parsing (pure Rust)
imageStill images
renderGPU presentation via wgpu — a surface, not a window
windowrender plus winit, so vtome opens its own windows
embedrender against a surface someone else owns — the Tauri path
decode-*One decoder backend each
encode-av1, mux, transcodeWriting AV1 into WebM

§A first look

use vtome::{identify, Placement, MonitorSelector};

// What is this file, really? The extension is a claim; the bytes are not.
let container = identify::identify_path("clip.mp4")?;
println!("{container}");

// Second monitor, top-left quarter of it.
let placement = Placement::new(MonitorSelector::Index(1))
    .area(vtome::geometry::Rect::from_size(960.0, 540.0));

Re-exports§

pub use clock::Clock;
pub use clock::MasterClock;
pub use clock::Pacing;
pub use color::ColorSpace;
pub use decode::Decoder;
pub use frame::Frame;
pub use frame::FramePool;
pub use frame::PixelFormat;
pub use geometry::Fit;
pub use geometry::Point;
pub use geometry::Quad;
pub use geometry::Rect;
pub use identify::identify_bytes;
pub use identify::identify_path;
pub use identify::Container;
pub use identify::Encoding;
pub use media::MediaInfo;
pub use media::Packet;
pub use media::TrackInfo;
pub use media::TrackKind;
pub use placement::Monitor;
pub use placement::MonitorSelector;
pub use placement::Placement;
pub use placement::ResolvedPlacement;
pub use demux::open as open_media;
pub use demux::Demuxer;
pub use still::load_image;

Modules§

bitstream
Length-prefixed and start-code bitstreams, and the conversion between them.
clock
When to show a frame, and what to do when it is late.
color
Colour metadata, and the matrix that turns YUV into RGB.
decode
Turning compressed packets into pictures.
demux
Taking a container apart, without decoding anything inside it.
frame
One decoded picture, and the pool that stops decoding from allocating.
geometry
Rectangles, quadrilaterals, and the projective map between them.
identify
What a file is, read from its first bytes rather than its name.
media
What a file contains, and the compressed pieces that come out of it.
placement
Which monitor, and where on it.
still
Still images, down the same pipe as video.

Enums§

Error
What went wrong.

Type Aliases§

Result
Result with this crate’s error type.