Skip to main content

mp4/mp4box/
minf.rs

1use serde::Serialize;
2use std::io::{Read, Seek, Write};
3
4use crate::mp4box::*;
5use crate::mp4box::{dinf::DinfBox, smhd::SmhdBox, stbl::StblBox, vmhd::VmhdBox};
6
7#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
8pub struct MinfBox {
9    #[serde(skip_serializing_if = "Option::is_none")]
10    pub vmhd: Option<VmhdBox>,
11
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub smhd: Option<SmhdBox>,
14
15    pub dinf: DinfBox,
16    pub stbl: StblBox,
17}
18
19impl MinfBox {
20    pub fn get_type(&self) -> BoxType {
21        BoxType::MinfBox
22    }
23
24    pub fn get_size(&self) -> u64 {
25        let mut size = HEADER_SIZE;
26        if let Some(ref vmhd) = self.vmhd {
27            size += vmhd.box_size();
28        }
29        if let Some(ref smhd) = self.smhd {
30            size += smhd.box_size();
31        }
32        size += self.dinf.box_size();
33        size += self.stbl.box_size();
34        size
35    }
36}
37
38impl Mp4Box for MinfBox {
39    fn box_type(&self) -> BoxType {
40        self.get_type()
41    }
42
43    fn box_size(&self) -> u64 {
44        self.get_size()
45    }
46
47    fn to_json(&self) -> Result<String> {
48        Ok(serde_json::to_string(&self).unwrap())
49    }
50
51    fn summary(&self) -> Result<String> {
52        let s = String::new();
53        Ok(s)
54    }
55}
56
57impl<R: Read + Seek> ReadBox<&mut R> for MinfBox {
58    fn read_box(reader: &mut R, size: u64) -> Result<Self> {
59        let start = box_start(reader)?;
60
61        let mut vmhd = None;
62        let mut smhd = None;
63        let mut dinf = None;
64        let mut stbl = None;
65
66        let mut current = reader.stream_position()?;
67        let end = start + size;
68        while current < end {
69            // Get box header.
70            let header = BoxHeader::read(reader)?;
71            let BoxHeader { name, size: s } = header;
72            if s > size {
73                return Err(Error::InvalidData(
74                    "minf box contains a box with a larger size than it",
75                ));
76            }
77
78            match name {
79                BoxType::VmhdBox => {
80                    vmhd = Some(VmhdBox::read_box(reader, s)?);
81                }
82                BoxType::SmhdBox => {
83                    smhd = Some(SmhdBox::read_box(reader, s)?);
84                }
85                BoxType::DinfBox => {
86                    dinf = Some(DinfBox::read_box(reader, s)?);
87                }
88                BoxType::StblBox => {
89                    stbl = Some(StblBox::read_box(reader, s)?);
90                }
91                _ => {
92                    // XXX warn!()
93                    skip_box(reader, s)?;
94                }
95            }
96
97            current = reader.stream_position()?;
98        }
99
100        if dinf.is_none() {
101            return Err(Error::BoxNotFound(BoxType::DinfBox));
102        }
103        if stbl.is_none() {
104            return Err(Error::BoxNotFound(BoxType::StblBox));
105        }
106
107        skip_bytes_to(reader, start + size)?;
108
109        Ok(MinfBox {
110            vmhd,
111            smhd,
112            dinf: dinf.unwrap(),
113            stbl: stbl.unwrap(),
114        })
115    }
116}
117
118impl<W: Write> WriteBox<&mut W> for MinfBox {
119    fn write_box(&self, writer: &mut W) -> Result<u64> {
120        let size = self.box_size();
121        BoxHeader::new(self.box_type(), size).write(writer)?;
122
123        if let Some(ref vmhd) = self.vmhd {
124            vmhd.write_box(writer)?;
125        }
126        if let Some(ref smhd) = self.smhd {
127            smhd.write_box(writer)?;
128        }
129        self.dinf.write_box(writer)?;
130        self.stbl.write_box(writer)?;
131
132        Ok(size)
133    }
134}