Skip to main content

mp4/mp4box/
mvex.rs

1use serde::Serialize;
2use std::io::{Read, Seek, Write};
3
4use crate::mp4box::*;
5use crate::mp4box::{mehd::MehdBox, trex::TrexBox};
6
7#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
8pub struct MvexBox {
9    pub mehd: Option<MehdBox>,
10    pub trex: TrexBox,
11}
12
13impl MvexBox {
14    pub fn get_type(&self) -> BoxType {
15        BoxType::MdiaBox
16    }
17
18    pub fn get_size(&self) -> u64 {
19        HEADER_SIZE + self.mehd.as_ref().map(|x| x.box_size()).unwrap_or(0) + self.trex.box_size()
20    }
21}
22
23impl Mp4Box for MvexBox {
24    fn box_type(&self) -> BoxType {
25        self.get_type()
26    }
27
28    fn box_size(&self) -> u64 {
29        self.get_size()
30    }
31
32    fn to_json(&self) -> Result<String> {
33        Ok(serde_json::to_string(&self).unwrap())
34    }
35
36    fn summary(&self) -> Result<String> {
37        let s = String::new();
38        Ok(s)
39    }
40}
41
42impl<R: Read + Seek> ReadBox<&mut R> for MvexBox {
43    fn read_box(reader: &mut R, size: u64) -> Result<Self> {
44        let start = box_start(reader)?;
45
46        let mut mehd = None;
47        let mut trex = None;
48
49        let mut current = reader.stream_position()?;
50        let end = start + size;
51        while current < end {
52            // Get box header.
53            let header = BoxHeader::read(reader)?;
54            let BoxHeader { name, size: s } = header;
55            if s > size {
56                return Err(Error::InvalidData(
57                    "mvex box contains a box with a larger size than it",
58                ));
59            }
60
61            match name {
62                BoxType::MehdBox => {
63                    mehd = Some(MehdBox::read_box(reader, s)?);
64                }
65                BoxType::TrexBox => {
66                    trex = Some(TrexBox::read_box(reader, s)?);
67                }
68                _ => {
69                    // XXX warn!()
70                    skip_box(reader, s)?;
71                }
72            }
73
74            current = reader.stream_position()?;
75        }
76
77        if trex.is_none() {
78            return Err(Error::BoxNotFound(BoxType::TrexBox));
79        }
80
81        skip_bytes_to(reader, start + size)?;
82
83        Ok(MvexBox {
84            mehd,
85            trex: trex.unwrap(),
86        })
87    }
88}
89
90impl<W: Write> WriteBox<&mut W> for MvexBox {
91    fn write_box(&self, writer: &mut W) -> Result<u64> {
92        let size = self.box_size();
93        BoxHeader::new(self.box_type(), size).write(writer)?;
94
95        if let Some(mehd) = &self.mehd {
96            mehd.write_box(writer)?;
97        }
98        self.trex.write_box(writer)?;
99
100        Ok(size)
101    }
102}