1use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
2use serde::Serialize;
3use std::io::{Read, Seek, Write};
4
5use crate::mp4box::*;
6
7#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
8pub struct TrexBox {
9 pub version: u8,
10 pub flags: u32,
11 pub track_id: u32,
12 pub default_sample_description_index: u32,
13 pub default_sample_duration: u32,
14 pub default_sample_size: u32,
15 pub default_sample_flags: u32,
16}
17
18impl TrexBox {
19 pub fn get_type(&self) -> BoxType {
20 BoxType::TrexBox
21 }
22
23 pub fn get_size(&self) -> u64 {
24 HEADER_SIZE + HEADER_EXT_SIZE + 20
25 }
26}
27
28impl Mp4Box for TrexBox {
29 fn box_type(&self) -> BoxType {
30 self.get_type()
31 }
32
33 fn box_size(&self) -> u64 {
34 self.get_size()
35 }
36
37 fn to_json(&self) -> Result<String> {
38 Ok(serde_json::to_string(&self).unwrap())
39 }
40
41 fn summary(&self) -> Result<String> {
42 let s = format!(
43 "track_id={} default_sample_duration={}",
44 self.track_id, self.default_sample_duration
45 );
46 Ok(s)
47 }
48}
49
50impl<R: Read + Seek> ReadBox<&mut R> for TrexBox {
51 fn read_box(reader: &mut R, size: u64) -> Result<Self> {
52 let start = box_start(reader)?;
53
54 let (version, flags) = read_box_header_ext(reader)?;
55
56 let track_id = reader.read_u32::<BigEndian>()?;
57 let default_sample_description_index = reader.read_u32::<BigEndian>()?;
58 let default_sample_duration = reader.read_u32::<BigEndian>()?;
59 let default_sample_size = reader.read_u32::<BigEndian>()?;
60 let default_sample_flags = reader.read_u32::<BigEndian>()?;
61
62 skip_bytes_to(reader, start + size)?;
63
64 Ok(TrexBox {
65 version,
66 flags,
67 track_id,
68 default_sample_description_index,
69 default_sample_duration,
70 default_sample_size,
71 default_sample_flags,
72 })
73 }
74}
75
76impl<W: Write> WriteBox<&mut W> for TrexBox {
77 fn write_box(&self, writer: &mut W) -> Result<u64> {
78 let size = self.box_size();
79 BoxHeader::new(self.box_type(), size).write(writer)?;
80
81 write_box_header_ext(writer, self.version, self.flags)?;
82
83 writer.write_u32::<BigEndian>(self.track_id)?;
84 writer.write_u32::<BigEndian>(self.default_sample_description_index)?;
85 writer.write_u32::<BigEndian>(self.default_sample_duration)?;
86 writer.write_u32::<BigEndian>(self.default_sample_size)?;
87 writer.write_u32::<BigEndian>(self.default_sample_flags)?;
88
89 Ok(size)
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 use crate::mp4box::BoxHeader;
97 use std::io::Cursor;
98
99 #[test]
100 fn test_trex() {
101 let src_box = TrexBox {
102 version: 0,
103 flags: 0,
104 track_id: 1,
105 default_sample_description_index: 1,
106 default_sample_duration: 1000,
107 default_sample_size: 0,
108 default_sample_flags: 65536,
109 };
110 let mut buf = Vec::new();
111 src_box.write_box(&mut buf).unwrap();
112 assert_eq!(buf.len(), src_box.box_size() as usize);
113
114 let mut reader = Cursor::new(&buf);
115 let header = BoxHeader::read(&mut reader).unwrap();
116 assert_eq!(header.name, BoxType::TrexBox);
117 assert_eq!(src_box.box_size(), header.size);
118
119 let dst_box = TrexBox::read_box(&mut reader, header.size).unwrap();
120 assert_eq!(src_box, dst_box);
121 }
122}