scuffle_mp4/object_description/
sl_config.rs1use isobmff::IsoSized;
2use nutype_enum::nutype_enum;
3use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize};
4use scuffle_bytes_util::{BitReader, BitWriter};
5
6use super::{BaseDescriptor, DescriptorTag};
7
8nutype_enum! {
9 pub enum SLConfigDescriptorPredefined(u8) {
11 Custom = 0,
13 NullSLPacketHeader = 1,
15 }
16}
17
18impl<'a> Deserialize<'a> for SLConfigDescriptorPredefined {
19 fn deserialize<R>(reader: R) -> std::io::Result<Self>
20 where
21 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
22 {
23 u8::deserialize(reader).map(Into::into)
24 }
25}
26
27impl Serialize for SLConfigDescriptorPredefined {
28 fn serialize<W>(&self, writer: W) -> std::io::Result<()>
29 where
30 W: std::io::Write,
31 {
32 self.0.serialize(writer)
33 }
34}
35
36impl IsoSized for SLConfigDescriptorPredefined {
37 fn size(&self) -> usize {
38 1
39 }
40}
41
42#[derive(Debug, PartialEq, Eq)]
46pub struct SLConfigDescriptor {
47 pub predefined: SLConfigDescriptorPredefined,
49 pub custom: Option<SLConfigDescriptorCustom>,
51}
52
53impl SLConfigDescriptor {
54 pub fn base_descriptor(&self) -> BaseDescriptor {
56 BaseDescriptor {
57 tag: DescriptorTag::SLConfigDescrTag,
58 size_of_instance: self.payload_size() as u32,
59 }
60 }
61
62 fn payload_size(&self) -> usize {
63 self.predefined.size() + self.custom.size()
64 }
65}
66
67impl<'a> Deserialize<'a> for SLConfigDescriptor {
68 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
69 where
70 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
71 {
72 let base_descriptor = BaseDescriptor::deserialize(&mut reader)?;
73 let mut reader = reader.take(base_descriptor.size_of_instance as usize);
74
75 let predefined = SLConfigDescriptorPredefined::deserialize(&mut reader)?;
76
77 let predefined_0 = if predefined == SLConfigDescriptorPredefined::Custom {
78 Some(SLConfigDescriptorCustom::deserialize(&mut reader)?)
79 } else {
80 None
81 };
82
83 Ok(Self {
84 predefined,
85 custom: predefined_0,
86 })
87 }
88}
89
90impl Serialize for SLConfigDescriptor {
91 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
92 where
93 W: std::io::Write,
94 {
95 self.base_descriptor().serialize(&mut writer)?;
96 self.predefined.serialize(&mut writer)?;
97
98 if self.predefined == SLConfigDescriptorPredefined::Custom {
99 self.custom
100 .as_ref()
101 .ok_or(std::io::Error::new(
102 std::io::ErrorKind::InvalidData,
103 "predefined_0 is required when predefined is 0",
104 ))?
105 .serialize(&mut writer)?;
106 }
107
108 Ok(())
109 }
110}
111
112impl IsoSized for SLConfigDescriptor {
113 fn size(&self) -> usize {
114 self.base_descriptor().size() + self.payload_size()
115 }
116}
117
118#[derive(Debug, PartialEq, Eq)]
120pub struct SLConfigDescriptorCustom {
121 pub use_access_unit_start_flag: bool,
124 pub use_access_unit_end_flag: bool,
127 pub use_random_access_point_flag: bool,
130 pub has_random_access_units_only_flag: bool,
133 pub use_padding_flag: bool,
136 pub use_time_stamps_flag: bool,
141 pub use_idle_flag: bool,
143 pub duration_flag: bool,
146 pub time_stamp_resolution: u32,
148 pub ocr_resolution: u32,
150 pub time_stamp_length: u8,
153 pub ocr_length: u8,
157 pub au_length: u8,
160 pub instant_bitrate_length: u8,
163 pub degradation_priority_length: u8,
166 pub au_seq_num_length: u8,
169 pub packet_seq_num_length: u8,
172 pub reserved: u8,
174 pub duration: Option<SLConfigDescriptorDuration>,
176 pub time_stamps: Option<SLConfigDescriptorTimeStamps>,
178}
179
180impl<'a> Deserialize<'a> for SLConfigDescriptorCustom {
181 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
182 where
183 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
184 {
185 let byte = u8::deserialize(&mut reader)?;
186 let use_access_unit_start_flag = byte & 0b1000_0000 != 0;
187 let use_access_unit_end_flag = byte & 0b0100_0000 != 0;
188 let use_random_access_point_flag = byte & 0b0010_0000 != 0;
189 let has_random_access_units_only_flag = byte & 0b0001_0000 != 0;
190 let use_padding_flag = byte & 0b0000_1000 != 0;
191 let use_time_stamps_flag = byte & 0b0000_0100 != 0;
192 let use_idle_flag = byte & 0b0000_0010 != 0;
193 let duration_flag = byte & 0b0000_0001 != 0;
194
195 let time_stamp_resolution = u32::deserialize(&mut reader)?;
196 let ocr_resolution = u32::deserialize(&mut reader)?;
197 let time_stamp_length = u8::deserialize(&mut reader)?;
198 if time_stamp_length > 64 {
199 return Err(std::io::Error::new(
200 std::io::ErrorKind::InvalidData,
201 "timeStampLength must be <= 64",
202 ));
203 }
204
205 let ocr_length = u8::deserialize(&mut reader)?;
206 if ocr_length > 64 {
207 return Err(std::io::Error::new(
208 std::io::ErrorKind::InvalidData,
209 "OCRLength must be <= 64",
210 ));
211 }
212
213 let au_length = u8::deserialize(&mut reader)?;
214 if au_length > 32 {
215 return Err(std::io::Error::new(
216 std::io::ErrorKind::InvalidData,
217 "AU_Length must be <= 64",
218 ));
219 }
220
221 let instant_bitrate_length = u8::deserialize(&mut reader)?;
222
223 let bytes = u16::deserialize(&mut reader)?;
224 let degradation_priority_length = ((bytes & 0b1111_0000_0000_0000) >> 12) as u8;
225 let au_seq_num_length = ((bytes & 0b0000_1111_1000_0000) >> 7) as u8;
226 if au_seq_num_length > 16 {
227 return Err(std::io::Error::new(
228 std::io::ErrorKind::InvalidData,
229 "AU_SeqNumLength must be <= 16",
230 ));
231 }
232 let packet_seq_num_length = (byte & 0b0000_0000_0111_1100) >> 2;
233 if packet_seq_num_length > 16 {
234 return Err(std::io::Error::new(
235 std::io::ErrorKind::InvalidData,
236 "packetSeqNumLength must be <= 16",
237 ));
238 }
239 let reserved = byte & 0b0000_0000_0000_0011;
240
241 let duration = if duration_flag {
242 Some(SLConfigDescriptorDuration::deserialize(&mut reader)?)
243 } else {
244 None
245 };
246
247 let time_stamps = if use_time_stamps_flag {
248 Some(SLConfigDescriptorTimeStamps::deserialize_seed(
249 &mut reader,
250 time_stamp_length,
251 )?)
252 } else {
253 None
254 };
255
256 Ok(Self {
257 use_access_unit_start_flag,
258 use_access_unit_end_flag,
259 use_random_access_point_flag,
260 has_random_access_units_only_flag,
261 use_padding_flag,
262 use_time_stamps_flag,
263 use_idle_flag,
264 duration_flag,
265 time_stamp_resolution,
266 ocr_resolution,
267 time_stamp_length,
268 ocr_length,
269 au_length,
270 instant_bitrate_length,
271 degradation_priority_length,
272 au_seq_num_length,
273 packet_seq_num_length,
274 reserved,
275 duration,
276 time_stamps,
277 })
278 }
279}
280
281impl Serialize for SLConfigDescriptorCustom {
282 fn serialize<W>(&self, writer: W) -> std::io::Result<()>
283 where
284 W: std::io::Write,
285 {
286 let mut bit_writer = BitWriter::new(writer);
287
288 bit_writer.write_bit(self.use_access_unit_start_flag)?;
289 bit_writer.write_bit(self.use_access_unit_end_flag)?;
290 bit_writer.write_bit(self.use_random_access_point_flag)?;
291 bit_writer.write_bit(self.has_random_access_units_only_flag)?;
292 bit_writer.write_bit(self.use_padding_flag)?;
293 bit_writer.write_bit(self.use_time_stamps_flag)?;
294 bit_writer.write_bit(self.use_idle_flag)?;
295 bit_writer.write_bit(self.duration_flag)?;
296
297 self.time_stamp_resolution.serialize(&mut bit_writer)?;
298 self.ocr_resolution.serialize(&mut bit_writer)?;
299 self.time_stamp_length.serialize(&mut bit_writer)?;
300 self.ocr_length.serialize(&mut bit_writer)?;
301 self.au_length.serialize(&mut bit_writer)?;
302 self.instant_bitrate_length.serialize(&mut bit_writer)?;
303 self.degradation_priority_length.serialize(&mut bit_writer)?;
304 self.au_seq_num_length.serialize(&mut bit_writer)?;
305 self.packet_seq_num_length.serialize(&mut bit_writer)?;
306 self.reserved.serialize(&mut bit_writer)?;
307
308 if self.duration_flag {
309 self.duration
310 .as_ref()
311 .ok_or(std::io::Error::new(
312 std::io::ErrorKind::InvalidData,
313 "duration is required when duration_flag is set",
314 ))?
315 .serialize(&mut bit_writer)?;
316 }
317
318 if self.use_time_stamps_flag {
319 self.time_stamps
320 .as_ref()
321 .ok_or(std::io::Error::new(
322 std::io::ErrorKind::InvalidData,
323 "time_stamps is required when use_time_stamps_flag is set",
324 ))?
325 .serialize(&mut bit_writer, self.time_stamp_length)?;
326 }
327
328 Ok(())
329 }
330}
331
332impl IsoSized for SLConfigDescriptorCustom {
333 fn size(&self) -> usize {
334 let mut size = 1; size += self.time_stamp_resolution.size();
336 size += self.ocr_resolution.size();
337 size += self.time_stamp_length.size();
338 size += self.ocr_length.size();
339 size += self.au_length.size();
340 size += self.instant_bitrate_length.size();
341 size += self.degradation_priority_length.size();
342 size += self.au_seq_num_length.size();
343 size += self.packet_seq_num_length.size();
344 size += self.reserved.size();
345 size += self.duration.size();
346
347 if let Some(time_stamps) = &self.time_stamps {
348 size += time_stamps.size(self.time_stamp_length);
349 }
350
351 size
352 }
353}
354
355#[derive(Debug, PartialEq, Eq)]
357pub struct SLConfigDescriptorDuration {
358 pub time_scale: u32,
361 pub access_unit_duration: u16,
363 pub composition_unit_duration: u16,
365}
366
367impl<'a> Deserialize<'a> for SLConfigDescriptorDuration {
368 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
369 where
370 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
371 {
372 Ok(Self {
373 time_scale: u32::deserialize(&mut reader)?,
374 access_unit_duration: u16::deserialize(&mut reader)?,
375 composition_unit_duration: u16::deserialize(&mut reader)?,
376 })
377 }
378}
379
380impl Serialize for SLConfigDescriptorDuration {
381 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
382 where
383 W: std::io::Write,
384 {
385 self.time_scale.serialize(&mut writer)?;
386 self.access_unit_duration.serialize(&mut writer)?;
387 self.composition_unit_duration.serialize(&mut writer)?;
388 Ok(())
389 }
390}
391
392impl IsoSized for SLConfigDescriptorDuration {
393 fn size(&self) -> usize {
394 self.time_scale.size() + self.access_unit_duration.size() + self.composition_unit_duration.size()
395 }
396}
397
398#[derive(Debug, PartialEq, Eq)]
400pub struct SLConfigDescriptorTimeStamps {
401 pub start_decoding_time_stamp: u64,
404 pub start_composition_time_stamp: u64,
408}
409
410impl<'a> DeserializeSeed<'a, u8> for SLConfigDescriptorTimeStamps {
411 fn deserialize_seed<R>(mut reader: R, seed: u8) -> std::io::Result<Self>
412 where
413 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
414 {
415 let mut bit_reader = BitReader::new(reader.as_std());
416
417 Ok(Self {
418 start_decoding_time_stamp: bit_reader.read_bits(seed)?,
419 start_composition_time_stamp: bit_reader.read_bits(seed)?,
420 })
421 }
422}
423
424impl SLConfigDescriptorTimeStamps {
425 pub fn serialize<W>(&self, writer: W, time_stamp_length: u8) -> std::io::Result<()>
427 where
428 W: std::io::Write,
429 {
430 let mut bit_writer = BitWriter::new(writer);
431 bit_writer.write_bits(self.start_decoding_time_stamp, time_stamp_length)?;
432 bit_writer.write_bits(self.start_composition_time_stamp, time_stamp_length)?;
433 Ok(())
434 }
435
436 pub fn size(&self, time_stamp_length: u8) -> usize {
438 time_stamp_length as usize * 2
439 }
440}