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 Aac,
24 Ac3,
25 Eac3,
26 Opus,
27 WebVtt,
28 /// Anything else, keyed by its fourcc or registration string.
29 Other(String),
30}
31
32impl Codec {
33 /// The RFC 6381 `codecs=` prefix used in DASH/HLS manifests.
34 pub fn rfc6381_family(&self) -> &str {
35 match self {
36 Codec::H264 => "avc1",
37 Codec::H265 => "hvc1",
38 Codec::Av1 => "av01",
39 Codec::Aac => "mp4a",
40 Codec::Ac3 => "ac-3",
41 Codec::Eac3 => "ec-3",
42 Codec::Opus => "Opus",
43 Codec::WebVtt => "wvtt",
44 Codec::Other(s) => s.as_str(),
45 }
46 }
47}
48
49/// Everything the packager needs to know about one elementary stream.
50#[derive(Debug, Clone)]
51pub struct StreamInfo {
52 /// Video / audio / text.
53 pub kind: MediaKind,
54 /// The codec carried.
55 pub codec: Codec,
56 /// The stream's media timescale.
57 pub timescale: Timescale,
58 /// Width/height in pixels for video; `None` otherwise.
59 pub resolution: Option<(u32, u32)>,
60 /// Sample rate in Hz for audio; `None` otherwise.
61 pub sample_rate: Option<u32>,
62 /// Average bitrate in bits/sec, if known.
63 pub bitrate: Option<u32>,
64 /// Full RFC 6381 `codecs=` string (e.g. `avc1.640028`, `mp4a.40.2`), if the
65 /// codec configuration was parsed. Falls back to the codec family otherwise.
66 pub codec_string: Option<String>,
67}
68
69impl StreamInfo {
70 /// The RFC 6381 `codecs=` value for this stream: the parsed
71 /// [`StreamInfo::codec_string`] if present, else the bare codec family.
72 pub fn rfc6381(&self) -> String {
73 self.codec_string
74 .clone()
75 .unwrap_or_else(|| self.codec.rfc6381_family().to_string())
76 }
77}