flowly_mp4/mp4box/
dinf.rs

1use serde::Serialize;
2use std::io::Write;
3
4use crate::mp4box::*;
5
6#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
7pub struct DinfBox {
8    dref: DrefBox,
9}
10
11impl DinfBox {
12    pub fn get_type(&self) -> BoxType {
13        BoxType::DinfBox
14    }
15
16    pub fn get_size(&self) -> u64 {
17        HEADER_SIZE + self.dref.box_size()
18    }
19}
20
21impl Mp4Box for DinfBox {
22    const TYPE: BoxType = BoxType::DinfBox;
23
24    fn box_size(&self) -> u64 {
25        self.get_size()
26    }
27
28    fn to_json(&self) -> Result<String, Error> {
29        Ok(serde_json::to_string(&self).unwrap())
30    }
31
32    fn summary(&self) -> Result<String, Error> {
33        let s = String::new();
34        Ok(s)
35    }
36}
37
38impl BlockReader for DinfBox {
39    fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
40        Ok(DinfBox {
41            dref: reader.find_box::<DrefBox>()?,
42        })
43    }
44
45    fn size_hint() -> usize {
46        DrefBox::size_hint()
47    }
48}
49
50impl<W: Write> WriteBox<&mut W> for DinfBox {
51    fn write_box(&self, writer: &mut W) -> Result<u64, Error> {
52        let size = self.box_size();
53        BoxHeader::new(Self::TYPE, size).write(writer)?;
54        self.dref.write_box(writer)?;
55        Ok(size)
56    }
57}
58
59#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
60pub struct DrefBox {
61    pub version: u8,
62    pub flags: u32,
63
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub url: Option<UrlBox>,
66}
67
68impl Default for DrefBox {
69    fn default() -> Self {
70        DrefBox {
71            version: 0,
72            flags: 0,
73            url: Some(UrlBox::default()),
74        }
75    }
76}
77
78impl DrefBox {
79    pub fn get_size(&self) -> u64 {
80        let mut size = HEADER_SIZE + HEADER_EXT_SIZE + 4;
81        if let Some(ref url) = self.url {
82            size += url.box_size();
83        }
84        size
85    }
86}
87
88impl Mp4Box for DrefBox {
89    const TYPE: BoxType = BoxType::DrefBox;
90
91    fn box_size(&self) -> u64 {
92        self.get_size()
93    }
94
95    fn to_json(&self) -> Result<String, Error> {
96        Ok(serde_json::to_string(&self).unwrap())
97    }
98
99    fn summary(&self) -> Result<String, Error> {
100        let s = String::new();
101        Ok(s)
102    }
103}
104
105impl BlockReader for DrefBox {
106    fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
107        let (version, flags) = read_box_header_ext(reader);
108        let mut url = None;
109        let entry_count = reader.get_u32();
110
111        for _i in 0..entry_count {
112            url = reader.try_find_box()?;
113        }
114
115        Ok(DrefBox {
116            version,
117            flags,
118            url,
119        })
120    }
121
122    fn size_hint() -> usize {
123        8
124    }
125}
126
127impl<W: Write> WriteBox<&mut W> for DrefBox {
128    fn write_box(&self, writer: &mut W) -> Result<u64, Error> {
129        let size = self.box_size();
130        BoxHeader::new(Self::TYPE, size).write(writer)?;
131
132        write_box_header_ext(writer, self.version, self.flags)?;
133
134        writer.write_u32::<BigEndian>(1)?;
135
136        if let Some(ref url) = self.url {
137            url.write_box(writer)?;
138        }
139
140        Ok(size)
141    }
142}
143
144#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
145pub struct UrlBox {
146    pub version: u8,
147    pub flags: u32,
148    pub location: String,
149}
150
151impl Default for UrlBox {
152    fn default() -> Self {
153        UrlBox {
154            version: 0,
155            flags: 1,
156            location: String::default(),
157        }
158    }
159}
160
161impl UrlBox {
162    pub fn get_size(&self) -> u64 {
163        let mut size = HEADER_SIZE + HEADER_EXT_SIZE;
164
165        if !self.location.is_empty() {
166            size += self.location.len() as u64 + 1;
167        }
168
169        size
170    }
171}
172
173impl Mp4Box for UrlBox {
174    const TYPE: BoxType = BoxType::UrlBox;
175
176    fn box_size(&self) -> u64 {
177        self.get_size()
178    }
179
180    fn to_json(&self) -> Result<String, Error> {
181        Ok(serde_json::to_string(&self).unwrap())
182    }
183
184    fn summary(&self) -> Result<String, Error> {
185        let s = format!("location={}", self.location);
186        Ok(s)
187    }
188}
189
190impl BlockReader for UrlBox {
191    fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
192        let (version, flags) = read_box_header_ext(reader);
193
194        Ok(UrlBox {
195            version,
196            flags,
197            location: reader.get_null_terminated_string(),
198        })
199    }
200
201    fn size_hint() -> usize {
202        4
203    }
204}
205
206impl<W: Write> WriteBox<&mut W> for UrlBox {
207    fn write_box(&self, writer: &mut W) -> Result<u64, Error> {
208        let size = self.box_size();
209        BoxHeader::new(Self::TYPE, size).write(writer)?;
210
211        write_box_header_ext(writer, self.version, self.flags)?;
212
213        if !self.location.is_empty() {
214            writer.write_all(self.location.as_bytes())?;
215            writer.write_u8(0)?;
216        }
217
218        Ok(size)
219    }
220}