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