1use std::error;
2use std::fmt;
3
4pub type Result<T> = std::result::Result<T, Error>;
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9#[non_exhaustive]
10pub enum ErrorKind {
11 InvalidInput,
12 Unsupported,
13 MalformedMedia,
14 ResourceLimit,
15 Io,
16 Codec,
17 Graphics,
18 Canceled,
19 InvalidState,
20 Internal,
21 WouldBlock,
27}
28
29#[derive(Clone, Debug, Eq, PartialEq)]
31pub struct Error {
32 kind: ErrorKind,
33 message: String,
34}
35
36impl Error {
37 pub fn new(kind: ErrorKind, message: impl Into<String>) -> Self {
38 Self {
39 kind,
40 message: message.into(),
41 }
42 }
43
44 pub const fn kind(&self) -> ErrorKind {
45 self.kind
46 }
47
48 pub fn message(&self) -> &str {
49 &self.message
50 }
51}
52
53impl fmt::Display for Error {
54 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(formatter, "{}", self.message)
56 }
57}
58
59impl error::Error for Error {}
60
61#[derive(Clone, Debug, Eq, PartialEq)]
63pub enum Support {
64 Available,
65 Unavailable { reason: String },
66}
67
68impl Support {
69 pub const fn is_available(&self) -> bool {
70 matches!(self, Self::Available)
71 }
72}
73
74#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
76#[non_exhaustive]
77pub enum TransferMode {
78 Shared,
79 GpuCopy,
80 CpuCopy,
81 Unsupported,
82}
83
84#[derive(Clone, Debug, Eq, PartialEq)]
86pub struct Capability {
87 pub name: String,
88 pub support: Support,
89 pub transfer_mode: Option<TransferMode>,
90}
91
92#[derive(Clone, Copy, Debug, Eq, PartialEq)]
94pub struct Limits {
95 pub max_width: u32,
96 pub max_height: u32,
97 pub max_audio_channels: u16,
98 pub max_sample_rate: u32,
99 pub max_tracks: u16,
100 pub max_allocation_bytes: u64,
101 pub max_cached_frames: u32,
102 pub max_decode_samples_per_seek: u32,
103 pub max_av1_obus_per_unit: u32,
105 pub max_av1_operating_points: u8,
107 pub max_av1_tiles_per_frame: u32,
109 pub max_av1_blocks_per_frame: u32,
111}
112
113impl Default for Limits {
114 fn default() -> Self {
115 Self {
116 max_width: 8_192,
117 max_height: 8_192,
118 max_audio_channels: 32,
119 max_sample_rate: 384_000,
120 max_tracks: 64,
121 max_allocation_bytes: 512 * 1024 * 1024,
122 max_cached_frames: 32,
123 max_decode_samples_per_seek: 4_096,
124 max_av1_obus_per_unit: 4_096,
125 max_av1_operating_points: 32,
126 max_av1_tiles_per_frame: 4_096,
127 max_av1_blocks_per_frame: 4_194_304,
128 }
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn errors_keep_their_stable_category() {
138 let error = Error::new(ErrorKind::MalformedMedia, "box exceeds its parent");
139 assert_eq!(error.kind(), ErrorKind::MalformedMedia);
140 assert_eq!(error.to_string(), "box exceeds its parent");
141 }
142
143 #[test]
144 fn default_limits_are_conservative_and_nonzero() {
145 let limits = Limits::default();
146 assert!(limits.max_width > 0);
147 assert!(limits.max_allocation_bytes > 0);
148 assert!(limits.max_cached_frames > 0);
149 assert!(limits.max_decode_samples_per_seek > 0);
150 assert!(limits.max_av1_obus_per_unit > 0);
151 assert!(limits.max_av1_operating_points > 0);
152 assert!(limits.max_av1_tiles_per_frame > 0);
153 assert!(limits.max_av1_blocks_per_frame > 0);
154 }
155}