async_mp4/mp4box/
box_root.rs1use async_trait::async_trait;
2use std::io::SeekFrom;
3use std::ops::{Deref, DerefMut};
4use futures::AsyncSeekExt;
5use crate::bytes_read::ReadMp4;
6use crate::bytes_write::{Mp4Writable, WriteMp4};
7use crate::error::MalformedBoxError::{ReadingWrongBox, UnknownSizeForUnknownBox};
8use crate::error::MP4Error;
9use crate::header::BoxHeader;
10use crate::mp4box::box_trait::{BoxRead, BoxWrite, IBox, PartialBox, PartialBoxRead, PartialBoxWrite};
11use crate::r#type::BoxType;
12use crate::size::BoxSize::Known;
13
14#[derive(Debug, Clone, Default, Eq, PartialEq, Hash)]
15pub struct MP4Box<P>
16 where
17 P: PartialBox<ParentData=()>
18{
19 pub inner: P,
20}
21
22impl<P> From<P> for MP4Box<P> where
23 P: PartialBox<ParentData=()>
24{
25 fn from(inner: P) -> Self {
26 Self{inner}
27 }
28}
29
30impl<P> MP4Box<P>
31 where
32 P: PartialBox<ParentData=()>
33{
34 fn header(&self) -> BoxHeader {
35 BoxHeader::from_id_and_inner_size(P::ID, self.inner.byte_size())
36 }
37}
38
39impl<P> BoxWrite for MP4Box<P>
40 where
41 P: PartialBox<ParentData=()> + PartialBoxWrite + Send + Sync,
42{
43 fn write<W: WriteMp4>(&self, writer: &mut W) -> Result<usize, MP4Error> {
44 let mut count = 0;
45 count += self.header().write(writer)?;
46 count += self.inner.write_data(writer)?;
47 count += self.inner.write_children(writer)?;
48 debug_assert!(count == self.byte_size(), "Byte Size is not equal to written size");
49 Ok(count)
50 }
51}
52
53impl<P> IBox for MP4Box<P>
54 where
55 P: PartialBox<ParentData=()>
56{
57 fn byte_size(&self) -> usize {
58 self.header().byte_size() + self.inner.byte_size()
59 }
60
61 const ID: BoxType = P::ID;
62}
63
64#[async_trait]
65impl<P> BoxRead for MP4Box<P>
66 where
67 P: PartialBox<ParentData=()> + PartialBoxRead + Send + Sync,
68{
69 async fn read<R: ReadMp4>(header: BoxHeader, reader: &mut R) -> Result<Self, MP4Error> {
70 let actual = header.id;
71 let target = Self::ID;
72 if actual != target {
73 return Err(ReadingWrongBox {actual, target}.into())
74 }
75 let start = reader.seek(SeekFrom::Current(0)).await? - header.byte_size() as u64;
76 let size = header.size;
77 let mut inner = P::read_data((), reader).await?;
78 while !size.ended(start, reader).await? {
79 let header: BoxHeader = reader.read().await?;
80 let pos = reader.seek(SeekFrom::Current(0)).await?;
81 let size = header.size_minus_self();
82 inner.read_child(header, reader).await?;
83 if let Known(size) = size { reader.seek(SeekFrom::Start(pos + size as u64)).await?;
85 } else {
86 return Err(UnknownSizeForUnknownBox.into());
87 }
88 }
89 Ok(Self { inner })
90 }
91}
92
93impl<P> Deref for MP4Box<P>
94 where
95 P: PartialBox<ParentData=()>
96{
97 type Target = P;
98
99 fn deref(&self) -> &Self::Target {
100 &self.inner
101 }
102}
103
104impl<P> DerefMut for MP4Box<P>
105 where
106 P: PartialBox<ParentData=()>
107{
108 fn deref_mut (&mut self) -> &mut Self::Target {
109 &mut self.inner
110 }
111}