1use std::fmt::Debug;
4
5use scuffle_bytes_util::BytesCow;
6use scuffle_bytes_util::zero_copy::{Deserialize, Serialize};
7
8use crate::{FullBoxHeader, IsoBox, IsoSized};
9
10#[derive(IsoBox, PartialEq, Eq)]
14#[iso_box(box_type = b"mdat", crate_path = crate)]
15pub struct MediaDataBox<'a> {
16 pub data: BytesCow<'a>,
18}
19
20impl<'a> MediaDataBox<'a> {
21 pub fn new(data: BytesCow<'a>) -> Self {
23 Self { data }
24 }
25}
26
27impl Debug for MediaDataBox<'_> {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.debug_struct("MediaDataBox").field("data.len", &self.data.len()).finish()
30 }
31}
32
33#[derive(IsoBox, PartialEq, Eq)]
37#[iso_box(box_type = b"free", crate_path = crate)]
38pub struct FreeSpaceBox<'a> {
39 pub data: BytesCow<'a>,
41}
42
43impl Debug for FreeSpaceBox<'_> {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 f.debug_struct("FreeSpaceBox").field("data.len", &self.data.len()).finish()
46 }
47}
48
49#[derive(IsoBox, PartialEq, Eq)]
55#[iso_box(box_type = b"skip", crate_path = crate)]
56pub struct SkipBox<'a> {
57 pub data: BytesCow<'a>,
59}
60
61impl Debug for SkipBox<'_> {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 f.debug_struct("SkipBox").field("data.len", &self.data.len()).finish()
64 }
65}
66
67#[derive(IsoBox, Debug, PartialEq, Eq)]
71#[iso_box(box_type = b"pdin", crate_path = crate)]
72pub struct ProgressiveDownloadInfoBox {
73 pub full_header: FullBoxHeader,
75 #[iso_box(repeated)]
77 pub properties: Vec<ProgressiveDownloadInfoBoxProperties>,
78}
79
80#[derive(Debug, PartialEq, Eq)]
82pub struct ProgressiveDownloadInfoBoxProperties {
83 pub rate: u32,
85 pub initial_delay: u32,
89}
90
91impl<'a> Deserialize<'a> for ProgressiveDownloadInfoBoxProperties {
92 fn deserialize<R>(mut reader: R) -> std::io::Result<Self>
93 where
94 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
95 {
96 let rate = u32::deserialize(&mut reader)?;
97 let initial_delay = u32::deserialize(&mut reader)?;
98
99 Ok(ProgressiveDownloadInfoBoxProperties { rate, initial_delay })
100 }
101}
102
103impl Serialize for ProgressiveDownloadInfoBoxProperties {
104 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
105 where
106 W: std::io::Write,
107 {
108 self.rate.serialize(&mut writer)?;
109 self.initial_delay.serialize(&mut writer)?;
110 Ok(())
111 }
112}
113
114impl IsoSized for ProgressiveDownloadInfoBoxProperties {
115 fn size(&self) -> usize {
116 self.rate.size() + self.initial_delay.size()
117 }
118}
119
120#[derive(IsoBox, PartialEq, Eq)]
124#[iso_box(box_type = b"imda", crate_path = crate)]
125pub struct IdentifiedMediaDataBox<'a> {
126 pub imda_identifier: u32,
129 pub data: BytesCow<'a>,
131}
132
133impl Debug for IdentifiedMediaDataBox<'_> {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 f.debug_struct("IdentifiedMediaDataBox")
136 .field("imda_identifier", &self.imda_identifier)
137 .field("data.len", &self.data.len())
138 .finish()
139 }
140}
141
142#[cfg(test)]
143#[cfg_attr(all(test, coverage_nightly), coverage(off))]
144mod tests {
145 use scuffle_bytes_util::zero_copy::{Deserialize, Slice};
146
147 use super::MediaDataBox;
148
149 #[test]
150 fn demux_mdat() {
151 #[rustfmt::skip]
152 let data = [
153 0x00, 0x00, 0x00, 0x0C, b'm', b'd', b'a', b't', 0x42, 0x00, 0x42, 0x00, 0x01,
157 ];
158
159 let mdat = MediaDataBox::deserialize(Slice::from(&data[..])).unwrap();
160 assert_eq!(mdat.data.len(), 4);
161 assert_eq!(mdat.data.as_bytes()[0], 0x42);
162 assert_eq!(mdat.data.as_bytes()[1], 0x00);
163 assert_eq!(mdat.data.as_bytes()[2], 0x42);
164 assert_eq!(mdat.data.as_bytes()[3], 0x00);
165 }
166}