mp4_atom/moov/trak/mdia/minf/stbl/stsd/
taic.rs

1use crate::*;
2
3#[derive(Clone, Debug, Default, Eq, PartialEq)]
4#[repr(u8)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub enum ClockType {
7    #[default]
8    Unknown = 0,
9    DoesNotSync = 1,
10    CanSync = 2,
11    Reserved = 3,
12}
13
14impl From<u8> for ClockType {
15    fn from(value: u8) -> Self {
16        match value {
17            0 => ClockType::Unknown,
18            1 => ClockType::DoesNotSync,
19            2 => ClockType::CanSync,
20            _ => ClockType::Reserved,
21        }
22    }
23}
24
25#[derive(Clone, Debug, Default, Eq, PartialEq)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27pub struct Taic {
28    pub time_uncertainty: u64,
29    pub clock_resolution: u32,
30    pub clock_drift_rate: i32,
31    pub clock_type: ClockType,
32}
33
34impl Taic {
35    pub fn new(
36        time_uncertainty: u64,
37        clock_resolution: u32,
38        clock_drift_rate: i32,
39        clock_type: ClockType,
40    ) -> Result<Self> {
41        Ok(Taic {
42            time_uncertainty,
43            clock_resolution,
44            clock_drift_rate,
45            clock_type,
46        })
47    }
48}
49
50impl AtomExt for Taic {
51    type Ext = ();
52    const KIND_EXT: FourCC = FourCC::new(b"taic");
53
54    fn decode_body_ext<B: Buf>(buf: &mut B, _ext: ()) -> Result<Self> {
55        let time_uncertainty = u64::decode(buf)?;
56        let clock_resolution = u32::decode(buf)?;
57        let clock_drift_rate = i32::decode(buf)?;
58        let clock_type_with_reserved = u8::decode(buf)?;
59        let clock_type: ClockType = (clock_type_with_reserved >> 6).into();
60        Ok(Taic {
61            time_uncertainty,
62            clock_resolution,
63            clock_drift_rate,
64            clock_type,
65        })
66    }
67
68    fn encode_body_ext<B: BufMut>(&self, buf: &mut B) -> Result<()> {
69        self.time_uncertainty.encode(buf)?;
70        self.clock_resolution.encode(buf)?;
71        self.clock_drift_rate.encode(buf)?;
72        let clock_type_with_reserved: u8 = (self.clock_type.clone() as u8) << 6;
73        clock_type_with_reserved.encode(buf)?;
74        Ok(())
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    const ENCODED_TAIC: &[u8] = &[
83        0x00, 0x00, 0x00, 0x1d, b't', b'a', b'i', b'c', 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
84        0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x27, 0x10, 0x7f, 0xff, 0xff, 0xff, 0x80,
85    ];
86
87    #[test]
88    fn test_taic_decode() {
89        let buf: &mut std::io::Cursor<&&[u8]> = &mut std::io::Cursor::new(&ENCODED_TAIC);
90
91        let taic = Taic::decode(buf).expect("failed to decode taic");
92
93        assert_eq!(
94            taic,
95            Taic {
96                time_uncertainty: u64::MAX,
97                clock_resolution: 10000,
98                clock_drift_rate: i32::MAX,
99                clock_type: ClockType::CanSync,
100            }
101        );
102    }
103
104    #[test]
105    fn test_taic_encode() {
106        let taic = Taic {
107            time_uncertainty: u64::MAX,
108            clock_resolution: 10000,
109            clock_drift_rate: i32::MAX,
110            clock_type: ClockType::CanSync,
111        };
112
113        let mut buf = Vec::new();
114        taic.encode(&mut buf).unwrap();
115
116        assert_eq!(buf.as_slice(), ENCODED_TAIC);
117    }
118}