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 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 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}