mp4_atom/moof/traf/
tfhd.rs1use crate::*;
2
3ext! {
4 name: Tfhd,
5 versions: [0],
6 flags: {
7 base_data_offset = 0,
8 sample_description_index = 1,
9 default_sample_duration = 3,
10 default_sample_size = 4,
11 default_sample_flags = 5,
12 duration_is_empty = 16,
13 default_base_is_moof = 17,
14 }
15}
16
17#[derive(Debug, Clone, PartialEq, Eq, Default)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub struct Tfhd {
20 pub track_id: u32,
21 pub base_data_offset: Option<u64>,
22 pub sample_description_index: Option<u32>,
23 pub default_sample_duration: Option<u32>,
24 pub default_sample_size: Option<u32>,
25 pub default_sample_flags: Option<u32>,
26 pub duration_is_empty: bool,
27 pub default_base_is_moof: bool,
28}
29
30impl AtomExt for Tfhd {
31 const KIND_EXT: FourCC = FourCC::new(b"tfhd");
32
33 type Ext = TfhdExt;
34
35 fn decode_body_ext<B: Buf>(buf: &mut B, ext: TfhdExt) -> Result<Self> {
36 let track_id = u32::decode(buf)?;
37
38 let base_data_offset = match ext.base_data_offset {
39 true => u64::decode(buf)?.into(),
40 false => None,
41 };
42
43 let sample_description_index = match ext.sample_description_index {
44 true => u32::decode(buf)?.into(),
45 false => None,
46 };
47
48 let default_sample_duration = match ext.default_sample_duration {
49 true => u32::decode(buf)?.into(),
50 false => None,
51 };
52
53 let default_sample_size = match ext.default_sample_size {
54 true => u32::decode(buf)?.into(),
55 false => None,
56 };
57
58 let default_sample_flags = match ext.default_sample_flags {
59 true => u32::decode(buf)?.into(),
60 false => None,
61 };
62
63 Ok(Tfhd {
64 track_id,
65 base_data_offset,
66 sample_description_index,
67 default_sample_duration,
68 default_sample_size,
69 default_sample_flags,
70 duration_is_empty: ext.duration_is_empty,
71 default_base_is_moof: ext.default_base_is_moof,
72 })
73 }
74
75 fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<TfhdExt> {
76 let ext = TfhdExt {
77 base_data_offset: self.base_data_offset.is_some(),
78 sample_description_index: self.sample_description_index.is_some(),
79 default_sample_duration: self.default_sample_duration.is_some(),
80 default_sample_size: self.default_sample_size.is_some(),
81 default_sample_flags: self.default_sample_flags.is_some(),
82 duration_is_empty: self.duration_is_empty,
83 default_base_is_moof: self.default_base_is_moof,
84 ..Default::default()
85 };
86
87 self.track_id.encode(buf)?;
88 self.base_data_offset.encode(buf)?;
89 self.sample_description_index.encode(buf)?;
90 self.default_sample_duration.encode(buf)?;
91 self.default_sample_size.encode(buf)?;
92 self.default_sample_flags.encode(buf)?;
93
94 Ok(ext)
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_tfhd() {
104 let expected = Tfhd {
105 track_id: 1,
106 base_data_offset: None,
107 sample_description_index: None,
108 default_sample_duration: None,
109 default_sample_size: None,
110 default_sample_flags: None,
111 duration_is_empty: false,
112 default_base_is_moof: false,
113 };
114 let mut buf = Vec::new();
115 expected.encode(&mut buf).unwrap();
116
117 let mut buf = buf.as_ref();
118 let decoded = Tfhd::decode(&mut buf).unwrap();
119 assert_eq!(decoded, expected);
120 }
121
122 #[test]
123 fn test_tfhd_with_flags() {
124 let expected = Tfhd {
125 track_id: 1,
126 base_data_offset: None,
127 sample_description_index: Some(1),
128 default_sample_duration: Some(512),
129 default_sample_size: None,
130 default_sample_flags: Some(0x1010000),
131 duration_is_empty: false,
132 default_base_is_moof: false,
133 };
134 let mut buf = Vec::new();
135 expected.encode(&mut buf).unwrap();
136
137 let mut buf = buf.as_ref();
138 let decoded = Tfhd::decode(&mut buf).unwrap();
139 assert_eq!(decoded, expected);
140 }
141
142 #[test]
143 fn test_tfhd_duration_is_empty() {
144 let expected = Tfhd {
145 track_id: 1,
146 duration_is_empty: true,
147 ..Default::default()
148 };
149 let mut buf = Vec::new();
150 expected.encode(&mut buf).unwrap();
151
152 let mut buf = buf.as_ref();
153 let decoded = Tfhd::decode(&mut buf).unwrap();
154 assert_eq!(decoded, expected);
155 }
156
157 #[test]
158 fn test_tfhd_default_base_is_moof() {
159 let expected = Tfhd {
160 track_id: 1,
161 default_base_is_moof: true,
162 default_sample_duration: Some(512),
163 default_sample_size: Some(0),
164 default_sample_flags: Some(0x1010000),
165 ..Default::default()
166 };
167 let mut buf = Vec::new();
168 expected.encode(&mut buf).unwrap();
169
170 let mut buf = buf.as_ref();
171 let decoded = Tfhd::decode(&mut buf).unwrap();
172 assert_eq!(decoded, expected);
173 }
174}