mp4_atom/moov/trak/mdia/minf/stbl/stsd/
urim.rs1use crate::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct Uri {
9 pub the_uri: String,
10}
11
12impl AtomExt for Uri {
13 type Ext = ();
14
15 const KIND_EXT: FourCC = FourCC::new(b"uri ");
16
17 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
18 Ok(Self {
19 the_uri: String::decode(buf)?,
20 })
21 }
22
23 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
24 self.the_uri.as_str().encode(buf)
25 }
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
32#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
33pub struct UriI {
34 pub uri_initialization_data: Vec<u8>,
35}
36
37impl AtomExt for UriI {
38 type Ext = ();
39
40 const KIND_EXT: FourCC = FourCC::new(b"uriI");
41
42 fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
43 Ok(Self {
44 uri_initialization_data: Vec::decode(buf)?,
45 })
46 }
47
48 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
49 self.uri_initialization_data.encode(buf)
50 }
51}
52
53#[derive(Debug, Clone, PartialEq, Eq)]
57#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
58pub struct Urim {
59 pub metadata: MetaData,
60 pub the_label: Uri,
61 pub init: Option<UriI>,
62 pub btrt: Option<Btrt>,
63}
64
65impl Atom for Urim {
66 const KIND: FourCC = FourCC::new(b"urim");
67
68 fn decode_body<B: Buf>(buf: &mut B) -> Result<Self> {
69 let metadata = MetaData::decode(buf)?;
70
71 let the_label = Uri::decode(buf)?;
72
73 let mut init = None;
74 let mut btrt = None;
75 while let Some(atom) = Any::decode_maybe(buf)? {
76 match atom {
77 Any::UriI(atom) => init = atom.into(),
78 Any::Btrt(atom) => btrt = atom.into(),
79 unknown => Self::decode_unknown(&unknown)?,
80 }
81 }
82 skip_trailing_padding(buf);
83
84 Ok(Self {
85 metadata,
86 the_label,
87 init,
88 btrt,
89 })
90 }
91
92 fn encode_body<B: BufMut>(&self, buf: &mut B) -> Result<()> {
93 self.metadata.encode(buf)?;
94
95 self.the_label.encode(buf)?;
96 self.init.encode(buf)?;
97 self.btrt.encode(buf)?;
98 Ok(())
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_urim_roundtrip() {
108 let urim = Urim {
109 metadata: MetaData {
110 data_reference_index: 1,
111 },
112 the_label: Uri {
113 the_uri: "urn:example:uri-metadata".into(),
114 },
115 init: Some(UriI {
116 uri_initialization_data: vec![1, 2, 3, 4],
117 }),
118 btrt: Some(Btrt {
119 buffer_size_db: 1,
120 max_bitrate: 2000,
121 avg_bitrate: 400,
122 }),
123 };
124
125 let mut buf = Vec::new();
126 urim.encode(&mut buf).unwrap();
127
128 let decoded = Urim::decode(&mut buf.as_slice()).expect("failed to decode urim");
129 assert_eq!(decoded, urim);
130 }
131
132 #[test]
133 fn test_urim_roundtrip_no_init() {
134 let urim = Urim {
135 metadata: MetaData {
136 data_reference_index: 1,
137 },
138 the_label: Uri {
139 the_uri: "https://example.com/schema.xsd".into(),
140 },
141 init: None,
142 btrt: None,
143 };
144
145 let mut buf = Vec::new();
146 urim.encode(&mut buf).unwrap();
147
148 let decoded = Urim::decode(&mut buf.as_slice()).expect("failed to decode urim");
149 assert_eq!(decoded, urim);
150 }
151
152 #[test]
153 fn test_urim_missing_uri() {
154 let mut buf = Vec::new();
155 0u32.encode(&mut buf).unwrap(); 0u16.encode(&mut buf).unwrap(); 1u16.encode(&mut buf).unwrap(); let err = Urim::decode_body(&mut buf.as_slice()).unwrap_err();
160 assert!(matches!(err, Error::OutOfBounds));
161 }
162}