Skip to main content

moq_transcode/
config.rs

1//! Transcoder configuration: the rung ladder and catalog wiring.
2
3use moq_net::PathRelativeOwned;
4
5/// One candidate output rendition: a target resolution (by height) and bitrate.
6///
7/// The width is derived from the source aspect ratio at runtime, and a rung is
8/// only offered when it is strictly below the source (see [`Config::rungs`]).
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10#[non_exhaustive]
11pub struct Rung {
12	/// Output height in pixels. Rounded down to even (I420 chroma is 2x2).
13	pub height: u32,
14
15	/// Target bitrate in bits per second: the CBR target and the bitrate
16	/// advertised in the derivative catalog.
17	pub bitrate: u64,
18}
19
20impl Rung {
21	/// A rung at `height` pixels and `bitrate` bits per second.
22	pub fn new(height: u32, bitrate: u64) -> Self {
23		Self { height, bitrate }
24	}
25}
26
27/// Transcoder configuration for [`run`](crate::run).
28///
29/// `#[non_exhaustive]`: build via `Config::default()` and set fields, so future
30/// knobs don't break callers.
31#[derive(Clone, Debug)]
32#[non_exhaustive]
33pub struct Config {
34	/// Candidate output renditions. Only rungs strictly below the source
35	/// survive: a rung is dropped when its height exceeds the source, when its
36	/// bitrate is not below the source bitrate (when known), or when it matches
37	/// the source height without a known source bitrate to undercut. A 480p
38	/// source is never transcoded up to 720p.
39	pub rungs: Vec<Rung>,
40
41	/// Where the source broadcast lives relative to the output broadcast, e.g.
42	/// `".."` when the output is published at `<source>/transcode.hang`. When
43	/// set, the derivative catalog references the source renditions (all video
44	/// and audio) through this path so players fetch them from the source
45	/// directly; the transcoder never proxies or subscribes them. `None` omits
46	/// them from the derivative catalog.
47	pub source: Option<PathRelativeOwned>,
48
49	/// Which video encoder implementation encodes the rungs. The default
50	/// prefers hardware (NVENC on Linux, VideoToolbox on macOS, Media
51	/// Foundation on Windows) and falls back to openh264.
52	pub encoder: moq_video::encode::Kind,
53
54	/// Which video decoder implementation decodes the source. The default
55	/// prefers hardware and falls back to openh264 (H.264 only; H.265 sources
56	/// need a hardware decoder).
57	pub decoder: moq_video::decode::Kind,
58}
59
60impl Default for Config {
61	fn default() -> Self {
62		Self {
63			// The default ladder, top rung first, filtered against the source at
64			// runtime so only strictly-lower renditions are offered.
65			rungs: vec![
66				Rung::new(1080, 5_000_000),
67				Rung::new(720, 2_500_000),
68				Rung::new(480, 1_200_000),
69				Rung::new(360, 600_000),
70				Rung::new(240, 350_000),
71			],
72			source: None,
73			encoder: moq_video::encode::Kind::default(),
74			decoder: moq_video::decode::Kind::default(),
75		}
76	}
77}