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.
| Feature | What it adds |
|---|---|
demux | MP4 and Matroska/WebM parsing (pure Rust) |
image | Still images |
render | GPU presentation via wgpu — a surface, not a window |
window | render plus winit, so vtome opens its own windows |
embed | render against a surface someone else owns — the Tauri path |
decode-* | One decoder backend each |
encode-av1, mux, transcode | Writing 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.