sheathe_core/stream.rs
1//! Elementary-stream description: what a track *is*, independent of container.
2
3use crate::time::Timescale;
4
5/// The broad category of an elementary stream.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum MediaKind {
8 /// Video / image sequence.
9 Video,
10 /// Audio.
11 Audio,
12 /// Timed text / subtitles / captions.
13 Text,
14}
15
16/// The codec carried by a stream. The string in [`Codec::Other`] is a
17/// best-effort fourcc/codec id for formats not yet first-classed.
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub enum Codec {
20 H264,
21 H265,
22 Av1,
23 Vp8,
24 Vp9,
25 Aac,
26 Ac3,
27 Eac3,
28 Mp3,
29 Flac,
30 Opus,
31 WebVtt,
32 /// TTML / IMSC 1.0/1.1 timed text (`stpp`).
33 Stpp,
34 /// Anything else, keyed by its fourcc or registration string.
35 Other(String),
36}
37
38impl Codec {
39 /// The RFC 6381 `codecs=` prefix used in DASH/HLS manifests.
40 pub fn rfc6381_family(&self) -> &str {
41 match self {
42 Codec::H264 => "avc1",
43 Codec::H265 => "hvc1",
44 Codec::Av1 => "av01",
45 Codec::Vp8 => "vp08",
46 Codec::Vp9 => "vp09",
47 Codec::Aac => "mp4a",
48 Codec::Ac3 => "ac-3",
49 Codec::Eac3 => "ec-3",
50 Codec::Mp3 => "mp4a",
51 Codec::Flac => "fLaC",
52 Codec::Opus => "Opus",
53 Codec::WebVtt => "wvtt",
54 Codec::Stpp => "stpp",
55 Codec::Other(s) => s.as_str(),
56 }
57 }
58}
59
60/// Everything the packager needs to know about one elementary stream.
61#[derive(Debug, Clone)]
62pub struct StreamInfo {
63 /// Video / audio / text.
64 pub kind: MediaKind,
65 /// The codec carried.
66 pub codec: Codec,
67 /// The stream's media timescale.
68 pub timescale: Timescale,
69 /// Width/height in pixels for video; `None` otherwise.
70 pub resolution: Option<(u32, u32)>,
71 /// Sample rate in Hz for audio; `None` otherwise.
72 pub sample_rate: Option<u32>,
73 /// Average bitrate in bits/sec, if known.
74 pub bitrate: Option<u32>,
75 /// Full RFC 6381 `codecs=` string (e.g. `avc1.640028`, `mp4a.40.2`), if the
76 /// codec configuration was parsed. Falls back to the codec family otherwise.
77 pub codec_string: Option<String>,
78}
79
80impl StreamInfo {
81 /// The RFC 6381 `codecs=` value for this stream: the parsed
82 /// [`StreamInfo::codec_string`] if present, else the bare codec family.
83 pub fn rfc6381(&self) -> String {
84 self.codec_string.clone().unwrap_or_else(|| self.codec.rfc6381_family().to_string())
85 }
86}