async_mp4/mp4box/
ftyp.rs

1use std::io::SeekFrom;
2use futures::{AsyncSeekExt};
3use crate::bytes_read::ReadMp4;
4use crate::bytes_write::{Mp4Writable, WriteMp4};
5use crate::error::MP4Error;
6use crate::header::BoxHeader;
7use crate::id::BoxId;
8use crate::mp4box::box_trait::{BoxRead, BoxWrite, IBox};
9use crate::r#type::BoxType;
10
11pub type FtypBox = Ftyp;
12
13#[derive(Debug, Clone, Eq, PartialEq, Hash)]
14pub struct Ftyp {
15    pub major_brand: [u8; 4],
16    pub minor_version: u32,
17    pub compatible_brands: Vec<[u8; 4]>
18}
19
20impl Ftyp {
21    fn inner_byte_size(&self) -> usize {
22        self.major_brand.byte_size() + self.minor_version.byte_size() + self.compatible_brands.iter().map(Mp4Writable::byte_size).sum::<usize>()
23    }
24
25    fn header(&self) -> BoxHeader {
26        BoxHeader::from_id_and_inner_size(Self::ID, self.inner_byte_size())
27    }
28}
29
30impl IBox for Ftyp {
31    fn byte_size(&self) -> usize {
32        self.header().byte_size() + self.inner_byte_size()
33    }
34
35    const ID: BoxType = BoxType::Id(BoxId(*b"ftyp"));
36}
37
38#[async_trait::async_trait]
39impl BoxRead for Ftyp {
40    async fn read<R: ReadMp4>(header: BoxHeader, reader: &mut R) -> Result<Self, MP4Error> {
41        let start = reader.seek(SeekFrom::Current(0)).await?;
42        let size = header.size_minus_self();
43        let major_brand = reader.read().await?;
44        let minor_version = reader.read().await?;
45        let mut compatible_brands = vec![];
46        while !size.ended(start, reader).await? {
47            compatible_brands.push(reader.read().await?);
48        }
49        Ok(Self {
50            major_brand,
51            minor_version,
52            compatible_brands
53        })
54    }
55}
56
57impl BoxWrite for Ftyp {
58
59    fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
60        let mut count = 0;
61        count += self.header().write(writer)?;
62        count += self.major_brand.write(writer)?;
63        count += self.minor_version.write(writer)?;
64        count += self.compatible_brands.write(writer)?;
65        Ok(count)
66    }
67}