1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! Native video capture, encoding, and publishing for Media over QUIC.
//!
//! Counterpart to [`moq-audio`](https://crates.io/crates/moq-audio) for video
//! tracks, and shaped the same way: both split into `capture` / `encode` /
//! `decode` role modules over a shared root [`Error`]. Sits on top of [`moq_mux`]
//! (and the `hang` catalog) and adds the native pieces a desktop/CLI publisher
//! needs:
//!
//! - [`capture`] describes a frame source ([`capture::Config`]) and grabs
//! frames per platform: AVFoundation/ScreenCaptureKit on macOS, native V4L2
//! on Linux, native Media Foundation (camera) and DXGI Desktop Duplication
//! (screen) on Windows. [`capture::Source`] picks a camera, a display, or
//! (macOS only) a single window or every window of an application;
//! [`capture::cameras`], [`capture::displays`], [`capture::windows`], and
//! [`capture::apps`] list what's available and hand back the ids it takes.
//! - [`encode`] encodes frames with a native backend and publishes them through
//! the matching `moq_mux::codec` importer, which handles catalog registration
//! and framing. The codec is chosen via [`encode::Codec`]: H.264 (openh264 /
//! VideoToolbox / Media Foundation / NVENC / VAAPI) or H.265 (VideoToolbox /
//! Media Foundation / NVENC). Two entry points:
//! - [`encode::publish_capture`] captures a webcam and publishes it (turnkey).
//! It encodes strictly on demand: the track and catalog are advertised up
//! front, but the camera opens only while a subscriber is watching and is
//! released when the last one leaves.
//! - [`encode::Producer`] publishes packets you encoded yourself.
//! - [`decode`] subscribes to an H.264, H.265, or AV1 track and decodes it to
//! raw frames with a native backend (VideoToolbox on macOS, Media Foundation /
//! DXVA on Windows, NVDEC on Linux, openh264 software fallback for H.264).
//! [`decode::Consumer`] is the mirror of `moq_audio::decode::Consumer`. An
//! NVDEC frame stays in CUDA memory and feeds [`encode::Encoder::encode`]
//! zero-copy (the transcode path), scaled in hardware via
//! [`decode::Config::resize`]. [`Size`] names a resolution wherever one
//! crosses the API.
//!
//! ## API stability
//!
//! The public API is codec-agnostic: no public type, signature, or error
//! variant names a backend (openh264 / VideoToolbox / NVENC / NVDEC) or a
//! capture implementation. [`encode::Encoder`] takes raw RGBA bytes,
//! [`decode::Consumer`] returns opaque [`decode::Frame`]s (CPU I420 on demand,
//! GPU-resident when hardware decoded), and the camera capture path stays
//! internal. So swapping or bumping any backend crate is not a breaking change
//! for consumers. Config structs are `#[non_exhaustive]`: build them via
//! `default()`/`new()` and set fields, so new options stay additive.
pub use Error;
pub use Size;