flowly_mp4/mp4box/
trex.rs1use byteorder::{BigEndian, WriteBytesExt};
2use serde::Serialize;
3use std::io::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 const TYPE: BoxType = BoxType::TrexBox;
30
31 fn box_size(&self) -> u64 {
32 self.get_size()
33 }
34
35 fn to_json(&self) -> Result<String, Error> {
36 Ok(serde_json::to_string(&self).unwrap())
37 }
38
39 fn summary(&self) -> Result<String, Error> {
40 let s = format!(
41 "track_id={} default_sample_duration={}",
42 self.track_id, self.default_sample_duration
43 );
44 Ok(s)
45 }
46}
47
48impl BlockReader for TrexBox {
49 fn read_block<'a>(reader: &mut impl Reader<'a>) -> Result<Self, Error> {
50 let (version, flags) = read_box_header_ext(reader);
51
52 let track_id = reader.get_u32();
53 let default_sample_description_index = reader.get_u32();
54 let default_sample_duration = reader.get_u32();
55 let default_sample_size = reader.get_u32();
56 let default_sample_flags = reader.get_u32();
57
58 Ok(TrexBox {
59 version,
60 flags,
61 track_id,
62 default_sample_description_index,
63 default_sample_duration,
64 default_sample_size,
65 default_sample_flags,
66 })
67 }
68
69 fn size_hint() -> usize {
70 24
71 }
72}
73
74impl<W: Write> WriteBox<&mut W> for TrexBox {
75 fn write_box(&self, writer: &mut W) -> Result<u64, Error> {
76 let size = self.box_size();
77 BoxHeader::new(Self::TYPE, size).write(writer)?;
78
79 write_box_header_ext(writer, self.version, self.flags)?;
80
81 writer.write_u32::<BigEndian>(self.track_id)?;
82 writer.write_u32::<BigEndian>(self.default_sample_description_index)?;
83 writer.write_u32::<BigEndian>(self.default_sample_duration)?;
84 writer.write_u32::<BigEndian>(self.default_sample_size)?;
85 writer.write_u32::<BigEndian>(self.default_sample_flags)?;
86
87 Ok(size)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94 use crate::mp4box::BoxHeader;
95
96 #[tokio::test]
97 async fn test_trex() {
98 let src_box = TrexBox {
99 version: 0,
100 flags: 0,
101 track_id: 1,
102 default_sample_description_index: 1,
103 default_sample_duration: 1000,
104 default_sample_size: 0,
105 default_sample_flags: 65536,
106 };
107 let mut buf = Vec::new();
108 src_box.write_box(&mut buf).unwrap();
109 assert_eq!(buf.len(), src_box.box_size() as usize);
110
111 let mut reader = buf.as_slice();
112 let header = BoxHeader::read(&mut reader, &mut 0).await.unwrap().unwrap();
113 assert_eq!(header.kind, BoxType::TrexBox);
114 assert_eq!(src_box.box_size(), header.size);
115
116 let dst_box = TrexBox::read_block(&mut reader).unwrap();
117 assert_eq!(src_box, dst_box);
118 }
119}