Skip to main content

mp4_edit/atom/container/
stbl.rs

1use std::fmt::Debug;
2
3use crate::atom::atom_ref::{self, unwrap_atom_data};
4use crate::FourCC;
5use crate::{
6    atom::{
7        stco_co64::{ChunkOffsetAtom, STCO},
8        stsc::{SampleToChunkAtom, STSC},
9        stsd::{SampleDescriptionTableAtom, STSD},
10        stsz::{SampleSizeAtom, STSZ},
11        stts::{TimeToSampleAtom, STTS},
12    },
13    Atom, AtomData,
14};
15
16pub const STBL: FourCC = FourCC::new(b"stbl");
17
18#[derive(Debug)]
19pub struct StblAtomRef<'a>(pub(crate) atom_ref::AtomRef<'a>);
20
21impl<'a> StblAtomRef<'a> {
22    pub fn children(&self) -> impl Iterator<Item = &'a Atom> {
23        self.0.children()
24    }
25
26    /// Finds the STSD atom
27    pub fn sample_description(&self) -> Option<&'a SampleDescriptionTableAtom> {
28        let atom = self.0.find_child(STSD)?;
29        match atom.data.as_ref()? {
30            AtomData::SampleDescriptionTable(data) => Some(data),
31            _ => None,
32        }
33    }
34
35    /// Finds the STTS atom
36    pub fn time_to_sample(&self) -> Option<&'a TimeToSampleAtom> {
37        let atom = self.0.find_child(STTS)?;
38        match atom.data.as_ref()? {
39            AtomData::TimeToSample(data) => Some(data),
40            _ => None,
41        }
42    }
43
44    /// Finds the STSC atom
45    pub fn sample_to_chunk(&self) -> Option<&'a SampleToChunkAtom> {
46        let atom = self.0.find_child(STSC)?;
47        match atom.data.as_ref()? {
48            AtomData::SampleToChunk(data) => Some(data),
49            _ => None,
50        }
51    }
52
53    /// Finds the STSZ atom
54    pub fn sample_size(&self) -> Option<&'a SampleSizeAtom> {
55        let atom = self.0.find_child(STSZ)?;
56        match atom.data.as_ref()? {
57            AtomData::SampleSize(data) => Some(data),
58            _ => None,
59        }
60    }
61
62    /// Finds the STCO atom
63    pub fn chunk_offset(&self) -> Option<&'a ChunkOffsetAtom> {
64        let atom = self.0.find_child(STCO)?;
65        match atom.data.as_ref()? {
66            AtomData::ChunkOffset(data) => Some(data),
67            _ => None,
68        }
69    }
70}
71
72#[derive(Debug)]
73pub struct StblAtomRefMut<'a>(pub(crate) atom_ref::AtomRefMut<'a>);
74
75impl<'a> StblAtomRefMut<'a> {
76    pub fn as_ref(&self) -> StblAtomRef<'_> {
77        StblAtomRef(self.0.as_ref())
78    }
79
80    pub fn into_ref(self) -> StblAtomRef<'a> {
81        StblAtomRef(self.0.into_ref())
82    }
83
84    pub fn into_children(self) -> impl Iterator<Item = &'a mut Atom> {
85        self.0.into_children()
86    }
87
88    /// Finds or inserts the STSD atom
89    pub fn sample_description(&mut self) -> &'_ mut SampleDescriptionTableAtom {
90        unwrap_atom_data!(
91            self.0
92                .find_or_insert_child(STSD)
93                .insert_data(AtomData::SampleDescriptionTable(
94                    SampleDescriptionTableAtom::default(),
95                ))
96                .call(),
97            AtomData::SampleDescriptionTable,
98        )
99    }
100
101    /// Finds or inserts the STTS atom
102    pub fn time_to_sample(&mut self) -> &mut TimeToSampleAtom {
103        unwrap_atom_data!(
104            self.0
105                .find_or_insert_child(STTS)
106                .insert_after(vec![STTS, STSD])
107                .insert_data(AtomData::TimeToSample(TimeToSampleAtom::default()))
108                .call(),
109            AtomData::TimeToSample,
110        )
111    }
112
113    /// Finds or inserts the STSC atom
114    pub fn sample_to_chunk(&mut self) -> &mut SampleToChunkAtom {
115        unwrap_atom_data!(
116            self.0
117                .find_or_insert_child(STSC)
118                .insert_after(vec![STTS, STSD])
119                .insert_data(AtomData::SampleToChunk(SampleToChunkAtom::default()))
120                .call(),
121            AtomData::SampleToChunk,
122        )
123    }
124
125    /// Finds or inserts the STSZ atom
126    pub fn sample_size(&mut self) -> &mut SampleSizeAtom {
127        unwrap_atom_data!(
128            self.0
129                .find_or_insert_child(STSZ)
130                .insert_after(vec![STSC, STSD])
131                .insert_data(AtomData::SampleSize(SampleSizeAtom::default()))
132                .call(),
133            AtomData::SampleSize,
134        )
135    }
136
137    /// Finds or inserts the STCO atom
138    pub fn chunk_offset(&mut self) -> &mut ChunkOffsetAtom {
139        unwrap_atom_data!(
140            self.0
141                .find_or_insert_child(STCO)
142                .insert_after(vec![STSZ, STSD])
143                .insert_data(AtomData::ChunkOffset(ChunkOffsetAtom::default()))
144                .call(),
145            AtomData::ChunkOffset,
146        )
147    }
148}