Skip to main content

mp4/mp4box/
stsd.rs

1use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
2use serde::Serialize;
3use std::io::{Read, Seek, Write};
4
5use crate::mp4box::vp09::Vp09Box;
6use crate::mp4box::*;
7use crate::mp4box::{avc1::Avc1Box, hev1::Hev1Box, mp4a::Mp4aBox, tx3g::Tx3gBox};
8
9#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
10pub struct StsdBox {
11    pub version: u8,
12    pub flags: u32,
13
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub avc1: Option<Avc1Box>,
16
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub hev1: Option<Hev1Box>,
19
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub vp09: Option<Vp09Box>,
22
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub mp4a: Option<Mp4aBox>,
25
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub tx3g: Option<Tx3gBox>,
28}
29
30impl StsdBox {
31    pub fn get_type(&self) -> BoxType {
32        BoxType::StsdBox
33    }
34
35    pub fn get_size(&self) -> u64 {
36        let mut size = HEADER_SIZE + HEADER_EXT_SIZE + 4;
37        if let Some(ref avc1) = self.avc1 {
38            size += avc1.box_size();
39        } else if let Some(ref hev1) = self.hev1 {
40            size += hev1.box_size();
41        } else if let Some(ref vp09) = self.vp09 {
42            size += vp09.box_size();
43        } else if let Some(ref mp4a) = self.mp4a {
44            size += mp4a.box_size();
45        } else if let Some(ref tx3g) = self.tx3g {
46            size += tx3g.box_size();
47        }
48        size
49    }
50}
51
52impl Mp4Box for StsdBox {
53    fn box_type(&self) -> BoxType {
54        self.get_type()
55    }
56
57    fn box_size(&self) -> u64 {
58        self.get_size()
59    }
60
61    fn to_json(&self) -> Result<String> {
62        Ok(serde_json::to_string(&self).unwrap())
63    }
64
65    fn summary(&self) -> Result<String> {
66        let s = String::new();
67        Ok(s)
68    }
69}
70
71impl<R: Read + Seek> ReadBox<&mut R> for StsdBox {
72    fn read_box(reader: &mut R, size: u64) -> Result<Self> {
73        let start = box_start(reader)?;
74
75        let (version, flags) = read_box_header_ext(reader)?;
76
77        reader.read_u32::<BigEndian>()?; // XXX entry_count
78
79        let mut avc1 = None;
80        let mut hev1 = None;
81        let mut vp09 = None;
82        let mut mp4a = None;
83        let mut tx3g = None;
84
85        // Get box header.
86        let header = BoxHeader::read(reader)?;
87        let BoxHeader { name, size: s } = header;
88        if s > size {
89            return Err(Error::InvalidData(
90                "stsd box contains a box with a larger size than it",
91            ));
92        }
93
94        match name {
95            BoxType::Avc1Box => {
96                avc1 = Some(Avc1Box::read_box(reader, s)?);
97            }
98            BoxType::Hev1Box => {
99                hev1 = Some(Hev1Box::read_box(reader, s)?);
100            }
101            BoxType::Vp09Box => {
102                vp09 = Some(Vp09Box::read_box(reader, s)?);
103            }
104            BoxType::Mp4aBox => {
105                mp4a = Some(Mp4aBox::read_box(reader, s)?);
106            }
107            BoxType::Tx3gBox => {
108                tx3g = Some(Tx3gBox::read_box(reader, s)?);
109            }
110            _ => {}
111        }
112
113        skip_bytes_to(reader, start + size)?;
114
115        Ok(StsdBox {
116            version,
117            flags,
118            avc1,
119            hev1,
120            vp09,
121            mp4a,
122            tx3g,
123        })
124    }
125}
126
127impl<W: Write> WriteBox<&mut W> for StsdBox {
128    fn write_box(&self, writer: &mut W) -> Result<u64> {
129        let size = self.box_size();
130        BoxHeader::new(self.box_type(), size).write(writer)?;
131
132        write_box_header_ext(writer, self.version, self.flags)?;
133
134        writer.write_u32::<BigEndian>(1)?; // entry_count
135
136        if let Some(ref avc1) = self.avc1 {
137            avc1.write_box(writer)?;
138        } else if let Some(ref hev1) = self.hev1 {
139            hev1.write_box(writer)?;
140        } else if let Some(ref vp09) = self.vp09 {
141            vp09.write_box(writer)?;
142        } else if let Some(ref mp4a) = self.mp4a {
143            mp4a.write_box(writer)?;
144        } else if let Some(ref tx3g) = self.tx3g {
145            tx3g.write_box(writer)?;
146        }
147
148        Ok(size)
149    }
150}