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)│ ──▶ H.264 (OS) or AV1 out (import)
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; every clip here follows one engine timeline, which with Audio::atome is atome’s output clock (see clock) — vtome never opens a device.

§Nothing patent-pooled is ever bundled

vtome reads H.264 and AV1, and writes them: H.264 by default, but only ever through the operating system’s own codec — VideoToolbox today — whose vendor already holds the licence; AV1 through the bundled, royalty-free rav1e, wherever the OS has no H.264 encoder or when asked. HEVC and VP9 are out of scope. import writes a proxy at the output path first and the full-quality file through a queue — see planning/TODO.md §14 and §15.

§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-platform, encode-av1, muxH.264 through the OS into MP4, AV1 through rav1e into WebM
transcode (= import)[transcode] and the import queue; rav1e always comes with it
atome, split-audioVideo following atome’s clock; a film’s audio to FLAC on import

§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::Follower;
pub use clock::MasterClock;
pub use clock::Monotonic;
pub use clock::Pacing;
pub use clock::SharedClock;
pub use color::ColorSpace;
pub use compositor::Compositor;
pub use compositor::CompositorStats;
pub use decode::Decoder;
pub use decode::Hardware;
pub use encode::Encoder;
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 output::Output;
pub use output_layer::OutputLayer;
pub use placement::Monitor;
pub use placement::MonitorSelector;
pub use placement::Placement;
pub use placement::ResolvedPlacement;
pub use plugin::Plugin;
pub use player::Player;
pub use video_source::cache_frames;
pub use video_source::FrameCache;
pub use video_source::VideoSource;
pub use demux::open as open_media;
pub use demux::open_reader as open_media_reader;
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.
compositor
Compositor — sources, and the outputs that show them in layers.
decode
Turning compressed packets into pictures.
demux
Taking a container apart, without decoding anything inside it.
encode
Turning pictures into packets: H.264 through the operating system, AV1 through the bundled rav1e.
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.
output
Output scenes — composition targets with multiple layers and backgrounds.
output_layer
Output layers — video sources positioned and sized within an output.
placement
Which monitor, and where on it.
player
Player — simple wrapper for single-source playback to a single output.
plugin
Video frame plugins for effects and transformations.
scale
Moving pictures between layouts and sizes on the CPU — the small pure-Rust scaler a transcode needs where there is no FFmpeg to lean on.
still
Still images, down the same pipe as video.
video_source
Video sources — input files with demuxing, decoding, and frame queuing.

Enums§

Error
What went wrong.

Traits§

ReadSeek
A seekable byte source that can move to another thread — a file, a Cursor, an entry of an archive. What media is opened from when it is not a file of its own: open_media_reader, [Clip::video_reader].

Type Aliases§

Result
Result with this crate’s error type.