1use fixed::traits::ToFixed;
4use fixed::types::extra::{U8, U16};
5use fixed::{FixedI16, FixedI32};
6use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize};
7
8use super::{MetaBox, MovieExtendsBox, TrackBox, UserDataBox};
9use crate::{BoxHeader, FullBoxHeader, IsoBox, IsoSized, UnknownBox};
10
11#[derive(IsoBox, Debug, PartialEq, Eq)]
15#[iso_box(box_type = b"moov", crate_path = crate)]
16pub struct MovieBox<'a> {
17 #[iso_box(nested_box)]
19 pub mvhd: MovieHeaderBox,
20 #[iso_box(nested_box(collect))]
22 pub meta: Option<MetaBox<'a>>,
23 #[iso_box(nested_box(collect))]
25 pub trak: Vec<TrackBox<'a>>,
26 #[iso_box(nested_box(collect))]
28 pub mvex: Option<MovieExtendsBox>,
29 #[iso_box(nested_box(collect_unknown))]
31 pub unknown_boxes: Vec<UnknownBox<'a>>,
32 #[iso_box(nested_box(collect))]
34 pub udta: Option<UserDataBox<'a>>,
35}
36
37#[derive(IsoBox, Debug, PartialEq, Eq)]
41#[iso_box(box_type = b"mvhd", skip_impl(deserialize_seed, serialize, sized), crate_path = crate)]
42pub struct MovieHeaderBox {
43 pub full_header: FullBoxHeader,
45 pub creation_time: u64,
48 pub modification_time: u64,
51 pub timescale: u32,
55 pub duration: u64,
59 pub rate: FixedI32<U16>,
61 pub volume: FixedI16<U8>,
63 pub reserved1: u16,
65 pub reserved2: u64,
67 pub matrix: [i32; 9],
70 pub pre_defined: [u32; 6],
72 pub next_track_id: u32,
77}
78
79impl MovieHeaderBox {
80 pub fn new(creation_time: u64, modification_time: u64, timescale: u32, duration: u64, next_track_id: u32) -> Self {
84 Self {
85 full_header: FullBoxHeader::default(),
86 creation_time,
87 modification_time,
88 timescale,
89 duration,
90 rate: 1.to_fixed(),
91 volume: 1.to_fixed(),
92 reserved1: 0,
93 reserved2: 0,
94 matrix: [0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000],
95 pre_defined: [0; 6],
96 next_track_id,
97 }
98 }
99}
100
101impl<'a> DeserializeSeed<'a, BoxHeader> for MovieHeaderBox {
102 fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> std::io::Result<Self>
103 where
104 R: scuffle_bytes_util::zero_copy::ZeroCopyReader<'a>,
105 {
106 let full_header = FullBoxHeader::deserialize(&mut reader)?;
107
108 let creation_time = if full_header.version == 1 {
109 u64::deserialize(&mut reader)?
110 } else {
111 u32::deserialize(&mut reader)? as u64
112 };
113 let modification_time = if full_header.version == 1 {
114 u64::deserialize(&mut reader)?
115 } else {
116 u32::deserialize(&mut reader)? as u64
117 };
118 let timescale = u32::deserialize(&mut reader)?;
119 let duration = if full_header.version == 1 {
120 u64::deserialize(&mut reader)?
121 } else {
122 u32::deserialize(&mut reader)? as u64
123 };
124
125 let rate = FixedI32::from_bits(i32::deserialize(&mut reader)?);
126 let volume = FixedI16::from_bits(i16::deserialize(&mut reader)?);
127
128 let reserved1 = u16::deserialize(&mut reader)?;
129 let reserved2 = u64::deserialize(&mut reader)?;
130
131 let mut matrix = [0; 9];
132 for m in &mut matrix {
133 *m = i32::deserialize(&mut reader)?;
134 }
135
136 let mut pre_defined = [0; 6];
137 for p in &mut pre_defined {
138 *p = u32::deserialize(&mut reader)?;
139 }
140
141 let next_track_id = u32::deserialize(&mut reader)?;
142
143 Ok(Self {
144 full_header,
145 creation_time,
146 modification_time,
147 timescale,
148 duration,
149 rate,
150 volume,
151 reserved1,
152 reserved2,
153 matrix,
154 pre_defined,
155 next_track_id,
156 })
157 }
158}
159
160impl Serialize for MovieHeaderBox {
161 fn serialize<W>(&self, mut writer: W) -> std::io::Result<()>
162 where
163 W: std::io::Write,
164 {
165 self.serialize_box_header(&mut writer)?;
166 self.full_header.serialize(&mut writer)?;
167
168 if self.full_header.version == 1 {
169 self.creation_time.serialize(&mut writer)?;
170 self.modification_time.serialize(&mut writer)?;
171 self.timescale.serialize(&mut writer)?;
172 self.duration.serialize(&mut writer)?;
173 } else {
174 (self.creation_time as u32).serialize(&mut writer)?;
175 (self.modification_time as u32).serialize(&mut writer)?;
176 self.timescale.serialize(&mut writer)?;
177 (self.duration as u32).serialize(&mut writer)?;
178 }
179
180 self.rate.to_bits().serialize(&mut writer)?;
181 self.volume.to_bits().serialize(&mut writer)?;
182 self.reserved1.serialize(&mut writer)?;
183 self.reserved2.serialize(&mut writer)?;
184 self.matrix.serialize(&mut writer)?;
185 self.pre_defined.serialize(&mut writer)?;
186 self.next_track_id.serialize(writer)?;
187
188 Ok(())
189 }
190}
191
192impl IsoSized for MovieHeaderBox {
193 fn size(&self) -> usize {
194 let mut size = self.full_header.size();
195 if self.full_header.version == 1 {
196 size += 8 + 8 + 4 + 8; } else {
198 size += 4 + 4 + 4 + 4; }
200 size += 4 + 2 + 2 + 8 + self.matrix.size()
205 + self.pre_defined.size()
206 + 4; Self::add_header_size(size)
209 }
210}