1use byteorder::{BigEndian, ReadBytesExt};
2use serde::Serialize;
3use std::io::{Read, Seek};
4
5use crate::mp4box::{
6 box_start, read_box_header_ext, skip_bytes_to, BoxType, Error, Mp4Box, ReadBox, Result,
7 HEADER_EXT_SIZE, HEADER_SIZE,
8};
9
10#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)]
11pub struct TfdtBox {
12 pub version: u8,
13 pub flags: u32,
14 pub base_media_decode_time: u64,
15}
16
17impl TfdtBox {
18 pub fn get_type(&self) -> BoxType {
19 BoxType::TfdtBox
20 }
21
22 pub fn get_size(&self) -> u64 {
23 let mut sum = HEADER_SIZE + HEADER_EXT_SIZE;
24 if self.version == 1 {
25 sum += 8;
26 } else {
27 sum += 4;
28 }
29 sum
30 }
31}
32
33impl Mp4Box for TfdtBox {
34 fn box_type(&self) -> BoxType {
35 self.get_type()
36 }
37
38 fn box_size(&self) -> u64 {
39 self.get_size()
40 }
41
42 fn to_json(&self) -> Result<String> {
43 Ok(serde_json::to_string(&self).expect("Failed to convert to JSON"))
44 }
45
46 fn summary(&self) -> Result<String> {
47 let s = format!("base_media_decode_time={}", self.base_media_decode_time);
48 Ok(s)
49 }
50}
51
52impl<R: Read + Seek> ReadBox<&mut R> for TfdtBox {
53 fn read_box(reader: &mut R, size: u64) -> Result<Self> {
54 let start = box_start(reader)?;
55
56 let (version, flags) = read_box_header_ext(reader)?;
57
58 let base_media_decode_time = if version == 1 {
59 reader.read_u64::<BigEndian>()?
60 } else if version == 0 {
61 reader.read_u32::<BigEndian>()? as u64
62 } else {
63 return Err(Error::InvalidData("version must be 0 or 1"));
64 };
65
66 skip_bytes_to(reader, start + size)?;
67
68 Ok(Self {
69 version,
70 flags,
71 base_media_decode_time,
72 })
73 }
74}