isobmff/boxes/
sample_table.rs

1use std::io;
2
3use scuffle_bytes_util::zero_copy::{Deserialize, Serialize, ZeroCopyReader};
4
5use super::{
6    ChunkLargeOffsetBox, ChunkOffsetBox, CompactSampleSizeBox, CompactSampleToGroupBox, CompositionOffsetBox,
7    CompositionToDecodeBox, PaddingBitsBox, SampleAuxiliaryInformationOffsetsBox, SampleAuxiliaryInformationSizesBox,
8    SampleDependencyTypeBox, SampleGroupDescriptionBox, SampleSizeBox, SampleToChunkBox, SampleToGroupBox,
9    ShadowSyncSampleBox, SubSampleInformationBox, SyncSampleBox, TimeToSampleBox,
10};
11use crate::{FullBoxHeader, IsoBox, IsoSized, UnknownBox};
12
13/// Sample table box
14///
15/// ISO/IEC 14496-12 - 8.5.1
16#[derive(IsoBox, Debug, PartialEq, Eq)]
17#[iso_box(box_type = b"stbl", crate_path = crate)]
18pub struct SampleTableBox<'a> {
19    /// The contained [`SampleDescriptionBox`]. (mandatory)
20    #[iso_box(nested_box)]
21    pub stsd: SampleDescriptionBox<'a>,
22    /// The contained [`TimeToSampleBox`]. (mandatory)
23    #[iso_box(nested_box)]
24    pub stts: TimeToSampleBox,
25    /// The contained [`CompositionOffsetBox`]. (optional)
26    #[iso_box(nested_box(collect))]
27    pub ctts: Option<CompositionOffsetBox>,
28    /// The contained [`CompositionToDecodeBox`]. (optional)
29    #[iso_box(nested_box(collect))]
30    pub cslg: Option<CompositionToDecodeBox>,
31    /// The contained [`SampleToChunkBox`]. (mandatory)
32    #[iso_box(nested_box)]
33    pub stsc: SampleToChunkBox,
34    /// The contained [`SampleSizeBox`].
35    ///
36    /// One of [`stsz`](Self::stsz) or [`stz2`](Self::stz2) must be present.
37    #[iso_box(nested_box(collect))]
38    pub stsz: Option<SampleSizeBox>,
39    /// The contained [`CompactSampleSizeBox`].
40    ///
41    /// One of [`stsz`](Self::stsz) or [`stz2`](Self::stz2) must be present.
42    #[iso_box(nested_box(collect))]
43    pub stz2: Option<CompactSampleSizeBox<'a>>,
44    /// The contained [`ChunkOffsetBox`].
45    ///
46    /// One of [`stco`](Self::stco) or [`co64`](Self::co64) must be present
47    #[iso_box(nested_box(collect))]
48    pub stco: Option<ChunkOffsetBox>,
49    /// The contained [`ChunkLargeOffsetBox`].
50    ///
51    /// One of [`stco`](Self::stco) or [`co64`](Self::co64) must be present
52    #[iso_box(nested_box(collect))]
53    pub co64: Option<ChunkLargeOffsetBox>,
54    /// The contained [`SyncSampleBox`]. (optional)
55    #[iso_box(nested_box(collect))]
56    pub stss: Option<SyncSampleBox>,
57    /// The contained [`ShadowSyncSampleBox`]. (optional)
58    #[iso_box(nested_box(collect))]
59    pub stsh: Option<ShadowSyncSampleBox>,
60    /// The contained [`PaddingBitsBox`]. (optional)
61    #[iso_box(nested_box(collect))]
62    pub padb: Option<PaddingBitsBox>,
63    /// The contained [`DegradationPriorityBox`]. (optional)
64    #[iso_box(nested_box(collect))]
65    pub stdp: Option<DegradationPriorityBox>,
66    /// The contained [`SampleDependencyTypeBox`]. (optional)
67    #[iso_box(nested_box(collect))]
68    pub sdtp: Option<SampleDependencyTypeBox>,
69    /// The contained [`SampleToGroupBox`]. (optional)
70    #[iso_box(nested_box(collect))]
71    pub sbgp: Vec<SampleToGroupBox>,
72    /// The contained [`SampleGroupDescriptionBox`]. (optional)
73    #[iso_box(nested_box(collect))]
74    pub sgpd: Vec<SampleGroupDescriptionBox<'a>>,
75    /// The contained [`SubSampleInformationBox`]. (optional)
76    #[iso_box(nested_box(collect))]
77    pub subs: Vec<SubSampleInformationBox>,
78    /// The contained [`SampleAuxiliaryInformationSizesBox`]. (optional)
79    #[iso_box(nested_box(collect))]
80    pub saiz: Vec<SampleAuxiliaryInformationSizesBox<'a>>,
81    /// The contained [`SampleAuxiliaryInformationOffsetsBox`]. (optional)
82    #[iso_box(nested_box(collect))]
83    pub saio: Vec<SampleAuxiliaryInformationOffsetsBox>,
84    /// The contained [`CompactSampleToGroupBox`]. (optional)
85    #[iso_box(nested_box(collect))]
86    pub csgp: Vec<CompactSampleToGroupBox>,
87}
88
89impl<'a> SampleTableBox<'a> {
90    /// Creates a new [`SampleTableBox`] with the mandatory boxes and optional boxes set to `None`.
91    pub fn new(
92        stsd: SampleDescriptionBox<'a>,
93        stts: TimeToSampleBox,
94        stsc: SampleToChunkBox,
95        stsz: Option<SampleSizeBox>,
96        stco: ChunkOffsetBox,
97    ) -> Self {
98        Self {
99            stsd,
100            stts,
101            ctts: None,
102            cslg: None,
103            stsc,
104            stsz,
105            stz2: None,
106            stco: Some(stco),
107            co64: None,
108            stss: None,
109            stsh: None,
110            padb: None,
111            stdp: None,
112            sdtp: None,
113            sbgp: vec![],
114            sgpd: vec![],
115            subs: vec![],
116            saiz: vec![],
117            saio: vec![],
118            csgp: vec![],
119        }
120    }
121}
122
123/// Sample entry
124///
125/// ISO/IEC 14496-12 - 8.5.2
126///
127/// Sub boxes:
128/// - [`btrt`](BitRateBox)
129#[derive(Debug, PartialEq, Eq)]
130pub struct SampleEntry {
131    /// Reserved 6 bytes, must be zero.
132    pub reserved: [u8; 6],
133    /// An integer that contains the index of the `DataEntry` to use to retrieve
134    /// data associated with samples that use this sample description. Data entries are stored in
135    /// [`DataReferenceBox`](super::DataReferenceBox)es. The index ranges from 1 to the number of data entries.
136    pub data_reference_index: u16,
137}
138
139impl Default for SampleEntry {
140    fn default() -> Self {
141        Self {
142            reserved: [0; 6],
143            data_reference_index: 1,
144        }
145    }
146}
147
148impl<'a> Deserialize<'a> for SampleEntry {
149    fn deserialize<R>(mut reader: R) -> io::Result<Self>
150    where
151        R: ZeroCopyReader<'a>,
152    {
153        let reserved = <[u8; 6]>::deserialize(&mut reader)?;
154        let data_reference_index = u16::deserialize(&mut reader)?;
155
156        Ok(Self {
157            reserved,
158            data_reference_index,
159        })
160    }
161}
162
163impl Serialize for SampleEntry {
164    fn serialize<W>(&self, mut writer: W) -> io::Result<()>
165    where
166        W: std::io::Write,
167    {
168        self.reserved.serialize(&mut writer)?;
169        self.data_reference_index.serialize(&mut writer)?;
170        Ok(())
171    }
172}
173
174impl IsoSized for SampleEntry {
175    fn size(&self) -> usize {
176        self.reserved.size() + self.data_reference_index.size()
177    }
178}
179
180/// BitRateBox
181///
182/// ISO/IEC 14496-12 - 8.5.2
183#[derive(IsoBox, Debug, PartialEq, Eq)]
184#[iso_box(box_type = b"btrt", crate_path = crate)]
185pub struct BitRateBox {
186    /// Gives the size of the decoding buffer for the elementary stream in bytes.
187    pub buffer_size_db: u32,
188    /// Gives the maximum rate in bits/second over any window of one second; this is a measured
189    /// value for stored content, or a value that a stream is configured not to exceed; the stream shall not
190    /// exceed this bitrate.
191    pub max_bitrate: u32,
192    /// Gives the average rate in bits/second of the stream; this is a measured value (cumulative
193    /// over the entire presentation) for stored content, or the configured target average bitrate for a
194    /// stream.
195    pub avg_bitrate: u32,
196}
197
198/// Sample description box
199///
200/// ISO/IEC 14496-12 - 8.5.2
201#[derive(IsoBox, Debug, PartialEq, Eq)]
202#[iso_box(box_type = b"stsd", crate_path = crate)]
203pub struct SampleDescriptionBox<'a> {
204    /// The full box header.
205    pub full_header: FullBoxHeader,
206    /// An integer that gives the number of entries in the [`boxes`](Self::boxes) vec.
207    pub entry_count: u32,
208    /// The contained boxes, which can be any sample entry box.
209    #[iso_box(nested_box(collect_unknown))]
210    pub boxes: Vec<UnknownBox<'a>>,
211}
212
213impl<'a> SampleDescriptionBox<'a> {
214    /// Creates a new [`SampleDescriptionBox`] with the given sample entry boxes.
215    pub fn new(boxes: Vec<UnknownBox<'a>>) -> Self {
216        Self {
217            full_header: FullBoxHeader::default(),
218            entry_count: boxes.len() as u32,
219            boxes,
220        }
221    }
222}
223
224/// Degradation priority box
225///
226/// ISO/IEC 14496-12 - 8.5.3
227#[derive(IsoBox, Debug, PartialEq, Eq)]
228#[iso_box(box_type = b"stdp", crate_path = crate)]
229pub struct DegradationPriorityBox {
230    /// The full box header.
231    pub full_header: FullBoxHeader,
232    /// An integer specifying the degradation priority for each sample.
233    #[iso_box(repeated)]
234    pub priority: Vec<u16>,
235}