Skip to main content

vsd_mp4/boxes/
schm.rs

1use crate::{ParsedBox, Result};
2
3/// Scheme Type Box (schm) - identifies the protection scheme.
4///
5/// The Scheme Type Box is used to identify the protection scheme applied to the track.
6/// Key scheme types include:
7/// - `cenc` (0x63656E63) - AES-CTR full sample encryption
8/// - `cens` (0x63656E73) - AES-CTR subsample pattern encryption
9/// - `cbc1` (0x63626331) - AES-CBC full sample encryption
10/// - `cbcs` (0x63626373) - AES-CBC pattern encryption
11#[derive(Debug, Clone)]
12pub struct SchmBox {
13    /// The scheme type as a 4-byte code (e.g., 'cenc', 'cbcs').
14    pub scheme_type: u32,
15    /// The version of the scheme.
16    pub scheme_version: u32,
17    /// An optional URI providing details on the protection scheme.
18    pub scheme_uri: Option<String>,
19}
20
21impl SchmBox {
22    /// Parses a `schm` box from a `ParsedBox`.
23    ///
24    /// This method parses the scheme type, version, and optional URI if the
25    /// appropriate flag is set.
26    pub fn new(box_: &mut ParsedBox) -> Result<Self> {
27        let reader = &mut box_.reader;
28        let flags = box_.flags.unwrap_or(0);
29
30        let scheme_type = reader.read_u32()?;
31        let scheme_version = reader.read_u32()?;
32
33        // If flags indicate scheme_uri is present (flag 0x000001)
34        let scheme_uri = if flags & 0x000001 != 0 {
35            let remaining = (reader.get_length() - reader.get_position()) as usize;
36            if remaining > 0 {
37                let bytes = reader.read_bytes_u8(remaining)?;
38                let s = String::from_utf8_lossy(&bytes);
39                Some(s.trim_end_matches('\0').to_string())
40            } else {
41                None
42            }
43        } else {
44            None
45        };
46
47        Ok(Self {
48            scheme_type,
49            scheme_version,
50            scheme_uri,
51        })
52    }
53}