scuffle_mp4/boxes/types/
minf.rs

1use std::io;
2
3use bytes::{Buf, Bytes};
4
5use super::dinf::Dinf;
6use super::hmhd::Hmhd;
7use super::nmhd::Nmhd;
8use super::smhd::Smhd;
9use super::stbl::Stbl;
10use super::vmhd::Vmhd;
11use crate::boxes::DynBox;
12use crate::boxes::header::BoxHeader;
13use crate::boxes::traits::BoxType;
14
15#[derive(Debug, Clone, PartialEq)]
16/// Media Information Box
17/// ISO/IEC 14496-12:2022(E) - 8.4.4
18pub struct Minf {
19    pub header: BoxHeader,
20    pub vmhd: Option<Vmhd>,
21    pub smhd: Option<Smhd>,
22    pub hmhd: Option<Hmhd>,
23    pub nmhd: Option<Nmhd>,
24    pub dinf: Dinf,
25    pub stbl: Stbl,
26    pub unknown: Vec<DynBox>,
27}
28
29impl Minf {
30    pub fn new(stbl: Stbl, vmhd: Option<Vmhd>, smhd: Option<Smhd>) -> Self {
31        Self {
32            header: BoxHeader::new(Self::NAME),
33            vmhd,
34            smhd,
35            hmhd: None,
36            nmhd: None,
37            dinf: Dinf::new(),
38            stbl,
39            unknown: Vec::new(),
40        }
41    }
42}
43
44impl BoxType for Minf {
45    const NAME: [u8; 4] = *b"minf";
46
47    fn demux(header: BoxHeader, data: Bytes) -> io::Result<Self> {
48        let mut reader = io::Cursor::new(data);
49        let mut vmhd = None;
50        let mut smhd = None;
51        let mut hmhd = None;
52        let mut nmhd = None;
53        let mut dinf = None;
54        let mut stbl = None;
55        let mut unknown = Vec::new();
56
57        while reader.has_remaining() {
58            let dyn_box = DynBox::demux(&mut reader)?;
59
60            match dyn_box {
61                DynBox::Vmhd(b) => {
62                    vmhd = Some(*b);
63                }
64                DynBox::Smhd(b) => {
65                    smhd = Some(*b);
66                }
67                DynBox::Hmhd(b) => {
68                    hmhd = Some(*b);
69                }
70                DynBox::Nmhd(b) => {
71                    nmhd = Some(*b);
72                }
73                DynBox::Dinf(b) => {
74                    dinf = Some(*b);
75                }
76                DynBox::Stbl(b) => {
77                    stbl = Some(*b);
78                }
79                _ => {
80                    unknown.push(dyn_box);
81                }
82            }
83        }
84
85        let dinf = dinf.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "minf: dinf box is required"))?;
86        let stbl = stbl.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "minf: stbl box is required"))?;
87
88        Ok(Self {
89            header,
90            vmhd,
91            smhd,
92            hmhd,
93            nmhd,
94            dinf,
95            stbl,
96            unknown,
97        })
98    }
99
100    fn primitive_size(&self) -> u64 {
101        self.vmhd.as_ref().map(|b| b.size()).unwrap_or(0) // vmhd 
102        + self.smhd.as_ref().map(|b| b.size()).unwrap_or(0) // smhd
103        + self.hmhd.as_ref().map(|b| b.size()).unwrap_or(0) // hmhd
104        + self.nmhd.as_ref().map(|b| b.size()).unwrap_or(0) // nmhd
105        + self.dinf.size() // dinf
106        + self.stbl.size() // stbl
107        + self.unknown.iter().map(|b| b.size()).sum::<u64>() // unknown boxes
108    }
109
110    fn primitive_mux<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
111        if let Some(b) = &self.vmhd {
112            b.mux(writer)?;
113        }
114
115        if let Some(b) = &self.smhd {
116            b.mux(writer)?;
117        }
118
119        if let Some(b) = &self.hmhd {
120            b.mux(writer)?;
121        }
122
123        if let Some(b) = &self.nmhd {
124            b.mux(writer)?;
125        }
126
127        self.dinf.mux(writer)?;
128
129        self.stbl.mux(writer)?;
130
131        for b in &self.unknown {
132            b.mux(writer)?;
133        }
134
135        Ok(())
136    }
137}