1mod mvex;
2mod mvhd;
3mod trak;
4mod udta;
5
6pub use mvex::*;
7pub use mvhd::*;
8pub use trak::*;
9pub use udta::*;
10
11use crate::*;
12
13#[derive(Debug, Clone, PartialEq, Default)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct Moov {
16 pub mvhd: Mvhd,
17 pub meta: Option<Meta>,
18 pub mvex: Option<Mvex>,
19 pub trak: Vec<Trak>,
20 pub udta: Option<Udta>,
21}
22
23impl Atom for Moov {
24 const KIND: FourCC = FourCC::new(b"moov");
25
26 nested! {
27 required: [ Mvhd ],
28 optional: [ Meta, Mvex, Udta ],
29 multiple: [ Trak ],
30 }
31}
32
33#[cfg(test)]
34mod test {
35 use super::*;
36
37 #[test]
38 fn test_meta() {
39 const ENCODED: &[u8] = &[
40 0x00, 0x00, 0x03, 0x3A, 0x6D, 0x6F, 0x6F, 0x76, 0x00, 0x00, 0x00, 0x6C, 0x6D, 0x76,
41 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xEF, 0xCF, 0xD6, 0xE0, 0xEF, 0xCF, 0xD6,
42 0x00, 0x01, 0x5F, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x8D, 0x6D, 0x65, 0x74, 0x61, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x68, 0x64, 0x6C, 0x72, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x49, 0x44, 0x33, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x49, 0x44, 0x33, 0x32,
52 0x00, 0x00, 0x00, 0x00, 0x15, 0xC7, 0x49, 0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x49, 0x50, 0x52, 0x49, 0x56, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x68, 0x74,
54 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2E, 0x63,
55 0x6F, 0x6D, 0x2F, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x2F, 0x73, 0x68, 0x61, 0x6B,
56 0x61, 0x2D, 0x70, 0x61, 0x63, 0x6B, 0x61, 0x67, 0x65, 0x72, 0x00, 0x76, 0x32, 0x2E,
57 0x36, 0x2E, 0x31, 0x2D, 0x36, 0x33, 0x34, 0x61, 0x66, 0x36, 0x35, 0x2D, 0x72, 0x65,
58 0x6C, 0x65, 0x61, 0x73, 0x65, 0x00, 0x00, 0x02, 0x01, 0x74, 0x72, 0x61, 0x6B, 0x00,
59 0x00, 0x00, 0x5C, 0x74, 0x6B, 0x68, 0x64, 0x00, 0x00, 0x00, 0x07, 0xE0, 0xEF, 0xCF,
60 0xD6, 0xE0, 0xEF, 0xCF, 0xD6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x07,
65 0x80, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00, 0x01, 0x79, 0x6D, 0x64, 0x69,
66 0x61, 0x00, 0x00, 0x00, 0x20, 0x6D, 0x64, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0xE0,
67 0xEF, 0xCF, 0xD6, 0xE0, 0xEF, 0xCF, 0xD6, 0x00, 0x01, 0x5F, 0x90, 0x00, 0x00, 0x00,
68 0x00, 0x55, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x68, 0x64, 0x6C, 0x72, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x64, 0x65, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x69, 0x64, 0x65, 0x6F,
71 0x48, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x72, 0x00, 0x00, 0x00, 0x01, 0x24, 0x6D, 0x69,
72 0x6E, 0x66, 0x00, 0x00, 0x00, 0x24, 0x64, 0x69, 0x6E, 0x66, 0x00, 0x00, 0x00, 0x1C,
73 0x64, 0x72, 0x65, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
74 0x00, 0x0C, 0x75, 0x72, 0x6C, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xE4,
75 0x73, 0x74, 0x62, 0x6C, 0x00, 0x00, 0x00, 0x98, 0x73, 0x74, 0x73, 0x64, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x88, 0x61, 0x76, 0x63, 0x31,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x04, 0x38,
79 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
80 0x0A, 0x41, 0x56, 0x43, 0x20, 0x43, 0x6F, 0x64, 0x69, 0x6E, 0x67, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x32, 0x61, 0x76,
83 0x63, 0x43, 0x01, 0x64, 0x00, 0x28, 0xFF, 0xE1, 0x00, 0x1A, 0x67, 0x64, 0x00, 0x28,
84 0xAC, 0xD9, 0x40, 0x78, 0x02, 0x27, 0xE5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00,
85 0x00, 0x03, 0x00, 0xF0, 0x3C, 0x60, 0xC6, 0x58, 0x01, 0x00, 0x05, 0x68, 0xEB, 0xEC,
86 0xB2, 0x2C, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x74, 0x73, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x73, 0x74, 0x73, 0x63, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x73, 0x74, 0x73, 0x7A,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x10, 0x73, 0x74, 0x63, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x14, 0x76, 0x6D, 0x68, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x65, 0x64, 0x74, 0x73,
93 0x00, 0x00, 0x00, 0x1C, 0x65, 0x6C, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x70, 0x00, 0x01, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x38, 0x6D, 0x76, 0x65, 0x78, 0x00, 0x00, 0x00, 0x10, 0x6D, 0x65,
96 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB9, 0x31, 0x50, 0x00, 0x00, 0x00, 0x20,
97 0x74, 0x72, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
98 0x00, 0x01, 0x00, 0x00, 0x0B, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 ];
100
101 let decoded = Moov::decode(&mut &ENCODED[..]).unwrap();
102 assert_eq!(
103 decoded,
104 Moov {
105 mvhd: Mvhd {
106 creation_time: 3773812694,
107 modification_time: 3773812694,
108 timescale: 90000,
109 rate: 1.into(),
110 volume: 1.into(),
111 next_track_id: 2,
112 ..Default::default()
113 },
114 meta: Some(Meta::Unknown {
115 hdlr: Hdlr {
116 handler: b"ID32".into(),
117 name: "".to_string(),
118 },
119 data: vec![
120 0, 0, 0, 97, 73, 68, 51, 50, 0, 0, 0, 0, 21, 199, 73, 68, 51, 4, 0, 0, 0,
121 0, 0, 73, 80, 82, 73, 86, 0, 0, 0, 63, 0, 0, 104, 116, 116, 112, 115, 58,
122 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 103, 111, 111,
123 103, 108, 101, 47, 115, 104, 97, 107, 97, 45, 112, 97, 99, 107, 97, 103,
124 101, 114, 0, 118, 50, 46, 54, 46, 49, 45, 54, 51, 52, 97, 102, 54, 53, 45,
125 114, 101, 108, 101, 97, 115, 101
126 ]
127 }),
128 mvex: Some(Mvex {
129 mehd: Some(Mehd {
130 fragment_duration: 28914000
131 }),
132 trex: vec![Trex {
133 track_id: 1,
134 default_sample_description_index: 1,
135 default_sample_duration: 3000,
136 ..Default::default()
137 }]
138 }),
139 trak: vec![Trak {
140 tkhd: Tkhd {
141 creation_time: 3773812694,
142 modification_time: 3773812694,
143 track_id: 1,
144 enabled: true,
145 width: 1920.into(),
146 height: 1080.into(),
147 ..Default::default()
148 },
149 edts: Some(Edts {
150 elst: Some(Elst {
151 entries: vec![ElstEntry {
152 media_time: 6000,
153 media_rate: 1,
154 ..Default::default()
155 }]
156 })
157 }),
158 meta: None,
159 mdia: Mdia {
160 mdhd: Mdhd {
161 creation_time: 3773812694,
162 modification_time: 3773812694,
163 timescale: 90000,
164 duration: 0,
165 language: "und".to_string(),
166 },
167 hdlr: Hdlr {
168 handler: b"vide".into(),
169 name: "VideoHandler".to_string(),
170 },
171 minf: Minf {
172 vmhd: Some(Vmhd {
173 graphics_mode: 0,
174 op_color: RgbColor {
175 red: 0,
176 green: 0,
177 blue: 0
178 }
179 }),
180 smhd: None,
181 dinf: Dinf {
182 dref: Dref {
183 urls: vec![Url::default()]
184 }
185 },
186 stbl: Stbl {
187 stsd: Stsd {
188 codecs: vec![Avc1 {
189 visual: Visual {
190 data_reference_index: 1,
191 width: 1920,
192 height: 1080,
193 horizresolution: 72.into(),
194 vertresolution: 72.into(),
195 frame_count: 1,
196 compressor: "\nAVC Coding".into(),
197 depth: 24,
198 },
199 avcc: Avcc {
200 configuration_version: 1,
201 avc_profile_indication: 100,
202 profile_compatibility: 0,
203 avc_level_indication: 40,
204 length_size: 4,
205 sequence_parameter_sets: vec![vec![
206 103, 100, 0, 40, 172, 217, 64, 120, 2, 39, 229,
207 132, 0, 0, 3, 0, 4, 0, 0, 3, 0, 240, 60, 96, 198,
208 88
209 ]],
210 picture_parameter_sets: vec![vec![
211 104, 235, 236, 178, 44
212 ]],
213 ext: None,
214 }
215 }
216 .into()],
217 },
218 stco: Some(Stco::default()),
219 ..Default::default()
220 }
221 }
222 }
223 }],
224 udta: None,
225 }
226 )
227 }
228}