isobmff/boxes/
post_decoder_requirements.rs

1use std::io;
2
3use scuffle_bytes_util::zero_copy::{Deserialize, DeserializeSeed, Serialize, ZeroCopyReader};
4use scuffle_bytes_util::{BytesCow, IoResultExt};
5
6use super::{OriginalFormatBox, SchemeInformationBox, SchemeTypeBox};
7use crate::{BoxHeader, FullBoxHeader, IsoBox, UnknownBox, Utf8String};
8
9/// Restricted scheme information box
10///
11/// ISO/IEC 14496-12 - 8.15.3
12#[derive(IsoBox, Debug, PartialEq, Eq)]
13#[iso_box(box_type = b"rinf", crate_path = crate)]
14pub struct RestrictedSchemeInfoBox<'a> {
15    /// The contained [`OriginalFormatBox`]. (mandatory)
16    #[iso_box(nested_box)]
17    pub original_format: OriginalFormatBox,
18    /// The contained [`SchemeTypeBox`]. (mandatory)
19    #[iso_box(nested_box)]
20    pub scheme_type: SchemeTypeBox,
21    /// The contained [`SchemeInformationBox`]. (optional)
22    #[iso_box(nested_box(collect))]
23    pub info: Option<SchemeInformationBox<'a>>,
24    /// The contained [`CompatibleSchemeTypeBox`]es. (any quantity)
25    #[iso_box(nested_box(collect))]
26    pub csch: Vec<CompatibleSchemeTypeBox>,
27}
28
29/// Stereo video box
30///
31/// ISO/IEC 14496-12 - 8.15.4.2
32#[derive(IsoBox, Debug, PartialEq, Eq)]
33#[iso_box(box_type = b"stvi", skip_impl(deserialize_seed), crate_path = crate)]
34pub struct StereoVideoBox<'a> {
35    /// The full box header.
36    pub full_header: FullBoxHeader,
37    /// An integer. A zero value indicates that the content may only be displayed on
38    /// stereoscopic displays. When (`single_view_allowed` & 1) is equal to 1, it is allowed to display the
39    /// right view on a monoscopic single-view display. When (`single_view_allowed` & 2) is equal to 2, it is
40    /// allowed to display the left view on a monoscopic single-view display.
41    pub single_view_allowed: u8,
42    /// An integer that indicates the stereo arrangement scheme used and the stereo
43    /// indication type according to the used scheme.
44    /// The following values for `stereo_scheme` are specified:
45    ///
46    /// - `1`: The frame packing scheme as specified by the Frame packing arrangement Supplemental
47    ///   Enhancement Information message of ISO/IEC 14496-10:2014.
48    /// - `2`: The stereo scheme as specified in ISO/IEC 23000-11 for both frame/service compatible and
49    ///   2D/3D mixed services.
50    /// - `3`: The arrangement type scheme as specified in ISO/IEC 13818-2:2013, Annex D
51    ///   a value of `VideoFramePackingType` as defined in ISO/IEC 23091-2.
52    ///
53    /// Other values of stereo_scheme are reserved.
54    pub stereo_scheme: u32,
55    /// Indicates the number of bytes for the `stereo_indication_type` field.
56    pub length: u32,
57    /// Indicates the stereo arrangement type according to the used stereo indication
58    /// scheme. The syntax and semantics of `stereo_indication_type` depend on the value of `stereo_scheme`.
59    /// The syntax and semantics for stereo_indication_type for the following values of stereo_
60    /// scheme are specified as follows:
61    ///
62    /// - `stereo_scheme` equal to 1: The value of length shall be 4 and `stereo_indication_type` shall
63    ///   be `unsigned int(32)` which contains the `frame_packing_arrangement_type` value from
64    ///   ISO/IEC 14496-10:2014, Table D.8 ('Definition of frame_packing_arrangement_type').
65    /// - `stereo_scheme` equal to 2: The value of length shall be 4 and `stereo_indication_type` shall be
66    ///   `unsigned int(32)` which contains the type value from ISO/IEC 13818-2:2013, Table D.1
67    ///   ('Definition of arrangement_type').
68    /// - `stereo_scheme` equal to 3: The value of length shall be 2 and `stereo_indication_type` shall
69    ///   contain two syntax elements of `unsigned int(8)`. The first syntax element shall contain the
70    ///   stereoscopic composition type from ISO/IEC 23000-11:2009, Table 4. The least significant
71    ///   bit of the second syntax element shall contain the value of `is_left_first` as specified in
72    ///   ISO/IEC 23000-11:2009, subclause 8.4.3, while the other bits are reserved and shall be set
73    ///   to 0.
74    /// - `stereo_scheme` equal to 4: The value of length shall be 2 and `stereo_indication_type` shall
75    ///   contain two syntax elements of `unsigned int(8)`. The first syntax element shall contain a
76    ///   `VideoFramePackingType` from ISO/IEC 23091-2. The least significant bit of the second syntax
77    ///   element shall contain the value of `QuincunxSamplingFlag` as specified in ISO/IEC 23091-2,
78    ///   while the other bits are reserved and shall be set to 0. `PackedContentInterpretationType`
79    ///   specified in ISO/IEC 23091-2 is inferred to be equal to 1.
80    /// - `stereo_scheme` equal to 5: The value of length shall be 3 and `stereo_indication_type` shall contain
81    ///   three syntax elements of type `unsigned int(8)`. The first syntax element shall contain a
82    ///   `VideoFramePackingType` from ISO/IEC 23091-2. The least significant bit of the second syntax
83    ///   element shall contain the value of `QuincunxSamplingFlag` as specified in ISO/IEC 23091-2,
84    ///   while the other bits are reserved and shall be set to 0. The third syntax element shall contain
85    ///   the `PackedContentInterpretationType` from ISO/IEC 23091-2.
86    pub stereo_indication_type: BytesCow<'a>,
87    /// Any other contained boxes.
88    #[iso_box(nested_box(collect_unknown))]
89    pub any_box: Vec<UnknownBox<'a>>,
90}
91
92impl<'a> DeserializeSeed<'a, BoxHeader> for StereoVideoBox<'a> {
93    fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> io::Result<Self>
94    where
95        R: ZeroCopyReader<'a>,
96    {
97        let full_header = FullBoxHeader::deserialize(&mut reader)?;
98
99        let single_view_allowed = u32::deserialize(&mut reader)?;
100        let single_view_allowed = (single_view_allowed & 0b11) as u8;
101        let stereo_scheme = u32::deserialize(&mut reader)?;
102
103        let length = u32::deserialize(&mut reader)?;
104        let stereo_indication_type = reader.try_read(length as usize)?;
105
106        let mut any_box = Vec::new();
107        loop {
108            let Some(box_header) = BoxHeader::deserialize(&mut reader).eof_to_none()? else {
109                break;
110            };
111            let Some(unknown_box) = UnknownBox::deserialize_seed(&mut reader, box_header).eof_to_none()? else {
112                break;
113            };
114            any_box.push(unknown_box);
115        }
116
117        Ok(Self {
118            full_header,
119            single_view_allowed,
120            stereo_scheme,
121            length,
122            stereo_indication_type,
123            any_box,
124        })
125    }
126}
127
128/// Compatible scheme type box
129///
130/// ISO/IEC 14496-12 - 8.15.5
131#[derive(IsoBox, Debug, PartialEq, Eq)]
132#[iso_box(box_type = b"csch", skip_impl(deserialize_seed, serialize), crate_path = crate)]
133pub struct CompatibleSchemeTypeBox {
134    /// The full box header.
135    pub full_header: FullBoxHeader,
136    /// The code defining the protection or restriction scheme, normally expressed as a four character code.
137    pub scheme_type: [u8; 4],
138    /// The version of the scheme (used to create the content).
139    pub scheme_version: u32,
140    /// An absolute URI allowing for the option of directing the user to a web-page if they do not
141    /// have the scheme installed on their system.
142    pub scheme_uri: Option<Utf8String>,
143}
144
145impl<'a> DeserializeSeed<'a, BoxHeader> for CompatibleSchemeTypeBox {
146    fn deserialize_seed<R>(mut reader: R, _seed: BoxHeader) -> io::Result<Self>
147    where
148        R: ZeroCopyReader<'a>,
149    {
150        let full_header = FullBoxHeader::deserialize(&mut reader)?;
151
152        let scheme_type = <[u8; 4]>::deserialize(&mut reader)?;
153        let scheme_version = u32::deserialize(&mut reader)?;
154        let scheme_uri = if (*full_header.flags & 0x000001) != 0 {
155            Some(Utf8String::deserialize(&mut reader)?)
156        } else {
157            None
158        };
159
160        Ok(Self {
161            full_header,
162            scheme_type,
163            scheme_version,
164            scheme_uri,
165        })
166    }
167}
168
169impl Serialize for CompatibleSchemeTypeBox {
170    fn serialize<W>(&self, mut writer: W) -> io::Result<()>
171    where
172        W: std::io::Write,
173    {
174        self.serialize_box_header(&mut writer)?;
175        self.full_header.serialize(&mut writer)?;
176
177        self.scheme_type.serialize(&mut writer)?;
178        self.scheme_version.serialize(&mut writer)?;
179
180        if (*self.full_header.flags & 0x000001) != 0 {
181            self.scheme_uri
182                .as_ref()
183                .ok_or(io::Error::new(io::ErrorKind::InvalidData, "scheme_uri is required"))?
184                .serialize(&mut writer)?;
185        }
186
187        Ok(())
188    }
189}