mp4_atom/meta/
mod.rs

1mod idat;
2mod iinf;
3mod iloc;
4mod ilst;
5mod iprp;
6mod iref;
7mod pitm;
8mod properties;
9
10pub use idat::*;
11pub use iinf::*;
12pub use iloc::*;
13pub use ilst::*;
14pub use iprp::*;
15pub use iref::*;
16pub use pitm::*;
17pub use properties::*;
18
19use crate::*;
20
21// MetaBox, ISO/IEC 14496:2022 Secion 8.11.1
22// Its like a container box, but derived from FullBox
23
24// TODO: add ItemProtectionBox, IPMPControlBox
25
26#[derive(Debug, Clone, PartialEq)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub struct Meta {
29    pub hdlr: Hdlr,
30    pub pitm: Option<Pitm>,
31    pub dinf: Option<Dinf>,
32    pub iloc: Option<Iloc>,
33    pub iinf: Option<Iinf>,
34    pub iprp: Option<Iprp>,
35    pub iref: Option<Iref>,
36    pub idat: Option<Idat>,
37    pub ilst: Option<Ilst>,
38    pub unknown: Vec<crate::Any>,
39}
40
41impl Eq for Meta {}
42
43impl AtomExt for Meta {
44    type Ext = ();
45
46    const KIND_EXT: FourCC = FourCC::new(b"meta");
47
48    fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
49        let hdlr = Hdlr::decode(buf)?;
50        let mut pitm = None;
51        let mut dinf = None;
52        let mut iloc = None;
53        let mut iinf = None;
54        let mut iprp = None;
55        let mut iref = None;
56        let mut idat = None;
57        let mut ilst = None;
58        let mut unknown_boxes = vec![];
59        while let Some(atom) = Any::decode_maybe(buf)? {
60            match atom {
61                Any::Pitm(atom) => pitm = Some(atom),
62                Any::Dinf(atom) => dinf = Some(atom),
63                Any::Iloc(atom) => iloc = Some(atom),
64                Any::Iinf(atom) => iinf = Some(atom),
65                Any::Iprp(atom) => iprp = Some(atom),
66                Any::Iref(atom) => iref = Some(atom),
67                Any::Idat(atom) => idat = Some(atom),
68                Any::Ilst(atom) => ilst = Some(atom),
69                _ => {
70                    unknown_boxes.push(atom);
71                }
72            }
73        }
74
75        Ok(Self {
76            hdlr,
77            pitm,
78            dinf,
79            iloc,
80            iinf,
81            iprp,
82            iref,
83            idat,
84            ilst,
85            unknown: unknown_boxes,
86        })
87    }
88
89    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
90        self.hdlr.encode(buf)?;
91        if self.pitm.is_some() {
92            self.pitm.encode(buf)?;
93        }
94        if self.dinf.is_some() {
95            self.dinf.encode(buf)?;
96        }
97        if self.iloc.is_some() {
98            self.iloc.encode(buf)?;
99        }
100        if self.iinf.is_some() {
101            self.iinf.encode(buf)?;
102        }
103        if self.iprp.is_some() {
104            self.iprp.encode(buf)?;
105        }
106        if self.iref.is_some() {
107            self.iref.encode(buf)?;
108        }
109        if self.idat.is_some() {
110            self.idat.encode(buf)?;
111        }
112        if self.ilst.is_some() {
113            self.ilst.encode(buf)?;
114        }
115        for atom in &self.unknown {
116            atom.encode(buf)?;
117        }
118        Ok(())
119    }
120}
121
122#[cfg(test)]
123mod tests {
124    use super::*;
125
126    #[test]
127    fn test_meta_empty() {
128        let expected = Meta {
129            hdlr: Hdlr {
130                handler: b"fake".into(),
131                name: "".into(),
132            },
133            pitm: None,
134            dinf: None,
135            iloc: None,
136            iinf: None,
137            iprp: None,
138            iref: None,
139            idat: None,
140            ilst: None,
141            unknown: vec![],
142        };
143        let mut buf = Vec::new();
144        expected.encode(&mut buf).unwrap();
145
146        let mut buf = buf.as_ref();
147        let output = Meta::decode(&mut buf).unwrap();
148        assert_eq!(output, expected);
149    }
150
151    #[test]
152    fn test_meta_mdir() {
153        let expected = Meta {
154            hdlr: Hdlr {
155                handler: b"mdir".into(),
156                name: "".into(),
157            },
158            pitm: Some(Pitm { item_id: 3 }),
159            dinf: Some(Dinf {
160                dref: Dref {
161                    urls: vec![Url {
162                        location: "".into(),
163                    }],
164                },
165            }),
166            iloc: Some(Iloc {
167                item_locations: vec![ItemLocation {
168                    item_id: 3,
169                    construction_method: 0,
170                    data_reference_index: 0,
171                    base_offset: 0,
172                    extents: vec![ItemLocationExtent {
173                        item_reference_index: 0,
174                        offset: 200,
175                        length: 100,
176                    }],
177                }],
178            }),
179            iinf: Some(Iinf { item_infos: vec![] }),
180            iprp: Some(Iprp {
181                ipco: Ipco { properties: vec![] },
182                ipma: vec![Ipma {
183                    item_properties: vec![
184                        PropertyAssociations {
185                            item_id: 1,
186                            associations: vec![
187                                PropertyAssociation {
188                                    essential: true,
189                                    property_index: 1,
190                                },
191                                PropertyAssociation {
192                                    essential: false,
193                                    property_index: 2,
194                                },
195                                PropertyAssociation {
196                                    essential: false,
197                                    property_index: 3,
198                                },
199                                PropertyAssociation {
200                                    essential: false,
201                                    property_index: 5,
202                                },
203                                PropertyAssociation {
204                                    essential: true,
205                                    property_index: 4,
206                                },
207                            ],
208                        },
209                        PropertyAssociations {
210                            item_id: 2,
211                            associations: vec![
212                                PropertyAssociation {
213                                    essential: true,
214                                    property_index: 6,
215                                },
216                                PropertyAssociation {
217                                    essential: false,
218                                    property_index: 3,
219                                },
220                                PropertyAssociation {
221                                    essential: false,
222                                    property_index: 7,
223                                },
224                                PropertyAssociation {
225                                    essential: true,
226                                    property_index: 8,
227                                },
228                                PropertyAssociation {
229                                    essential: true,
230                                    property_index: 4,
231                                },
232                            ],
233                        },
234                    ],
235                }],
236            }),
237            iref: Some(Iref {
238                references: vec![Reference {
239                    reference_type: b"cdsc".into(),
240                    from_item_id: 2,
241                    to_item_ids: vec![1, 3],
242                }],
243            }),
244            idat: Some(Idat {
245                data: vec![0x01, 0xFF, 0xFE, 0x03],
246            }),
247            ilst: Some(Ilst::default()),
248            unknown: vec![],
249        };
250        let mut buf = Vec::new();
251        expected.encode(&mut buf).unwrap();
252
253        let mut buf = buf.as_ref();
254        let output = Meta::decode(&mut buf).unwrap();
255        assert_eq!(output, expected);
256    }
257}