mp4_atom/moof/traf/
tfhd.rs

1use 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}
27
28impl AtomExt for Tfhd {
29    const KIND_EXT: FourCC = FourCC::new(b"tfhd");
30
31    type Ext = TfhdExt;
32
33    fn decode_body_ext<B: Buf>(buf: &mut B, ext: TfhdExt) -> Result<Self> {
34        let track_id = u32::decode(buf)?;
35
36        let base_data_offset = match ext.base_data_offset {
37            true => u64::decode(buf)?.into(),
38            false => None,
39        };
40
41        let sample_description_index = match ext.sample_description_index {
42            true => u32::decode(buf)?.into(),
43            false => None,
44        };
45
46        let default_sample_duration = match ext.default_sample_duration {
47            true => u32::decode(buf)?.into(),
48            false => None,
49        };
50
51        let default_sample_size = match ext.default_sample_size {
52            true => u32::decode(buf)?.into(),
53            false => None,
54        };
55
56        let default_sample_flags = match ext.default_sample_flags {
57            true => u32::decode(buf)?.into(),
58            false => None,
59        };
60
61        Ok(Tfhd {
62            track_id,
63            base_data_offset,
64            sample_description_index,
65            default_sample_duration,
66            default_sample_size,
67            default_sample_flags,
68        })
69    }
70
71    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<TfhdExt> {
72        let ext = TfhdExt {
73            base_data_offset: self.base_data_offset.is_some(),
74            sample_description_index: self.sample_description_index.is_some(),
75            default_sample_duration: self.default_sample_duration.is_some(),
76            default_sample_size: self.default_sample_size.is_some(),
77            default_sample_flags: self.default_sample_flags.is_some(),
78            ..Default::default()
79        };
80
81        self.track_id.encode(buf)?;
82        self.base_data_offset.encode(buf)?;
83        self.sample_description_index.encode(buf)?;
84        self.default_sample_duration.encode(buf)?;
85        self.default_sample_size.encode(buf)?;
86        self.default_sample_flags.encode(buf)?;
87
88        Ok(ext)
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95
96    #[test]
97    fn test_tfhd() {
98        let expected = Tfhd {
99            track_id: 1,
100            base_data_offset: None,
101            sample_description_index: None,
102            default_sample_duration: None,
103            default_sample_size: None,
104            default_sample_flags: None,
105        };
106        let mut buf = Vec::new();
107        expected.encode(&mut buf).unwrap();
108
109        let mut buf = buf.as_ref();
110        let decoded = Tfhd::decode(&mut buf).unwrap();
111        assert_eq!(decoded, expected);
112    }
113
114    #[test]
115    fn test_tfhd_with_flags() {
116        let expected = Tfhd {
117            track_id: 1,
118            base_data_offset: None,
119            sample_description_index: Some(1),
120            default_sample_duration: Some(512),
121            default_sample_size: None,
122            default_sample_flags: Some(0x1010000),
123        };
124        let mut buf = Vec::new();
125        expected.encode(&mut buf).unwrap();
126
127        let mut buf = buf.as_ref();
128        let decoded = Tfhd::decode(&mut buf).unwrap();
129        assert_eq!(decoded, expected);
130    }
131}