Skip to main content

mp4/mp4box/
mdia.rs

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